From ed81a2fe41cbdfb4b3f02f1017ddd0c9ad44105a Mon Sep 17 00:00:00 2001 From: mhoennig Date: Thu, 27 Aug 2026 05:33:34 +0200 Subject: [PATCH] =?UTF-8?q?fix(men=C3=BC):=20Wiederherstellen=20nur=20noch?= =?UTF-8?q?=20=C3=BCber=20den=20Neu-laden-Knopf=20der=20Titelzeile=20(D81-?= =?UTF-8?q?Nachtrag=202)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Das Zeilen-Symbol im Dokumenten-Menü konnte ein UNGEÖFFNETES mitgeliefertes Dokument zurücksetzen — ohne zu sehen, was man verwirft (Nutzer-Einwand). Umbenennen und Löschen bleiben je Zeile; restoreDoc() wirkt nur noch auf das geöffnete Dokument und prüft das selbst. Co-Authored-By: Claude Fable 5 --- docs/CHANGELOG.md | 2 +- docs/DECISIONS.md | 12 ++++++++++++ docs/examples/werkbaum.werkbaum | 7 ++++--- frontend/CLAUDE.md | 10 ++++++---- frontend/src/app.js | 33 +++++++++++++++------------------ 5 files changed, 38 insertions(+), 26 deletions(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index b120143..0dc0b5a 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -24,7 +24,7 @@ reverse. ## 2026-08-26 - The document picker moved into the app header: `Werkbaum › name` opens the menu — on the phone it is reachable from both panes, and the name takes over the subtitle line -- The document menu groups by kind — included, yours, sources — carries rename, delete and restore on each row, and scrolls instead of being cut off on small screens +- The document menu groups by kind — included, yours, sources — carries rename and delete on each row, and scrolls instead of being cut off on small screens - The editor title bar is labelled `Text editor` again and holds the document's own buttons: save, snapshot, history, reload from the source, and a short `Share` button that puts the plan on a server - The address bar follows the document you switch to: `?live=` and `?sourceUrl=` name what is in front of you, so a reload brings back the same plan - Switching to a server document in the picker now really opens it live — before it only showed its last state diff --git a/docs/DECISIONS.md b/docs/DECISIONS.md index f12b8d1..01485a0 100644 --- a/docs/DECISIONS.md +++ b/docs/DECISIONS.md @@ -7041,3 +7041,15 @@ cross-origin. Abbruch tut nichts; die Probe gegen das echte Backend liefert `{name:"editor-backend"}`. `infoUrl()` liegt headless in live.js (39 Live-Tests, +1). + +**Nachtrag 2 — Wiederherstellen fliegt aus den Menü-Zeilen wieder raus.** +Nutzer-Einwand nach dem ersten Arbeiten damit: Im Menü ließe sich ein +**ungeöffnetes** Dokument zurücksetzen — „was keinen Sinn ergäbe". Der +Einwand trifft: Wiederherstellen verwirft Änderungen, und wer das Dokument +nicht vor sich hat, sieht nicht, was er verwirft. Umbenennen und Löschen +bleiben je Zeile (dort ist der Blick auf den Inhalt nicht nötig — der Name +steht da, und Löschen fragt nach); Wiederherstellen wirkt nur noch über den +**Neu-laden-Knopf der Editor-Titelzeile**, also auf das geöffnete Dokument. +`restoreDoc()` prüft das selbst (`d.id !== activeId` → nichts), statt sich +auf den Aufrufer zu verlassen. Der D81-Haupttext oben beschreibt insoweit +den Zwischenstand von einem Tag. diff --git a/docs/examples/werkbaum.werkbaum b/docs/examples/werkbaum.werkbaum index 2459524..446c3f5 100644 --- a/docs/examples/werkbaum.werkbaum +++ b/docs/examples/werkbaum.werkbaum @@ -532,9 +532,10 @@ #ed.docs.picker The app header reads "Werkbaum > name": the chip opens the menu, grouped by - kind (shipped, yours, sources), with rename, delete and restore on each row. - It scrolls as a whole instead of being cut off on small screens, and on the - phone it is reachable from both panes. + kind (shipped, yours, sources), with rename and delete on each row. Restore + lives on the editor title bar's reload button instead, acting only on the + open document. The menu scrolls as a whole instead of being cut off on + small screens, and on the phone it is reachable from both panes. #ed.docs.url A link can carry the address of a text file, which is then fetched on every diff --git a/frontend/CLAUDE.md b/frontend/CLAUDE.md index 67d83e0..35d31aa 100644 --- a/frontend/CLAUDE.md +++ b/frontend/CLAUDE.md @@ -155,10 +155,12 @@ verworfene Elemente. Quelle sind ES-Module unter `src/`; `index.html` ist der Text in den Editor. `saveSrc()` schreibt den Editortext ins aktive Dokument. Der Wähler ist eine **Brotkrume im App-Kopf** (`#docTrigger`/`#docMenu`, „Werkbaum › Name", D81); das Menü gruppiert nach Dokumentart (`docKind()` in - docurl.js, headless getestet) und trägt Umbenennen/Löschen/Wiederherstellen - als Symbole **je Zeile** — `renameDoc/deleteDoc/restoreDoc` nehmen deshalb - eine **id**, nicht das aktive Dokument, und Verwaltungs-Aktionen lassen das - Menü offen. Die Editor-Titelzeile heißt wieder „Text-Editor" und trägt die + docurl.js, headless getestet) und trägt Umbenennen/Löschen als Symbole + **je Zeile** — `renameDoc/deleteDoc` nehmen deshalb eine **id**, nicht das + aktive Dokument, und Verwaltungs-Aktionen lassen das Menü offen. + Wiederherstellen gibt es im Menü bewusst **nicht** (D81-Nachtrag 2): Es + läuft über den Neu-laden-Knopf der Titelzeile und wirkt nur auf das + geöffnete Dokument — `restoreDoc()` prüft das selbst. Die Editor-Titelzeile heißt wieder „Text-Editor" und trägt die Stand-Knöpfe (`saveBtn`/`snapAddBtn`/`snapBtn`/`reloadBtn`/`shareBtn` in der `.standgroup`); ihren Zustand setzt `updateDocButtons()` — aufgerufen aus `updateDocName()` UND am `input`-Ereignis, denn die Abweichung vom diff --git a/frontend/src/app.js b/frontend/src/app.js index 24ee573..268a6ed 100644 --- a/frontend/src/app.js +++ b/frontend/src/app.js @@ -3571,15 +3571,17 @@ function serverHostOf(id){ if(!roh.startsWith('live:')) return null; try{ return new URL(roh.slice(5)).host; }catch(_){ return null; } } -/* Kleine Zeilen-Icons (Feather-Stil wie überall): Stift, Papierkorb, - Wiederherstellen. Als Konstanten, damit der Renderer lesbar bleibt. */ +/* Kleine Zeilen-Icons (Feather-Stil wie überall): Stift, Papierkorb. + Als Konstanten, damit der Renderer lesbar bleibt. */ const IC_RENAME = ''; const IC_DELETE = ''; -const IC_RESTORE = ''; /* Eine Menüzeile: Wählen-Knopf + Zeilen-Aktionen als GESCHWISTER — ein Knopf im Knopf wäre ungültiges HTML. Die Aktionen sind immer sichtbar (Touch - kennt kein Hover): Umbenennen und Löschen überall, Wiederherstellen nur an - einem mitgelieferten Dokument, das vom Auslieferungsstand abweicht. */ + kennt kein Hover): Umbenennen und Löschen, beides überall. Wiederherstellen + gibt es hier bewusst NICHT (D81-Nachtrag 2): Es wirkt über den + Neu-laden-Knopf der Editor-Titelzeile nur auf das geöffnete Dokument — + ein ungeöffnetes zurückzusetzen, ohne zu sehen, was man verwirft, ergäbe + keinen Sinn. */ function docRowHtml(d){ if(d.id === renamingId){ /* Inline-Umbenennen direkt im Menü (kein window.prompt — das ist in @@ -3593,8 +3595,6 @@ function docRowHtml(d){ verriete den Unterschied. */ const host = serverHostOf(d.id); const zusatz = host ? `${esc(host)}` : ''; - const shipped = shippedStateOf(d.id); - const abweichend = shipped && (d.text !== shipped.text || d.name !== shipped.name); const iconBtn = (act, label, svg, extra) => ``; @@ -3604,7 +3604,6 @@ function docRowHtml(d){ `` + `${esc(d.name)}${zusatz}` + `` + - (abweichend ? iconBtn('restore', t('docRestore'), IC_RESTORE) : '') + iconBtn('rename', t('docRename'), IC_RENAME) + iconBtn('delete', t('docDelete'), IC_DELETE, ' docdelbtn') + ``; @@ -3682,22 +3681,21 @@ function updateDocButtons(){ speichern.title = t('docSaveFile') + (h ? '\n' + h.name : ''); } } -/* Wiederherstellen gilt jetzt je Zeile des Menüs UND — für das aktive - Dokument — dem Neu-laden-Knopf der Titelzeile. */ +/* Original wiederherstellen — erreichbar über den Neu-laden-Knopf der + Editor-Titelzeile und damit nur für das GEÖFFNETE mitgelieferte Dokument + (D81-Nachtrag 2): Ein ungeöffnetes zurückzusetzen, ohne zu sehen, was man + verwirft, ergäbe keinen Sinn. */ function restoreDoc(id){ const d = docs.find(x => x.id === id); const shipped = d && shippedStateOf(d.id); - if(!shipped) return; + if(!shipped || d.id !== activeId) return; if(!window.confirm(t('docRestoreConfirm', {name: d.name}))) return; d.text = shipped.text; d.name = shipped.name; - if(d.id === activeId){ - foldOverrides.clear(); - loadActiveIntoEditor(); - } + foldOverrides.clear(); + loadActiveIntoEditor(); persistDocs(); - if(!docMenu.hidden) renderDocMenu(); - updateDocButtons(); + if(!docMenu.hidden) renderDocMenu(); /* der Name kann sich zurückgeändert haben */ } /* Aus der Quelle neu laden (D81): mitgeliefert → Original wiederherstellen; URL-Dokument → frisch holen (die URL ist die Quelle der Wahrheit, D23); @@ -4964,7 +4962,6 @@ docList.addEventListener('click', e => { if(!id) return; if(akt.dataset.act === 'rename') renameDoc(id); else if(akt.dataset.act === 'delete') deleteDoc(id); - else if(akt.dataset.act === 'restore') restoreDoc(id); return; } const btn = e.target.closest('.docpick');