Added a new document-level activity log
This commit is contained in:
parent
1d47ace629
commit
e862d72cf6
File diff suppressed because one or more lines are too long
|
@ -1256,6 +1256,109 @@ App::get('/v1/database/collections/:collectionId/documents/:documentId')
|
||||||
$response->dynamic($document, Response::MODEL_DOCUMENT);
|
$response->dynamic($document, Response::MODEL_DOCUMENT);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
App::get('/v1/database/collections/:collectionId/documents/:documentId/logs')
|
||||||
|
->desc('List Document Logs')
|
||||||
|
->groups(['api', 'database'])
|
||||||
|
->label('scope', 'documents.read')
|
||||||
|
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
|
||||||
|
->label('sdk.namespace', 'database')
|
||||||
|
->label('sdk.method', 'listDocumentLogs')
|
||||||
|
->label('sdk.description', '/docs/references/database/get-document-logs.md')
|
||||||
|
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||||
|
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||||
|
->label('sdk.response.model', Response::MODEL_LOG_LIST)
|
||||||
|
->param('collectionId', '', new UID(), 'Collection unique ID.')
|
||||||
|
->param('documentId', null, new UID(), 'Document unique ID.')
|
||||||
|
->inject('response')
|
||||||
|
->inject('dbForInternal')
|
||||||
|
->inject('dbForExternal')
|
||||||
|
->inject('locale')
|
||||||
|
->inject('geodb')
|
||||||
|
->action(function ($collectionId, $documentId, $response, $dbForInternal, $dbForExternal, $locale, $geodb) {
|
||||||
|
/** @var Appwrite\Utopia\Response $response */
|
||||||
|
/** @var Utopia\Database\Document $project */
|
||||||
|
/** @var Utopia\Database\Database $dbForInternal */
|
||||||
|
/** @var Utopia\Database\Database $dbForExternal */
|
||||||
|
/** @var Utopia\Locale\Locale $locale */
|
||||||
|
/** @var MaxMind\Db\Reader $geodb */
|
||||||
|
|
||||||
|
$collection = $dbForInternal->getDocument('collections', $collectionId);
|
||||||
|
|
||||||
|
if ($collection->isEmpty()) {
|
||||||
|
throw new Exception('Collection not found', 404);
|
||||||
|
}
|
||||||
|
|
||||||
|
$document = $dbForExternal->getDocument($collectionId, $documentId);
|
||||||
|
|
||||||
|
if ($document->isEmpty()) {
|
||||||
|
throw new Exception('No document found', 404);
|
||||||
|
}
|
||||||
|
|
||||||
|
$audit = new Audit($dbForInternal);
|
||||||
|
|
||||||
|
$logs = $audit->getLogsByResource('database/document/'.$document->getId());
|
||||||
|
|
||||||
|
$output = [];
|
||||||
|
|
||||||
|
foreach ($logs as $i => &$log) {
|
||||||
|
$log['userAgent'] = (!empty($log['userAgent'])) ? $log['userAgent'] : 'UNKNOWN';
|
||||||
|
|
||||||
|
$dd = new DeviceDetector($log['userAgent']);
|
||||||
|
|
||||||
|
$dd->skipBotDetection(); // OPTIONAL: If called, bot detection will completely be skipped (bots will be detected as regular devices then)
|
||||||
|
|
||||||
|
$dd->parse();
|
||||||
|
|
||||||
|
$os = $dd->getOs();
|
||||||
|
$osCode = (isset($os['short_name'])) ? $os['short_name'] : '';
|
||||||
|
$osName = (isset($os['name'])) ? $os['name'] : '';
|
||||||
|
$osVersion = (isset($os['version'])) ? $os['version'] : '';
|
||||||
|
|
||||||
|
$client = $dd->getClient();
|
||||||
|
$clientType = (isset($client['type'])) ? $client['type'] : '';
|
||||||
|
$clientCode = (isset($client['short_name'])) ? $client['short_name'] : '';
|
||||||
|
$clientName = (isset($client['name'])) ? $client['name'] : '';
|
||||||
|
$clientVersion = (isset($client['version'])) ? $client['version'] : '';
|
||||||
|
$clientEngine = (isset($client['engine'])) ? $client['engine'] : '';
|
||||||
|
$clientEngineVersion = (isset($client['engine_version'])) ? $client['engine_version'] : '';
|
||||||
|
|
||||||
|
$output[$i] = new Document([
|
||||||
|
'event' => $log['event'],
|
||||||
|
'userId' => $log['userId'],
|
||||||
|
'userEmail' => $log['data']['userEmail'] ?? null,
|
||||||
|
'userName' => $log['data']['userName'] ?? null,
|
||||||
|
'mode' => $log['data']['mode'] ?? null,
|
||||||
|
'ip' => $log['ip'],
|
||||||
|
'time' => $log['time'],
|
||||||
|
|
||||||
|
'osCode' => $osCode,
|
||||||
|
'osName' => $osName,
|
||||||
|
'osVersion' => $osVersion,
|
||||||
|
'clientType' => $clientType,
|
||||||
|
'clientCode' => $clientCode,
|
||||||
|
'clientName' => $clientName,
|
||||||
|
'clientVersion' => $clientVersion,
|
||||||
|
'clientEngine' => $clientEngine,
|
||||||
|
'clientEngineVersion' => $clientEngineVersion,
|
||||||
|
'deviceName' => $dd->getDeviceName(),
|
||||||
|
'deviceBrand' => $dd->getBrandName(),
|
||||||
|
'deviceModel' => $dd->getModel(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$record = $geodb->get($log['ip']);
|
||||||
|
|
||||||
|
if ($record) {
|
||||||
|
$output[$i]['countryCode'] = $locale->getText('countries.'.strtolower($record['country']['iso_code']), false) ? \strtolower($record['country']['iso_code']) : '--';
|
||||||
|
$output[$i]['countryName'] = $locale->getText('countries.'.strtolower($record['country']['iso_code']), $locale->getText('locale.country.unknown'));
|
||||||
|
} else {
|
||||||
|
$output[$i]['countryCode'] = '--';
|
||||||
|
$output[$i]['countryName'] = $locale->getText('locale.country.unknown');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$response->dynamic(new Document(['logs' => $output]), Response::MODEL_LOG_LIST);
|
||||||
|
});
|
||||||
|
|
||||||
App::patch('/v1/database/collections/:collectionId/documents/:documentId')
|
App::patch('/v1/database/collections/:collectionId/documents/:documentId')
|
||||||
->desc('Update Document')
|
->desc('Update Document')
|
||||||
->groups(['api', 'database'])
|
->groups(['api', 'database'])
|
||||||
|
|
|
@ -218,6 +218,10 @@ App::get('/console/database/collection')
|
||||||
|
|
||||||
$logs
|
$logs
|
||||||
->setParam('interval', App::getEnv('_APP_MAINTENANCE_RETENTION_AUDIT', 0))
|
->setParam('interval', App::getEnv('_APP_MAINTENANCE_RETENTION_AUDIT', 0))
|
||||||
|
->setParam('method', 'database.listCollectionLogs')
|
||||||
|
->setParam('params', [
|
||||||
|
'collection-id' => '{{router.params.id}}',
|
||||||
|
])
|
||||||
;
|
;
|
||||||
|
|
||||||
$page = new View(__DIR__.'/../../views/console/database/collection.phtml');
|
$page = new View(__DIR__.'/../../views/console/database/collection.phtml');
|
||||||
|
@ -245,14 +249,45 @@ App::get('/console/database/document')
|
||||||
->action(function ($collection, $layout) {
|
->action(function ($collection, $layout) {
|
||||||
/** @var Utopia\View $layout */
|
/** @var Utopia\View $layout */
|
||||||
|
|
||||||
|
$logs = new View(__DIR__.'/../../views/console/comps/logs.phtml');
|
||||||
|
|
||||||
|
$logs
|
||||||
|
->setParam('interval', App::getEnv('_APP_MAINTENANCE_RETENTION_AUDIT', 0))
|
||||||
|
->setParam('method', 'database.listDocumentLogs')
|
||||||
|
->setParam('params', [
|
||||||
|
'collection-id' => '{{router.params.collection}}',
|
||||||
|
'document-id' => '{{router.params.id}}',
|
||||||
|
])
|
||||||
|
;
|
||||||
|
|
||||||
$page = new View(__DIR__.'/../../views/console/database/document.phtml');
|
$page = new View(__DIR__.'/../../views/console/database/document.phtml');
|
||||||
$searchFiles = new View(__DIR__.'/../../views/console/database/search/files.phtml');
|
|
||||||
$searchDocuments = new View(__DIR__.'/../../views/console/database/search/documents.phtml');
|
|
||||||
|
|
||||||
$page
|
$page
|
||||||
|
->setParam('new', false)
|
||||||
->setParam('collection', $collection)
|
->setParam('collection', $collection)
|
||||||
->setParam('searchFiles', $searchFiles)
|
->setParam('logs', $logs)
|
||||||
->setParam('searchDocuments', $searchDocuments)
|
;
|
||||||
|
|
||||||
|
$layout
|
||||||
|
->setParam('title', APP_NAME.' - Database Document')
|
||||||
|
->setParam('body', $page);
|
||||||
|
});
|
||||||
|
|
||||||
|
App::get('/console/database/document/new')
|
||||||
|
->groups(['web', 'console'])
|
||||||
|
->label('permission', 'public')
|
||||||
|
->label('scope', 'console')
|
||||||
|
->param('collection', '', new UID(), 'Collection unique ID.')
|
||||||
|
->inject('layout')
|
||||||
|
->action(function ($collection, $layout) {
|
||||||
|
/** @var Utopia\View $layout */
|
||||||
|
|
||||||
|
$page = new View(__DIR__.'/../../views/console/database/document.phtml');
|
||||||
|
|
||||||
|
$page
|
||||||
|
->setParam('new', true)
|
||||||
|
->setParam('collection', $collection)
|
||||||
|
->setParam('logs', new View())
|
||||||
;
|
;
|
||||||
|
|
||||||
$layout
|
$layout
|
||||||
|
|
|
@ -1,78 +1,88 @@
|
||||||
<?php
|
<?php
|
||||||
$interval = floor((int)$this->getParam('interval', 0) / 86400);
|
$interval = floor((int)$this->getParam('interval', 0) / 86400);
|
||||||
|
$method = $this->getParam('method', '');
|
||||||
|
$params = $this->getParam('params', []);
|
||||||
?>
|
?>
|
||||||
<div
|
<div
|
||||||
|
data-service="<?php echo $method; ?>"
|
||||||
data-service="database.listCollectionLogs"
|
data-service="database.listCollectionLogs"
|
||||||
data-param-collection-id="{{router.params.id}}"
|
<?php foreach($params as $key => $value): ?>
|
||||||
|
data-param-<?php echo $key; ?>="<?php echo $value; ?>"
|
||||||
|
<?php endforeach; ?>
|
||||||
data-scope="sdk"
|
data-scope="sdk"
|
||||||
data-event="load"
|
data-event="load"
|
||||||
data-name="project-collection-logs">
|
data-name="logs">
|
||||||
|
<div data-ls-if="0 == {{logs.logs.length}}">
|
||||||
<div class="box margin-bottom">
|
<div class="box margin-bottom">
|
||||||
<div data-ls-if="0 == {{project-collection-logs.logs.length}}">
|
|
||||||
<h3 class="margin-bottom-small text-bold">No Logs Found</h3>
|
<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>
|
<p class="margin-bottom-no">Logs are retained for <?php echo $this->escape($interval); ?> days.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<table class="vertical small" data-ls-if="0 != {{project-collection-logs.logs.length}}">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th width="120">Date</th>
|
|
||||||
<th width="180">Initiator</th>
|
|
||||||
<th>Event</th>
|
|
||||||
<th width="110">Location</th>
|
|
||||||
<th width="90">IP</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody data-ls-loop="project-collection-logs.logs" data-ls-as="log" class="text-size-small">
|
|
||||||
<tr>
|
|
||||||
<td data-title="Date: "><span class="text-fade" data-ls-bind="{{log.time|dateTime}}"></span></td>
|
|
||||||
<td data-title="Initiator: ">
|
|
||||||
<span data-ls-if="{{log.userName|escape}} !== '' && {{log.mode}} === ''"><i class="icon-user"></i> <a data-ls-attrs="href=/console/users/user?id={{log.userId}}&project={{router.params.project}}" data-ls-bind="{{log.userName}}"></a></span>
|
|
||||||
<span data-ls-if="{{log.userName|escape}} === '' && {{log.userEmail}} !== '' && {{log.mode}} !== 'key'"><i class="icon-user"></i> Unknown</span>
|
|
||||||
<span data-ls-if="{{log.userName|escape}} === '' && {{log.userEmail}} === '' && {{log.mode}} !== 'key'"><i class="icon-user"></i> Anonymous User</span>
|
|
||||||
<span data-ls-if="{{log.mode}} === 'admin'">
|
|
||||||
<img src="" data-ls-attrs="src={{log.userName|avatar}}" data-size="45" alt="User Avatar" class="avatar xxs inline margin-end-small" loading="lazy" width="30" height="30" /> <span data-ls-bind="{{log.userName}}"></span> <span class="text-fade text-size-xs">(Admin)</span>
|
|
||||||
</span>
|
|
||||||
<span data-ls-if="{{log.mode}} === 'key'"> <i class="icon-key"></i> API Key</span>
|
|
||||||
</td>
|
|
||||||
<td data-title="Event: "><span data-ls-bind="{{log.event}}"></span></td>
|
|
||||||
<td data-title="Location: ">
|
|
||||||
<img onerror="this.onerror=null;this.className='avatar xxs hide'" data-ls-attrs="src={{env.API}}/avatars/flags/{{log.countryCode}}?width=80&height=80&project={{env.PROJECT}}" class="avatar xxs inline margin-end-small" />
|
|
||||||
<span data-ls-bind="{{log.countryName}}"></span>
|
|
||||||
</td>
|
|
||||||
<td data-title="IP: "><span data-ls-bind="{{log.ip}}"></span></td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="pull-end text-align-center paging">
|
<div data-ls-if="0 != {{logs.logs.length}}">
|
||||||
<form
|
<div class="margin-bottom-small margin-top-negative text-align-end text-size-small text-fade">Showing logs from the last <?php echo $this->escape($interval); ?> days</div>
|
||||||
data-service="database.listCollectionLogs"
|
|
||||||
data-event="submit"
|
|
||||||
data-param-collection-id="{{router.params.id}}"
|
|
||||||
data-param-limit="<?php echo APP_PAGING_LIMIT; ?>"
|
|
||||||
data-param-order-type="DESC"
|
|
||||||
data-scope="sdk"
|
|
||||||
data-name="project-collection-logs"
|
|
||||||
data-success="state"
|
|
||||||
data-success-param-state-keys="search,offset">
|
|
||||||
<button name="offset" data-paging-back data-offset="{{router.params.offset}}" data-sum="{{project-collection-logs.sum}}" class="margin-end-small round small" aria-label="Back"><i class="icon-left-open"></i></button>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<form
|
<div class="box margin-bottom">
|
||||||
data-service="database.listCollectionLogs"
|
<table class="vertical small">
|
||||||
data-event="submit"
|
<thead>
|
||||||
data-param-collection-id="{{router.params.id}}"
|
<tr>
|
||||||
data-param-limit="<?php echo APP_PAGING_LIMIT; ?>"
|
<th width="120">Date</th>
|
||||||
data-param-order-type="DESC"
|
<th width="180">Initiator</th>
|
||||||
data-scope="sdk"
|
<th>Event</th>
|
||||||
data-name="project-collection-logs"
|
<th width="110">Location</th>
|
||||||
data-success="state"
|
<th width="90">IP</th>
|
||||||
data-success-param-state-keys="search,offset">
|
</tr>
|
||||||
<button name="offset" data-paging-next data-offset="{{router.params.offset}}" data-sum="{{project-collection-logs.sum}}" class="margin-start-small round small" aria-label="Next"><i class="icon-right-open"></i></button>
|
</thead>
|
||||||
</form>
|
<tbody data-ls-loop="logs.logs" data-ls-as="log" class="text-size-small">
|
||||||
</div>
|
<tr>
|
||||||
|
<td data-title="Date: "><span class="text-fade" data-ls-bind="{{log.time|dateTime}}"></span></td>
|
||||||
|
<td data-title="Initiator: ">
|
||||||
|
<span data-ls-if="{{log.userName|escape}} !== '' && {{log.mode}} === ''"><i class="icon-user"></i> <a data-ls-attrs="href=/console/users/user?id={{log.userId}}&project={{router.params.project}}" data-ls-bind="{{log.userName}}"></a></span>
|
||||||
|
<span data-ls-if="{{log.userName|escape}} === '' && {{log.userEmail}} !== '' && {{log.mode}} !== 'key'"><i class="icon-user"></i> Unknown</span>
|
||||||
|
<span data-ls-if="{{log.userName|escape}} === '' && {{log.userEmail}} === '' && {{log.mode}} !== 'key'"><i class="icon-user"></i> Anonymous User</span>
|
||||||
|
<span data-ls-if="{{log.mode}} === 'admin'">
|
||||||
|
<img src="" data-ls-attrs="src={{log.userName|avatar}}" data-size="45" alt="User Avatar" class="avatar xxs inline margin-end-small" loading="lazy" width="30" height="30" /> <span data-ls-bind="{{log.userName}}"></span> <span class="text-fade text-size-xs">(Admin)</span>
|
||||||
|
</span>
|
||||||
|
<span data-ls-if="{{log.mode}} === 'key'"> <i class="icon-key"></i> API Key</span>
|
||||||
|
</td>
|
||||||
|
<td data-title="Event: "><span data-ls-bind="{{log.event}}"></span></td>
|
||||||
|
<td data-title="Location: ">
|
||||||
|
<img onerror="this.onerror=null;this.className='avatar xxs hide'" data-ls-attrs="src={{env.API}}/avatars/flags/{{log.countryCode}}?width=80&height=80&project={{env.PROJECT}}" class="avatar xxs inline margin-end-small" />
|
||||||
|
<span data-ls-bind="{{log.countryName}}"></span>
|
||||||
|
</td>
|
||||||
|
<td data-title="IP: "><span data-ls-bind="{{log.ip}}"></span></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="pull-end text-align-center paging">
|
||||||
|
<form
|
||||||
|
data-service="database.listCollectionLogs"
|
||||||
|
data-event="submit"
|
||||||
|
data-param-collection-id="{{router.params.id}}"
|
||||||
|
data-param-limit="<?php echo APP_PAGING_LIMIT; ?>"
|
||||||
|
data-param-order-type="DESC"
|
||||||
|
data-scope="sdk"
|
||||||
|
data-name="logs"
|
||||||
|
data-success="state"
|
||||||
|
data-success-param-state-keys="search,offset">
|
||||||
|
<button name="offset" data-paging-back data-offset="{{router.params.offset}}" data-sum="{{logs.sum}}" class="margin-end-small round small" aria-label="Back"><i class="icon-left-open"></i></button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<form
|
||||||
|
data-service="database.listCollectionLogs"
|
||||||
|
data-event="submit"
|
||||||
|
data-param-collection-id="{{router.params.id}}"
|
||||||
|
data-param-limit="<?php echo APP_PAGING_LIMIT; ?>"
|
||||||
|
data-param-order-type="DESC"
|
||||||
|
data-scope="sdk"
|
||||||
|
data-name="logs"
|
||||||
|
data-success="state"
|
||||||
|
data-success-param-state-keys="search,offset">
|
||||||
|
<button name="offset" data-paging-next data-offset="{{router.params.offset}}" data-sum="{{logs.sum}}" class="margin-start-small round small" aria-label="Next"><i class="icon-right-open"></i></button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -117,7 +117,7 @@ $logs = $this->getParam('logs', null);
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a data-ls-if="0 < {{project-collection.attributes.length}}" data-ls-attrs="href=/console/database/document?collection={{router.params.id}}&project={{router.params.project}}&buster={{project-collection.dateUpdated}}" class="button">
|
<a data-ls-if="0 < {{project-collection.attributes.length}}" data-ls-attrs="href=/console/database/document/new?collection={{router.params.id}}&project={{router.params.project}}" class="button">
|
||||||
Add Document
|
Add Document
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
@ -321,7 +321,7 @@ $logs = $this->getParam('logs', null);
|
||||||
<button class="new-index">Add Index</button>
|
<button class="new-index">Add Index</button>
|
||||||
</li>
|
</li>
|
||||||
<li data-state="/console/database/collection/activity?id={{router.params.id}}&project={{router.params.project}}">
|
<li data-state="/console/database/collection/activity?id={{router.params.id}}&project={{router.params.project}}">
|
||||||
<h2>Activity <span class="badge" data-ls-bind="{{project-collection-logs.logs.length}}"></span></h2>
|
<h2>Activity <span class="badge" data-ls-bind="{{logs.logs.length}}"></span></h2>
|
||||||
|
|
||||||
<?php echo $logs->render(); ?>
|
<?php echo $logs->render(); ?>
|
||||||
</li>
|
</li>
|
||||||
|
@ -516,16 +516,71 @@ $logs = $this->getParam('logs', null);
|
||||||
<div class="row responsive thin">
|
<div class="row responsive thin">
|
||||||
<div class="col span-6 margin-bottom-small">
|
<div class="col span-6 margin-bottom-small">
|
||||||
<label for="integer-min">Min</label>
|
<label for="integer-min">Min</label>
|
||||||
<input id="integer-min" type="number" class="full-width" name="min" value="0" required autocomplete="off" data-cast-to="integer" />
|
<input id="integer-min" type="number" step="1" class="full-width" name="min" value="0" required autocomplete="off" data-cast-to="integer" />
|
||||||
</div>
|
</div>
|
||||||
<div class="col span-6 margin-bottom-small">
|
<div class="col span-6 margin-bottom-small">
|
||||||
<label for="integer-max">Max</label>
|
<label for="integer-max">Max</label>
|
||||||
<input id="integer-max" type="number" class="full-width" name="max" value="0" required autocomplete="off" data-cast-to="integer" />
|
<input id="integer-max" type="number" step="1" class="full-width" name="max" value="0" required autocomplete="off" data-cast-to="integer" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<label for="integer-default">Default Value</label>
|
<label for="integer-default">Default Value</label>
|
||||||
<input id="integer-default" name="default" type="number" value="0" class="margin-bottom-large" autocomplete="off" data-cast-to="integer">
|
<input id="integer-default" name="default" type="number" step="1" value="0" class="margin-bottom-large" autocomplete="off" data-cast-to="integer">
|
||||||
|
|
||||||
|
<footer>
|
||||||
|
<button type="submit">Create</button> <button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
|
||||||
|
</footer>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-ui-modal class="modal box close sticky-footer" data-button-alias=".new-attribute-float">
|
||||||
|
<button type="button" class="close pull-end" data-ui-modal-close=""><i class="icon-cancel"></i></button>
|
||||||
|
|
||||||
|
<h1>Add Float Attribute</h1>
|
||||||
|
|
||||||
|
<form
|
||||||
|
data-analytics
|
||||||
|
data-analytics-activity
|
||||||
|
data-analytics-event="submit"
|
||||||
|
data-analytics-category="console"
|
||||||
|
data-analytics-label="Create Collection Attribute (float)"
|
||||||
|
data-service="database.createFloatAttribute"
|
||||||
|
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="float-attributeId">Attribute ID</label>
|
||||||
|
<input type="text" class="full-width" name="attributeId" required autocomplete="off" maxlength="128" />
|
||||||
|
|
||||||
|
<div class="margin-bottom">
|
||||||
|
<input name="required" type="hidden" data-forms-switch data-cast-to="boolean" /> 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" /> Array <span class="tooltip" data-tooltip="Mark whether this attribute should act as an array"><i class="icon-info-circled"></i></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row responsive thin">
|
||||||
|
<div class="col span-6 margin-bottom-small">
|
||||||
|
<label for="integer-min">Min</label>
|
||||||
|
<input id="integer-min" type="number" step="0.01" class="full-width" name="min" value="0.00" required autocomplete="off" data-cast-to="float" />
|
||||||
|
</div>
|
||||||
|
<div class="col span-6 margin-bottom-small">
|
||||||
|
<label for="integer-max">Max</label>
|
||||||
|
<input id="integer-max" type="number" step="0.01" class="full-width" name="max" value="0.00" required autocomplete="off" data-cast-to="float" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<label for="integer-default">Default Value</label>
|
||||||
|
<input id="integer-default" name="default" type="number" step="0.01" value="0.00" class="margin-bottom-large" autocomplete="off" data-cast-to="float">
|
||||||
|
|
||||||
<footer>
|
<footer>
|
||||||
<button type="submit">Create</button> <button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
|
<button type="submit">Create</button> <button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$new = $this->getParam('new', false);
|
||||||
|
$logs = $this->getParam('logs', null);
|
||||||
|
|
||||||
|
?>
|
||||||
<div
|
<div
|
||||||
data-service="database.getCollection"
|
data-service="database.getCollection"
|
||||||
data-param-collection-id="{{router.params.collection}}"
|
data-param-collection-id="{{router.params.collection}}"
|
||||||
|
@ -40,9 +46,9 @@
|
||||||
<div class="zone xl margin-bottom-no">
|
<div class="zone xl margin-bottom-no">
|
||||||
<ul class="phases clear" data-ui-phases data-selected="{{router.params.tab}}">
|
<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}}">
|
<li data-state="/console/database/document?id={{router.params.id}}&collection={{router.params.collection}}&project={{router.params.project}}">
|
||||||
<h2>Overview</h2>
|
<h2 class="margin-bottom">Overview</h2>
|
||||||
|
|
||||||
<div class="row responsive margin-top-negative">
|
<div class="row responsive">
|
||||||
<div class="col span-8 margin-bottom">
|
<div class="col span-8 margin-bottom">
|
||||||
<form
|
<form
|
||||||
data-analytics
|
data-analytics
|
||||||
|
@ -62,11 +68,22 @@
|
||||||
data-failure-param-alert-classname="error">
|
data-failure-param-alert-classname="error">
|
||||||
|
|
||||||
<input type="hidden" name="collectionId" data-ls-bind="{{project-collection.$id}}" />
|
<input type="hidden" name="collectionId" data-ls-bind="{{project-collection.$id}}" />
|
||||||
<input type="hidden" name="documentId" data-ls-bind="{{project-document.$id}}" />
|
<?php if(!$new): ?><input type="hidden" name="documentId" data-ls-bind="{{project-document.$id}}" /><?php endif; ?>
|
||||||
|
|
||||||
<label> </label>
|
|
||||||
|
|
||||||
<div class="box">
|
<div class="box">
|
||||||
|
<?php if($new): ?>
|
||||||
|
<label for="documentId">Document ID</label>
|
||||||
|
<input
|
||||||
|
type="hidden"
|
||||||
|
data-custom-id
|
||||||
|
data-id-type="auto"
|
||||||
|
data-validator="database.getDocument"
|
||||||
|
required
|
||||||
|
maxlength="36"
|
||||||
|
name="documentId"
|
||||||
|
id="documentId" />
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
<fieldset name="data" data-cast-to="object">
|
<fieldset name="data" data-cast-to="object">
|
||||||
<ul data-ls-loop="project-collection.attributes" data-ls-as="attribute">
|
<ul data-ls-loop="project-collection.attributes" data-ls-as="attribute">
|
||||||
<li>
|
<li>
|
||||||
|
@ -75,7 +92,7 @@
|
||||||
<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-danger text-fade">required</div>
|
||||||
<div data-ls-if="!{{attribute.required}}" class="text-size-xs text-fade">optional</div>
|
<div data-ls-if="!{{attribute.required}}" class="text-size-xs text-fade">optional</div>
|
||||||
</label>
|
</label>
|
||||||
<textarea data-ls-attrs="name={{attribute.key}}" data-ls-bind="{{project-document|documentAttribute}}"></textarea>
|
<div data-ls-template="template-{{attribute.type}}" data-type="script"></div>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
@ -145,10 +162,45 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
<?php if(!$new): ?>
|
||||||
|
<li data-state="/console/database/document/activity?id={{router.params.id}}&collection={{router.params.collection}}&project={{router.params.project}}">
|
||||||
|
<h2>Activity <span class="badge" data-ls-bind="{{logs.logs.length}}"></span></h2>
|
||||||
|
|
||||||
|
<?php echo $logs->render(); ?>
|
||||||
|
</li>
|
||||||
|
<?php endif; ?>
|
||||||
<!-- <li data-ls-if="{{project-document.$id}}" data-state="/console/database/document/activity?id={{router.params.id}}&collection={{router.params.collection}}&project={{router.params.project}}">
|
<!-- <li data-ls-if="{{project-document.$id}}" data-state="/console/database/document/activity?id={{router.params.id}}&collection={{router.params.collection}}&project={{router.params.project}}">
|
||||||
<h2>Activity</h2>
|
<h2>Activity</h2>
|
||||||
</li> -->
|
</li> -->
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<script type="text/html" id="template-string">
|
||||||
|
<textarea data-forms-text-resize data-forms-text-direction data-ls-attrs="name={{attribute.key}}" data-ls-bind="{{project-document|documentAttribute}}"></textarea>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script type="text/html" id="template-integer">
|
||||||
|
<input type="number" step="1" data-ls-attrs="name={{attribute.key}}" data-ls-bind="{{project-document|documentAttribute}}" data-cast-to="integer" />
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script type="text/html" id="template-double">
|
||||||
|
<input type="number" step="0.01" data-ls-attrs="name={{attribute.key}}" data-ls-bind="{{project-document|documentAttribute}}" data-cast-to="float" />
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script type="text/html" id="template-boolean">
|
||||||
|
<input type="hidden" data-forms-switch data-ls-attrs="name={{attribute.key}}" data-ls-bind="{{project-document|documentAttribute}}" data-cast-to="boolean" class="margin-bottom-no" />
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script type="text/html" id="template-url">
|
||||||
|
<input type="url" data-ls-attrs="name={{attribute.key}}" data-ls-bind="{{project-document|documentAttribute}}" />
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script type="text/html" id="template-email">
|
||||||
|
<input type="email" data-ls-attrs="name={{attribute.key}}" data-ls-bind="{{project-document|documentAttribute}}" />
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script type="text/html" id="template-ip">
|
||||||
|
<input type="text" data-ls-attrs="name={{attribute.key}}" data-ls-bind="{{project-document|documentAttribute}}" 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>
|
|
@ -423,18 +423,18 @@ $auth = $this->getParam('auth', []);
|
||||||
data-scope="console">
|
data-scope="console">
|
||||||
<ul class="tiles cell-3 margin-bottom-small">
|
<ul class="tiles cell-3 margin-bottom-small">
|
||||||
<?php foreach ($providers as $provider => $data):
|
<?php foreach ($providers as $provider => $data):
|
||||||
if (isset($data['enabled']) && !$data['enabled']) {continue;}
|
if (isset($data['enabled']) && !$data['enabled']) {continue;}
|
||||||
// if (isset($data['mock']) && $data['mock']) {continue;}
|
// if (isset($data['mock']) && $data['mock']) {continue;}
|
||||||
$sandbox = $data['sandbox'] ?? false;
|
$sandbox = $data['sandbox'] ?? false;
|
||||||
$form = $data['form'] ?? false;
|
$form = $data['form'] ?? false;
|
||||||
$name = $data['name'] ?? 'Unknown';
|
$name = $data['name'] ?? 'Unknown';
|
||||||
$beta = $data['beta'] ?? false;
|
$beta = $data['beta'] ?? false;
|
||||||
?>
|
?>
|
||||||
<li class="<?php echo (isset($data['enabled']) && !$data['enabled']) ? 'dev-feature' : ''; ?>">
|
<li class="<?php echo (isset($data['enabled']) && !$data['enabled']) ? 'dev-feature' : ''; ?>">
|
||||||
<div data-ui-modal class="modal close" data-button-alias="none" data-open-event="provider-update-<?php echo $provider; ?>">
|
<div data-ui-modal class="modal close" data-button-alias="none" data-open-event="provider-update-<?php echo $provider; ?>">
|
||||||
<button type="button" class="close pull-end" data-ui-modal-close=""><i class="icon-cancel"></i></button>
|
<button type="button" class="close pull-end" data-ui-modal-close=""><i class="icon-cancel"></i></button>
|
||||||
|
|
||||||
<h1><?php echo $this->escape($name); ?> <?php if ($sandbox): ?>Sandbox<?php endif;?> OAuth2 Settings</h1>
|
<h1><?php echo $this->escape($name); ?> <?php if ($sandbox): ?>Sandbox<?php endif;?> OAuth2 Settings</h1>
|
||||||
|
|
||||||
<form
|
<form
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
let sdk = new Appwrite();
|
||||||
|
|
||||||
|
sdk
|
||||||
|
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
|
||||||
|
.setProject('5df5acd0d48c2') // Your project ID
|
||||||
|
;
|
||||||
|
|
||||||
|
let promise = sdk.database.listDocumentLogs('[COLLECTION_ID]', '[DOCUMENT_ID]');
|
||||||
|
|
||||||
|
promise.then(function (response) {
|
||||||
|
console.log(response); // Success
|
||||||
|
}, function (error) {
|
||||||
|
console.log(error); // Failure
|
||||||
|
});
|
1
docs/references/database/get-document-logs.md
Normal file
1
docs/references/database/get-document-logs.md
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Get the document activity logs list by its unique ID.
|
6
public/dist/scripts/app-all.js
vendored
6
public/dist/scripts/app-all.js
vendored
|
@ -196,7 +196,9 @@ if(typeof read!=='undefined'){payload['read']=read;}
|
||||||
if(typeof write!=='undefined'){payload['write']=write;}
|
if(typeof write!=='undefined'){payload['write']=write;}
|
||||||
const uri=new URL(this.config.endpoint+path);return yield this.call('patch',uri,{'content-type':'application/json',},payload);}),deleteDocument:(collectionId,documentId)=>__awaiter(this,void 0,void 0,function*(){if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
|
const uri=new URL(this.config.endpoint+path);return yield this.call('patch',uri,{'content-type':'application/json',},payload);}),deleteDocument:(collectionId,documentId)=>__awaiter(this,void 0,void 0,function*(){if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
|
||||||
if(typeof documentId==='undefined'){throw new AppwriteException('Missing required parameter: "documentId"');}
|
if(typeof documentId==='undefined'){throw new AppwriteException('Missing required parameter: "documentId"');}
|
||||||
let path='/database/collections/{collectionId}/documents/{documentId}'.replace('{collectionId}',collectionId).replace('{documentId}',documentId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),listIndexes:(collectionId)=>__awaiter(this,void 0,void 0,function*(){if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
|
let path='/database/collections/{collectionId}/documents/{documentId}'.replace('{collectionId}',collectionId).replace('{documentId}',documentId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),listDocumentLogs:(collectionId,documentId)=>__awaiter(this,void 0,void 0,function*(){if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
|
||||||
|
if(typeof documentId==='undefined'){throw new AppwriteException('Missing required parameter: "documentId"');}
|
||||||
|
let path='/database/collections/{collectionId}/documents/{documentId}/logs'.replace('{collectionId}',collectionId).replace('{documentId}',documentId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),listIndexes:(collectionId)=>__awaiter(this,void 0,void 0,function*(){if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
|
||||||
let path='/database/collections/{collectionId}/indexes'.replace('{collectionId}',collectionId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),createIndex:(collectionId,indexId,type,attributes,orders)=>__awaiter(this,void 0,void 0,function*(){if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
|
let path='/database/collections/{collectionId}/indexes'.replace('{collectionId}',collectionId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),createIndex:(collectionId,indexId,type,attributes,orders)=>__awaiter(this,void 0,void 0,function*(){if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
|
||||||
if(typeof indexId==='undefined'){throw new AppwriteException('Missing required parameter: "indexId"');}
|
if(typeof indexId==='undefined'){throw new AppwriteException('Missing required parameter: "indexId"');}
|
||||||
if(typeof type==='undefined'){throw new AppwriteException('Missing required parameter: "type"');}
|
if(typeof type==='undefined'){throw new AppwriteException('Missing required parameter: "type"');}
|
||||||
|
@ -2271,7 +2273,7 @@ if(!match){return fail}
|
||||||
for(i=0,len=match.length;i<len;i++){if(!process(match[i])){return fail}}
|
for(i=0,len=match.length;i<len;i++){if(!process(match[i])){return fail}}
|
||||||
return(date.getTime()/1000)}
|
return(date.getTime()/1000)}
|
||||||
return{format:format,strtotime:strtotime}}(),true);})(window);(function(window){"use strict";window.ls.container.set('env',function(){return APP_ENV;},true);})(window);(function(window){"use strict";window.ls.container.set('form',function(){function cast(value,to){if(value&&Array.isArray(value)&&to!=='array'){value=value.map(element=>cast(element,to));return value;}
|
return{format:format,strtotime:strtotime}}(),true);})(window);(function(window){"use strict";window.ls.container.set('env',function(){return APP_ENV;},true);})(window);(function(window){"use strict";window.ls.container.set('form',function(){function cast(value,to){if(value&&Array.isArray(value)&&to!=='array'){value=value.map(element=>cast(element,to));return value;}
|
||||||
switch(to){case'int':case'integer':value=parseInt(value);break;case'numeric':value=Number(value);break;case'string':value=value.toString();break;case'json':value=(value)?JSON.parse(value):[];break;case'array':value=(value&&value.constructor&&value.constructor===Array)?value:[value];break;case'array-empty':value=[];break;case'bool':case'boolean':value=(value==='false')?false:value;value=!!value;break;}
|
switch(to){case'int':case'integer':value=parseInt(value);break;case'float':value=parseFloat(parseFloat(value).toFixed(2));break;case'numeric':value=Number(value);break;case'string':value=value.toString();break;case'json':value=(value)?JSON.parse(value):[];break;case'array':value=(value&&value.constructor&&value.constructor===Array)?value:[value];break;case'array-empty':value=[];break;case'bool':case'boolean':value=(value==='false')?false:value;value=!!value;break;}
|
||||||
return value;}
|
return value;}
|
||||||
function toJson(element,json){json=json||{};let name=element.getAttribute('name');let type=element.getAttribute('type');let castTo=element.getAttribute('data-cast-to');let ref=json;if(name&&'FORM'!==element.tagName){if(name.startsWith('[')){let splitName=name.split('.');if(splitName.length>1&&splitName[0].endsWith(']')){name=splitName[splitName.length-1];}}
|
function toJson(element,json){json=json||{};let name=element.getAttribute('name');let type=element.getAttribute('type');let castTo=element.getAttribute('data-cast-to');let ref=json;if(name&&'FORM'!==element.tagName){if(name.startsWith('[')){let splitName=name.split('.');if(splitName.length>1&&splitName[0].endsWith(']')){name=splitName[splitName.length-1];}}
|
||||||
if('FIELDSET'===element.tagName){if(castTo==='object'){if(json[name]===undefined){json[name]={};}
|
if('FIELDSET'===element.tagName){if(castTo==='object'){if(json[name]===undefined){json[name]={};}
|
||||||
|
|
4
public/dist/scripts/app-dep.js
vendored
4
public/dist/scripts/app-dep.js
vendored
|
@ -196,7 +196,9 @@ if(typeof read!=='undefined'){payload['read']=read;}
|
||||||
if(typeof write!=='undefined'){payload['write']=write;}
|
if(typeof write!=='undefined'){payload['write']=write;}
|
||||||
const uri=new URL(this.config.endpoint+path);return yield this.call('patch',uri,{'content-type':'application/json',},payload);}),deleteDocument:(collectionId,documentId)=>__awaiter(this,void 0,void 0,function*(){if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
|
const uri=new URL(this.config.endpoint+path);return yield this.call('patch',uri,{'content-type':'application/json',},payload);}),deleteDocument:(collectionId,documentId)=>__awaiter(this,void 0,void 0,function*(){if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
|
||||||
if(typeof documentId==='undefined'){throw new AppwriteException('Missing required parameter: "documentId"');}
|
if(typeof documentId==='undefined'){throw new AppwriteException('Missing required parameter: "documentId"');}
|
||||||
let path='/database/collections/{collectionId}/documents/{documentId}'.replace('{collectionId}',collectionId).replace('{documentId}',documentId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),listIndexes:(collectionId)=>__awaiter(this,void 0,void 0,function*(){if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
|
let path='/database/collections/{collectionId}/documents/{documentId}'.replace('{collectionId}',collectionId).replace('{documentId}',documentId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),listDocumentLogs:(collectionId,documentId)=>__awaiter(this,void 0,void 0,function*(){if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
|
||||||
|
if(typeof documentId==='undefined'){throw new AppwriteException('Missing required parameter: "documentId"');}
|
||||||
|
let path='/database/collections/{collectionId}/documents/{documentId}/logs'.replace('{collectionId}',collectionId).replace('{documentId}',documentId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),listIndexes:(collectionId)=>__awaiter(this,void 0,void 0,function*(){if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
|
||||||
let path='/database/collections/{collectionId}/indexes'.replace('{collectionId}',collectionId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),createIndex:(collectionId,indexId,type,attributes,orders)=>__awaiter(this,void 0,void 0,function*(){if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
|
let path='/database/collections/{collectionId}/indexes'.replace('{collectionId}',collectionId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),createIndex:(collectionId,indexId,type,attributes,orders)=>__awaiter(this,void 0,void 0,function*(){if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
|
||||||
if(typeof indexId==='undefined'){throw new AppwriteException('Missing required parameter: "indexId"');}
|
if(typeof indexId==='undefined'){throw new AppwriteException('Missing required parameter: "indexId"');}
|
||||||
if(typeof type==='undefined'){throw new AppwriteException('Missing required parameter: "type"');}
|
if(typeof type==='undefined'){throw new AppwriteException('Missing required parameter: "type"');}
|
||||||
|
|
2
public/dist/scripts/app.js
vendored
2
public/dist/scripts/app.js
vendored
|
@ -242,7 +242,7 @@ if(!match){return fail}
|
||||||
for(i=0,len=match.length;i<len;i++){if(!process(match[i])){return fail}}
|
for(i=0,len=match.length;i<len;i++){if(!process(match[i])){return fail}}
|
||||||
return(date.getTime()/1000)}
|
return(date.getTime()/1000)}
|
||||||
return{format:format,strtotime:strtotime}}(),true);})(window);(function(window){"use strict";window.ls.container.set('env',function(){return APP_ENV;},true);})(window);(function(window){"use strict";window.ls.container.set('form',function(){function cast(value,to){if(value&&Array.isArray(value)&&to!=='array'){value=value.map(element=>cast(element,to));return value;}
|
return{format:format,strtotime:strtotime}}(),true);})(window);(function(window){"use strict";window.ls.container.set('env',function(){return APP_ENV;},true);})(window);(function(window){"use strict";window.ls.container.set('form',function(){function cast(value,to){if(value&&Array.isArray(value)&&to!=='array'){value=value.map(element=>cast(element,to));return value;}
|
||||||
switch(to){case'int':case'integer':value=parseInt(value);break;case'numeric':value=Number(value);break;case'string':value=value.toString();break;case'json':value=(value)?JSON.parse(value):[];break;case'array':value=(value&&value.constructor&&value.constructor===Array)?value:[value];break;case'array-empty':value=[];break;case'bool':case'boolean':value=(value==='false')?false:value;value=!!value;break;}
|
switch(to){case'int':case'integer':value=parseInt(value);break;case'float':value=parseFloat(parseFloat(value).toFixed(2));break;case'numeric':value=Number(value);break;case'string':value=value.toString();break;case'json':value=(value)?JSON.parse(value):[];break;case'array':value=(value&&value.constructor&&value.constructor===Array)?value:[value];break;case'array-empty':value=[];break;case'bool':case'boolean':value=(value==='false')?false:value;value=!!value;break;}
|
||||||
return value;}
|
return value;}
|
||||||
function toJson(element,json){json=json||{};let name=element.getAttribute('name');let type=element.getAttribute('type');let castTo=element.getAttribute('data-cast-to');let ref=json;if(name&&'FORM'!==element.tagName){if(name.startsWith('[')){let splitName=name.split('.');if(splitName.length>1&&splitName[0].endsWith(']')){name=splitName[splitName.length-1];}}
|
function toJson(element,json){json=json||{};let name=element.getAttribute('name');let type=element.getAttribute('type');let castTo=element.getAttribute('data-cast-to');let ref=json;if(name&&'FORM'!==element.tagName){if(name.startsWith('[')){let splitName=name.split('.');if(splitName.length>1&&splitName[0].endsWith(']')){name=splitName[splitName.length-1];}}
|
||||||
if('FIELDSET'===element.tagName){if(castTo==='object'){if(json[name]===undefined){json[name]={};}
|
if('FIELDSET'===element.tagName){if(castTo==='object'){if(json[name]===undefined){json[name]={};}
|
||||||
|
|
|
@ -1627,6 +1627,30 @@
|
||||||
'content-type': 'application/json',
|
'content-type': 'application/json',
|
||||||
}, payload);
|
}, payload);
|
||||||
}),
|
}),
|
||||||
|
/**
|
||||||
|
* List Document Logs
|
||||||
|
*
|
||||||
|
* Get the document activity logs list by its unique ID.
|
||||||
|
*
|
||||||
|
* @param {string} collectionId
|
||||||
|
* @param {string} documentId
|
||||||
|
* @throws {AppwriteException}
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
listDocumentLogs: (collectionId, documentId) => __awaiter(this, void 0, void 0, function* () {
|
||||||
|
if (typeof collectionId === 'undefined') {
|
||||||
|
throw new AppwriteException('Missing required parameter: "collectionId"');
|
||||||
|
}
|
||||||
|
if (typeof documentId === 'undefined') {
|
||||||
|
throw new AppwriteException('Missing required parameter: "documentId"');
|
||||||
|
}
|
||||||
|
let path = '/database/collections/{collectionId}/documents/{documentId}/logs'.replace('{collectionId}', collectionId).replace('{documentId}', documentId);
|
||||||
|
let payload = {};
|
||||||
|
const uri = new URL(this.config.endpoint + path);
|
||||||
|
return yield this.call('get', uri, {
|
||||||
|
'content-type': 'application/json',
|
||||||
|
}, payload);
|
||||||
|
}),
|
||||||
/**
|
/**
|
||||||
* List Indexes
|
* List Indexes
|
||||||
*
|
*
|
||||||
|
|
|
@ -13,6 +13,9 @@
|
||||||
case 'integer':
|
case 'integer':
|
||||||
value = parseInt(value);
|
value = parseInt(value);
|
||||||
break;
|
break;
|
||||||
|
case 'float':
|
||||||
|
value = parseFloat(parseFloat(value).toFixed(2));
|
||||||
|
break;
|
||||||
case 'numeric':
|
case 'numeric':
|
||||||
value = Number(value);
|
value = Number(value);
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue