editor: manage a container's children in the owner's form, saved with it #259
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#259
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
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?
Summary
A container's children (
accordion→accordion-item) are managed from the container's own form, TYPO3-style: a rows list in the owner's form with reorder, enable/disable, remove, an edit link to the child's own form and an Add button. Reorder, enabled state and removals are pending until the form is saved and go in the same save as the owner's params. This is the first half of "one way to show and edit an element's children"; the second half (#260, the overview digest that replaces nested cards) depends on it, because once the page overview stops nesting cards the form is the only place a container child can be reached.Mockup (private artifact, decided with the maintainer; the "Accordion form (container)", "Cards form (items)" and "Image form (items)" tabs are this issue): https://claude.ai/artifact/7TnAN5rACaDYNv6iZPsak5
Current behavior
image,text-media,cards) edits its hidden rows inside its own form: the repeatable collection inweb/src/components/ElementForm.tsx(grip, up/down, eye toggle, trash can, collapsible rows with a thumbnail for the first image field, Add via the media picker or an empty row), all pending until Save, sent as theitemsarray ofPOST /api/page/save(savePageRequestininternal/server/server.go) and replaced wholesale.container: true) has no such section. Its children are reached only on the page overview, wherehasSubList(web/src/elementcard.ts) nests them as cards under the parent card with their own insert rows, drag and drop, ⋮ menu and eye toggle, each operation applied immediately through/api/element/{move,delete,insert}and/api/element/enabled.insertinweb/src/stores/pageEditor.ts) creates the element immediately and navigates to its edit page.Desired behavior
The form of a container element gains a children section, in the same place and with the same row shape as an items collection:
role: "element"child in the served tree), in document order: grip (drag to reorder), the child's element icon, its served summary (label when empty), its#uid, a Disabled chip when disabled, then up, down, eye toggle, a pencil and a trash can.returnto this form, like the overview's pencil.web/src/leave.ts). Discard restores the served order and states.items), and makes the save one undo step.Decisions
container,items,summaryand placement keys decide everything.Key interfaces
POST /api/page/save(savePageRequest,internal/server/server.go): a new optional children field besideitems, absent = leave children untouched; present = the final order of existing child uids with per-uid enabled state and the removed uids. Validation: every uid must be a currentrole: "element"child of this element, no duplicates, no unknown uids; a refusal reports a field error the client can show on the section.POST /api/formdescription (formDescription,internal/server/forms.go): the form needs to know it describes a container and what label to show for the children section; the children themselves come from the page tree the client already holds (roles and summaries are the server's verdicts,internal/elemops), so the description need not repeat them.internal/server/element.go(move, delete) andelement_enabled.go; the pending-changes and translation code paths those already run through.web/src/components/ElementForm.tsxis the row vocabulary to reuse (ItemRow,RowsBaseline, dirty tracking, the row header);insertand the navigation-with-return inweb/src/stores/pageEditor.ts; the picker filter for a parent inweb/src/elementcrud.ts(insertRefusal,pickerVisible); the unsaved-changes guard inweb/src/leave.ts.elemops.ChildRole/elemops.ElementSummaryvia the servedroleandsummaryon every node — the client reads them, never re-derives (CLAUDE.md "Every rule has exactly one owner").scaffold/site/AGENTS.md— the "Containers" paragraph of the element sidecar section and the editor description of how an element's children are edited;scaffold/site/.claude/skills/add-element/SKILL.md(the Children bullet and the verification step for a container element now says to check the children section of the parent's form);edit-content/SKILL.mdwhere it describes visible children;verify-site/preview-siteif they walk the overview's nested cards.scaffold/skills_test.goandinternal/element/agentsdoc_test.gomust stay green.Acceptance criteria
accordionelement's form shows a children section listing itsaccordion-itemchildren in document order with served summary, uid, enabled state, grip, up/down, eye, pencil and trash can; a container with no children shows the empty section with Add.disabledset per the toggles and removed children gone, every surviving child keeping its uid, params and body.itemsreplace).scaffold/site/AGENTS.mdand the affected skills describe the children section; drift tests pass.How to verify
go test ./...(needsweb/dist),cd web && npm test,harness checkon the scaffolded site.harness servethe scaffold site, open the showcase page's accordion, reorder and disable items, Save, reload, check the rendered page.Assumptions to check
ElementForm.tsx); confirm nothing there needs changing beyond sharing the row header with the new section./api/element/movecan be composed inside the save handler without re-reading the page between steps; if the operations each load and write the file, the save must still be atomic (apply on one in-memory document, write once).internal/serverpending-change code andweb/src/undoinfo.tsbefore deciding how one save is reported.Out of scope
Blocked by
None - can start immediately