feat(editor): form screen with General · Appearance · Access tabs, validation at rest, one unsaved-changes guard #175
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!175
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "afk/172"
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 #172
What changes
Server / scaffold
tab:general(default) |appearance; page-type fields may also useaccess(navigation flags such ashidden).tab: accesson an element param, or an unknown value, is a load error.tab; the Enabled field is on Access (it keepsgroup: access), and the backend layout pickers are on Appearance.POST /api/formreturnserrorsfor element and properties forms. These are the messages a save of the loaded values would report, keyed like the 422 (name,items[i].name), and the existing save checks produce them.side,cols,lightbox,variantandsizeare on Appearance, andhidden/footerare on Access. The testdata site's sidecars follow the same split.scaffold/site/AGENTS.mddocumentstab. The drift test now requirestab,general,appearanceandaccess. The README's/api/formcontract is updated too.ce-bridge.js) scrolls a highlight into view when asked (scroll: true).Editor
EditPaneis replaced byFormScreen(Docheader +ElementForm).#uid, and the status ("Unsaved changes" badge or "Saved just now").ElementFormreplacesFormPane;FormPane.tsxandFormItems.test.tsxare gone, and the tests moved toElementForm.test.tsx.PageFormreplacesPageSettings, with the same tabs:FieldGroup,FieldFrame,FormTabsandproblemTabs(the red dot per tab), inFormLayout.tsx.leaveForm()inguard.ts. The shell'suseBeforeLeaveand the host links both call it, so Close, Esc, the Content/Properties tabs, the tree, the module rail, browser back, host navigation and the docheader's structural actions all show one dialog: Stay / Discard changes / Save & continue, titled "in ".useFormShortcuts: ⌘/Ctrl+S saves. Esc closes the form only when no menu or dialog layer is open (#140 rule)./view/<lang>/<page>?element=<uid>. The View module resolves the uid and highlights the element, and the preview scrolls it into view.Notes and decisions
leaveForm, so Save & continue saves before they run. Delete… asks only its own confirmation (the edits go with the element) and then closes unguarded.tab: access. It is allowed on page-type fields only; element sidecars still choose only between general and appearance.Verification
make test: 80 vitest files, 2322 tests, plusgo test ./..., all green.tsc --noEmit,go vetandmake buildare clean.?element=;tabload rules and/api/formerrors.testdata/site: with the hero's requiredtitleremoved,POST /api/formreturnserrors: {title: "this field is required"}, andaligncomes back withtab: appearance. The UI was not exercised in a real browser.🤖 Generated with Claude Code
tabkey and validation at rest on POST /api/form 4d8e521f62[autoland] verdict: pass
Verdict: CONCERNS (non-blocking). Validated against #172.
ci / build-and-testis green (run 167, 12m15s), so it was not re-run.Closes #172, head already containsmain(no conflict).scaffold/site/AGENTS.mdand the drift test are updated fortab.Concerns (worth a follow-up, none blocks the merge):
FormScreen.tsxdoSave(~258) andPageScreen.tsxsaveProps(~218) callsubmit()without checkingsaving(). NeitherElementForm.submit(~794) norPageForm.submit(~212) refuses a second call. Two ⌘S presses during a slow save post the page twice. The mutation lock runs the two saves one after the other, but item rows that have no uid yet get uids stamped twice.guard.tsavoids this same race insaveAndContinue. Fix: return early whensaving().tabon item elements.scaffold/site/AGENTS.md:91-92says item elements "taketabthe same way".ElementFormrenders every item-row field inside the row on General, so the key is validated but changes nothing there. CLAUDE.md requires the prose to be truthful: either say it is ignored inside rows, or implement it.tab: appearanceand which has no body and no items opens on a blank General tab (ElementForm.tsx:1294-1316). The scaffoldspaceris one, after this PR. Appearance has an "empty" note; General has none.Nits:
RichTextField.tsx:505still renders aTable ▾glyph.returnwritten by a preview click (App.tsx:286) keeps?element=X, so closing a form opened from the preview re-reveals the old element.PageFormshows a content path with the hint "Set by the page tree."[autoland] verdict: pass
Re-validated at
8219fc3. Verdict: PASS.ci / build-and-testis green on the new head (run 168, 11m10s), so it was not re-run.Closes #172, no conflict withmain).All three earlier concerns are resolved:
submit()inElementFormandPageFormnow joins a save in flight instead of posting again. It saves once more only if an edit made meanwhile left the form dirty. The reset runs before any joiner's follow-up, so nothing posts in parallel. Covered by tests in ElementForm, PageForm and FormScreen (⌘S).tabis checked but has no effect on item elements.Still open, non-blocking nits:
Table ▾glyph inRichTextField.tsx?element=kept in the return link a preview click writes (App.tsx:286)PageFormPath hint