BUG-06: Auto-Pack Undo via Snapshot + actionable Toast
Auto-Pack rief vorher layout_mod.pack() auf und schickte einen
simplen success-Toast. Wer aus Versehen klickte, hatte alle
manuellen Positionen verloren — kein Undo, kein Recovery.
Fix:
- packAll() speichert layoutItems als JSON-Snapshot in einer
local closure (vor dem pack-Call).
- Nach erfolgreichem Pack: toast() bekommt einen 4. Parameter
action={label, onClick}.
- Neues toast()-Feature: action-Button im Toast, clickbar trotz
dismiss-on-click. Klick ruft onClick und dismissed den Toast.
- Bei Undo-Klick: POST /api/layout mit den snapshot-Items →
Server restored → renderGrid() → 'Layout wiederhergestellt'.
- Modal-Text weist auf die 10s Undo-Möglichkeit hin.
Vorteile:
- Versehentlicher Klick auf Auto-Pack ist recoverable.
- Kein sessionStorage-Bloat, kein Multi-Tab-Konflikt
(Closure-Variable statt global Storage).
- Toast-Pattern ist jetzt generisch — andere Aktionen
(z.B. 'Snapshot wiederherstellen' aus Sidebar) können
denselben Mechanismus nutzen.
Beweis: tests/test_autopack_undo.js (8/8 grün)
1. Snapshot (JSON.stringify(layoutItems)) wird erstellt
2. Toast mit action={label:'Rückgängig'}
3. Undo ruft POST /api/layout mit snapshot-Items
4. Modal-Body erwähnt 'rückgängig'
5. CSS .toast-action Klasse vorhanden
6. toast() unterstützt 4-Args (action-Parameter)
7. Action-Button Click ruft onClick + dismiss
8. .toast-action hat pointer-events:auto
Live-Test: GET /?demo=1 → 200, 90847 bytes
toast-action: 6 occurrences (CSS + JS)
Rückgängig: 1 mention
JSON.stringify(layoutItems): 1
Closes #8
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
// BUG-06 Test: Auto-Pack Undo via Snapshot
|
||||
//
|
||||
// Erwartung:
|
||||
// 1) packAll() speichert layoutItems als JSON vor dem Pack
|
||||
// 2) Toast wird mit action={label:"Rückgängig", onClick} aufgerufen (statt nur Text)
|
||||
// 3) onClick sendet POST /api/layout mit den snapshot-Items
|
||||
// 4) Modal-Text erwähnt "10 Sekunden lang rückgängig"
|
||||
// 5) CSS: .toast-action Klasse vorhanden
|
||||
// 6) toast()-Funktion unterstützt action-Parameter (4-Args-Signatur)
|
||||
|
||||
const fs = require('fs');
|
||||
const html = fs.readFileSync('templates/index.html', 'utf8');
|
||||
const js = html.match(/<script>\s*\n([\s\S]*?)<\/script>/)[1];
|
||||
|
||||
function check(name, fn) {
|
||||
const r = fn();
|
||||
console.log((r ? '✓' : '✗') + ' ' + name);
|
||||
if (!r) process.exitCode = 1;
|
||||
}
|
||||
|
||||
// 1) Snapshot wird erstellt (JSON.stringify vor pack-Call)
|
||||
check('packAll speichert Snapshot (JSON.stringify(layoutItems))', () =>
|
||||
/async function packAll[\s\S]*?JSON\.stringify\(layoutItems\)/.test(js));
|
||||
|
||||
// 2) Toast mit action-Parameter
|
||||
check('Toast wird mit action-Parameter aufgerufen', () =>
|
||||
/toast\([^,]+,\s*['"]success['"],\s*\d+,\s*\{[\s\S]*?label:\s*['"]Rückgängig['"]/.test(js));
|
||||
|
||||
// 3) Undo-Click ruft POST /api/layout mit snapshot
|
||||
check('Undo ruft POST /api/layout mit snapshot-Items', () =>
|
||||
/fetch\(['"]\/api\/layout['"][\s\S]*?JSON\.parse\(snapshot\)/.test(js));
|
||||
|
||||
// 4) Modal-Body erwähnt Undo-Möglichkeit
|
||||
check('Modal-Body erwähnt "rückgängig"', () =>
|
||||
/rückgängig machen/i.test(js));
|
||||
|
||||
// 5) CSS: .toast-action Klasse
|
||||
check('.toast-action CSS-Klasse vorhanden', () => {
|
||||
const css = html.match(/<style>([\s\S]*?)<\/style>/g).join('\n');
|
||||
return /\.toast-action\s*\{/.test(css);
|
||||
});
|
||||
|
||||
// 6) toast() hat 4-Args Signatur
|
||||
check('toast() unterstützt 4-Args (action-Parameter)', () =>
|
||||
/function toast\(\s*text[^)]*\)\s*\{/.test(js) && /action\s*=/.test(js));
|
||||
|
||||
// 7) Undo-Button ruft bei Click onClick und dismissed Toast
|
||||
check('Action-Button: Click ruft onClick + dismiss', () =>
|
||||
/\.toast-action['"]\)\.addEventListener\(['"]click['"][\s\S]*?action\.onClick\(\)/.test(js));
|
||||
|
||||
// 8) Pointer-events:auto auf Action-Button (sonst klickt Toast-Click-Handler)
|
||||
check('.toast-action hat pointer-events:auto', () => {
|
||||
const css = html.match(/<style>([\s\S]*?)<\/style>/g).join('\n');
|
||||
return /\.toast-action\s*\{[^}]*pointer-events:\s*auto/.test(css);
|
||||
});
|
||||
|
||||
console.log('\n========');
|
||||
process.exit(process.exitCode || 0);
|
||||
Reference in New Issue
Block a user