1
0
Fork 0
mirror of synced 2024-05-20 12:42:39 +12:00

Added documents list

This commit is contained in:
Eldad Fux 2021-08-16 00:09:40 +03:00
parent e7aadb495b
commit 826a4527a0
20 changed files with 331 additions and 73 deletions

View file

@ -1,8 +1,10 @@
<?php
use Appwrite\Utopia\Response;
use Appwrite\Database\Validator\CustomId;
use Utopia\App;
use Utopia\Exception;
use Utopia\Audit\Audit;
use Utopia\Validator\Boolean;
use Utopia\Validator\FloatValidator;
use Utopia\Validator\Integer;
@ -11,6 +13,9 @@ use Utopia\Validator\WhiteList;
use Utopia\Validator\Text;
use Utopia\Validator\ArrayList;
use Utopia\Validator\JSON;
use Utopia\Database\Database;
use Utopia\Database\Document;
use Utopia\Database\Query;
use Utopia\Database\Validator\Key;
use Utopia\Database\Validator\Permissions;
use Utopia\Database\Validator\QueryValidator;
@ -18,13 +23,9 @@ use Utopia\Database\Validator\Queries as QueriesValidator;
use Utopia\Database\Validator\Structure;
use Utopia\Database\Validator\UID;
use Utopia\Database\Exception\Authorization as AuthorizationException;
use Utopia\Database\Exception\Duplicate as DuplicateException;
use Utopia\Database\Exception\Structure as StructureException;
use Appwrite\Utopia\Response;
use DeviceDetector\DeviceDetector;
use Utopia\Audit\Audit;
use Utopia\Database\Database;
use Utopia\Database\Document;
use Utopia\Database\Query;
$attributesCallback = function ($attribute, $response, $dbForExternal, $database, $audits) {
/** @var Utopia\Database\Document $document*/
@ -85,7 +86,7 @@ $attributesCallback = function ($attribute, $response, $dbForExternal, $database
}
}
$success = $dbForExternal->addAttributeInQueue($collectionId, $attributeId, $type, $size, $required, $default, $signed, $array, $format, $filters);
$dbForExternal->addAttributeInQueue($collectionId, $attributeId, $type, $size, $required, $default, $signed, $array, $format, $filters);
// Database->addAttributeInQueue() does not return a document
// So we need to create one for the response
@ -916,7 +917,7 @@ App::post('/v1/database/collections/:collectionId/indexes')
$lengths[$key] = ($attributeType === Database::VAR_STRING) ? $attributeSize : null;
}
$success = $dbForExternal->addIndexInQueue($collectionId, $indexId, $type, $attributes, $lengths, $orders);
$dbForExternal->addIndexInQueue($collectionId, $indexId, $type, $attributes, $lengths, $orders);
// Database->createIndex() does not return a document
// So we need to create one for the response
@ -1141,7 +1142,8 @@ App::post('/v1/database/collections/:collectionId/documents')
try {
$document = $dbForExternal->createDocument($collectionId, new Document($data));
} catch (StructureException $exception) {
}
catch (StructureException $exception) {
throw new Exception($exception->getMessage(), 400);
}
@ -1307,11 +1309,13 @@ App::patch('/v1/database/collections/:collectionId/documents/:documentId')
try {
$document = $dbForExternal->updateDocument($collection->getId(), $document->getId(), new Document($data));
} catch (AuthorizationException $exception) {
}
catch (AuthorizationException $exception) {
throw new Exception('Unauthorized permissions', 401);
} catch (StructureException $exception) {
}
catch (StructureException $exception) {
throw new Exception('Bad structure. '.$exception->getMessage(), 400);
}
}
$audits
->setParam('event', 'database.documents.update')
@ -1357,7 +1361,7 @@ App::delete('/v1/database/collections/:collectionId/documents/:documentId')
throw new Exception('No document found', 404);
}
$success = $dbForExternal->deleteDocument($collectionId, $documentId);
$dbForExternal->deleteDocument($collectionId, $documentId);
$events
->setParam('eventData', $response->output($document, Response::MODEL_DOCUMENT))

View file

@ -215,6 +215,11 @@ App::get('/console/database/collection')
/** @var Utopia\View $layout */
$logs = new View(__DIR__.'/../../views/console/comps/logs.phtml');
$logs
->setParam('interval', App::getEnv('_APP_MAINTENANCE_RETENTION_AUDIT', 0))
;
$page = new View(__DIR__.'/../../views/console/database/collection.phtml');
$page->setParam('logs', $logs);

View file

@ -1,3 +1,6 @@
<?php
$interval = floor((int)$this->getParam('interval', 0) / 86400);
?>
<div
data-service="database.listCollectionLogs"
data-param-collection-id="{{router.params.id}}"
@ -6,7 +9,13 @@
data-name="project-collection-logs">
<div class="box margin-bottom">
<table class="vertical small">
<div data-ls-if="0 == {{project-collection-logs.logs.length}}">
<h3 class="margin-bottom-small text-bold">No Logs Found</h3>
<p class="margin-bottom-no">Logs are retained for <?php echo $this->escape($interval); ?> days.</p>
</div>
<table class="vertical small" data-ls-if="0 != {{project-collection-logs.logs.length}}">
<thead>
<tr>
<th width="120">Date</th>

View file

@ -45,7 +45,8 @@ $logs = $this->getParam('logs', null);
data-param-search="{{router.params.search}}"
data-param-limit="<?php echo APP_PAGING_LIMIT; ?>"
data-param-offset="{{router.params.offset}}"
data-param-order-type="DESC"
data-param-order-types="DESC"
data-param-order-types-cast-to="array"
data-scope="sdk"
data-name="project-documents">
@ -55,19 +56,27 @@ $logs = $this->getParam('logs', null);
<p class="margin-bottom-no">Add your first document to get started</p>
</div>
<div data-ls-if="({{project-documents.sum}})">
<div xdata-ls-if="({{project-documents.sum}})" class="margin-top-negative">
<div class="margin-bottom-small margin-end-small text-align-end text-size-small"><span data-ls-bind="{{project-documents.sum}}"></span> documents found</div>
<div class="box margin-bottom y-scroll">
<table class="vertical">
<div class="box margin-bottom y-scroll text-size-small">
<table class="vertical borders">
<thead>
<tr>
<td>UID</td>
<tr data-ls-loop="project-collection.attributes" data-ls-as="attribute" data-ls-prefix="template-attribute-title-first" data-ls-limit="20">
<td style="width: 170px">
<i data-ls-attrs="class=pull-end icon-{{attribute.type}} text-size-xs"></i>
<span class="text-bold" data-ls-bind="{{attribute.$id}}"></span>
<span class="text-size-small" data-ls-if="{{attribute.array}}">[]</span>
</td>
</tr>
</thead>
<tbody data-ls-loop="project-documents.documents" data-ls-as="node">
<tr>
<td>42343</td>
<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-attrs="data-title={{attribute.$id}}: ">
<!-- <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>
<span data-ls-if="!{{node|documentAttribute}}" class="text-fade">n/a</span>
</td>
</tr>
</tbody>
</table>
@ -124,8 +133,9 @@ $logs = $this->getParam('logs', null);
<table class="vertical" data-ls-if="0 < {{project-collection.attributes.length}} || 0 < {{project-collection.attributesInQueue.length}}">
<thead>
<tr>
<th width="120"></th>
<th width="140">Attribute ID</th>
<th width="30"></th>
<th width="80"></th>
<th width="130">Attribute ID</th>
<th width="100">Type</th>
<th width="180">Default</th>
<th></th>
@ -134,8 +144,11 @@ $logs = $this->getParam('logs', null);
</thead>
<tbody data-ls-loop="project-collection.attributes" data-ls-as="attribute">
<tr>
<td>
<i data-ls-attrs="class=icon-{{attribute.type}}"></i>
</td>
<td data-title="Status">
<span class="text-size-small text-success"><i class="icon-ok-circled"></i> Available&nbsp;</span>
<span class="text-size-small text-success">available&nbsp;</span>
</td>
<td data-title="Attribute ID: ">
@ -153,7 +166,7 @@ $logs = $this->getParam('logs', null);
</td>
<td data-title="">
<span class="text-size-small text-danger" data-ls-if="{{attribute.required}}">Required *</span>
<span class="text-size-small text-danger" data-ls-if="{{attribute.required}}">required</span>
</td>
<td data-title="">
@ -190,11 +203,14 @@ $logs = $this->getParam('logs', null);
<table class="vertical" data-ls-if="0 < {{project-collection.attributesInQueue.length}}">
<tbody data-ls-loop="project-collection.attributesInQueue" data-ls-as="attribute">
<tr>
<td width="120" data-title="Status">
<span class="text-size-small text-info"><i class="icon-dot-circled"></i> Creating&nbsp;</span>
<td width="30">
<i data-ls-attrs="class=icon-{{attribute.type}}"></i>
</td>
<td width="80" data-title="Status">
<span class="text-size-small text-info">creating&nbsp;</span>
</td>
<td width="140" data-title="Attribute ID: ">
<td width="130" data-title="Attribute ID: ">
<span class="text-size-small" data-ls-bind="{{attribute.$id}}"></span><span class="text-size-small" data-ls-if="{{attribute.size}}" data-ls-bind=" ({{attribute.size}})"></span>
</td>
@ -209,7 +225,7 @@ $logs = $this->getParam('logs', null);
</td>
<td data-title="">
<span class="text-size-small text-danger" data-ls-if="{{attribute.required}}">Required *</span>
<span class="text-size-small text-danger" data-ls-if="{{attribute.required}}">required</span>
</td>
</tr>
</tbody>
@ -246,8 +262,9 @@ $logs = $this->getParam('logs', null);
<table class="vertical multi-line" data-ls-if="0 < {{project-collection.indexes.length}} || 0 < {{project-collection.indexesInQueue.length}}">
<thead>
<tr>
<th width="120"></th>
<th width="140">Index ID</th>
<th width="30"></th>
<th width="80"></th>
<th width="130">Index ID</th>
<th width="100">Type</th>
<th width="180">Attributes</th>
<th></th>
@ -256,8 +273,12 @@ $logs = $this->getParam('logs', null);
</thead>
<tbody data-ls-loop="project-collection.indexes" data-ls-as="index">
<tr>
<td>
<i class="icon-key"></i>
</td>
<td data-title="Status">
<span class="text-size-small text-success"><i class="icon-ok-circled"></i> Available&nbsp;</span>
<span class="text-size-small text-success">available</span>
</td>
<td data-title="Index ID: ">
@ -274,7 +295,7 @@ $logs = $this->getParam('logs', null);
</td>
<td data-title="">
<span class="text-size-small text-danger" data-ls-if="{{index.required}}">Required *</span>
<span class="text-size-small text-danger" data-ls-if="{{index.required}}">required</span>
</td>
<td data-title="">
@ -297,7 +318,7 @@ $logs = $this->getParam('logs', null);
<input type="hidden" name="projectId" data-ls-bind="{{router.params.project}}" />
<input type="hidden" name="collectionId" data-ls-bind="{{project-collection.$id}}" />
<input type="hidden" name="attributeId" data-ls-bind="{{attribute.$id}}" />
<input type="hidden" name="indexId" data-ls-bind="{{index.$id}}" />
<button class="danger small">Delete</button>
</form>
@ -311,11 +332,15 @@ $logs = $this->getParam('logs', null);
<table class="vertical multi-line" data-ls-if="0 < {{project-collection.indexesInQueue.length}}">
<tbody data-ls-loop="project-collection.indexesInQueue" data-ls-as="index">
<tr>
<td width="120" data-title="Status">
<span class="text-size-small text-info"><i class="icon-dot-circled"></i> Creating&nbsp;</span>
<td width="30">
<i class="icon-key"></i>
</td>
<td width="140" data-title="Index ID: ">
<td width="80" data-title="Status">
<span class="text-size-small text-info">creating</span>
</td>
<td width="130" data-title="Index ID: ">
<span class="text-size-small" data-ls-bind="{{index.$id}}"></span><span class="text-size-small" data-ls-if="{{index.size}}" data-ls-bind="({{index.size}})"></span>
</td>
@ -329,7 +354,7 @@ $logs = $this->getParam('logs', null);
</td>
<td data-title="">
<span class="text-size-small text-danger" data-ls-if="{{index.required}}">Required *</span>
<span class="text-size-small text-danger" data-ls-if="{{index.required}}">required</span>
</td>
<td width="80" data-title="">
@ -362,10 +387,9 @@ $logs = $this->getParam('logs', null);
data-scope="sdk"
data-event="submit"
data-param-collection-id="{{router.params.id}}"
data-success="alert,trigger,redirect"
data-success="alert,trigger"
data-success-param-alert-text="Updated collection successfully"
data-success-param-trigger-events="database.updateCollection"
data-success-param-redirect-url="/console/database/collection/settings?id={{serviceData.$id}}&project={{router.params.project}}"
data-failure="alert"
data-failure-param-alert-text="Failed to update collection"
data-failure-param-alert-classname="error">
@ -634,4 +658,12 @@ $logs = $this->getParam('logs', null);
data-event="load,database.createCollection,database.updateCollection,database.deleteCollection"
data-scope="sdk"
data-name="project-collections">
</div>
</div>
<script type="text/html" id="template-attribute-title-first">
<i data-ls-attrs="class=pull-end icon-key text-size-xs"></i>
<span class="text-bold">$id</span>
</script>
<script type="text/html" id="template-attribute-body-first">
<span class="text-fade" data-ls-bind="{{node.$id}}" data-general-copy data-class="icon-docs note copy text-fade pull-end"></span>
</script>

View file

@ -2,7 +2,7 @@
data-service="database.getCollection"
data-param-collection-id="{{router.params.collection}}"
data-scope="sdk"
data-event="load,database.updateCollection"
data-event="load,database.updateDocument"
data-name="project-collection">
<div
@ -10,7 +10,7 @@
data-param-collection-id="{{router.params.collection}}"
data-param-document-id="{{router.params.id}}"
data-scope="sdk"
data-event="load,database.updateDocument"
data-event="load"
data-name="project-document"
data-success="default">
@ -40,7 +40,7 @@
<div class="zone xl margin-bottom-no">
<ul class="phases clear" data-ui-phases data-selected="{{router.params.tab}}">
<li data-state="/console/database/document?id={{router.params.id}}&collection={{router.params.collection}}&project={{router.params.project}}">
<h2>Update</h2>
<h2>Overview</h2>
<div class="row responsive margin-top-negative">
<div class="col span-8 margin-bottom">
@ -54,17 +54,32 @@
data-name="project-document"
data-scope="sdk"
data-event="submit"
data-success="alert,trigger{{|documentSuccess}}"
data-success="alert,trigger"
data-success-param-alert-text="Updated document successfully"
data-success-param-trigger-events="database.updateDocument"
data-success-param-redirect-url="/console/database/document?id={{serviceData.$id}}&collection={{router.params.collection}}&project={{router.params.project}}"
data-failure="alert"
data-failure-param-alert-text="Failed to update document"
data-failure-param-alert-classname="error">
<input type="hidden" name="collectionId" data-ls-bind="{{project-collection.$id}}" />
<input type="hidden" name="documentId" data-ls-bind="{{project-document.$id}}" />
<label>&nbsp;</label>
<div class="box">
<fieldset name="data" data-cast-to="object">
<ul data-ls-loop="project-collection.attributes" data-ls-as="attribute">
<li>
<label>
<div data-ls-bind="{{attribute.$id}}" class="margin-bottom-tiny"></div>
<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>
<textarea data-ls-attrs="name={{attribute.$id}}" data-ls-bind="{{project-document|documentAttribute}}"></textarea>
</li>
</ul>
</fieldset>
<div class="toggle margin-bottom" data-ls-ui-open data-button-aria="Open Permissions">
<i class="icon-plus pull-end margin-top-tiny"></i>
<i class="icon-minus pull-end margin-top-tiny"></i>
@ -72,11 +87,11 @@
<h3 class="margin-bottom-large">Permissions</h3>
<label for="collection-read">Read Access <span class="text-size-small">(<a data-ls-attrs="href={{env.HOME}}/docs/permissions" target="_blank" rel="noopener">Learn more</a>)</span></label>
<input type="hidden" id="collection-read" name="read" data-forms-tags data-cast-to="json" data-ls-bind="{{project-document.$permissions.read}}" placeholder="User ID, Team ID or Role" />
<input type="hidden" id="collection-read" name="read" data-forms-tags data-cast-to="json" data-ls-bind="{{project-document.$read}}" placeholder="User ID, Team ID or Role" />
<div class="text-fade text-size-xs margin-top-negative-small margin-bottom">Add 'role:all' for wildcard access</div>
<label for="collection-write">Write Access <span class="text-size-small">(<a data-ls-attrs="href={{env.HOME}}/docs/permissions" target="_blank" rel="noopener">Learn more</a>)</label>
<input type="hidden" id="collection-write" name="write" data-forms-tags data-cast-to="json" data-ls-bind="{{project-document.$permissions.write}}" placeholder="User ID, Team ID or Role" />
<input type="hidden" id="collection-write" name="write" data-forms-tags data-cast-to="json" data-ls-bind="{{project-document.$write}}" placeholder="User ID, Team ID or Role" />
<div class="text-fade text-size-xs margin-top-negative-small margin-bottom">Add 'role:all' for wildcard access</div>
</div>

View file

@ -98,6 +98,12 @@ services:
- _APP_FUNCTIONS_MEMORY
- _APP_FUNCTIONS_MEMORY_SWAP
- _APP_FUNCTIONS_RUNTIMES
- _APP_STATSD_HOST
- _APP_STATSD_PORT
- _APP_MAINTENANCE_INTERVAL
- _APP_MAINTENANCE_RETENTION_EXECUTION
- _APP_MAINTENANCE_RETENTION_ABUSE
- _APP_MAINTENANCE_RETENTION_AUDIT
appwrite-worker-usage:
image: <?php echo $organization; ?>/<?php echo $image; ?>:<?php echo $version."\n"; ?>

View file

@ -124,6 +124,10 @@ services:
- _APP_FUNCTIONS_RUNTIMES
- _APP_STATSD_HOST
- _APP_STATSD_PORT
- _APP_MAINTENANCE_INTERVAL
- _APP_MAINTENANCE_RETENTION_EXECUTION
- _APP_MAINTENANCE_RETENTION_ABUSE
- _APP_MAINTENANCE_RETENTION_AUDIT
appwrite-worker-audits:
entrypoint: worker-audits

View file

@ -69,6 +69,7 @@ const configApp = {
'public/scripts/views/forms/upload.js',
'public/scripts/views/general/cookies.js',
'public/scripts/views/general/copy.js',
'public/scripts/views/general/page-title.js',
'public/scripts/views/general/scroll-to.js',
'public/scripts/views/general/scroll-direction.js',

View file

@ -2128,13 +2128,15 @@ result+'")": '+
error);}
if(debug){console.info("debug-ls-if result:",result);}
paths=expression.getPaths();let prv=element.$lsSkip;element.$lsSkip=!result;if(!result){element.style.visibility="hidden";element.style.display="none";}else{element.style.removeProperty("display");element.style.removeProperty("visibility");}
if(prv===true&&element.$lsSkip===false){view.render(element);}};check();for(let i=0;i<paths.length;i++){let path=paths[i].split(".");while(path.length){container.bind(element,path.join("."),check);path.pop();}}},});window.ls.container.get("view").add({selector:"data-ls-loop",template:false,nested:false,controller:function(element,view,container,window,expression){let expr=expression.parse(element.getAttribute("data-ls-loop"));let as=element.getAttribute("data-ls-as");let key=element.getAttribute("data-ls-key")||"$index";let limit=parseInt(expression.parse(element.getAttribute("data-limit")||"")||-1);let debug=element.getAttribute("data-debug")||false;let echo=function(){let array=container.path(expr);let counter=0;array=!array?[]:array;let watch=!!(array&&array.__proxy);while(element.hasChildNodes()){element.removeChild(element.lastChild);element.lastChild=null;}
if(prv===true&&element.$lsSkip===false){view.render(element);}};check();for(let i=0;i<paths.length;i++){let path=paths[i].split(".");while(path.length){container.bind(element,path.join("."),check);path.pop();}}},});window.ls.container.get("view").add({selector:"data-ls-loop",template:false,nested:false,controller:function(element,view,container,filter,window,expression){let expr=expression.parse(element.getAttribute("data-ls-loop"));let as=element.getAttribute("data-ls-as");let filterName=element.getAttribute("data-ls-filter");let key=element.getAttribute("data-ls-key")||"$index";let prefix=element.getAttribute("data-ls-prefix")||null;let postfix=element.getAttribute("data-ls-postfix")||null;let limit=parseInt(expression.parse(element.getAttribute("data-ls-limit")||"")||-1);let debug=element.getAttribute("data-debug")||false;let echo=function(){let array=container.path(expr);let counter=0;array=!array?[]:array;if(filterName){array=filter.apply(filterName,array);console.log(array);}
let watch=!!(array&&array.__proxy);while(element.hasChildNodes()){element.removeChild(element.lastChild);element.lastChild=null;}
if(array instanceof Array&&typeof array!=="object"){throw new Error("Reference value must be array or object. "+typeof array+" given");}
let children=[];element.$lsSkip=true;element.style.visibility=0===array.length&&element.style.visibility==""?"hidden":"visible";for(let prop in array){if(counter==limit){break;}
let children=[];element.$lsSkip=true;element.style.visibility=0===array.length&&element.style.visibility==""?"hidden":"visible";if(prefix){prefixElement=document.getElementById(prefix);let html=prefixElement.innerHTML;prefixElement=template.cloneNode(true);if(prefixElement){prefixElement.innerHTML=html;element.appendChild(prefixElement);view.render(prefixElement);}}
for(let prop in array){if(counter==limit){break;}
counter++;if(!array.hasOwnProperty(prop)){continue;}
children[prop]=template.cloneNode(true);element.appendChild(children[prop]);((index)=>{let context=expr+"."+index;container.addNamespace(as,context);if(debug){console.info("debug-ls-loop","index",index);console.info("debug-ls-loop","context",context);console.info("debug-ls-loop","context-path",container.path(context).name);console.info("debug-ls-loop","namespaces",container.namespaces);}
container.set(as,container.path(context),true,watch);container.set(key,index,true,false);view.render(children[prop]);container.removeNamespace(as);})(prop);}
element.dispatchEvent(new Event("looped"));};let template=element.children.length===1?element.children[0]:window.document.createElement("li");echo();container.bind(element,expr+".length",echo);let path=(expr+".length").split(".");while(path.length){container.bind(element,path.join("."),echo);path.pop();}},});window.ls.container.get("view").add({selector:"data-ls-template",template:false,controller:function(element,view,http,expression,document,container){let template=element.getAttribute("data-ls-template")||"";let type=element.getAttribute("data-type")||"url";let debug=element.getAttribute("data-debug")||false;let paths=[];let check=function(init=false){let source=expression.parse(template);paths=expression.getPaths();element.innerHTML="";if("script"===type){let inlineTemplate=document.getElementById(source);if(inlineTemplate&&inlineTemplate.innerHTML){element.innerHTML=inlineTemplate.innerHTML;element.dispatchEvent(new CustomEvent("template-loaded",{bubbles:true,cancelable:false,}));}else{if(debug){console.error('Missing template "'+source+'"');}}
element.dispatchEvent(new Event("looped"));};let template=element.children.length>=1?element.children[0]:window.document.createElement("li");echo();container.bind(element,expr+".length",echo);let path=(expr+".length").split(".");while(path.length){container.bind(element,path.join("."),echo);path.pop();}},});window.ls.container.get("view").add({selector:"data-ls-template",template:false,controller:function(element,view,http,expression,document,container){let template=element.getAttribute("data-ls-template")||"";let type=element.getAttribute("data-type")||"url";let debug=element.getAttribute("data-debug")||false;let paths=[];let check=function(init=false){let source=expression.parse(template);paths=expression.getPaths();element.innerHTML="";if("script"===type){let inlineTemplate=document.getElementById(source);if(inlineTemplate&&inlineTemplate.innerHTML){element.innerHTML=inlineTemplate.innerHTML;element.dispatchEvent(new CustomEvent("template-loaded",{bubbles:true,cancelable:false,}));}else{if(debug){console.error('Missing template "'+source+'"');}}
if(!init){view.render(element);}
return;}
http.get(source).then((function(element){return function(data){element.innerHTML=data;view.render(element);element.dispatchEvent(new CustomEvent("template-loaded",{bubbles:true,cancelable:false,}));};})(element),function(){throw new Error("Failed loading template");});};check(true);for(let i=0;i<paths.length;i++){let path=paths[i].split(".");while(path.length){container.bind(element,path.join("."),check);path.pop();}}},});window.ls.error=function(){return function(error){window.console.error(error);if(window.location.pathname!=='/console'){window.location='/console';}};};window.addEventListener("error",function(event){console.error("ERROR-EVENT:",event.error.message,event.error.stack);});document.addEventListener("account.deleteSession",function(){window.location="/auth/signin";});document.addEventListener("account.create",function(){let container=window.ls.container;let form=container.get('serviceForm');let sdk=container.get('console');let promise=sdk.account.createSession(form.email,form.password);container.set("serviceForm",{},true,true);promise.then(function(){var subscribe=document.getElementById('newsletter').checked;if(subscribe){let alerts=container.get('alerts');let loaderId=alerts.add({text:'Loading...',class:""},0);fetch('https://appwrite.io/v1/newsletter/subscribe',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({name:form.name,email:form.email,}),}).finally(function(){alerts.remove(loaderId);window.location='/console';});}else{window.location='/console';}},function(error){window.location='/auth/signup?failure=1';});});(function(window){"use strict";window.ls.container.set('alerts',function(window){return{list:[],ids:0,counter:0,max:5,add:function(message,time){var scope=this;message.id=scope.ids++;message.remove=function(){scope.remove(message.id);};scope.counter++;scope.list.unshift(message);if(scope.counter>scope.max){scope.list.pop();scope.counter--;}
@ -2310,7 +2312,9 @@ return $value.join(", ").replace(/,\s([^,]+)$/,' and $1');}).add("runtimeName",f
return'';}).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]){return env.RUNTIMES[$value].version;}
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);});function abbreviate(number,maxPlaces,forcePlaces,forceLetter){number=Number(number);forceLetter=forceLetter||false;if(forceLetter!==false){return annotate(number,maxPlaces,forcePlaces,forceLetter);}
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.$id]){return $value[attribute.$id];}
return null;});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;}
@ -2427,7 +2431,8 @@ var file=document.createElement("li");var image=document.createElement("img");im
result+"/preview?width="+
previewWidth+"&height="+
previewHeight+"&project="+project+"&mode=admin";image.alt=previewAlt;file.className="file avatar";file.tabIndex=0;file.appendChild(image);preview.appendChild(file);var remove=(function(result){return function(event){render(result.$id);element.value='';};})(result);file.addEventListener("click",remove);file.addEventListener("keypress",remove);element.value=result;};input.addEventListener("change",function(){var message=alerts.add({text:labelLoading,class:""},0);var files=input.files;var read=JSON.parse(expression.parse(element.dataset["read"]||"[]"));var write=JSON.parse(expression.parse(element.dataset["write"]||"[]"));sdk.storage.createFile('unique()',files[0],read,write,1).then(function(response){onComplete(message);render(response.$id);},function(error){alerts.add({text:"An error occurred!",class:""},3000);onComplete(message);});input.disabled=true;});element.addEventListener("change",function(){if(!element.value){return;}
render(element.value);wrapper.scrollIntoView();});upload.addEventListener("keypress",function(){input.click();});element.parentNode.insertBefore(wrapper,element);wrapper.appendChild(preview);wrapper.appendChild(progress);wrapper.appendChild(upload);upload.appendChild(input);render(output);if(searchButton){let searchOpen=document.createElement("button");searchOpen.type='button';searchOpen.innerHTML='<i class="icon icon-search"></i> Search';searchOpen.classList.add('reverse');let path=container.scope(searchButton);searchOpen.addEventListener('click',function(){search.selected=element.value;search.path=path;document.dispatchEvent(new CustomEvent("open-file-serach",{bubbles:false,cancelable:true}));});wrapper.appendChild(searchOpen);}}});})(window);(function(window){window.ls.container.get("view").add({selector:"data-cookies",controller:function(element,alerts,cookie,env){if(!cookie.get("cookie-alert")){let text=element.dataset["cookies"]||"";alerts.add({text:text,class:"cookie-alert",link:env.HOME+"/policy/cookies",label:'Learn More',callback:function(){cookie.set("cookie-alert","true",365*10);}},0);}}});})(window);(function(window){window.ls.container.get("view").add({selector:"data-page-title",repeat:true,controller:function(element,document,expression){document.title=expression.parse(element.getAttribute("data-page-title"))||document.title;}});})(window);(function(window){"use strict";window.ls.view.add({selector:'data-general-scroll-to',repeat:false,controller:function(element,window){let button=window.document.createElement('button');button.className='scroll-to icon-up-dir';button.alt='Back To Top';button.title='Back To Top';button.addEventListener('click',function(){element.scrollIntoView(true,{behavior:'smooth'});button.blur();},false);element.appendChild(button);}});})(window);(function(window){"use strict";window.ls.view.add({selector:'data-general-scroll-direction',repeat:false,controller:function(element,window){let position=0;let check=function(){let direction=window.document.documentElement.scrollTop;if(direction>position){element.classList.remove('scroll-to-top')
render(element.value);wrapper.scrollIntoView();});upload.addEventListener("keypress",function(){input.click();});element.parentNode.insertBefore(wrapper,element);wrapper.appendChild(preview);wrapper.appendChild(progress);wrapper.appendChild(upload);upload.appendChild(input);render(output);if(searchButton){let searchOpen=document.createElement("button");searchOpen.type='button';searchOpen.innerHTML='<i class="icon icon-search"></i> Search';searchOpen.classList.add('reverse');let path=container.scope(searchButton);searchOpen.addEventListener('click',function(){search.selected=element.value;search.path=path;document.dispatchEvent(new CustomEvent("open-file-serach",{bubbles:false,cancelable:true}));});wrapper.appendChild(searchOpen);}}});})(window);(function(window){window.ls.container.get("view").add({selector:"data-cookies",controller:function(element,alerts,cookie,env){if(!cookie.get("cookie-alert")){let text=element.dataset["cookies"]||"";alerts.add({text:text,class:"cookie-alert",link:env.HOME+"/policy/cookies",label:'Learn More',callback:function(){cookie.set("cookie-alert","true",365*10);}},0);}}});})(window);(function(window){"use strict";window.ls.view.add({selector:'data-general-copy',repeat:false,controller:function(document,element,alerts){let button=document.createElement("i");button.type="button";button.title="Copy to Clipboard";button.className=element.getAttribute("data-class")||"icon-docs note copy";button.style.cursor="pointer";element.parentNode.insertBefore(button,element.nextSibling);let copy=function(event){window.getSelection().removeAllRanges();let range=document.createRange();range.selectNode(element);window.getSelection().addRange(range);try{document.execCommand("copy");alerts.add({text:"Copied to clipboard",class:""},3000);}catch(err){alerts.add({text:"Failed to copy text ",class:"error"},3000);}
window.getSelection().removeAllRanges();};button.addEventListener("click",copy);}});})(window);(function(window){window.ls.container.get("view").add({selector:"data-page-title",repeat:true,controller:function(element,document,expression){document.title=expression.parse(element.getAttribute("data-page-title"))||document.title;}});})(window);(function(window){"use strict";window.ls.view.add({selector:'data-general-scroll-to',repeat:false,controller:function(element,window){let button=window.document.createElement('button');button.className='scroll-to icon-up-dir';button.alt='Back To Top';button.title='Back To Top';button.addEventListener('click',function(){element.scrollIntoView(true,{behavior:'smooth'});button.blur();},false);element.appendChild(button);}});})(window);(function(window){"use strict";window.ls.view.add({selector:'data-general-scroll-direction',repeat:false,controller:function(element,window){let position=0;let check=function(){let direction=window.document.documentElement.scrollTop;if(direction>position){element.classList.remove('scroll-to-top')
element.classList.add('scroll-to-bottom')}
else{element.classList.remove('scroll-to-bottom')
element.classList.add('scroll-to-top')}

View file

@ -111,13 +111,15 @@ result+'")": '+
error);}
if(debug){console.info("debug-ls-if result:",result);}
paths=expression.getPaths();let prv=element.$lsSkip;element.$lsSkip=!result;if(!result){element.style.visibility="hidden";element.style.display="none";}else{element.style.removeProperty("display");element.style.removeProperty("visibility");}
if(prv===true&&element.$lsSkip===false){view.render(element);}};check();for(let i=0;i<paths.length;i++){let path=paths[i].split(".");while(path.length){container.bind(element,path.join("."),check);path.pop();}}},});window.ls.container.get("view").add({selector:"data-ls-loop",template:false,nested:false,controller:function(element,view,container,window,expression){let expr=expression.parse(element.getAttribute("data-ls-loop"));let as=element.getAttribute("data-ls-as");let key=element.getAttribute("data-ls-key")||"$index";let limit=parseInt(expression.parse(element.getAttribute("data-limit")||"")||-1);let debug=element.getAttribute("data-debug")||false;let echo=function(){let array=container.path(expr);let counter=0;array=!array?[]:array;let watch=!!(array&&array.__proxy);while(element.hasChildNodes()){element.removeChild(element.lastChild);element.lastChild=null;}
if(prv===true&&element.$lsSkip===false){view.render(element);}};check();for(let i=0;i<paths.length;i++){let path=paths[i].split(".");while(path.length){container.bind(element,path.join("."),check);path.pop();}}},});window.ls.container.get("view").add({selector:"data-ls-loop",template:false,nested:false,controller:function(element,view,container,filter,window,expression){let expr=expression.parse(element.getAttribute("data-ls-loop"));let as=element.getAttribute("data-ls-as");let filterName=element.getAttribute("data-ls-filter");let key=element.getAttribute("data-ls-key")||"$index";let prefix=element.getAttribute("data-ls-prefix")||null;let postfix=element.getAttribute("data-ls-postfix")||null;let limit=parseInt(expression.parse(element.getAttribute("data-ls-limit")||"")||-1);let debug=element.getAttribute("data-debug")||false;let echo=function(){let array=container.path(expr);let counter=0;array=!array?[]:array;if(filterName){array=filter.apply(filterName,array);console.log(array);}
let watch=!!(array&&array.__proxy);while(element.hasChildNodes()){element.removeChild(element.lastChild);element.lastChild=null;}
if(array instanceof Array&&typeof array!=="object"){throw new Error("Reference value must be array or object. "+typeof array+" given");}
let children=[];element.$lsSkip=true;element.style.visibility=0===array.length&&element.style.visibility==""?"hidden":"visible";for(let prop in array){if(counter==limit){break;}
let children=[];element.$lsSkip=true;element.style.visibility=0===array.length&&element.style.visibility==""?"hidden":"visible";if(prefix){prefixElement=document.getElementById(prefix);let html=prefixElement.innerHTML;prefixElement=template.cloneNode(true);if(prefixElement){prefixElement.innerHTML=html;element.appendChild(prefixElement);view.render(prefixElement);}}
for(let prop in array){if(counter==limit){break;}
counter++;if(!array.hasOwnProperty(prop)){continue;}
children[prop]=template.cloneNode(true);element.appendChild(children[prop]);((index)=>{let context=expr+"."+index;container.addNamespace(as,context);if(debug){console.info("debug-ls-loop","index",index);console.info("debug-ls-loop","context",context);console.info("debug-ls-loop","context-path",container.path(context).name);console.info("debug-ls-loop","namespaces",container.namespaces);}
container.set(as,container.path(context),true,watch);container.set(key,index,true,false);view.render(children[prop]);container.removeNamespace(as);})(prop);}
element.dispatchEvent(new Event("looped"));};let template=element.children.length===1?element.children[0]:window.document.createElement("li");echo();container.bind(element,expr+".length",echo);let path=(expr+".length").split(".");while(path.length){container.bind(element,path.join("."),echo);path.pop();}},});window.ls.container.get("view").add({selector:"data-ls-template",template:false,controller:function(element,view,http,expression,document,container){let template=element.getAttribute("data-ls-template")||"";let type=element.getAttribute("data-type")||"url";let debug=element.getAttribute("data-debug")||false;let paths=[];let check=function(init=false){let source=expression.parse(template);paths=expression.getPaths();element.innerHTML="";if("script"===type){let inlineTemplate=document.getElementById(source);if(inlineTemplate&&inlineTemplate.innerHTML){element.innerHTML=inlineTemplate.innerHTML;element.dispatchEvent(new CustomEvent("template-loaded",{bubbles:true,cancelable:false,}));}else{if(debug){console.error('Missing template "'+source+'"');}}
element.dispatchEvent(new Event("looped"));};let template=element.children.length>=1?element.children[0]:window.document.createElement("li");echo();container.bind(element,expr+".length",echo);let path=(expr+".length").split(".");while(path.length){container.bind(element,path.join("."),echo);path.pop();}},});window.ls.container.get("view").add({selector:"data-ls-template",template:false,controller:function(element,view,http,expression,document,container){let template=element.getAttribute("data-ls-template")||"";let type=element.getAttribute("data-type")||"url";let debug=element.getAttribute("data-debug")||false;let paths=[];let check=function(init=false){let source=expression.parse(template);paths=expression.getPaths();element.innerHTML="";if("script"===type){let inlineTemplate=document.getElementById(source);if(inlineTemplate&&inlineTemplate.innerHTML){element.innerHTML=inlineTemplate.innerHTML;element.dispatchEvent(new CustomEvent("template-loaded",{bubbles:true,cancelable:false,}));}else{if(debug){console.error('Missing template "'+source+'"');}}
if(!init){view.render(element);}
return;}
http.get(source).then((function(element){return function(data){element.innerHTML=data;view.render(element);element.dispatchEvent(new CustomEvent("template-loaded",{bubbles:true,cancelable:false,}));};})(element),function(){throw new Error("Failed loading template");});};check(true);for(let i=0;i<paths.length;i++){let path=paths[i].split(".");while(path.length){container.bind(element,path.join("."),check);path.pop();}}},});window.ls.error=function(){return function(error){window.console.error(error);if(window.location.pathname!=='/console'){window.location='/console';}};};window.addEventListener("error",function(event){console.error("ERROR-EVENT:",event.error.message,event.error.stack);});document.addEventListener("account.deleteSession",function(){window.location="/auth/signin";});document.addEventListener("account.create",function(){let container=window.ls.container;let form=container.get('serviceForm');let sdk=container.get('console');let promise=sdk.account.createSession(form.email,form.password);container.set("serviceForm",{},true,true);promise.then(function(){var subscribe=document.getElementById('newsletter').checked;if(subscribe){let alerts=container.get('alerts');let loaderId=alerts.add({text:'Loading...',class:""},0);fetch('https://appwrite.io/v1/newsletter/subscribe',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({name:form.name,email:form.email,}),}).finally(function(){alerts.remove(loaderId);window.location='/console';});}else{window.location='/console';}},function(error){window.location='/auth/signup?failure=1';});});(function(window){"use strict";window.ls.container.set('alerts',function(window){return{list:[],ids:0,counter:0,max:5,add:function(message,time){var scope=this;message.id=scope.ids++;message.remove=function(){scope.remove(message.id);};scope.counter++;scope.list.unshift(message);if(scope.counter>scope.max){scope.list.pop();scope.counter--;}
@ -293,7 +295,9 @@ return $value.join(", ").replace(/,\s([^,]+)$/,' and $1');}).add("runtimeName",f
return'';}).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]){return env.RUNTIMES[$value].version;}
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);});function abbreviate(number,maxPlaces,forcePlaces,forceLetter){number=Number(number);forceLetter=forceLetter||false;if(forceLetter!==false){return annotate(number,maxPlaces,forcePlaces,forceLetter);}
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.$id]){return $value[attribute.$id];}
return null;});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;}
@ -410,7 +414,8 @@ var file=document.createElement("li");var image=document.createElement("img");im
result+"/preview?width="+
previewWidth+"&height="+
previewHeight+"&project="+project+"&mode=admin";image.alt=previewAlt;file.className="file avatar";file.tabIndex=0;file.appendChild(image);preview.appendChild(file);var remove=(function(result){return function(event){render(result.$id);element.value='';};})(result);file.addEventListener("click",remove);file.addEventListener("keypress",remove);element.value=result;};input.addEventListener("change",function(){var message=alerts.add({text:labelLoading,class:""},0);var files=input.files;var read=JSON.parse(expression.parse(element.dataset["read"]||"[]"));var write=JSON.parse(expression.parse(element.dataset["write"]||"[]"));sdk.storage.createFile('unique()',files[0],read,write,1).then(function(response){onComplete(message);render(response.$id);},function(error){alerts.add({text:"An error occurred!",class:""},3000);onComplete(message);});input.disabled=true;});element.addEventListener("change",function(){if(!element.value){return;}
render(element.value);wrapper.scrollIntoView();});upload.addEventListener("keypress",function(){input.click();});element.parentNode.insertBefore(wrapper,element);wrapper.appendChild(preview);wrapper.appendChild(progress);wrapper.appendChild(upload);upload.appendChild(input);render(output);if(searchButton){let searchOpen=document.createElement("button");searchOpen.type='button';searchOpen.innerHTML='<i class="icon icon-search"></i> Search';searchOpen.classList.add('reverse');let path=container.scope(searchButton);searchOpen.addEventListener('click',function(){search.selected=element.value;search.path=path;document.dispatchEvent(new CustomEvent("open-file-serach",{bubbles:false,cancelable:true}));});wrapper.appendChild(searchOpen);}}});})(window);(function(window){window.ls.container.get("view").add({selector:"data-cookies",controller:function(element,alerts,cookie,env){if(!cookie.get("cookie-alert")){let text=element.dataset["cookies"]||"";alerts.add({text:text,class:"cookie-alert",link:env.HOME+"/policy/cookies",label:'Learn More',callback:function(){cookie.set("cookie-alert","true",365*10);}},0);}}});})(window);(function(window){window.ls.container.get("view").add({selector:"data-page-title",repeat:true,controller:function(element,document,expression){document.title=expression.parse(element.getAttribute("data-page-title"))||document.title;}});})(window);(function(window){"use strict";window.ls.view.add({selector:'data-general-scroll-to',repeat:false,controller:function(element,window){let button=window.document.createElement('button');button.className='scroll-to icon-up-dir';button.alt='Back To Top';button.title='Back To Top';button.addEventListener('click',function(){element.scrollIntoView(true,{behavior:'smooth'});button.blur();},false);element.appendChild(button);}});})(window);(function(window){"use strict";window.ls.view.add({selector:'data-general-scroll-direction',repeat:false,controller:function(element,window){let position=0;let check=function(){let direction=window.document.documentElement.scrollTop;if(direction>position){element.classList.remove('scroll-to-top')
render(element.value);wrapper.scrollIntoView();});upload.addEventListener("keypress",function(){input.click();});element.parentNode.insertBefore(wrapper,element);wrapper.appendChild(preview);wrapper.appendChild(progress);wrapper.appendChild(upload);upload.appendChild(input);render(output);if(searchButton){let searchOpen=document.createElement("button");searchOpen.type='button';searchOpen.innerHTML='<i class="icon icon-search"></i> Search';searchOpen.classList.add('reverse');let path=container.scope(searchButton);searchOpen.addEventListener('click',function(){search.selected=element.value;search.path=path;document.dispatchEvent(new CustomEvent("open-file-serach",{bubbles:false,cancelable:true}));});wrapper.appendChild(searchOpen);}}});})(window);(function(window){window.ls.container.get("view").add({selector:"data-cookies",controller:function(element,alerts,cookie,env){if(!cookie.get("cookie-alert")){let text=element.dataset["cookies"]||"";alerts.add({text:text,class:"cookie-alert",link:env.HOME+"/policy/cookies",label:'Learn More',callback:function(){cookie.set("cookie-alert","true",365*10);}},0);}}});})(window);(function(window){"use strict";window.ls.view.add({selector:'data-general-copy',repeat:false,controller:function(document,element,alerts){let button=document.createElement("i");button.type="button";button.title="Copy to Clipboard";button.className=element.getAttribute("data-class")||"icon-docs note copy";button.style.cursor="pointer";element.parentNode.insertBefore(button,element.nextSibling);let copy=function(event){window.getSelection().removeAllRanges();let range=document.createRange();range.selectNode(element);window.getSelection().addRange(range);try{document.execCommand("copy");alerts.add({text:"Copied to clipboard",class:""},3000);}catch(err){alerts.add({text:"Failed to copy text ",class:"error"},3000);}
window.getSelection().removeAllRanges();};button.addEventListener("click",copy);}});})(window);(function(window){window.ls.container.get("view").add({selector:"data-page-title",repeat:true,controller:function(element,document,expression){document.title=expression.parse(element.getAttribute("data-page-title"))||document.title;}});})(window);(function(window){"use strict";window.ls.view.add({selector:'data-general-scroll-to',repeat:false,controller:function(element,window){let button=window.document.createElement('button');button.className='scroll-to icon-up-dir';button.alt='Back To Top';button.title='Back To Top';button.addEventListener('click',function(){element.scrollIntoView(true,{behavior:'smooth'});button.blur();},false);element.appendChild(button);}});})(window);(function(window){"use strict";window.ls.view.add({selector:'data-general-scroll-direction',repeat:false,controller:function(element,window){let position=0;let check=function(){let direction=window.document.documentElement.scrollTop;if(direction>position){element.classList.remove('scroll-to-top')
element.classList.add('scroll-to-bottom')}
else{element.classList.remove('scroll-to-bottom')
element.classList.add('scroll-to-top')}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1121,18 +1121,26 @@ window.ls.container.get("view").add({
selector: "data-ls-loop",
template: false,
nested: false,
controller: function (element, view, container, window, expression) {
controller: function (element, view, container, filter, window, expression) {
let expr = expression.parse(element.getAttribute("data-ls-loop"));
let as = element.getAttribute("data-ls-as");
let filterName = element.getAttribute("data-ls-filter");
let key = element.getAttribute("data-ls-key") || "$index";
let prefix = element.getAttribute("data-ls-prefix") || null;
let postfix = element.getAttribute("data-ls-postfix") || null;
let limit = parseInt(
expression.parse(element.getAttribute("data-limit") || "") || -1
expression.parse(element.getAttribute("data-ls-limit") || "") || -1
);
let debug = element.getAttribute("data-debug") || false;
let echo = function () {
let array = container.path(expr);
let counter = 0;
array = !array ? [] : array;
if(filterName) {
array = filter.apply(filterName, array);
}
let watch = !!(array && array.__proxy);
while (element.hasChildNodes()) {
element.removeChild(element.lastChild);
@ -1149,6 +1157,18 @@ window.ls.container.get("view").add({
0 === array.length && element.style.visibility == ""
? "hidden"
: "visible";
if(prefix) {
prefixElement = document.getElementById(prefix);
let html = prefixElement.innerHTML;
prefixElement = template.cloneNode(true);
if(prefixElement) {
prefixElement.innerHTML = html;
element.appendChild(prefixElement);
view.render(prefixElement);
}
}
for (let prop in array) {
if (counter == limit) {
break;
@ -1181,7 +1201,7 @@ window.ls.container.get("view").add({
element.dispatchEvent(new Event("looped"));
};
let template =
element.children.length === 1
element.children.length >= 1
? element.children[0]
: window.document.createElement("li");
echo();

View file

@ -263,6 +263,24 @@ window.ls.filter
}
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.$id]) {
return $value[attribute.$id];
}
return null;
})
;
function abbreviate(number, maxPlaces, forcePlaces, forceLetter) {

View file

@ -0,0 +1,44 @@
(function(window) {
"use strict";
window.ls.view.add({
selector: 'data-general-copy',
repeat: false,
controller: function(document, element, alerts) {
let button = document.createElement("i");
button.type = "button";
button.title = "Copy to Clipboard";
button.className = element.getAttribute("data-class") || "icon-docs note copy";
button.style.cursor = "pointer";
element.parentNode.insertBefore(button, element.nextSibling);
let copy = function(event) {
window.getSelection().removeAllRanges();
let range = document.createRange();
range.selectNode(element);
window.getSelection().addRange(range);
try {
document.execCommand("copy");
alerts.add({
text: "Copied to clipboard",
class: ""
}, 3000);
} catch (err) {
alerts.add({
text: "Failed to copy text ",
class: "error"
}, 3000);
}
window.getSelection().removeAllRanges();
};
button.addEventListener("click", copy);
}
});
})(window);

View file

@ -64,11 +64,11 @@
line-height: 15px;
padding: 3px;
text-align: center;
font-weight: 600!important;
font-weight: 500!important;
position: absolute;
top: -5px;
right: -35px;
font-size: 13px;
font-size: 12px;
}
.selected {

View file

@ -707,6 +707,82 @@
"css": "reddit",
"code": 59473,
"src": "elusive"
},
{
"uid": "5b43525a8080befb3493998ea77195e0",
"css": "integer",
"code": 59475,
"src": "custom_icons",
"selected": true,
"svg": {
"path": "M381.7 825.7L279.7 825.7 313.1 625 202.7 625 202.7 533.6 327.9 533.6 347.8 409.3 240.4 409.3 240.4 316.8 363.3 316.8 397.6 113.3 498.5 113.3 465.2 316.8 541.3 316.8 574.6 113.3 676.5 113.3 642.2 316.8 757.6 316.8 757.6 409.3 626.3 409.3 605.9 533.6 720.3 533.6 720.3 625 591.5 625 558.2 825.7 457.3 825.7 490.6 625 415 625 381.7 825.7ZM449.8 409.3L429.4 533.6 505 533.6 525.3 409.3 449.8 409.3Z",
"width": 1000
},
"search": [
"integer"
]
},
{
"uid": "23359bf9000e958419520fc09f111a22",
"css": "float",
"code": 59476,
"src": "custom_icons",
"selected": true,
"svg": {
"path": "M381.7 825.7L279.7 825.7 313.1 625 202.7 625 202.7 533.6 327.9 533.6 347.8 409.3 240.4 409.3 240.4 316.8 363.3 316.8 397.6 113.3 498.5 113.3 465.2 316.8 541.3 316.8 574.6 113.3 676.5 113.3 642.2 316.8 757.6 316.8 757.6 409.3 626.3 409.3 605.9 533.6 720.3 533.6 720.3 625 591.5 625 558.2 825.7 457.3 825.7 490.6 625 415 625 381.7 825.7ZM449.8 409.3L429.4 533.6 505 533.6 525.3 409.3 449.8 409.3Z",
"width": 1000
},
"search": [
"float"
]
},
{
"uid": "bbbebc5835cb7e7dd8cecdc59a4dad47",
"css": "ip",
"code": 59477,
"src": "custom_icons",
"selected": true,
"svg": {
"path": "M378.7 683.7L147.5 683.7 147.5 606.5 196.1 594.4 196.1 365.8 138.3 353.7 138.3 276.2 330.4 276.2 330.4 594.4 378.7 606.5 378.7 683.7ZM330.4 198.9L192.3 198.9 192.3 96.1 330.4 96.1 330.4 198.9ZM640.9 840.3L409.3 840.3 409.3 762.8 460.6 750.7 460.6 365.8 402.4 353.7 402.4 276.2 586.5 276.2 591.1 322.1C602.3 305.1 615.9 291.9 631.7 282.6 647.5 273.3 666.9 268.6 689.9 268.6 722.5 268.6 750.6 277.5 774.1 295.2 797.6 312.9 815.6 337.7 828.3 369.6 840.9 401.4 847.2 438.5 847.2 480.7L847.2 488.6C847.2 529.3 840.9 564.8 828.3 595.4 815.6 625.9 797.4 649.5 773.7 666.3 750 683.2 721.4 691.6 688 691.6 667.6 691.6 649.6 687.8 634.2 680.3 618.7 672.7 605.4 661.7 594.2 647.1L594.2 750.7 640.9 762.8 640.9 840.3ZM648.2 591C672.4 591 689.3 582 698.7 564.1 708.1 546.1 712.9 521 712.9 488.6L712.9 480.7C712.9 458.3 710.7 438.9 706.4 422.3 702 405.7 695.1 392.9 685.5 383.7 675.9 374.5 663.2 369.9 647.4 369.9 635.9 369.9 625.5 372.5 616.2 377.5 606.9 382.5 599.6 390 594.2 400.1L594.2 566.2C599.6 574.4 607 580.7 616.4 584.8 625.8 589 636.4 591 648.2 591Z",
"width": 1000
},
"search": [
"ip"
]
},
{
"uid": "ffd1698833bf4ed2d4c04041051f336b",
"css": "string",
"code": 59474,
"src": "custom_icons",
"selected": true,
"svg": {
"path": "M659.6 835.5L339.5 835.5 339.5 736.9 413.8 721.5 413.8 266.2 303.8 266.2 299.4 341.6 169.9 341.6 169.9 135.4 831.2 135.4 831.2 341.6 700.2 341.6 696.2 266.2 585.3 266.2 585.3 721.5 659.6 736.9 659.6 835.5Z",
"width": 1000
},
"search": [
"string"
]
},
{
"uid": "d91a2d9df5ed8188f0eb0eaeeebd675d",
"css": "more",
"code": 59478,
"src": "custom_icons",
"selected": true,
"svg": {
"path": "M970 500C970 759.6 759.6 970 500 970 240.4 970 30 759.6 30 500 30 240.4 240.4 30 500 30 759.6 30 970 240.4 970 500ZM680.1 623.6C641.2 623.6 609.6 655.1 609.6 694 609.6 732.9 641.2 764.5 680.1 764.5 719 764.5 750.5 732.9 750.5 694 750.5 655.1 719 623.6 680.1 623.6ZM308.5 621.5C269.6 621.5 238.1 653 238.1 692 238.1 730.9 269.6 762.4 308.5 762.4 347.4 762.4 378.9 730.9 378.9 692 378.9 653 347.4 621.5 308.5 621.5ZM493.6 621.9C454.7 621.9 423.1 653.4 423.1 692.3 423.1 731.2 454.7 762.7 493.6 762.7 532.5 762.7 564 731.2 564 692.3 564 653.4 532.5 621.9 493.6 621.9ZM751.5 694C751.5 713.7 743.4 731.7 730.6 744.5 717.7 757.4 699.7 765.5 680.1 765.5 660.4 765.5 642.4 757.4 629.5 744.5 616.7 731.7 608.6 713.7 608.6 694 608.6 674.4 616.7 656.4 629.5 643.5 642.4 630.6 660.4 622.6 680.1 622.6 699.7 622.6 717.7 630.6 730.6 643.5 743.4 656.4 751.5 674.4 751.5 694ZM729.2 644.9C716.5 632.3 699.3 624.6 680.1 624.6 660.8 624.6 643.6 632.3 631 644.9 618.3 657.5 610.6 674.8 610.6 694 610.6 713.3 618.3 730.5 631 743.1 643.6 755.7 660.8 763.5 680.1 763.5 699.3 763.5 716.5 755.7 729.2 743.1 741.8 730.5 749.5 713.3 749.5 694 749.5 674.8 741.8 657.5 729.2 644.9ZM379.9 692C379.9 711.6 371.9 729.6 359 742.5 346.1 755.3 328.1 763.4 308.5 763.4 288.8 763.4 270.9 755.3 258 742.5 245.1 729.6 237.1 711.6 237.1 692 237.1 672.3 245.1 654.3 258 641.4 270.9 628.6 288.8 620.5 308.5 620.5 328.1 620.5 346.1 628.6 359 641.4 371.9 654.3 379.9 672.3 379.9 692ZM357.6 642.9C345 630.2 327.7 622.5 308.5 622.5 289.2 622.5 272 630.2 259.4 642.9 246.8 655.5 239.1 672.7 239.1 692 239.1 711.2 246.8 728.4 259.4 741.1 272 753.7 289.2 761.4 308.5 761.4 327.7 761.4 345 753.7 357.6 741.1 370.2 728.4 377.9 711.2 377.9 692 377.9 672.7 370.2 655.5 357.6 642.9ZM565 692.3C565 712 557 729.9 544.1 742.8 531.2 755.7 513.2 763.7 493.6 763.7 473.9 763.7 455.9 755.7 443.1 742.8 430.2 729.9 422.1 712 422.1 692.3 422.1 672.6 430.2 654.7 443.1 641.8 455.9 628.9 473.9 620.9 493.6 620.9 513.2 620.9 531.2 628.9 544.1 641.8 557 654.7 565 672.6 565 692.3ZM542.7 643.2C530.1 630.6 512.8 622.9 493.6 622.9 474.3 622.9 457.1 630.6 444.5 643.2 431.9 655.8 424.1 673.1 424.1 692.3 424.1 711.6 431.9 728.8 444.5 741.4 457.1 754 474.3 761.7 493.6 761.7 512.8 761.7 530.1 754 542.7 741.4 555.3 728.8 563 711.6 563 692.3 563 673.1 555.3 655.8 542.7 643.2Z",
"width": 1000
},
"search": [
"more"
]
},
{
"uid": "272e08e0e16226aadf94dcbf33aab2b2",
"css": "key",
"code": 59479,
"src": "elusive"
}
]
}

File diff suppressed because one or more lines are too long

View file

@ -19,6 +19,16 @@ table {
}
}
&.borders {
td, th {
.func-border-end(1px, var(--config-border-fade-super));
&:last-child{
border: none;
}
}
}
thead {
box-shadow: 0 0 2px rgba(0,0,0,.25);
border-bottom: solid 1px var(--config-color-fade-super);
@ -102,10 +112,6 @@ table {
&:first-child {
.func-padding-start(30px);
}
&:last-child {
.func-padding-end(30px);
}
}
td, th {

View file

@ -31,6 +31,7 @@
--config-color-info: #386fd2;
--config-border-color: #f3f3f3;
--config-border-fade: #e0e3e4;
--config-border-fade-super: #f7f7f7;
--config-border-radius: 10px;
--config-prism-background: #373738;
--config-prism-numbers: #39393c;
@ -113,6 +114,7 @@
--config-color-info: #386fd2;
--config-border-color: #262D50;
--config-border-fade: #19203a;
--config-border-fade-super: #262D50;
--config-prism-background: #1F253F;
--config-prism-numbers: #1F253F;
--config-note-background: #171e33;