Uh oh!
There was an error while loading. Please reload this page.
fix(form): evaluate view-level FormField.visibleOn with the canonical CEL engine - #2214
Merged
Conversation
The latest updates on your projects. Learn more about Vercel for GitHub. |
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
Uh oh!
There was an error while loading. Please reload this page.
… CEL engine Fixes#2212. The spec ships `visibleOn` as an Expression object `{ dialect: 'cel', source }` (what the P template emits) or a bare string, but the chain dropped it end to end: - sectionFields.ts attachVisibility and ObjectForm's normalizeVisibility only accepted the bare-string shape, and even then attached a dead `visible()` closure no renderer ever called; the Expression object was silently discarded. - The form renderer destructured `visibleOn` out of the field config and never evaluated it. - RecordFormPage dropped a `simple` form view's `sections` entirely, so page-mode create/edit fell back to the raw schema (every field, no authored selection or conditional visibility) while the New/Edit modal honored the same view via resolveFormViewLayout. - ObjectForm's grouped-sections path matched section fields by name only, dropping per-field `visibleOn` overrides. `visibleOn` now flows through normalization verbatim (both wire shapes) and the form renderer evaluates it reactively with `evalFieldPredicate` — the same canonical engine, record scope, and fail-open semantics as field-level `visibleWhen` (ADR-0036); visibleOn AND visibleWhen must both allow a field. Sectioned/flat normalization also copies the field-level visibleWhen / readonlyWhen / requiredWhen rules it previously lost. Verified in the browser against examples/app-showcase showcase_task (`notes` with visibleOn `record.priority == 'urgent'`): page-mode edit and the New-record modal both hide/show the field reactively as priority changes. Co-Authored-By: Claude <noreply@anthropic.com>
os-sales pushed a commit
that referenced
this pull request
Aug 21, 2026
`apps/console/src/components/FormPage.tsx` is a second, independent form renderer — it serves both `/f/:slug` (public, anonymous) and `/forms/:name` (internal) — and it read neither spelling of the FormView field visibility predicate. A field conditioned on `record.priority == 'urgent'` rendered unconditionally on both routes: fail-open and silent. objectui#2212 recorded the same symptom and PR #2214 fixed it on the OTHER chain (ModalForm -> resolveFormViewLayout -> plugin-form sectionFields.ts -> components renderers/form/form.tsx), which this file is on at no point, and that fix's regression pin lives with that chain. Applies #2212's ruling verbatim rather than inventing a second predicate semantics: the predicate is routed through the canonical engine, `evalFieldPredicate` (@object-ui/core, evaluator/fieldRules.ts), with the same `record.`/`previous.` scope, the same accepted wire shapes (bare CEL string and `{ dialect, source }`), and the same fail-open-but-loud behaviour. Resolution is canonical-first — `visibleWhen ?? visibleOn` — matching plugin-form's `sectionFields.ts` and app-shell's `readVisibility`. The regression pin lives with THIS renderer, next to the copy it describes: a pin that cannot see the second copy is how the first gap survived. Out of scope by triage fence: FormPage is not folded onto the plugin-form chain. The second-renderer convergence question stays with the #5596 track. Fixes#5594 Claude-Session: https://claude.ai/code/session_012u2pRjcqAYtoEjgr3wwhnK
This was referenced Aug 21, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes#2212 — view-level
FormField.visibleOn(CEL) never took effect anywhere in the form chain, while field-levelvisibleWhenworked.Root causes (all confirmed by source scan, file:line in #2212)
visibleOnas{ dialect: 'cel', source }(what the specPtemplate emits).sectionFields.tsattachVisibilityandObjectForm.tsxnormalizeVisibilityonly acceptedtypeof expr === 'string', so the object shape was silently dropped.visible()closure built onevaluateCondition, which is not a CEL evaluator (it only understands{field, operator, value}legacy objects and defaults unknown input totrue) — and no renderer ever called that closure anyway. The form renderer destructuredvisibleOnout of the field config and dropped it.RecordFormPageonly forwardedsectionsfortabbed/wizard/split, so asimpleform view's authored field selection, grouping, andvisibleOnpredicates were all discarded in page-mode create/edit, while the New/Edit modal honored the same view viaresolveFormViewLayout.ObjectForm's simple-sections branch matched section fields by name only, losing the section field def'svisibleOn.Fix
visibleOnflows through normalization verbatim (both wire shapes) and the form renderer evaluates it reactively withevalFieldPredicate— the same canonical engine, record scope, and fail-open semantics as field-levelvisibleWhen(ADR-0036). When bothvisibleOnandvisibleWhenare present, both must allow the field.RecordFormPagenow forwards curatedsectionsfor every layout family, aligned with the modal path.fromObjectSchema) andModalFormflat normalization now also copy field-levelvisibleWhen/readonlyWhen/requiredWhenrules they previously lost.Tests
form-visibleon.test.tsx(4): object shape hides/shows reactively, bare-string shape, broken-CEL fail-open,visibleOn×visibleWhencombination.sectionFields.test.ts+5: both wire shapes survive normalization (no dead closure), runtime FormField shape, field-level rule copying.Browser verification (examples/app-showcase,
showcase_task.noteswithvisibleOn: record.priority == 'urgent')priority = Low→ 备注 hidden; switching toUrgentshows it live; back toLowhides it again. Sections (Task group header, authored 7-field selection) now render in page mode.Urgent.Co-Authored-By: Claude noreply@anthropic.com