7.0 KiB
phase, plan, subsystem, tags, status, requires, provides, affects, tech-stack, key-files, decisions, metrics, estimate, actuals, plan_head_before, plan_head_after
| phase | plan | subsystem | tags | status | requires | provides | affects | tech-stack | key-files | decisions | metrics | estimate | actuals | plan_head_before | plan_head_after | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| quick-261006-t5r | 01 | cabana forms / admin SPA |
|
complete |
|
|
|
|
|
|
|
|
7e2b1a909b |
5932172148 |
Quick 261006-t5r: Make SPA slug preset follow mltext source Summary
fields.yaml preset now works on mltext fields: cabana accepts text/mltext targets and sources, and the admin SPA follows an mltext title into an mltext slug per locale, stopping only the locale the administrator edits by hand.
What changed
Task 1 - cabana (7afad73, feat(cabana): accept preset on mltext fields)
compilePresetKeyadmitstype: textortype: mltext; anything else fails withpreset is only valid on type: text or mltext.checkPresetsadmits a text or mltext source; otherwisefield %s: preset field %s must be a text or mltext field.- New DB-free
TestPresetML(RED confirmed before the change) covers mltext->mltext (mapping, short form, exact), text->mltext, mltext->text, and the refusals (mlmarkdown and markdown targets, mlmarkdown source). The Journal-shaped field serializes with"type":"mltext"and"preset":{"field":"title","type":"slug"}. TestPresetSchema/TestPhase121BootErrorsrows updated to the new messages (testcontainers Postgres, green). Settings and relation forms still refusepreset.
Task 2 - admin SPA (b5d8506, feat(admin): follow presets on mltext fields per locale)
formState.ts:changedLocales(previous, next)andpresetUpdates(fields, source, previous, next, values, activeLocale, isEdited)(plusPresetEditedtype) hold every preset-follow rule; all values still go throughpresetValue, so slug/exact remain one implementation.FormView.vue:update()reads the previous value, records per-locale hand edits of ML fields ineditedLocales, and on create mergespresetUpdatesinto the next values.mlLocalefollows the windowML_LOCALE_CHANGEevent, starts on the first enabled locale after load, and resets to it whenactiveTabchanges. Update mode unchanged.- Tests: 6 new formState unit cases, 4 new FormView cases (Journal ML->ML per-locale with POST body check, update mode, mltext->text, text->mltext). The existing text preset test is unchanged and green. Full Vitest: 1064 passed; vue-tsc clean.
modules/boardwalk/distrebuilt (oldindex-7UEAlsFO.jsremoved,index-DPCIeFlT.jsadded; intentional hashed-bundle swap);check-admin-dist.shreports a match.
Task 3 - docs (5932172, docs(cabana): document preset on mltext fields)
schema_types.goPreset/FieldPreset comments and the form-schema swag description inadmin_openapi.goname text or mltext;admin.jsonandschema.d.tsregenerated withscripts/check-admin-openapi.sh(the--checkgate passes).modules/cabana/README.md(Features bullet,cabana.FieldPresetrow) anddocs/backend/forms.md(Field options list, preset paragraph, new multilingual-rules paragraph, start-up refusal sentence, and a pointer from the Markdown and multilingual fields section to#field-options).TestDocsTree,go vet ./...andgo test ./...green.
Discretion choices (from the plan)
- ML -> ML follows per locale: only the locales whose source text changed in this update are rewritten, each from its own locale.
- Edits of an ML target are tracked per locale: a hand edit of locale L stops L only.
- A preset never writes a locale the administrator neither typed in (source side) nor is looking at (target side): text -> mltext writes only the active locale; untouched locales stay empty so the server's translation fallback applies, and no unseen duplicate translations get saved.
- mltext -> text follows the source's active-locale string (FormView tracks the active ML locale).
- mlmarkdown stays out: the server admits text/mltext targets and text/mltext sources only.
Plugin follow-up (sm-journal-plugin, NOT edited in this task)
sm-journal-plugin was not edited. Apply in that repo:
models/post/fields.yaml, the slug field gains a preset:
slug:
label: golem15.journal::lang.post.slug
type: mltext
span: right
tab: golem15.journal::lang.post.tab_edit
required: true
preset:
field: title
type: slug
models/category/fields.yaml, the slug field gains preset: { field: name, type: slug } the same way (its source name is mltext). models/tag/fields.yaml already has a text -> text preset and needs nothing.
Deviations from Plan
None - plan executed exactly as written. (Process note: the formState helpers were written just before their tests; RED was then demonstrated by running the new tests against the committed formState.ts/FormView.vue — 9 failures — before restoring the implementation.)
Known Stubs
None.
Threat Flags
None. No new routes or trust-boundary surface; the server-side widening admits exactly text and mltext (pinned by TestPresetML), and preset output remains client convenience validated by the normal save path.