130 lines
6.0 KiB
PHP
130 lines
6.0 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
require_once __DIR__ . '/../includes/bootstrap.php';
|
|
$dashboardPage = 'trash';
|
|
$dashboardTitle = dbnToolsT('dash_title_trash', dbnToolsCurrentLanguage()) ?: 'Trash';
|
|
$dashboardLead = dbnToolsT('dash_lead_trash', dbnToolsCurrentLanguage()) ?: 'Items here are auto-deleted after 30 days.';
|
|
require_once __DIR__ . '/../includes/layout_dashboard.php';
|
|
?>
|
|
<section class="dms-shell dms-shell--single">
|
|
<div class="dms-main">
|
|
<div class="dms-toolbar">
|
|
<div class="dms-toolbar__crumbs"><span>🗑 Trash</span></div>
|
|
<div class="dms-toolbar__actions">
|
|
<button class="dash-btn" type="button" id="trashRestoreSel" disabled>Restore selected</button>
|
|
<button class="dash-btn dash-btn--danger" type="button" id="trashPurgeAll">Empty trash (admin)</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="trashList"><div class="dms-loading"></div></div>
|
|
</div>
|
|
</section>
|
|
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function () {
|
|
'use strict';
|
|
const DMS = window.DBN_DMS;
|
|
const $list = document.getElementById('trashList');
|
|
const $restore = document.getElementById('trashRestoreSel');
|
|
const $purge = document.getElementById('trashPurgeAll');
|
|
const selected = new Set();
|
|
|
|
async function load() {
|
|
$list.innerHTML = '<div class="dms-loading"></div>';
|
|
try {
|
|
const data = await DMS.api('/trash.php?action=list&limit=200');
|
|
const items = data.items || [];
|
|
if (!items.length) {
|
|
$list.innerHTML = '<div class="dms-list"><div class="dms-list__empty"><strong>Trash is empty</strong><span>Nothing to restore.</span></div></div>';
|
|
return;
|
|
}
|
|
const rows = items.map(it => {
|
|
const id = (it.kind === 'document' ? 'd' : 'f') + it.id;
|
|
const expires = (it.expires_in_days ?? 0) + 'd left';
|
|
return '<div class="dms-list__row" data-key="' + id + '" data-kind="' + it.kind + '" data-id="' + it.id + '">' +
|
|
'<input type="checkbox" class="dms-trash-sel">' +
|
|
'<div class="dms-list__title">' +
|
|
'<span class="dms-list__title-icon">' + (it.kind === 'folder' ? '📁' : DMS.fileIcon(it.source_type)) + '</span>' +
|
|
DMS.safe(it.title || it.name || '(untitled)') +
|
|
'</div>' +
|
|
'<div class="dms-list__cell dms-list__cell--muted">' + DMS.safe(it.kind) + '</div>' +
|
|
'<div class="dms-list__cell dms-list__cell--muted">' + DMS.fmtRelative(it.deleted_at) + '</div>' +
|
|
'<div class="dms-list__cell dms-list__cell--muted">' + expires + '</div>' +
|
|
'<div class="dms-list__cell"></div>' +
|
|
'<button class="dms-list__more" data-id="' + it.id + '" data-kind="' + it.kind + '" type="button">⋯</button>' +
|
|
'</div>';
|
|
}).join('');
|
|
$list.innerHTML = '<div class="dms-list">' +
|
|
'<div class="dms-list__head"><span></span><span>Title</span><span>Kind</span><span>Trashed</span><span>Expires</span><span></span><span></span></div>' +
|
|
rows + '</div>';
|
|
|
|
$list.querySelectorAll('.dms-trash-sel').forEach(cb => {
|
|
cb.addEventListener('change', e => {
|
|
const row = e.target.closest('.dms-list__row');
|
|
if (e.target.checked) selected.add(row.dataset.key); else selected.delete(row.dataset.key);
|
|
$restore.disabled = selected.size === 0;
|
|
});
|
|
});
|
|
$list.querySelectorAll('.dms-list__more').forEach(btn => {
|
|
btn.addEventListener('click', e => {
|
|
e.preventDefault();
|
|
const id = Number(btn.dataset.id);
|
|
const kind = btn.dataset.kind;
|
|
DMS.openCtxMenu(btn.getBoundingClientRect().left, btn.getBoundingClientRect().bottom, [
|
|
{ label: 'Restore', icon: '↩', onclick: () => restoreItems([{kind, id}]) },
|
|
'-',
|
|
{ label: 'Delete permanently', icon: '🔥', danger: true,
|
|
onclick: () => purgeItems([{kind, id}]) },
|
|
]);
|
|
});
|
|
});
|
|
} catch (e) {
|
|
$list.innerHTML = '<div class="dms-list__empty"><strong>Error</strong><span>' + DMS.safe(e.message) + '</span></div>';
|
|
}
|
|
}
|
|
|
|
async function restoreItems(items) {
|
|
const body = { document_ids: [], folder_ids: [] };
|
|
items.forEach(i => {
|
|
if (i.kind === 'folder') body.folder_ids.push(i.id);
|
|
else body.document_ids.push(i.id);
|
|
});
|
|
try {
|
|
await DMS.api('/trash.php?action=restore', { method: 'POST', body });
|
|
selected.clear();
|
|
$restore.disabled = true;
|
|
load();
|
|
} catch (e) { alert(e.message); }
|
|
}
|
|
|
|
async function purgeItems(items) {
|
|
if (!confirm('Permanently delete? This cannot be undone.')) return;
|
|
const body = { document_ids: [], folder_ids: [] };
|
|
items.forEach(i => {
|
|
if (i.kind === 'folder') body.folder_ids.push(i.id);
|
|
else body.document_ids.push(i.id);
|
|
});
|
|
try {
|
|
await DMS.api('/trash.php?action=purge', { method: 'POST', body });
|
|
load();
|
|
} catch (e) { alert(e.message); }
|
|
}
|
|
|
|
$restore.addEventListener('click', () => {
|
|
const items = Array.from(selected).map(k => ({ kind: k[0] === 'd' ? 'document' : 'folder', id: Number(k.slice(1)) }));
|
|
restoreItems(items);
|
|
});
|
|
$purge.addEventListener('click', async () => {
|
|
if (!confirm('Permanently delete ALL items in trash? This cannot be undone.')) return;
|
|
try {
|
|
await DMS.api('/trash.php?action=purge', { method: 'POST', body: { all: true } });
|
|
load();
|
|
} catch (e) { alert(e.message); }
|
|
});
|
|
|
|
load();
|
|
});
|
|
</script>
|
|
|
|
<?php require_once __DIR__ . '/../includes/layout_dashboard_footer.php'; ?>
|