File version history (list, download, restore) for Seafile files
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
561b6181a0
commit
70d69e7441
4 files changed
+39
-2
No files matched your search
@@ -2263,6 +2263,7 @@ function fileSheet(repo, path, name, dir) {
|
||||
if (OFFICE_EXT.has(ext(name))) acts.push({ label: 'Open in Seafile', icon: 'doc', run: () => window.open(`${cfg.seafile}/lib/${enc(repo)}/file${path.split('/').map(enc).join('/')}`, '_blank', 'noopener') });
|
||||
acts.push({ label: 'Share link', icon: 'copy', run: () => shareLink(repo, path, false) });
|
||||
acts.push({ label: 'Download', icon: 'dl', run: () => downloadItem(repo, path) });
|
||||
acts.push({ label: 'Version history', icon: 'refresh', run: () => fileHistory(repo, path, name, ro) });
|
||||
if (!ro) acts.push({ label: 'Rename', icon: 'edit', run: () => renameItem(repo, path, name, dir, false) });
|
||||
if (!ro) acts.push({ label: 'Move to…', icon: 'files', run: () => moveSheet('move', repo, dir, [it]) });
|
||||
acts.push({ label: 'Copy to…', icon: 'copy', run: () => moveSheet('copy', repo, dir, [it]) });
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
// Version history for a Seafile file: see earlier versions, download one, or restore it.
|
||||
// Uses sf, fmtSize, openSheet, confirmSheet, toast, esc and FORM from app.js.
|
||||
async function fileHistory(repo, path, name, readOnly) {
|
||||
const base = `/api2/repos/${encodeURIComponent(repo)}/file`;
|
||||
const el = openSheet('Version history', name, '<p class="empty">Loading…</p>');
|
||||
el.querySelector('.sheet').classList.add('wide');
|
||||
try {
|
||||
let commits = [], next = '';
|
||||
for (let page = 0; page < 3; page++) { // up to three pages of history
|
||||
const r = await sf.req(`${base}/history/?p=${encodeURIComponent(path)}${next ? '&commit_id=' + encodeURIComponent(next) : ''}`);
|
||||
commits = commits.concat(r.commits || []);
|
||||
next = r.next_start_commit; if (!next) break;
|
||||
}
|
||||
if (!document.body.contains(el)) return;
|
||||
if (!commits.length) { el.querySelector('.empty').textContent = 'No earlier versions are kept for this file.'; return; }
|
||||
const body = el.querySelector('.empty');
|
||||
body.outerHTML = `<div class="list" style="background:var(--panel2);border:0;max-height:55dvh;overflow:auto">${commits.map((c, i) => `
|
||||
<div class="row"><span class="grow"><b>${esc(new Date((c.ctime || 0) * 1000).toLocaleString([], { dateStyle: 'medium', timeStyle: 'short' }))}${i === 0 ? ' · current' : ''}</b>
|
||||
<small style="white-space:normal">${esc(fmtSize(c.rev_file_size || 0))}${c.creator_name ? ' · ' + esc(c.creator_name) : ''}</small></span>
|
||||
${i === 0 ? '' : `<button class="btn ghost" data-dl="${i}" style="min-height:36px">Download</button>${readOnly ? '' : `<button class="btn ghost" data-rs="${i}" style="min-height:36px">Restore</button>`}`}</div>`).join('')}</div>
|
||||
<div class="bar"><button class="btn ghost" id="sx" style="flex:1;justify-content:center">Close</button></div>`;
|
||||
el.querySelector('#sx').onclick = closeSheet;
|
||||
el.querySelectorAll('[data-dl]').forEach(b => b.onclick = async () => {
|
||||
const c = commits[+b.dataset.dl];
|
||||
try { window.open(await sf.req(`${base}/revision/?p=${encodeURIComponent(path)}&commit_id=${encodeURIComponent(c.id)}`), '_blank', 'noopener'); } catch (e) { toast(e.message); }
|
||||
});
|
||||
el.querySelectorAll('[data-rs]').forEach(b => b.onclick = () => {
|
||||
const c = commits[+b.dataset.rs], when = new Date((c.ctime || 0) * 1000).toLocaleString([], { dateStyle: 'medium', timeStyle: 'short' });
|
||||
confirmSheet('Restore this version?', name + ' goes back to how it was on ' + when + '. The current version stays in the history.', 'Restore', async () => {
|
||||
try { await sf.req(`${base}/revert/`, { method: 'POST', headers: FORM, body: new URLSearchParams({ p: path, commit_id: c.id }) }); toast('Restored'); if (typeof route === 'function') route(); }
|
||||
catch (e) { toast(e.message); }
|
||||
});
|
||||
});
|
||||
} catch (e) { const b = el.querySelector('.empty'); if (b) b.textContent = e.message; }
|
||||
}
|
||||
@@ -55,6 +55,7 @@
|
||||
<script src="/webauthn.js"></script>
|
||||
<script src="/links.js"></script>
|
||||
<script src="/palette.js"></script>
|
||||
<script src="/file-history.js"></script>
|
||||
<script src="/music-extras.js"></script>
|
||||
<script src="/calendar-views.js"></script>
|
||||
<script src="/app.js"></script>
|
||||
|
||||
Reference in new issue
Block a user