Skip to content

Console FormPage (the standalone /forms and internal FormView renderer) never evaluates visibleWhen/visibleOn — objectui#2212 was fixed in the OTHER form renderer #5594

Description

@os-sales

Found while implementing #5542 (converging the console's FormFieldSpec onto the
shared app-shell declaration). Filed unassigned for PM triage — outside that card's
declared file surface, which was the type declaration and its pin, not the renderer.

Mechanism

apps/console/src/components/FormPage.tsx is a second, independent form renderer:
it has its own buildSections and its own JSX, and it serves both the public
/forms/:slug route and the internal /forms/:name route. Verified on the merged ref
cad512fe1, it contains zero occurrences of visibleWhen or visibleOn:

grep -c 'visibleWhen\|visibleOn' apps/console/src/components/FormPage.tsx -> 0

The only visibility it honours is the static boolean, at :1300:

{sec.fields.filter((f) => !f.hidden).map((f) => (

So a FormView field carrying a conditional predicate — legal, spec-strict metadata that
@objectstack/spec normalises to visibleWhen (ADR-0089), and that the metadata-admin
designer both authors and honours — renders unconditionally on these two routes.
Fail-open and silent: an author who conditions a field on record.priority == 'urgent'
sees it always, with no diagnostic.

Why this is not a duplicate of #2212

#2212 recorded exactly this symptom and PR #2214 fixed it — in a different chain:
ModalFormresolveFormViewLayoutpackages/plugin-formsectionFields.ts
packages/componentsrenderers/form/form.tsx. FormPage.tsx is not on that chain at
any point; it never calls buildSectionFields and never renders through
SchemaRenderer type:'form'. The fix landed in one of the two renderers that read this
key, and the fact that there were two was not visible from inside either.

That is the same reason #5542 exists one level down: one contract, several independent
implementations, each only ever checked against itself. #2212's own regression test
lives with the chain it fixed, so nothing in the suite can see this renderer's copy.

Severity note

User-reachable, unlike #5542 — this is a rendered-page behaviour on the public form
route, not a typing gap. But it is a fail-open, not a data-integrity defect, and the
correct fix direction is #2212's ruling verbatim: route the predicate through the
canonical engine (evalFieldPredicate, packages/coreevaluator/fieldRules.ts),
which already accepts string and the dialect/source object arm. Whether that is
worth doing here or whether FormPage.tsx should instead be folded onto the plugin-form
chain is an architectural call, not mine at filing time — the second renderer is arguably
the real finding.

Boundary

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpm:dispatched

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions