bak
This commit is contained in:
1 parent
e85b5203cd
commit
0d4d369870
19 files changed
+2258
-1814
No files matched your search
@@ -0,0 +1,82 @@
|
||||
// ── Undo system ──
|
||||
|
||||
import { api } from './util.js';
|
||||
|
||||
const MAX_STACK = 30;
|
||||
const stack = [];
|
||||
|
||||
export function pushUndo(label, restoreFn) {
|
||||
stack.push({ label, restore: restoreFn, time: Date.now() });
|
||||
if (stack.length > MAX_STACK) stack.shift();
|
||||
showHint(label);
|
||||
}
|
||||
|
||||
export async function undo() {
|
||||
const entry = stack.pop();
|
||||
if (!entry) return;
|
||||
await entry.restore();
|
||||
await window._reloadAll();
|
||||
showHint(`undo: ${entry.label}`);
|
||||
}
|
||||
|
||||
export function canUndo() { return stack.length > 0; }
|
||||
export function lastLabel() { return stack.length ? stack[stack.length - 1].label : ''; }
|
||||
|
||||
// Snapshot helpers
|
||||
|
||||
export function snapshotCard(card) {
|
||||
return { ...card };
|
||||
}
|
||||
|
||||
export function snapshotCards(cards) {
|
||||
return cards.map(c => ({ ...c }));
|
||||
}
|
||||
|
||||
export function pushCardEdit(label, cardId, prevData) {
|
||||
pushUndo(label, async () => {
|
||||
await api(`api/cards/${cardId}`, { method: 'PATCH', body: prevData });
|
||||
});
|
||||
}
|
||||
|
||||
export function pushCardDelete(label, card) {
|
||||
pushUndo(label, async () => {
|
||||
await api('api/cards', { method: 'POST', body: {
|
||||
title: card.title, body: card.body, color: card.color,
|
||||
bucket_id: card.bucket_id, position: card.position,
|
||||
}});
|
||||
});
|
||||
}
|
||||
|
||||
export function pushReorder(label, cards) {
|
||||
const prev = cards.map(c => ({ id: c.id, position: c.position }));
|
||||
pushUndo(label, async () => {
|
||||
await Promise.all(prev.map(p => api(`api/cards/${p.id}`, { method: 'PATCH', body: { position: p.position } })));
|
||||
});
|
||||
}
|
||||
|
||||
export function pushBatch(label, patches) {
|
||||
// patches = [{cardId, prevData}, ...]
|
||||
pushUndo(label, async () => {
|
||||
await Promise.all(patches.map(p => api(`api/cards/${p.cardId}`, { method: 'PATCH', body: p.prevData })));
|
||||
});
|
||||
}
|
||||
|
||||
// Toast hint
|
||||
let hintTimer = null;
|
||||
function showHint(text) {
|
||||
let el = document.getElementById('undo-hint');
|
||||
if (!el) {
|
||||
el = document.createElement('div');
|
||||
el.id = 'undo-hint';
|
||||
el.className = 'fixed bottom-16 left-1/2 -translate-x-1/2 z-[95] bg-t-surface border border-t-border px-4 py-2 text-xs font-pixel text-t-muted shadow-lg transition-all';
|
||||
document.body.appendChild(el);
|
||||
}
|
||||
el.textContent = text + ' (ctrl+z undo)';
|
||||
el.style.opacity = '1';
|
||||
el.style.transform = 'translateX(-50%) translateY(0)';
|
||||
clearTimeout(hintTimer);
|
||||
hintTimer = setTimeout(() => {
|
||||
el.style.opacity = '0';
|
||||
el.style.transform = 'translateX(-50%) translateY(8px)';
|
||||
}, 2500);
|
||||
}
|
||||
Reference in new issue
Block a user