You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Form-view FormField.visibleOn (CEL) is never evaluated — conditional fields always render #2212
A form view section field with a CEL `visibleOn` predicate is always visible. Showcase repro (framework `examples/app-showcase/src/views/task.view.ts`):
The server meta correctly ships `"visibleOn": {"dialect":"cel","source":"record.priority == 'urgent'"}` (verified via `GET /api/v1/meta/view/showcase_task` → `.formViews.default.sections[0].fields[6]`), but the notes field renders even when priority = Low. Field-level `visibleWhen`/`readonlyWhen`/`requiredWhen` all work — only the view-level `FormField.visibleOn` is dead.
Object shape silently dropped — `sectionFields.ts` `attachVisibility()` (line 45) and `ObjectForm.tsx` `normalizeVisibility()` (line 411) only accept `typeof expr === 'string'`. The spec `P`-template wire shape is `{dialect:'cel', source}` → predicate never attached.
The evaluator isn't CEL — even for a string expr, the attached `visible(formData)` calls `evaluateCondition()` (`packages/fields/src/index.tsx:1833`), which only understands legacy `{field, operator, value}` objects and returns `true` for any unknown format ("Default to true").
Nothing consumes the predicate anyway — no renderer in the form chain ever calls `FormField.visible(formData)`; `form.tsx:538` destructures `visibleOn` out of the field config and drops it on the floor.
Meanwhile the working field-level rules go through the canonical engine: `resolveFieldRuleState`/`evalFieldPredicate` (`packages/core/src/evaluator/fieldRules.ts`), which already accepts `string | {dialect, source}` and binds `record` scope via `@objectstack/formula` ExpressionEngine (ADR-0036: no private expression DSL).
Fix direction
Route view-level `FormField.visibleOn` through the same canonical engine:
`form.tsx`: evaluate `visibleOn` with `evalFieldPredicate` against the live `ruleRecord` (fail-open), both at field render and in the stale-error-clearing effect.
`sectionFields.ts`: carry `visibleOn` (string or `{dialect, source}`) through `normalizeSectionField` instead of attaching a dead `visible()` closure; also carry field-level `visibleWhen`/`readonlyWhen`/`requiredWhen` from object-schema metadata so sectioned forms honor them like flat forms do.
`types/form.ts`: widen `FormField.visibleOn` to the spec Expression shape.
Found while dogfooding the framework app-showcase (list/form capability audit, P0-16).
Activity
fix(list): show real match total in record-count bar under server pag…
fix(form): harden the spec↔runtime form-field chokepoint, derive Sele…
fix(console): evaluate visibleWhen/visibleOn in FormPage
fix(console): evaluate visibleWhen/visibleOn in FormPage (objectstack…
feat(plugin-grid): one display page size read from the spec, and a di…