feat(editor): the element History sheet and its two menu entries #290
No reviewers
Labels
No labels
bug
enhancement
needs-triage
ready-for-agent
ready-for-human
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Cloonar/deckle!290
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "afk/284"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #284
What
History…in the element card's ⋮ menu and the form's More menu, a clock icon, in its own group directly above Delete… in both (the two menus put Move up/down between the clipboard group and Delete, so "above Delete" is the one position that is the same in both). A connected translation's locked card menu keeps it: the history is read-only and each language has its own.HistorySheet(web/src/components/HistorySheet.tsx) onSheet: the eyebrow "History", the title, a subtitle naming the element type, page, language and uid, and one request on open, with no polling. Rows are disclosure buttons (aria-expanded/aria-controls). The pending row comes first with the blue badge and "working tree, not on main". The first two rows are open. The per-field diff dispatches onkind/widget, never onfield: the server's word runs asdel/ins; Before/After boxes drawn by the widget's own read-only display (image thumbnail + ref, link, choice…); item rows tagged kept/added/removed/changed with their own field changes; Enabled shown with the switch's on/off hints; an absent side shows "none".Show olderonly when the answer hadnext. It sendsbefore, appends rows without duplicates (by commit) and is disabled while a request runs. Once the chain is exhausted it reads "No older entries" and stays disabled.unavailableshows its reason translated by its code. A 404 closes the sheet and shows the translated message in the screen'selement-action-errorstrip. Other errors show in the sheet body.web/src/api/history.ts: a decoder andfetchElementHistory, status-driven (ok | notFound | error).unavailablewas written twice before (publish.ts,stores/pageTree.ts). It is now oneunavailableReasoninapi/client.ts, used by all three callers. The switch's hint is exported (switchHint) instead of being copied.history.*,element.menu.historyandform.menu.historyinen.json/de.json("Verlauf", "Noch nicht veröffentlicht", "Geändert", "Erstellt", "Entfernt", "Ältere anzeigen"). The glossary gains history / history entry (Änderung) / working tree (Arbeitskopie) / before, after.docs/architecture.md's element-history paragraph. The scaffolded AGENTS.md and skills are not affected, because the editor menus are not part of what they document.Decisions where the brief was silent
Verification
cd web && npx tsc --noEmitis clean.npm testpasses: 126 files, 3255 tests, including i18nParity, i18nLeak and the source tests.npm run buildsucceeds.make build,go vet ./...andgo test ./...are green.web/src/test/HistorySheet.test.tsx(21 tests) runs against one fixture that covers every entry kind and widget, plusnext,unavailable, 404 and the keyboard. Menu tests inElementCrud,FormScreenandConnectedGuardcheck the position in both languages, exactly one request and none before, that the form is not opened from the card and stays mounted from the form, a 404 reaching the error strip, and Escape returning focus to the menu trigger.minmax(0, …), and@container shell (min-width: 721px)switches to the wide layout.🤖 Generated with Claude Code
[autoland] verdict: pass
PASS — validated by the lander.
Signal:
labctl pr checks 290aggregate success. ci / build-and-test ran npm ci, npm run build, npm test (vitest, i18n parity/leak/source tests included), go vet, go test and go build on this exact head, so it covers every file in the diff. Nothing was re-run locally.Conventions: the Conventional Commits title is feat(editor).
Closes #284is present. The branch is based on main's tip (5079051), so there is no conflict.Scope: in line with #284's brief. Both menu entries sit in their own group directly above Delete… (ElementCard.tsx elementMenuEntries, FormScreen.tsx menuEntries), and the locked menu keeps History…. HistorySheet.tsx renders the server's kinds, widgets, word runs and row statuses, and the decoder (api/history.ts) matches docs/api.md "GET /api/element/history". Show older dedupes rows by commit and ends disabled. A 404 goes to the element-action strip, and
unavailableis translated by its code. The edits to Sheet.tsx (eyebrow/detail) and theunavailableReasonconsolidation in publish.ts and pageTree.ts follow CLAUDE.md's one-owner rule and are not drive-bys. The CLAUDE.md doc rules are met: one sentence in docs/architecture.md, no new route, and nothing in AGENTS.md or the skills enumerates the element menu.Nit, not blocking: valueSide in HistorySheet.tsx gives every Before/After display the same
id="history-value". A switch-widget param would therefore render duplicate input ids. It has no functional effect, because the switch is named by aria-label.