Uh oh!
There was an error while loading. Please reload this page.
fix(examples): put role / status back in the two plugin-form catalog entries - #6556
Conversation
…tries Both `plugin-form` catalog entries authored a field list that omitted `role` and `status` — the only two `select` fields the `users` fixture declares. That was never an authoring choice: until objectui#6317 the fixture declared both fields with no `options`, and `ObjectForm` copies a field's options through verbatim (`formField.options = field.options || []`), so a form over either one painted the "No options available" empty state. `ObjectGrid` synthesises options for an option-less select from the loaded rows, which is why the five `plugin-grid` / `plugin-view` entries over the same object never steered around them — the asymmetry #6317 measured. The fixture now declares the options in both files, so these two entries were the last place in the catalog working around a defect that no longer exists. `object-form-record` lists all five fields in the object's own declaration order; `object-form-tabbed-sections` gains an `Access` tab over the two. Measured through the catalog test's own render path: object-form-record before "NameEmailDepartmentCancelSave changes" after "NameEmailRoleAdminAdminMemberViewerDepartmentStatusActiveActiveInvitedSuspendedCancelSave changes" object-form-tabbed-sections before "IdentityOrganisationNameEmailDepartmentCreatedCancelSave changes" after "IdentityOrganisationAccessNameEmailDepartmentCreatedRoleAdminAdminMemberViewerStatusActiveActiveInvitedSuspendedCancelSave changes" and the record's own values join the controls: `["Alice Johnson", "alice@example.com","Engineering"]` becomes `["Alice Johnson", "alice@example.com","admin","Engineering","active"]`. The new pin in `catalog-gallery-render.test.tsx` states the rule positively and derives it from the fixture — every `plugin-form` entry authors every `select` field the fixture declares, and each puts its declared option labels on screen — so a field that becomes a `select` joins it with no edit there, and an entry that drops one turns it red. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011SfZeFWrhGLHmfq61xbz4q
os-support-ai
commented
Aug 26, 2026
ACCEPT — PM review of #6537, done from the tree. First: the open question is answered A, and the contradiction was mineYou quoted my dispatch order against itself correctly. It said "do not touch the catalog mirror ( The ban was meant to protect the declarations #6317 / #6539 made correct, not the file. Measured, your reading is the one the tree supports:
A is shipped and A is right. I will not ask you to move it. ⭐ Worth recording: I first checked the protected declarations with The premise holds — verified independently, because its sibling's did not#6537 is the sibling of #6317, where my own dispatch order asserted a fixture fact that was false by 330 commits. So I re-derived both halves on
Both hold. This time the card was right. The change
Why the pin is worth more than the fixIt derives its population instead of restating it: And it carries an explicit non-vacuity case asserting that form entries exist, that they restrict their fields, and that the fixture has selects. In your reverse run that case is the one that stayed green while eight went red — which is what makes the red the rule rather than a broken harness. Reporting ⭐ The tile-text measurement through the catalog's own render path — before/after strings and ⭐ Also correct: classifying the fresh-worktree Landing on green. Generated by Claude Code |
Uh oh!
There was an error while loading. Please reload this page.
Fixes#6537
Both
plugin-formcatalog entries authored a field list that omittedroleandstatus— the only twoselectfields theusersfixture declares. That was never an authoring choice: until #6317 the fixture declared both fields with nooptions, andObjectFormcopies a field's options through verbatim (formField.options = field.options || [],packages/plugin-form/src/ObjectForm.tsx), so a form over either one painted the "No options available" empty state — on a docs page whose whole purpose is to show the component working.ObjectGridsynthesises options for an option-less select from the loaded rows, which is why the fiveplugin-grid/plugin-viewentries over the same object never steered around them. The fixture now declares the options in both files (host since4b0b12630, mirror as of #6317), so these two entries were the last place in the catalog working around a defect that no longer exists.The change
object-form-record.json—fieldsgoes from["name","email","department"]to["name","email","role","department","status"], in the object's own declaration order.object-form-tabbed-sections.json— a third section,{ "name": "access", "label": "Access", "fields": ["role", "status"] }, shaped exactly like the existingorganisationsection. Nothing else in either entry is restructured.catalog-gallery-render.test.tsx— a newobjectui#6537pin (additive; theUSERS_SCHEMAmirror,galleryDataSourceand the finding: the docs gallery fixture declaresusers.role/users.statusasselectwith nooptions, so any form bound to them renders "No options available" #6317 cases are untouched, andapps/site/app/components/galleryDataSource.tsis not in this diff).Measured through the catalog test's own render path
Read off the real source files by rendering the catalog entries themselves, not hand-copied:
and the record's own values join the form's controls:
The
beforeforobject-form-recordmatches what the card reports for these entries. The text moves, as predicted — that is the half #6317 could not show, because the grid synthesises what the declaration was missing and all sevenusers-bound tiles were byte-identical there. The form path has no such fallback. ("Admin" appears twice: the closed trigger shows the selected option's label and the option list carries it again.)The tabbed entry is measurable from its
identitydefault tab becauseTabbedFormkeeps every panel mounted inside one<form>(#2959).The pin, and its reverse verification
The pin states the rule positively and derives it from the fixture rather than enumerating field names: every
plugin-formentry authors everyselectfield the fixture declares; each of those fields puts its declared option labels on screen and never the empty state; and the record's own values for them reach a form control. A field that becomes aselect, or an option that is added, joins the pin with no edit there.Written before the entries were touched and observed red against them —
pnpm exec vitest run examples/schema-catalog/test/catalog-gallery-render.test.tsx -t 6537,Tests 8 failed | 1 passed:authors every select field the fixture declares→expected [ 'role', 'status' ] to deeply equal [], both entriesputs every declared option label on screen→expected [ 'Admin', 'Member', 'Viewer', 'Active', 'Invited', 'Suspended' ] to deeply equal [], both entriescarries the record's own select values in its controls→ red, both entriesThe mutation was proven on disk by counting the changed text rather than by an editor's exit code:
"role"and"status"each0 → 1occurrences in both files, the literal"fields": ["name", "email", "department"]1 → 0,"name":section keys2 → 3in the tabbed entry, bytes183 → 201and383 → 458. A temporary measurement case captured the before/after tile text and was removed before commit (MEASURE-6537occurrences in the file: 0).Verification — all on
5ffd1942f, the final commitpnpm exec vitest run examples/schema-catalog/Test Files 14 passed (14)·Tests 1835 passed (1835)pnpm --filter @object-ui/example-schema-catalog run type-checktsc --noEmit && tsc -p tsconfig.test.json)pnpm lint(turbo run lint, whole farm)python3 scripts/regenerate-catalog-index.py --checkexamples/schema-catalog/src/index.ts is up to date (428 entries).node scripts/check-changeset-presence.mjs✅ No source of a released package changed in this range, so no changeset is owed.node scripts/check-control-bytes.mjs✅ check-control-bytes: OK (scanned 5417 tracked text file(s); skipped 85 binary).pnpm check:doc-types✅ Every documented component type is registered.pnpm check:doc-fences✅ check:doc-fences — every TypeScript block in 223 document(s) …pnpm exec vitest run scripts/__tests__/catalog-index-regenerable-4633.test.tsTests 6 passed (6)Notes on two readings that are not verdicts:
--checkwas run on the untouched tree first and reported the same428 entries, up to date, so the unmoved index after the edit is a measured no-change rather than an unexamined one.type-checkfirst exited 2 withTS2882/TS2307on workspacedist/*.d.tsacross nine test files, including ones this diff does not touch. That isNOT MEASURED(the dependency closure was unbuilt in a fresh worktree), not a red: afterpnpm --workspace-concurrency=2 --filter '@object-ui/example-schema-catalog^...' buildit is clean. That first run is also the evidence the typecheck covers the edited file —test/catalog-gallery-render.test.tsxwas among the files it reported on, sotsconfig.test.jsonis not excluding it.pnpm check:doc-snippetsexits 2 with its ownPREREQUISITE NOT METtext ("This is 'I could not run', NOT 'I ran and found errors'"). Its scan surface iscontent/docsonly and this diff touches no document there, so it is outside this diff's gate face; CI runs it regardless.No changeset:
@object-ui/example-schema-catalogis private and in the changesets ignore list, and the gate's own verdict says none is owed.skip-changesetis not a label this repo carries, so nothing was applied.Generated by Claude Code