mirror of
https://github.com/appwrite/appwrite
synced 2026-05-22 08:28:42 +00:00
Merge branch 'feat-sb-uis' into feat-s3-integration
This commit is contained in:
commit
a3d7b5f60b
19 changed files with 16493 additions and 17673 deletions
1
.github/ISSUE_TEMPLATE/bug.yaml
vendored
1
.github/ISSUE_TEMPLATE/bug.yaml
vendored
|
|
@ -37,6 +37,7 @@ body:
|
|||
label: "🎲 Appwrite version"
|
||||
description: "What version of Appwrite are you running?"
|
||||
options:
|
||||
- Version 0.11.x
|
||||
- Version 0.10.x
|
||||
- Version 0.9.x
|
||||
- Version 0.8.x
|
||||
|
|
|
|||
|
|
@ -102,7 +102,6 @@ Getting started with Appwrite is as easy as creating a new project, choosing you
|
|||
* [Getting Started for Android](https://appwrite.io/docs/getting-started-for-android)
|
||||
* [Getting Started for Server](https://appwrite.io/docs/getting-started-for-server)
|
||||
* [Getting Started for CLI](https://appwrite.io/docs/command-line)
|
||||
* Getting Started for iOS (Coming soon...)
|
||||
|
||||
### Services
|
||||
|
||||
|
|
@ -139,8 +138,9 @@ Below is a list of currently supported platforms and languages. If you wish to h
|
|||
* ✅ [.NET](https://github.com/appwrite/sdk-for-dotnet) - **Experimental** (Maintained by the Appwrite Team)
|
||||
|
||||
#### Community
|
||||
* ✅ [Appcelerator Titanium](https://github.com/m1ga/ti.appwrite) (Maintained by [Michael Gangolf](https://github.com/m1ga/))
|
||||
|
||||
* ✅ [Appcelerator Titanium](https://github.com/m1ga/ti.appwrite) (Maintained by [Michael Gangolf](https://github.com/m1ga/))
|
||||
* ✅ [Godot Engine](https://github.com/GodotNuts/appwrite-sdk) (Maintained by [fenix-hub @GodotNuts](https://github.com/fenix-hub))
|
||||
|
||||
Looking for more SDKs? - Help us by contributing a pull request to our [SDK Generator](https://github.com/appwrite/sdk-generator)!
|
||||
|
||||
## Contributing
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ return [
|
|||
[
|
||||
'key' => 'web',
|
||||
'name' => 'Web',
|
||||
'version' => '4.0.4',
|
||||
'version' => '5.0.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-web',
|
||||
'package' => 'https://www.npmjs.com/package/appwrite',
|
||||
'enabled' => true,
|
||||
|
|
@ -190,7 +190,7 @@ return [
|
|||
[
|
||||
'key' => 'nodejs',
|
||||
'name' => 'Node.js',
|
||||
'version' => '2.5.1',
|
||||
'version' => '3.0.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-node',
|
||||
'package' => 'https://www.npmjs.com/package/node-appwrite',
|
||||
'enabled' => true,
|
||||
|
|
@ -208,11 +208,11 @@ return [
|
|||
[
|
||||
'key' => 'deno',
|
||||
'name' => 'Deno',
|
||||
'version' => '0.4.1',
|
||||
'version' => '1.0.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-deno',
|
||||
'package' => 'https://deno.land/x/appwrite',
|
||||
'enabled' => true,
|
||||
'beta' => true,
|
||||
'beta' => false,
|
||||
'dev' => false,
|
||||
'hidden' => false,
|
||||
'family' => APP_PLATFORM_SERVER,
|
||||
|
|
|
|||
|
|
@ -46,9 +46,20 @@ App::get('/v1/health/db')
|
|||
->action(function ($response, $utopia) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\App $utopia */
|
||||
$utopia->getResource('db');
|
||||
try {
|
||||
$db = $utopia->getResource('db'); /* @var $db PDO */
|
||||
|
||||
$response->json(['status' => 'OK']);
|
||||
// Run a small test to check the connection
|
||||
$statement = $db->prepare("SELECT 1;");
|
||||
|
||||
$statement->closeCursor();
|
||||
|
||||
$statement->execute();
|
||||
} catch (Exception $_e) {
|
||||
throw new Exception('Database is not available', 500);
|
||||
}
|
||||
|
||||
return $response->json(['status' => 'OK']);
|
||||
});
|
||||
|
||||
App::get('/v1/health/cache')
|
||||
|
|
@ -64,9 +75,14 @@ App::get('/v1/health/cache')
|
|||
->action(function ($response, $utopia) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\App $utopia */
|
||||
$utopia->getResource('cache');
|
||||
/** @var Redis */
|
||||
$redis = $utopia->getResource('cache');
|
||||
|
||||
$response->json(['status' => 'OK']);
|
||||
if ($redis->ping(true)) {
|
||||
return $response->json(['status' => 'OK']);
|
||||
} else {
|
||||
throw new Exception('Cache is not available', 500);
|
||||
}
|
||||
});
|
||||
|
||||
App::get('/v1/health/time')
|
||||
|
|
|
|||
|
|
@ -234,29 +234,74 @@ App::post('/v1/mock/tests/general/upload')
|
|||
->param('z', null, new ArrayList(new Text(256)), 'Sample array param')
|
||||
->param('file', [], new File(), 'Sample file param', false)
|
||||
->inject('request')
|
||||
->action(function ($x, $y, $z, $file, $request) {
|
||||
->inject('response')
|
||||
->action(function ($x, $y, $z, $file, $request, $response) {
|
||||
/** @var Utopia\Swoole\Request $request */
|
||||
/** @var Utopia\Swoole\Response $response */
|
||||
|
||||
$file = $request->getFiles('file');
|
||||
$file['tmp_name'] = (\is_array($file['tmp_name'])) ? $file['tmp_name'] : [$file['tmp_name']];
|
||||
$file['name'] = (\is_array($file['name'])) ? $file['name'] : [$file['name']];
|
||||
$file['size'] = (\is_array($file['size'])) ? $file['size'] : [$file['size']];
|
||||
|
||||
$contentRange = $request->getHeader('content-range');
|
||||
if(!empty($contentRange)) {
|
||||
$start = $request->getContentRangeStart();
|
||||
$end = $request->getContentRangeEnd();
|
||||
$size = $request->getContentRangeSize();
|
||||
$id = $request->getHeader('x-appwrite-id', '');
|
||||
$file['size'] = (\is_array($file['size'])) ? $file['size'] : [$file['size']];
|
||||
|
||||
foreach ($file['name'] as $i => $name) {
|
||||
if ($name !== 'file.png') {
|
||||
throw new Exception('Wrong file name', 400);
|
||||
if(is_null($start) || is_null($end) || is_null($size)) {
|
||||
throw new Exception('Invalid content-range header', 400);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($file['size'] as $i => $size) {
|
||||
if ($size !== 38756) {
|
||||
throw new Exception('Wrong file size', 400);
|
||||
if($start > $end || $end > $size) {
|
||||
throw new Exception('Invalid content-range header', 400);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($file['tmp_name'] as $i => $tmpName) {
|
||||
if (\md5(\file_get_contents($tmpName)) !== 'd80e7e6999a3eb2ae0d631a96fe135a4') {
|
||||
throw new Exception('Wrong file uploaded', 400);
|
||||
if($start === 0 && !empty($id)) {
|
||||
throw new Exception('First chunked request cannot have id header', 400);
|
||||
}
|
||||
|
||||
if($start !== 0 && $id !== 'newfileid') {
|
||||
throw new Exception('All chunked request must have id header (except first)', 400);
|
||||
}
|
||||
|
||||
if($end !== $size && $end-$start+1 !== 5*1024*1024) {
|
||||
throw new Exception('Chunk size must be 5MB (except last chunk)', 400);
|
||||
}
|
||||
|
||||
foreach ($file['size'] as $i => $sz) {
|
||||
if ($end !== $size && $sz !== 5*1024*1024) {
|
||||
throw new Exception('Wrong chunk size', 400);
|
||||
}
|
||||
|
||||
if($sz > 5*1024*1024) {
|
||||
throw new Exception('Chunk size must be 5MB or less', 400);
|
||||
}
|
||||
}
|
||||
if($end !== $size) {
|
||||
$response->json(['$id'=> 'newfileid']);
|
||||
}
|
||||
} else {
|
||||
$file['tmp_name'] = (\is_array($file['tmp_name'])) ? $file['tmp_name'] : [$file['tmp_name']];
|
||||
$file['name'] = (\is_array($file['name'])) ? $file['name'] : [$file['name']];
|
||||
$file['size'] = (\is_array($file['size'])) ? $file['size'] : [$file['size']];
|
||||
|
||||
foreach ($file['name'] as $i => $name) {
|
||||
if ($name !== 'file.png') {
|
||||
throw new Exception('Wrong file name', 400);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($file['size'] as $i => $size) {
|
||||
if ($size !== 38756) {
|
||||
throw new Exception('Wrong file size', 400);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($file['tmp_name'] as $i => $tmpName) {
|
||||
if (\md5(\file_get_contents($tmpName)) !== 'd80e7e6999a3eb2ae0d631a96fe135a4') {
|
||||
throw new Exception('Wrong file uploaded', 400);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -330,9 +330,9 @@ $fileLimitHuman = $this->getParam('fileLimitHuman', 0);
|
|||
|
||||
<h2>Usage</h2>
|
||||
|
||||
<h3 class="margin-bottom-tiny">Objects</h3>
|
||||
<p class="text-fade">Count of files over time</p>
|
||||
<div data-service="storage.getBucketUsage" data-event="load" data-name="usage" data-param-bucket-id="{{router.params.id}}">
|
||||
<h3 class="margin-bottom-tiny">Files</h3>
|
||||
<p class="text-fade">Count of files over time</p>
|
||||
<div class="box margin-bottom-small">
|
||||
<div class="margin-start-negative-small margin-end-negative-small margin-top-negative-small margin-bottom-negative-small">
|
||||
<div class="chart background-image-no border-no margin-bottom-no">
|
||||
|
|
@ -345,7 +345,7 @@ $fileLimitHuman = $this->getParam('fileLimitHuman', 0);
|
|||
<li>Files <span data-ls-bind="({{usage.filesCount|statsGetLast|statsTotal}})"></span></li>
|
||||
</ul>
|
||||
|
||||
<h3 class="margin-bottom-tiny">Files</h3>
|
||||
<h3 class="margin-bottom-tiny">Operations</h3>
|
||||
<p class="text-fade">Count of files create, read, update and delete operations over time</p>
|
||||
<div class="box margin-bottom-small">
|
||||
<div class="margin-start-negative-small margin-end-negative-small margin-top-negative-small margin-bottom-negative-small">
|
||||
|
|
@ -356,10 +356,10 @@ $fileLimitHuman = $this->getParam('fileLimitHuman', 0);
|
|||
</div>
|
||||
|
||||
<ul class="chart-notes crud margin-bottom-large">
|
||||
<li class="green">Create <span data-ls-bind="({{usage.filesCreate|statsGetLast|statsTotal}})"></span></li>
|
||||
<li class="green">Read <span data-ls-bind="({{usage.filesRead|statsGetLast|statsTotal}})"></span></li>
|
||||
<li class="green">Update <span data-ls-bind="({{usage.filesUpdate|statsGetLast|statsTotal}})"></span></li>
|
||||
<li class="green">Delete <span data-ls-bind="({{usage.filesDelete|statsGetLast|statsTotal}})"></span></li>
|
||||
<li>Create <span data-ls-bind="({{usage.filesCreate|statsGetLast|statsTotal}})"></span></li>
|
||||
<li>Read <span data-ls-bind="({{usage.filesRead|statsGetLast|statsTotal}})"></span></li>
|
||||
<li>Update <span data-ls-bind="({{usage.filesUpdate|statsGetLast|statsTotal}})"></span></li>
|
||||
<li>Delete <span data-ls-bind="({{usage.filesDelete|statsGetLast|statsTotal}})"></span></li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
data-param-search="{{router.params.search}}"
|
||||
data-param-limit="<?php echo APP_PAGING_LIMIT; ?>"
|
||||
data-param-offset="{{router.params.offset}}"
|
||||
data-param-order-type="ASC"
|
||||
data-param-order-type="DESC"
|
||||
data-scope="sdk"
|
||||
data-name="project-buckets">
|
||||
|
||||
|
|
@ -160,7 +160,7 @@
|
|||
<div class="box">
|
||||
<div class="margin-start-negative-small margin-end-negative-small margin-top-negative-small margin-bottom-negative-small">
|
||||
<div class="chart background-image-no border-no margin-bottom-no">
|
||||
<input type="hidden" data-ls-bind="{{usage}}" data-show-y-axis="true" data-forms-chart="Total Files=filesCount,Total Buckets=bucketsCount"/>
|
||||
<input type="hidden" data-ls-bind="{{usage}}" data-show-y-axis="true" data-forms-chart="Total Files=filesCount,Total Buckets=bucketsCount" data-height="140" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@
|
|||
}
|
||||
],
|
||||
"require-dev": {
|
||||
"appwrite/sdk-generator": "0.16.0",
|
||||
"appwrite/sdk-generator": "0.16.2",
|
||||
"phpunit/phpunit": "9.5.6",
|
||||
"swoole/ide-helper": "4.6.7",
|
||||
"textalk/websocket": "1.5.2",
|
||||
|
|
|
|||
14
composer.lock
generated
14
composer.lock
generated
|
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "bd77c6854e858381edef57388096a498",
|
||||
"content-hash": "d2f722e3c9fb35f72fba310543755c76",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adhocore/jwt",
|
||||
|
|
@ -2986,16 +2986,16 @@
|
|||
},
|
||||
{
|
||||
"name": "appwrite/sdk-generator",
|
||||
"version": "0.16.0",
|
||||
"version": "0.16.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/appwrite/sdk-generator.git",
|
||||
"reference": "5a57afe89ded393a3eca8d9ba96b8e2c479f2601"
|
||||
"reference": "e3a20c96a745a9c4aa048fd344650fcfbf41cf6f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/5a57afe89ded393a3eca8d9ba96b8e2c479f2601",
|
||||
"reference": "5a57afe89ded393a3eca8d9ba96b8e2c479f2601",
|
||||
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/e3a20c96a745a9c4aa048fd344650fcfbf41cf6f",
|
||||
"reference": "e3a20c96a745a9c4aa048fd344650fcfbf41cf6f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -3029,9 +3029,9 @@
|
|||
"description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms",
|
||||
"support": {
|
||||
"issues": "https://github.com/appwrite/sdk-generator/issues",
|
||||
"source": "https://github.com/appwrite/sdk-generator/tree/0.16.0"
|
||||
"source": "https://github.com/appwrite/sdk-generator/tree/0.16.2"
|
||||
},
|
||||
"time": "2021-10-21T06:49:55+00:00"
|
||||
"time": "2021-11-12T11:09:38+00:00"
|
||||
},
|
||||
{
|
||||
"name": "composer/semver",
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ client
|
|||
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
|
||||
.setSelfSigned() // Use only on dev mode with a self-signed SSL cert
|
||||
;
|
||||
|
||||
```
|
||||
|
||||
### Make your first request
|
||||
|
|
@ -22,13 +21,8 @@ Once your SDK object is set, create any of the Appwrite service objects and choo
|
|||
```typescript
|
||||
let users = new sdk.Users(client);
|
||||
|
||||
let promise = users.create('email@example.com', 'password');
|
||||
|
||||
promise.then(function (response) {
|
||||
console.log(response);
|
||||
}, function (error) {
|
||||
console.log(error);
|
||||
});
|
||||
let response = await users.create('email@example.com', 'password');
|
||||
console.log(response);
|
||||
```
|
||||
|
||||
### Full Example
|
||||
|
|
@ -45,13 +39,8 @@ client
|
|||
.setSelfSigned() // Use only on dev mode with a self-signed SSL cert
|
||||
;
|
||||
|
||||
let promise = users.create('email@example.com', 'password');
|
||||
|
||||
promise.then(function (response) {
|
||||
console.log(response);
|
||||
}, function (error) {
|
||||
console.log(error);
|
||||
});
|
||||
let response = await users.create('email@example.com', 'password');
|
||||
console.log(response);
|
||||
```
|
||||
|
||||
### Error Handling
|
||||
|
|
@ -61,7 +50,7 @@ The Appwrite Deno SDK raises `AppwriteException` object with `message`, `code` a
|
|||
let users = new sdk.Users(client);
|
||||
|
||||
try {
|
||||
let res = await users.create('email@example.com', 'password');
|
||||
let response = await users.create('email@example.com', 'password');
|
||||
} catch(e) {
|
||||
console.log(e.message);
|
||||
}
|
||||
|
|
|
|||
2481
public/dist/scripts/app-all.js
vendored
2481
public/dist/scripts/app-all.js
vendored
File diff suppressed because it is too large
Load diff
2475
public/dist/scripts/app-dep.js
vendored
2475
public/dist/scripts/app-dep.js
vendored
File diff suppressed because it is too large
Load diff
6
public/dist/scripts/app.js
vendored
6
public/dist/scripts/app.js
vendored
|
|
@ -374,8 +374,10 @@ button.addEventListener("click",function(){var clone=document.createElement(elem
|
|||
clone.innerHTML=template;clone.className=element.className;var input=clone.querySelector("input, select, textarea");view.render(clone);if(target){target.appendChild(clone);}else{button.parentNode.insertBefore(clone,button);}
|
||||
if(input){input.focus();}
|
||||
Array.prototype.slice.call(clone.querySelectorAll("[data-remove]")).map(function(obj){obj.addEventListener("click",function(){clone.parentNode.removeChild(clone);obj.scrollIntoView({behavior:"smooth"});});});Array.prototype.slice.call(clone.querySelectorAll("[data-up]")).map(function(obj){obj.addEventListener("click",function(){if(clone.previousElementSibling){clone.parentNode.insertBefore(clone,clone.previousElementSibling);obj.scrollIntoView({behavior:"smooth"});}});});Array.prototype.slice.call(clone.querySelectorAll("[data-down]")).map(function(obj){obj.addEventListener("click",function(){if(clone.nextElementSibling){clone.parentNode.insertBefore(clone.nextElementSibling,clone);obj.scrollIntoView({behavior:"smooth"});}});});});element.parentNode.insertBefore(button,element.nextSibling);element.parentNode.removeChild(element);button.form.addEventListener('reset',function(event){target.innerHTML='';if(first){button.click();}});if(first){button.click();}}});})(window);(function(window){"use strict";window.ls.container.get("view").add({selector:"data-forms-add",repeat:false,controller:function(element,view,container,document){for(var i=0;i<element.children.length;i++){let button=document.createElement("button");let template=element.children[i].cloneNode(true);let as=element.getAttribute('data-ls-as');let counter=0;button.type="button";button.innerText="Add";button.classList.add("reverse");button.classList.add("margin-end-small");button.addEventListener('click',function(){container.addNamespace(as,'new-'+counter++);console.log(container.namespaces,container.get(as),as);container.set(as,null,true,true);let child=template.cloneNode(true);view.render(child);element.appendChild(child);element.style.visibility='visible';let inputs=child.querySelectorAll('input,textarea');for(let index=0;index<inputs.length;++index){if(inputs[index].type!=='hidden'){inputs[index].focus();break;}}});element.after(button);}}});})(window);(function(window){"use strict";window.ls.container.get("view").add({selector:"data-forms-chart",controller:function(element,container,date,document){let wrapper=document.createElement("div");let child=document.createElement("canvas");let sources=element.getAttribute('data-forms-chart');let width=element.getAttribute('data-width')||500;let height=element.getAttribute('data-height')||175;let showXAxis=element.getAttribute('data-show-x-axis')||false;let showYAxis=element.getAttribute('data-show-y-axis')||false;let colors=(element.getAttribute('data-colors')||'blue,green,orange,red').split(',');let themes={'blue':'#29b5d9','green':'#4eb55b','orange':'#fba233','red':'#dc3232','create':'#00b680','read':'#009cde','update':'#696fd7','delete':'#da5d95',};let range={'24h':'H:i','7d':'d F Y','30d':'d F Y','90d':'d F Y'}
|
||||
element.parentNode.insertBefore(wrapper,element.nextSibling);wrapper.classList.add('content');child.width=width;child.height=height;sources=sources.split(',');wrapper.appendChild(child);let chart=null;let check=function(){let config={type:"line",data:{labels:[],datasets:[]},options:{responsive:true,title:{display:false,text:"Stats"},legend:{display:false},tooltips:{mode:"index",intersect:false,caretPadding:0},hover:{mode:"nearest",intersect:true},scales:{xAxes:[{display:showXAxis}],yAxes:[{display:showYAxis,ticks:{fontColor:"#8f8f8f"}}]}}};for(let i=0;i<sources.length;i++){let label=sources[i].substring(0,sources[i].indexOf('='));let path=sources[i].substring(sources[i].indexOf('=')+1);let usage=container.get('usage');let data=usage[path];let value=JSON.parse(element.value);config.data.labels[i]=label;config.data.datasets[i]={};config.data.datasets[i].label=label;config.data.datasets[i].borderColor=themes[colors[i]];config.data.datasets[i].backgroundColor=themes[colors[i]]+'36';config.data.datasets[i].borderWidth=2;config.data.datasets[i].data=[0,0,0,0,0,0,0];config.data.datasets[i].fill=true;if(!data){return;}
|
||||
let dateFormat=(value.range&&range[value.range])?range[value.range]:'d F Y';for(let x=0;x<data.length;x++){config.data.datasets[i].data[x]=data[x].value;config.data.labels[x]=date.format(dateFormat,data[x].date);}}
|
||||
let ticksCount=5;element.parentNode.insertBefore(wrapper,element.nextSibling);wrapper.classList.add('content');child.width=width;child.height=height;sources=sources.split(',');wrapper.appendChild(child);let chart=null;let check=function(){let config={type:"line",data:{labels:[],datasets:[]},options:{responsive:true,hover:{mode:"nearest",intersect:true},scales:{x:{display:showXAxis},y:{display:showYAxis,min:0,ticks:{count:ticksCount,},}},plugins:{title:{display:false,text:"Stats"},legend:{display:false},tooltip:{mode:"index",intersect:false,caretPadding:0},}}};let highest=0;for(let i=0;i<sources.length;i++){let label=sources[i].substring(0,sources[i].indexOf('='));let path=sources[i].substring(sources[i].indexOf('=')+1);let usage=container.get('usage');let data=usage[path];let value=JSON.parse(element.value);config.data.labels[i]=label;config.data.datasets[i]={};config.data.datasets[i].label=label;config.data.datasets[i].borderColor=themes[colors[i]];config.data.datasets[i].backgroundColor=themes[colors[i]]+'36';config.data.datasets[i].borderWidth=2;config.data.datasets[i].data=[0,0,0,0,0,0,0];config.data.datasets[i].fill=true;if(!data){return;}
|
||||
let dateFormat=(value.range&&range[value.range])?range[value.range]:'d F Y';for(let x=0;x<data.length;x++){if(data[x].value>highest){highest=data[x].value;}
|
||||
config.data.datasets[i].data[x]=data[x].value;config.data.labels[x]=date.format(dateFormat,data[x].date);}}
|
||||
if(highest==0){config.options.scales.y.ticks.stepSize=1;config.options.scales.y.max=ticksCount;}else{highest=Math.ceil(highest/ticksCount)*ticksCount;config.options.scales.y.ticks.stepSize=highest/ticksCount;config.options.scales.y.max=highest;}
|
||||
if(chart){chart.destroy();}
|
||||
else{}
|
||||
chart=new Chart(child.getContext("2d"),config);wrapper.dataset["canvas"]=true;}
|
||||
|
|
|
|||
2
public/dist/styles/default-ltr.css
vendored
2
public/dist/styles/default-ltr.css
vendored
File diff suppressed because one or more lines are too long
2
public/dist/styles/default-rtl.css
vendored
2
public/dist/styles/default-rtl.css
vendored
File diff suppressed because one or more lines are too long
Binary file not shown.
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 86 KiB |
File diff suppressed because it is too large
Load diff
|
|
@ -14,6 +14,7 @@
|
|||
let colors = (element.getAttribute('data-colors') || 'blue,green,orange,red').split(',');
|
||||
let themes = {'blue': '#29b5d9', 'green': '#4eb55b', 'orange': '#fba233', 'red': '#dc3232', 'create': '#00b680', 'read': '#009cde', 'update': '#696fd7', 'delete': '#da5d95',};
|
||||
let range = {'24h': 'H:i', '7d': 'd F Y', '30d': 'd F Y', '90d': 'd F Y'}
|
||||
let ticksCount = 5;
|
||||
|
||||
element.parentNode.insertBefore(wrapper, element.nextSibling);
|
||||
|
||||
|
|
@ -38,40 +39,40 @@
|
|||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
title: {
|
||||
display: false,
|
||||
text: "Stats"
|
||||
},
|
||||
legend: {
|
||||
display: false
|
||||
},
|
||||
tooltips: {
|
||||
mode: "index",
|
||||
intersect: false,
|
||||
caretPadding: 0
|
||||
},
|
||||
hover: {
|
||||
mode: "nearest",
|
||||
intersect: true
|
||||
},
|
||||
scales: {
|
||||
xAxes: [
|
||||
{
|
||||
display: showXAxis
|
||||
}
|
||||
],
|
||||
yAxes: [
|
||||
{
|
||||
display: showYAxis,
|
||||
ticks: {
|
||||
fontColor: "#8f8f8f"
|
||||
}
|
||||
}
|
||||
]
|
||||
x: {
|
||||
display: showXAxis
|
||||
},
|
||||
y: {
|
||||
display: showYAxis,
|
||||
min: 0,
|
||||
ticks: {
|
||||
count: ticksCount,
|
||||
},
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
title: {
|
||||
display: false,
|
||||
text: "Stats"
|
||||
},
|
||||
legend: {
|
||||
display: false
|
||||
},
|
||||
tooltip: {
|
||||
mode: "index",
|
||||
intersect: false,
|
||||
caretPadding: 0
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let highest = 0;
|
||||
for (let i = 0; i < sources.length; i++) {
|
||||
let label = sources[i].substring(0, sources[i].indexOf('='));
|
||||
let path = sources[i].substring(sources[i].indexOf('=') + 1);
|
||||
|
|
@ -95,10 +96,23 @@
|
|||
let dateFormat = (value.range && range[value.range]) ? range[value.range] : 'd F Y';
|
||||
|
||||
for (let x = 0; x < data.length; x++) {
|
||||
if(data[x].value > highest) {
|
||||
highest = data[x].value;
|
||||
}
|
||||
config.data.datasets[i].data[x] = data[x].value;
|
||||
config.data.labels[x] = date.format(dateFormat, data[x].date);
|
||||
}
|
||||
}
|
||||
|
||||
if(highest == 0) {
|
||||
config.options.scales.y.ticks.stepSize = 1;
|
||||
config.options.scales.y.max = ticksCount;
|
||||
} else {
|
||||
// ceiling of the highest value
|
||||
highest = Math.ceil(highest / ticksCount) * ticksCount;
|
||||
config.options.scales.y.ticks.stepSize = highest / ticksCount;
|
||||
config.options.scales.y.max = highest;
|
||||
}
|
||||
|
||||
if(chart) {
|
||||
chart.destroy();
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
--config-width-large: 700px;
|
||||
--config-width-medium: 550px;
|
||||
--config-width-small: 320px;
|
||||
--config-color-primary: #f02e65;
|
||||
--config-color-link: #1e849e;
|
||||
--config-color-background: #eceff1;
|
||||
--config-color-background-dark: #dfe2e4;
|
||||
|
|
@ -93,6 +94,7 @@
|
|||
--config-console-nav-switch-arrow: url("data:image/svg+xml;utf8,<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='24' height='24' viewBox='0 0 24 24'><path fill='%23868686' d='M7.406 7.828l4.594 4.594 4.594-4.594 1.406 1.406-6 6-6-6z'></path></svg>");
|
||||
|
||||
.theme-dark {
|
||||
--config-color-primary: #f02e65;
|
||||
--config-color-background: #061F2F;
|
||||
--config-color-background-dark: #262d50;
|
||||
--config-color-background-fade: #1c223a;
|
||||
|
|
|
|||
Loading…
Reference in a new issue