Repository navigation
fix(plugin-list): Display reset compares hidden fields and density with the view's own (objectui#12949) - #12953
Conversation
…th the view's own On a console list the user's stored hidden fields and density are laid over the view's in `schema` (objectui#12474), so after a reload the Display control's "Reset to view default" compared the user's choice with itself and stayed disabled. `ListView` gains a `viewDefaults` host prop carrying the view's own values; the trigger count and the reset compare against it, and the reset writes it through the controls' doors. The console object page passes it. A host that does not pass it compares against `schema`, as before. Fixes objectui#12949 via the PR. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XVp19E1MYUTFM3dnkwz8gB
The relay census reads the `rowHeight` rung for the `normalizeListViewSchema` fold that carries the retired `densityMode`; the rung reads it inline again, and `viewRowHeight` stays the same value for `viewDefaults`. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XVp19E1MYUTFM3dnkwz8gB
✅ 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: Inputs read: card #12949 (body, the triage comment 6248174986, the claim 6248223082 as amended, the os-dev-report 6248499536), PR #12953 (body, 5-file list, net diff against ① Derived judgments
② Semver level
③ Boundary flags
Implemented-by: VERDICT: PASS Generated by Claude Code |
The Display control's count and "Reset to view default" compare hidden fields and density with `viewDefaults` when a host passes it (objectui#12949). Document it beside the other host props, per AGENTS.md commandment 2. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XVp19E1MYUTFM3dnkwz8gB
✅ 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
|
Fixes #12949
Clause-②: yes
What changed
On a console list, after a user hid a column (or changed the density) and reloaded, the Display control's "Reset to view default" was disabled and its trigger counted nothing. Since objectui#12474 the console lays the user's stored
hiddenFields/rowHeightover the view's inschema, andListViewcompared the user's list againstschema, that is, against the user's own choice.@object-ui/plugin-list(ListView): a new optional host prop,viewDefaults?, typed asPickofListViewSchemaover the two keyshiddenFieldsandrowHeight(spelled out in words because GitHub strips angle-bracket generics from a body), carries the VIEW'S OWN values.displayDeviation.hiddenFieldsanddisplayDeviation.density(grid density; the gallery card size is unchanged) compare against it, so the trigger count follows, andresetDisplayToViewDefaultwrites it through the controls' own doors (updateHiddenFieldsand soonHiddenFieldsChange;density.setModeand soschema.onDensityChange), so the user's preference follows, as Show all does. When the prop is passed its members are the whole baseline (absenthiddenFields= the view hides nothing; absentrowHeight= the default density). Without it,schemais the view's own, exactly as before.displayDeviationis rewritten: it no longer says the console persists density and hidden fields back into the view.@object-ui/app-shell(ObjectView): computesviewRowHeightandviewHiddenFields(the view's values before the overlay) and passes them asviewDefaults. On a view that declares nocolumnsthe view's authoredhiddenFieldsis never applied (objectui#10694, objectui#12505), soviewHiddenFieldsisundefinedthere: the view hides nothing, and the reset returns to every drawn column. ThehiddenFieldsrung reads the new local; therowHeightrung keeps its inlinenormalizeListViewSchemafold, because the relay census (ObjectView.relayRungCensus-7559.test.ts) reads that rung's text for the retireddensityModealias.Mechanism readings (dispatch section 2)
ListViewSchemagains nothing (it mirrors the spec). The narrowest seam is one optional member on the exportedListViewProps, beside the existing host propsdefaultRowNumbersandtoolbarLeading. No existing prop could carry it:initialFilters/initialSearchTermcarry the user's state, and the{ [key: string]: any }rest on the destructure is untyped, which AGENTS.md commandment 0.1 rules out. So Clause-②: yes (widening), and the changeset levels@object-ui/plugin-listatminor(@object-ui/app-shellpatch; its exports do not change).app-shell'sObjectViewrelays a preference:git grepforonHiddenFieldsChange/onDensityChange/listPrefsoverpackages/*/srcandapps/*/src(tests excluded) finds it alone. The otherListViewhosts (InterfaceListPage,ObjectDataPage,StudioDesignSurface,plugin-view'sObjectView,ListViewBlock, the console's SDUI workbench preview) pass noviewDefaultsand keep comparing againstschema, which is pinned as a control below.Tests (at
388e1f9059)packages/plugin-list/src/__tests__/ListView.displayResetBaseline-12949.test.tsx(7 tests): (a) a user hidden set that differs fromviewDefaults.hiddenFields: on mount the reset is ENABLED and the count reads 1; pressing it callsonHiddenFieldsChangeonce with the view's set and the count goes; an absentviewDefaults.hiddenFieldsis the empty set; (b) the same for density (rowHeight: 'compact'over the view's'tall': the reset writes'spacious'throughschema.onDensityChange); both differing count 2; (c) CONTROL: a preference equal to the view's leaves the reset disabled and nothing counted; (d) CONTROL: noviewDefaults:schemais the baseline, as before.packages/app-shell/src/views/ObjectView.userListState-12418.test.tsx, new describe (4 tests, pin 6c in its header): after a reloadschemacarries the user's choice andviewDefaultsthe view's own; writingviewDefaultsback through the two doors lands as one save of the user's row with no view write; another user is handed the same value twice; on an unprojected saved viewviewDefaults.hiddenFieldsisundefined.--maxWorkers=1): the plugin-list families namingdisplayDeviation/display-reset-button/resetDisplayToViewDefault/viewPref/hiddenFields/viewDefaults:Test Files 4 passed (4),Tests 185 passed (185); the app-shell families on the same terms:Test Files 15 passed (15),Tests 162 passed (162). The first app-shell run went red on the relay census (densityMode's fold must stay spelled out on therowHeightrung); the second commit restores the inline fold, and the rerun above is green.type-checkfor@object-ui/plugin-listand@object-ui/app-shell(afterturbo run build --filter='@object-ui/app-shell^...'): exit 0. Both packages'tsconfig.test.jsonincludesrc/**/*.test.tsx, so the new tests are type-checked.ablation-replace.mjsswappedsortedNames(viewDefaultHiddenFields)back tosortedNames(schema.hiddenFields)(anchor 1 to 0, blobf33d106eda74to41e98e996bcd); the new plugin-list file wentTests 3 failed | 4 passed (7)(the hidden-field pins went red; density and controls stayed green, as expected). Restored: blob after restore = HEAD blobf33d106eda74,git diff HEADempty.packages/plugin-list/andpackages/app-shell/directories (not run locally, per the dispatch's lock rule).Gates (at
388e1f9059)All exit 0:
check:phantom-deps,check:self-import,check:unreferenced-sources,check:doc-example-readers,check:handler-key-reads,check:side-effects-array,check:element-data-source-declaration,check:spec-symbols,check:action-forward-parity,check:designer-field-key-parity,check:icon-record-names,check:i18n-keys,check:i18n-drift,check:i18n-designer-parity,check:control-bytes,check:new-line-citations,scripts/check-hand-rolled-comment-mask.mjs,scripts/check-changeset-fixed.mjs,scripts/check-changeset-presence.mjs,scripts/check-changeset-no-major.mjs.check:spec-floorsexits 1, as onmain(recorded, not owned here).Lint, narrowed and measured: the population is each package's
eslint .under the one rooteslint.config.js(no package-level config);eslint --format jsonover the four changed files reports 4 files, 0 errors. Warnings on the three edited files equal theirorigin/maincounts (194, 183, 11); the new test file carries 1. Invariance: the config sets noparserOptions.project/projectService, so linting is not type-aware and this diff cannot move a verdict in an untouched file.Acceptance notes
Generated by Claude Code