Repository navigation
fix(app-shell): an interface page relays its source view's hiddenFields and fieldOrder (objectui#10638) - #10667
Conversation
…ds and fieldOrder InterfaceListPage hand-projects the source view's columns, filter and sort into the list schema it hands ListView, and carried neither hiddenFields nor fieldOrder. Both now ride with the view's columns, as one unit: they apply only when the view supplies the columns (the page's own columns, or an empty view projection, carry neither). ListView's effectiveFields composes them. Pin: InterfaceListPage.viewFieldKeysRelay-10638.test.tsx. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN
|
changeset-claim-re-read
|
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
Contract reviewServed-tier: ① Derived judgmentsPrecedence ruling — holds. Spec read at objectstack Design-mode drag — reason holds, read at source. Head Empty- Object-route consistency — the divergence is real, the PR is the side that matches the spec, and it is stated. Pins — all six behave as claimed; measured. Worktree at head under the scratch dir,
Other keys — true, and it leaves the page half fallback-only; finding, not a blocker. Read at head: Edited header sentence — wording finding, non-blocking. The diff edits :9-11 to "the page REFERENCES one view ( ② Semver level
③ Boundary flags
Implemented-by: VERDICT: PASS Generated by Claude Code |
…k; changeset names the other carried keys Round 2 wording only, no code change. The InterfaceListPage header clause said the source view's columns, filter and sort are "never restated"; the page defines its own columns / filterBy / sort and the view is the ADR-0047 (revised) fallback. The changeset's list of carried keys now reads as non-exhaustive. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
Contract reviewServed-tier: ① Derived judgmentsDiff shape — as expected. Header clause — two legs true, one leg false. The new text is round 1's replacement applied verbatim. Read against head: "the page REFERENCES one view ( Changeset — true, frontmatter intact. md5 of lines 1-3 is Landing body — spec sourcing correct. 17.4.0 dist (package.json Landing body — Round 2 section true. The three fixes are as described; the md5 claim reproduces; the gate lines agree with the green Landing body — three wording faults.
No other changed sentence is false; no unchanged sentence regresses. Closing keyword: only Disclosed leftover — unversioned, not false. ② Semver levelUnchanged from round 1: ③ Boundary flags
Implemented-by: VERDICT: FAIL Wording only; the code is unchanged since round 1's PASS. To land: apply the Generated by Claude Code |
…ys inherited Round 3, comment only. The page's filterBy is appended to the source view's base filter and never displaces it; only columns (with their hiddenFields / fieldOrder) and sort fall back to the view. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
Contract reviewServed-tier: ① Derived judgmentsDiff shape — as expected. Header clause — true on all three legs at head. Landing body — every changed sentence true.
Round-2 record confirmed on the PR: comment ② Semver levelUnchanged: ③ Boundary flags
Implemented-by: VERDICT: PASS Generated by Claude Code |
Fixes #10638
Clause-②: no — an interface page begins honouring two declared per-view keys it drops today; no export, schema or accept set moves.
Executes triage
5833520187(bug · p2) under claim5833614033(domain:uiseat 2, sessionsession_014mXUNuFomfj24w7s1pZzhN). This PR puts the source view'shiddenFieldsandfieldOrderinto the list schemaInterfaceListPagehandsListView. It states the page config's precedence and mirrors the objectui#7516 relay pin.What changed
packages/app-shell/src/views/InterfaceListPage.tsx). The schema literal now gets two conditional spreads besidecolumns:hiddenFields: view.hiddenFieldsandfieldOrder: view.fieldOrder. Each is present only when the view authored the key and the view supplies the columns. The page composes nothing.ListView'seffectiveFieldsmemo already runscolumnsprojects →hiddenFieldssubtracts →fieldOrdersorts the survivors, and an unlisted survivor sorts last.InterfaceListPage.viewFieldKeysRelay-10638.test.tsx).ListViewis stubbed and itsschemaprop is captured, the same posture asObjectView.fieldOrderRelay-7516.test.tsx. Three FIX cases: the view'shiddenFieldsarrives verbatim; the view'sfieldOrderarrives verbatim; the whole composition arrives together. One PRECEDENCE case and two CONTROLs: an empty viewcolumns, and a view that authors neither key.sourceViewas a fallback: the view's columns (with itshiddenFields/fieldOrder) and sort are inherited unless the page defines its owncolumns/sort, and its base filter is always inherited with the page'sfilterByappended (ADR-0047 revised). The "never restated" wording it replaces was false on base as well..changeset/10638-interface-page-view-field-keys.md,'@object-ui/app-shell': patch.The precedence (H2): the whole composition, from one source
cfghas no spelling of either key.InterfacePageConfigSchemais astrictObject, and its alias map sendsfields/columnListtocolumnsand neither key anywhere. So the two keys resolve with the page's column list, as one unit, on the same three branchescolumnsalready used:columns. That list is used as it stands, and neither view key applies. Released spec (@objectstack/spec17.4.0): pagecolumnsare "Defined directly on the page (no view inheritance)", andsourceViewis "Still honored at runtime as a fallback when the page has no owncolumns".columns. The view'shiddenFieldsandfieldOrdercome with them.ListViewSchema.columnssays an empty list "declares no projection, so neither of them applies". This is spec source at objectstackorigin/main(objectstack#19598,9dcdb77), not yet in the released 17.4.0.Why not "the page's
columnsprojects, the view's keys subtract and sort", as the order's H2 sketched? The composition is declared per view. TheListViewSchemacomposition docblock says "Three keys on this schema together build one field list"; this is spec source at objectstackorigin/main(objectstack#19598), not yet in the released 17.4.0. Mixing sources would also break design mode. The design-mode column drag (onColumnStateChange) saves the order it shows as the page'scolumns. A relayed viewfieldOrderwould then sort that list straight back, so the drag would appear to do nothing. Ablation B below shows the pin catches that wiring.Premises, measured on base
4a3d500fdbefore the first editresolveSourceViewfeeds a schema literal with 0 mentions of either key. Fixture:columns: ['name','owner','stage'],hiddenFields: ['owner'],fieldOrder: ['stage','name'].ListViewreceives on base: the pin readsTests 3 failed | 3 passed (6),expected undefined to deeply equal [ 'owner' ]and… [ 'stage', 'name' ].schema.columnsarrives as['name','owner','stage'].InterfaceListPageand the realListView, with onlyobject-gridstubbed to record the column list it is handed. Base draws["name","owner","stage"]. Head draws["stage","name"].ListViewis untouched.packages/app-shell/README.mdsentence names which source-view keys the page honours.InterfaceListPage, only.changeset/7218-rowcolor-host-relay.mdnames the edited file (percheck:changeset-claims). Its paragraph ("has shippedrowColor: view.rowColornext togroupingandpagination") was re-read and is still true.Verification of the change, round 1, on
b172bf0fbAll runs went through the shared verify lock. Legs 2–4 ran in one hold, each with a trap-protected restore proven by the blob hash matching HEAD (
00977917bcae) andgit diff HEADempty.Tests 6 passed (6). Probe draws["stage","name"].git show 4a3d500fd:…; on disk theviewComposescount is 0 and the blob equals the base blobf3e2e80e0509): pinTests 3 failed | 3 passed (6), the three FIX cases. Probe draws["name","owner","stage"].ablation-replace.mjs(objectstack), anchorx1 → x0, blob00977917bcae → 740fff063f76; an in-rungrep -cread0and0. Predicted: three FIX cases red. Measured:Tests 3 failed | 3 passed (6), the three FIX cases. The probe draws["name","owner","stage"].viewComposes && view.→true && view.,--expect 2, anchorx2 → x0, replacementx0 → x2), so the keys are carried unconditionally. Predicted: PRECEDENCE and the empty-columnsCONTROL red. Measured:Tests 2 failed | 4 passed (6), exactly those two.turbo run build --filter='@object-ui/app-shell^...' --concurrency=2.Tasks: 28 successful, 28 total.@object-ui/app-shelltype-check:tsc --noEmit && tsc -p tsconfig.test.json, exit 0.--listFilesOnlyon the test project lists the new pin.InterfaceListPage(23 files across 9 packages):Test Files 23 passed (23),Tests 362 passed (362).isPathIgnoredis false for both changed.ts/.tsxfiles.InterfaceListPage.tsxhas 39 warnings on head and 39 on base. The pin has 9no-explicit-anywarnings, the same as its siblingInterfaceListPage.mapConfig.test.tsx.parserOptions.project/projectServiceunset), and no rule undereslint-rules/reads the filesystem, so this diff cannot move a verdict on any untouched file.check-changeset-presence✅2 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s)check:new-line-citationsVERDICT new-cross-file-line-citations: 0 new citation(s)check:control-bytes✅ OKcheck-changeset-no-major✅check-changeset-fixed✅check:pending-changeset-literals✅check:vi-mock-specifiers/-inherit/-override-shape✅ OKcheck:test-path-roots✅ OKcheck:changeset-claims: report-only; the one paragraph it names was re-read, as abovecheck-governed-queue-guard --teston the three paths:NOT GOVERNEDRound 2, on
2a26e30ec(wording only, no code change)The contract review passed the change and asked for three wording fixes:
sourceViewas the ADR-0047 (revised) fallback. The replaced text said "never restated", which was false on base too.columns,filter,sort(and its other keys)", so the list is no longer read as exhaustive. The frontmatter is byte-identical: md5 of its first three lines is4e8ce55021fe3b14329c8b4cb3f9f354before and after.origin/main(objectstack#19598).Gates on
2a26e30ec:check-changeset-presence✅2 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s)check-changeset-no-major✅check:control-bytes✅ OKcheck:new-line-citationsVERDICT new-cross-file-line-citations: 0 new citation(s)@object-ui/app-shelltype-check: exit 0, after the closure build (Tasks: 28 successful, 28 total, all cached)Merge check: fresh
origin/mained8251189has not touched the three files since base, andgit merge-treeis clean, so no merge commit was needed.Round 3, on
106a48803(one comment clause)The round-2 re-review found the header clause false on its filter leg: the page always spreads the view's
filterand appends its ownfilterBy(:437-440at this head), so the page never displaces the base filter. The clause now says so. Comment only;check:control-bytesandcheck:new-line-citationspass, the app-shell type-check exits 0, andgit merge-treeagainstorigin/mainf905090a1is clean.Not run locally; these are CI's: the full
pnpm testfarm,Lint, E2E, and the repo-widepnpm lint.Acceptance notes
filter,sort,grouping,rowColor,pagination,userFiltersand the other keys whether or not it authors its owncolumns. This PR does not change that; it scopes only the two new keys. Read from source, not measured.ObjectView) handles acolumns: []view differently. It fills in default columns, then relays that view'shiddenFields/fieldOrder, so the keys subtract from and sort the defaults there. This page applies neither key to its defaults. Carded by the seat as objectui#10694.Generated by Claude Code