1
0
Fork 0
mirror of synced 2024-06-26 18:20:43 +12:00

fix(ui): add basic pagination with after and enum attributes

This commit is contained in:
Torsten Dittmann 2021-10-29 14:01:48 +02:00
parent 620333a8d2
commit b8936c7674
5 changed files with 200 additions and 82 deletions

View file

@ -42,9 +42,9 @@ $logs = $this->getParam('logs', null);
data-service="database.listDocuments"
data-event="load,database.createDocument,database.updateDocument,database.deleteDocument"
data-param-collection-id="{{router.params.id}}"
data-param-search="{{router.params.search}}"
data-param-cursor="{{router.params.cursor}}"
data-param-cursor-direction="{{router.params.cursorDirection}}"
data-param-limit="<?php echo APP_PAGING_LIMIT; ?>"
data-param-offset="{{router.params.offset}}"
data-param-order-types="DESC"
data-param-order-types-cast-to="array"
data-scope="sdk"
@ -57,7 +57,7 @@ $logs = $this->getParam('logs', null);
</div>
<div data-ls-if="({{project-documents.sum}})" class="margin-top-negative">
<div class="margin-bottom-small text-align-end text-size-small text-fade"><span data-ls-bind="{{project-documents.sum}}"></span> documents found</div>
<div class="margin-bottom-small text-align-end text-size-small text-fade"><span data-ls-bind="{{project-documents.sum}}"></span><span data-ls-if="{{project-documents.sum}} == <?php echo APP_LIMIT_COUNT; ?>">+</span> documents found</div>
<div class="box margin-bottom y-scroll text-size-small">
<table class="vertical borders">
@ -76,7 +76,7 @@ $logs = $this->getParam('logs', null);
<tr data-ls-loop="project-collection.attributes" data-ls-as="attribute" data-ls-prefix="template-attribute-body-first" data-ls-limit="20">
<td data-ls-if="{{attribute.status}} === 'available'" data-ls-attrs="data-title={{attribute.key}}">
<!-- <a href="" target="_blank" rel="noopener" class="pull-end margin-start"><i class="icon-link-ext"></i></a> -->
<a data-ls-attrs="href=/console/database/document?id={{node.$id}}&collection={{router.params.id}}&project={{router.params.project}}"><span data-ls-bind="{{node|documentAttribute}}"></span></a>
<a data-ls-attrs="href=/console/database/document?id={{node.$id}}&collection={{node.$collection}}&project={{router.params.project}}"><span data-ls-bind="{{node|documentAttribute}}"></span></a>
<span data-ls-if="!{{node|documentAttribute}}" class="text-fade">n/a</span>
</td>
</tr>
@ -85,37 +85,38 @@ $logs = $this->getParam('logs', null);
</div>
</div>
<div class="pull-end text-align-center paging">
<div
data-ls-if="0 != {{project-documents.sum}}"
class="pull-end text-align-center paging">
<form
data-service="database.listDocuments"
data-event="submit"
data-param-collection-id="{{router.params.id}}"
data-param-search="{{router.params.search}}"
data-param-limit="<?php echo APP_PAGING_LIMIT; ?>"
data-param-order-types="DESC"
data-param-order-types-cast-to="array"
data-scope="sdk"
data-name="project-documents"
data-success="state"
data-success-param-state-keys="search,offset">
<button name="offset" data-paging-back data-offset="{{router.params.offset}}" data-sum="{{project-documents.sum}}" class="margin-end round small" aria-label="Back"><i class="icon-left-open"></i></button>
data-success-param-state-keys="cursor,cursorDirection">
<input type="hidden" name="cursorDirection" value="before">
<button name="cursor" data-ls-bind="{{project-documents.documents|first}}" class="margin-end round small" aria-label="Back"><i class="icon-left-open"></i></button>
</form>
<span data-ls-bind="{{router.params.offset|pageCurrent}} / {{project-documents.sum|pageTotal}}"></span>
<form
data-ls-if="<?php echo APP_PAGING_LIMIT; ?> == {{project-documents.documents.length}}"
data-service="database.listDocuments"
data-event="submit"
data-param-collection-id="{{router.params.id}}"
data-param-search="{{router.params.search}}"
data-param-limit="<?php echo APP_PAGING_LIMIT; ?>"
data-param-order-types="DESC"
data-param-order-types-cast-to="array"
data-scope="sdk"
data-name="project-documents"
data-success="state"
data-success-param-state-keys="search,offset">
<button name="offset" data-paging-next data-offset="{{router.params.offset}}" data-sum="{{project-documents.sum}}" class="margin-start round small" aria-label="Next"><i class="icon-right-open"></i></button>
data-success-param-state-keys="cursor,cursorDirection">
<input type="hidden" name="cursorDirection" value="after">
<button name="cursor" data-ls-bind="{{project-documents.documents|last}}" class="margin-start round small" aria-label="Next"><i class="icon-right-open"></i></button>
</form>
</div>
@ -237,6 +238,9 @@ $logs = $this->getParam('logs', null);
<li>
<div class="link new-attribute-ip"><i class="avatar icon-ip"></i> New IP Attribute</div>
</li>
<li>
<div class="link new-attribute-enum"><i class="avatar icon-string"></i> New Enum Attribute</div>
</li>
</ul>
</div>
</li>
@ -1107,6 +1111,100 @@ $logs = $this->getParam('logs', null);
</script>
</div>
<div data-ui-modal class="modal box close sticky-footer" data-button-alias=".new-attribute-enum">
<button type="button" class="close pull-end" data-ui-modal-close=""><i class="icon-cancel"></i></button>
<h1>Add Enum Attribute</h1>
<form
id="add-enum-attribute"
data-analytics
data-analytics-activity
data-analytics-event="submit"
data-analytics-category="console"
data-analytics-label="Create Collection Attribute (enum)"
data-service="database.createEnumAttribute"
data-scope="sdk"
data-event="submit"
data-success="alert,trigger,reset"
data-success-param-alert-text="Created new attribute successfully"
data-success-param-trigger-events="database.createAttribute"
data-failure="alert"
data-failure-param-alert-text="Failed to create attribute"
data-failure-param-alert-classname="error">
<input type="hidden" name="projectId" data-ls-bind="{{router.params.project}}" />
<input type="hidden" name="collectionId" data-ls-bind="{{router.params.id}}" />
<label for="string-attributeId">Attribute ID</label>
<input type="text" class="full-width" name="attributeId" required autocomplete="off" maxlength="128" />
<label>Elements</label>
<div id="elements-section"></div>
<div class="margin-bottom">
<div data-forms-clone="" data-label="Add Element" data-target="elements-section" data-first="1">
<div class="row responsive thin margin-bottom-tiny">
<div class="col span-11 margin-bottom-small">
<input type="text" class="full-width" name="elements" required autocomplete="off" maxlength="128" />
</div>
<div class="col span-1 margin-bottom-small">
<button type="button" data-remove class="dark danger small round pull-end" style="margin-top: 10px;"><i class="icon-cancel"></i></button>
</div>
</div>
</div>
</div>
<div class="margin-bottom">
<input name="required" type="hidden" data-forms-switch data-cast-to="boolean" /> &nbsp; Required <span class="tooltip" data-tooltip="Mark whether this is a required attribute"><i class="icon-info-circled"></i></span>
</div>
<div class="margin-bottom">
<input name="array" type="hidden" data-forms-switch data-cast-to="boolean" /> &nbsp; Array <span class="tooltip" data-tooltip="Mark whether this attribute should act as an array"><i class="icon-info-circled"></i></span>
</div>
<label for="string-default">Default Value</label>
<input id="string-default" name="xdefault" type="url" pattern="https://.*" title="Valid URL address" class="margin-bottom-large" autocomplete="off">
<footer>
<button type="submit">Create</button> &nbsp; <button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
</footer>
</form>
<script type="text/javascript">
(() => {
const form = document.getElementById("add-url-attribute");
const fields = {
required: {
array: ["disable", "uncheck"],
required: ["enable"]
},
array: {
required: ["disable", "uncheck"],
array: ["enable"]
},
xdefault: {
oneOf: {
if: ["array", "required"],
then: {
xdefault: ["unvalue", "disable"]
},
else: {
required: ["enable"],
array: ["enable"],
xdefault: ["enable"]
}
}
}
};
form.addEventListener('change', event => {
formValidation(form, fields);
});
})();
</script>
</div>
<div data-ui-modal class="modal box close sticky-footer" data-button-alias=".new-index">
<button type="button" class="close pull-end" data-ui-modal-close=""><i class="icon-cancel"></i></button>

View file

@ -92,14 +92,17 @@ $logs = $this->getParam('logs', null);
<div data-ls-if="{{attribute.required}}" class="text-size-xs text-danger text-fade">required</div>
<div data-ls-if="!{{attribute.required}}" class="text-size-xs text-fade">optional</div>
</label>
<div data-ls-if="!{{attribute.array}}" data-ls-template="template-{{attribute.type}}" data-type="script"></div>
<div data-ls-if="!{{attribute.array}}">
<div data-ls-if="{{attribute.format}}" data-ls-template="template-{{attribute.format}}" data-type="script"></div>
<div data-ls-if="!{{attribute.format}}" data-ls-template="template-{{attribute.type}}" data-type="script"></div>
</div>
<div data-ls-if="{{attribute.array}}">
<div data-ls-loop="project-document.{{attribute.key}}" data-ls-as="item" data-ls-attrs="id=attribute-{{attribute.key}}">
<div class="row responsive thin margin-bottom-tiny" data-forms-remove>
<div class="col span-11 margin-bottom-small">
<div data-ls-template="template-{{attribute.type}}-array" data-type="script"></div>
<div dfata-ls-if="{{attribute.typ}}" data-ls-template="template-{{attribute.format}}-array" data-type="script"></div>
<div data-ls-template="template-{{attribute.format}}-array" data-type="script"></div>
</div>
<div class="col span-1 margin-bottom-small">
<button type="button" data-remove class="dark danger small round pull-end" style="margin-top: 10px;"><i class="icon-cancel"></i></button>
@ -112,7 +115,8 @@ $logs = $this->getParam('logs', null);
<div data-forms-clone="" data-label="Add Attribute" data-target="attributes-section-{{attribute.key}}" data-first="0">
<div class="row responsive thin margin-bottom-tiny" data-forms-remove>
<div class="col span-11 margin-bottom-small">
<div data-ls-template="template-{{attribute.type}}-array" data-type="script"></div>
<div data-ls-template="template-{{attribute.format}}-array" data-type="script"></div>
<div data-ls-template="template-{{attribute.format}}-array" data-type="script"></div>
</div>
<div class="col span-1 margin-bottom-small">
<button type="button" data-remove class="dark danger small round pull-end" style="margin-top: 10px;"><i class="icon-cancel"></i></button>
@ -255,4 +259,14 @@ $logs = $this->getParam('logs', null);
<script type="text/html" id="template-ip-array">
<input type="text" data-ls-attrs="placeholder={{attribute.default}},name={{attribute.key}}" data-ls-bind="{{item}}" pattern="((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$))" title="Enter a valid IPV4 or IPV6 address" />
</script>
<script type="text/html" id="template-enum">
<select data-ls-attrs="name=elements" data-ls-loop="attribute.elements" data-ls-as="element" data-cast-to="array">
<option data-ls-attrs="value={{element}}" data-ls-bind="{{element}}"></option>
</select>
</script>
<script type="text/html" id="template-enum-array">
<input type="email" data-ls-attrs="placeholder={{attribute.default}},name={{attribute.key}}" data-ls-bind="{{item}}" />
</script>

View file

@ -2415,7 +2415,7 @@ return'';}).add("runtimeVersion",function($value,env){if(env&&env.RUNTIMES&&env.
return'';}).add("indexAttributes",function($value){let output='';for(let i=0;i<$value.attributes.length;i++){output+=$value.attributes[i]+' ('+$value.orders[i]+'), '}
return output.slice(0,-2);}).add("collectionAttributes",function($value){if(!Array.isArray($value)){return[];}
$value.unshift({$id:'$id'});return $value;}).add("documentAttribute",function($value,attribute){if($value[attribute.key]){return $value[attribute.key];}
return null;}).add("accessProject",function($value,router){return($value&&$value.hasOwnProperty(router.params.project))?$value[router.params.project]:0;});function abbreviate(number,maxPlaces,forcePlaces,forceLetter){number=Number(number);forceLetter=forceLetter||false;if(forceLetter!==false){return annotate(number,maxPlaces,forcePlaces,forceLetter);}
return null;}).add("accessProject",function($value,router){return($value&&$value.hasOwnProperty(router.params.project))?$value[router.params.project]:0;}).add("first",function($value){return $value[0].$id;}).add("last",function($value){return $value[$value.length-1].$id;});function abbreviate(number,maxPlaces,forcePlaces,forceLetter){number=Number(number);forceLetter=forceLetter||false;if(forceLetter!==false){return annotate(number,maxPlaces,forcePlaces,forceLetter);}
let abbr;if(number>=1e12){abbr="T";}else if(number>=1e9){abbr="B";}else if(number>=1e6){abbr="M";}else if(number>=1e3){abbr="K";}else{abbr="";}
return annotate(number,maxPlaces,forcePlaces,abbr);}
function annotate(number,maxPlaces,forcePlaces,abbr){let rounded=0;switch(abbr){case"T":rounded=number/1e12;break;case"B":rounded=number/1e9;break;case"M":rounded=number/1e6;break;case"K":rounded=number/1e3;break;case"":rounded=number;break;}

View file

@ -321,7 +321,7 @@ return'';}).add("runtimeVersion",function($value,env){if(env&&env.RUNTIMES&&env.
return'';}).add("indexAttributes",function($value){let output='';for(let i=0;i<$value.attributes.length;i++){output+=$value.attributes[i]+' ('+$value.orders[i]+'), '}
return output.slice(0,-2);}).add("collectionAttributes",function($value){if(!Array.isArray($value)){return[];}
$value.unshift({$id:'$id'});return $value;}).add("documentAttribute",function($value,attribute){if($value[attribute.key]){return $value[attribute.key];}
return null;}).add("accessProject",function($value,router){return($value&&$value.hasOwnProperty(router.params.project))?$value[router.params.project]:0;});function abbreviate(number,maxPlaces,forcePlaces,forceLetter){number=Number(number);forceLetter=forceLetter||false;if(forceLetter!==false){return annotate(number,maxPlaces,forcePlaces,forceLetter);}
return null;}).add("accessProject",function($value,router){return($value&&$value.hasOwnProperty(router.params.project))?$value[router.params.project]:0;}).add("first",function($value){return $value[0].$id;}).add("last",function($value){return $value[$value.length-1].$id;});function abbreviate(number,maxPlaces,forcePlaces,forceLetter){number=Number(number);forceLetter=forceLetter||false;if(forceLetter!==false){return annotate(number,maxPlaces,forcePlaces,forceLetter);}
let abbr;if(number>=1e12){abbr="T";}else if(number>=1e9){abbr="B";}else if(number>=1e6){abbr="M";}else if(number>=1e3){abbr="K";}else{abbr="";}
return annotate(number,maxPlaces,forcePlaces,abbr);}
function annotate(number,maxPlaces,forcePlaces,abbr){let rounded=0;switch(abbr){case"T":rounded=number/1e12;break;case"B":rounded=number/1e9;break;case"M":rounded=number/1e6;break;case"K":rounded=number/1e3;break;case"":rounded=number;break;}

View file

@ -1,16 +1,16 @@
window.ls.filter
.add("avatar", function($value, element) {
.add("avatar", function ($value, element) {
if (!$value) {
return "";
}
let size = element.dataset["size"] || 80;
let name = $value.name || $value || "";
name = (typeof name !== 'string') ? '--' : name;
return def =
"/v1/avatars/initials?project=console"+
"/v1/avatars/initials?project=console" +
"&name=" +
encodeURIComponent(name) +
"&width=" +
@ -18,26 +18,26 @@ window.ls.filter
"&height=" +
size;
})
.add("selectedCollection", function($value, router) {
.add("selectedCollection", function ($value, router) {
return $value === router.params.collectionId ? "selected" : "";
})
.add("selectedDocument", function($value, router) {
.add("selectedDocument", function ($value, router) {
return $value === router.params.documentId ? "selected" : "";
})
.add("localeString", function($value) {
.add("localeString", function ($value) {
$value = parseInt($value);
return !Number.isNaN($value) ? $value.toLocaleString() : "";
})
.add("date", function($value, date) {
.add("date", function ($value, date) {
return date.format("Y-m-d", $value);
})
.add("dateTime", function($value, date) {
.add("dateTime", function ($value, date) {
return date.format("Y-m-d H:i", $value);
})
.add("dateText", function($value, date) {
.add("dateText", function ($value, date) {
return date.format("d M Y", $value);
})
.add("timeSince", function($value) {
.add("timeSince", function ($value) {
$value = $value * 1000;
let seconds = Math.floor((Date.now() - $value) / 1000);
@ -50,7 +50,7 @@ window.ls.filter
}
let value = seconds;
if (seconds >= 31536000) {
value = Math.floor(seconds / 31536000);
unit = "year";
@ -71,10 +71,10 @@ window.ls.filter
if (value != 1) {
unit = unit + "s";
}
return value + " " + unit + " " + direction;
})
.add("ms2hum", function($value) {
.add("ms2hum", function ($value) {
let temp = $value;
const years = Math.floor(temp / 31536000),
days = Math.floor((temp %= 31536000) / 86400),
@ -95,37 +95,37 @@ window.ls.filter
return "< 1s";
})
.add("seconds2hum", function($value) {
.add("seconds2hum", function ($value) {
var seconds = ($value).toFixed(3);
var seconds = ($value).toFixed(3);
var minutes = ($value / (60)).toFixed(1);
var minutes = ($value / (60)).toFixed(1);
var hours = ($value / (60 * 60)).toFixed(1);
var hours = ($value / (60 * 60)).toFixed(1);
var days = ($value / (60 * 60 * 24)).toFixed(1);
var days = ($value / (60 * 60 * 24)).toFixed(1);
if (seconds < 60) {
return seconds + "s";
} else if (minutes < 60) {
return minutes + "m";
} else if (hours < 24) {
return hours + "h";
} else {
return days + "d"
}
if (seconds < 60) {
return seconds + "s";
} else if (minutes < 60) {
return minutes + "m";
} else if (hours < 24) {
return hours + "h";
} else {
return days + "d"
}
})
.add("markdown", function($value, markdown) {
.add("markdown", function ($value, markdown) {
return markdown.render($value);
})
.add("pageCurrent", function($value, env) {
.add("pageCurrent", function ($value, env) {
return Math.ceil(parseInt($value || 0) / env.PAGING_LIMIT) + 1;
})
.add("pageTotal", function($value, env) {
.add("pageTotal", function ($value, env) {
let total = Math.ceil(parseInt($value || 0) / env.PAGING_LIMIT);
return total ? total : 1;
})
.add("humanFileSize", function($value) {
.add("humanFileSize", function ($value) {
if (!$value) {
return 0;
}
@ -146,7 +146,7 @@ window.ls.filter
return $value.toFixed(1);
})
.add("humanFileUnit", function($value) {
.add("humanFileUnit", function ($value) {
if (!$value) {
return '';
}
@ -167,7 +167,7 @@ window.ls.filter
return units[u];
})
.add("statsTotal", function($value) {
.add("statsTotal", function ($value) {
if (!$value) {
return 0;
}
@ -176,102 +176,102 @@ window.ls.filter
return $value ?? "N/A";
})
.add("statsGetLast", function($value) {
.add("statsGetLast", function ($value) {
if (!$value || $value.length < 1) {
return 0;
}
return $value[$value.length - 1].value;
})
.add("isEmpty", function($value) {
.add("isEmpty", function ($value) {
return (!!$value);
})
.add("isEmptyObject", function($value) {
.add("isEmptyObject", function ($value) {
return ((Object.keys($value).length === 0 && $value.constructor === Object) || $value.length === 0)
})
.add("activeDomainsCount", function($value) {
.add("activeDomainsCount", function ($value) {
let result = [];
if(Array.isArray($value)) {
result = $value.filter(function(node) {
if (Array.isArray($value)) {
result = $value.filter(function (node) {
return (node.verification && node.certificateId);
});
}
return result.length;
})
.add("documentAction", function(container) {
.add("documentAction", function (container) {
let collection = container.get('project-collection');
let document = container.get('project-document');
if(collection && document && !document.$id) {
if (collection && document && !document.$id) {
return 'database.createDocument';
}
return 'database.updateDocument';
})
.add("documentSuccess", function(container) {
.add("documentSuccess", function (container) {
let document = container.get('project-document');
if(document && !document.$id) {
if (document && !document.$id) {
return ',redirect';
}
return '';
})
.add("firstElement", function($value) {
if($value && $value[0]) {
.add("firstElement", function ($value) {
if ($value && $value[0]) {
return $value[0];
}
return $value;
})
.add("platformsLimit", function($value) {
.add("platformsLimit", function ($value) {
return $value;
})
.add("limit", function($value) {
.add("limit", function ($value) {
let postfix = ($value.length >= 50) ? '...' : '';
return $value.substring(0, 50) + postfix;
;
})
.add("arraySentence", function($value) {
if(!Array.isArray($value)) {
.add("arraySentence", function ($value) {
if (!Array.isArray($value)) {
return '';
}
return $value.join(", ").replace(/,\s([^,]+)$/, ' and $1');
})
.add("runtimeName", function($value, env) {
if(env && env.RUNTIMES && env.RUNTIMES[$value]) {
.add("runtimeName", function ($value, env) {
if (env && env.RUNTIMES && env.RUNTIMES[$value]) {
return env.RUNTIMES[$value].name;
}
return '';
})
.add("runtimeLogo", function($value, env) {
if(env && env.RUNTIMES && env.RUNTIMES[$value]) {
.add("runtimeLogo", function ($value, env) {
if (env && env.RUNTIMES && env.RUNTIMES[$value]) {
return env.RUNTIMES[$value].logo;
}
return '';
})
.add("runtimeVersion", function($value, env) {
if(env && env.RUNTIMES && env.RUNTIMES[$value]) {
.add("runtimeVersion", function ($value, env) {
if (env && env.RUNTIMES && env.RUNTIMES[$value]) {
return env.RUNTIMES[$value].version;
}
return '';
})
.add("indexAttributes", function($value) {
.add("indexAttributes", function ($value) {
let output = '';
for(let i = 0; i < $value.attributes.length; i++) {
for (let i = 0; i < $value.attributes.length; i++) {
output += $value.attributes[i] + ' (' + $value.orders[i] + '), '
}
return output.slice(0, -2);
})
.add("collectionAttributes", function($value) {
if(!Array.isArray($value)) {
.add("collectionAttributes", function ($value) {
if (!Array.isArray($value)) {
return [];
}
@ -281,17 +281,23 @@ window.ls.filter
return $value;
})
.add("documentAttribute", function($value, attribute) {
if($value[attribute.key]) {
.add("documentAttribute", function ($value, attribute) {
if ($value[attribute.key]) {
return $value[attribute.key];
}
return null;
})
.add("accessProject", function($value, router) {
.add("accessProject", function ($value, router) {
return ($value && $value.hasOwnProperty(router.params.project)) ? $value[router.params.project] : 0;
})
;
.add("first", function ($value) {
return $value[0].$id;
})
.add("last", function ($value) {
return $value[$value.length - 1].$id;
})
;
function abbreviate(number, maxPlaces, forcePlaces, forceLetter) {
number = Number(number);