Skip to content
This repository was archived by the owner on Oct 26, 2026. It is now read-only.
This repository was archived by the owner on Oct 26, 2026. It is now read-only.

console list Display: after a user hides a column and reloads, "Reset to view default" is disabled, because ListView compares the hidden set against the user's own preference relayed as the view's value #12949

Closed

Description

@objectstack-fleet

Filing gate ①: a user-visible defect with a named producer. reach: the console UI, measured at 1440 px on @objectstack/* 18.0.0-next.3 (console .objectui-sha 5e15928b4631) by the objectstack-ai/hotcrm#2123 dev (report comment 6247507018 on that card; PR objectstack-ai/hotcrm#2149 turns on userActions.hideFields on HotCRM's grids). Filed by the repo:hotcrm seat (os-project-manager, session_01BDgipbNowaGa139em8Fhoq). ⛔ Not a claim. Grade and lane: triage's.

Reader who acts: the objectui triage seat routes it; the lane that owns packages/plugin-list and packages/app-shell's list-preference relay dispatches the fix. No HotCRM card waits on it.

What a user sees

  1. On a grid view that declares userActions.hideFields: true, open Display and untick a column (measured: Need Type on HotCRM's All Leads). The column goes, and Display shows Hide Fields with a badge of 1.
  2. Reload. The column stays hidden, which is correct (the choice persists in the user's own sys_user_preference row, key ui.list.<object>, per objectui#12474).
  3. "Reset to view default" (data-testid="display-reset-button") is now disabled. The label says there is nothing to reset, yet the list differs from the view's own setup.

The working ways back are Show all in the Hide Fields section and the header's Reset view; both were measured.

Producer (read on 5e15928b4631 and on main fb501bc)

  • packages/plugin-list/src/ListView.tsx, displayDeviation.hiddenFields (line 5011 at 5e15928b4631): sortedNames(hiddenFields) !== sortedNames(schema.hiddenFields).
  • The app-shell ObjectView relays the user's viewPref.hiddenFields into schema.hiddenFields. After a reload, the two sides of that comparison are the same value, so the deviation is false and the reset is disabled.
  • The comment above displayDeviation (objectui#12423; line 5023 on main fb501bc) says: "A setting the host persists back into the view (density and hidden fields in the console) stops counting once the write comes back, because the view's own value has moved with it." Since objectui#12474, the console no longer writes hidden fields back into the view: it writes the user's preference. So the comment's premise no longer holds, and the reset compares the user's choice against itself.
  • Density: the same shape by source reading (viewPref.rowHeight relayed as rowHeight). Not measured.

Expected

"Reset to view default" compares against the view's authored value (the shared view, not the user's preference), and is enabled whenever the user's list differs from it.

Dedupe

MCP search_issues on objectui: "Display menu Reset to view default disabled after reload hidden fields user preference" (1 hit: #12505, closed, a different defect: session-only persistence on a view with no columns); "displayDeviation hiddenFields compares schema hiddenFields viewPref relay reset button" (1 hit: #11780, closed, unrelated). Related, open: objectstack-ai/objectstack#25945 (the Display menu's design reference).

Activity

  1. objectstack-fleet commented on Oct 18, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: p3 · domain:ui · pm:queue · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-18T09:20Z

    Triage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015). ⛔ Not a claim, ⛔ not a dispatch.

    • Fresh read on objectui origin/main 03f1d65289:
      • packages/plugin-list/src/ListView.tsx:5034 compares sortedNames(hiddenFields) !== sortedNames(schema.hiddenFields);
      • packages/app-shell/src/views/ObjectView.tsx:3283 and :3289 relay viewPref?.hiddenFields into the list schema.
        The premise holds.
    • Grade p3. It is a disabled control, and two working ways back (Show all, and the header's Reset view) are measured on the card. The maintainer's standing word for a narrow item is 「不严重,不处理」. It stays on the queue at the lowest grade, not closed, because the control states something false.
    • For the lane: density is the same shape by source reading. If the fix reads the view's authored value for one setting, it reads it for both.

    Generated by Claude Code

  2. added
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    and removed on Oct 18, 2026
  3. objectstack-fleet commented on Oct 18, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 6 (priority:p3)
    Session: session_01XVp19E1MYUTFM3dnkwz8gB
    Account: baozhoutao (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-12949-display-reset-baseline
    Worktree: objectui-issue-12949
    Domain: domain:ui
    Seat: domain:ui#2
    File surface: packages/plugin-list/src/ListView.tsx (displayDeviation and resetDisplayToViewDefault, for hidden fields and density, and the props that carry the view's authored baseline), packages/app-shell/src/views/ObjectView.tsx (the viewPref relay at about :3283–:3289 and the matching rowHeight relay, to hand the authored value alongside the user's), and tests beside both. Plus one .changeset/12949-*.md for the touched packages. ⛔ No new key on ListViewSchema in @object-ui/types (it mirrors the spec). Stop on breach; explain in the report.
    Container & model: M, mode:subagent, model: opus (default tier; dispatch-gates --tier --repo objectstack-ai/objectui reads no path-derived mandate)
    Clause-②: yes
    Clause-② note: amended in place from no on the dev's measurement (report 6248499536): the exported ListViewProps gains one optional member, viewDefaults, so @object-ui/plugin-list levels minor and one CONTRACT_REVIEW_TIER review is owed before the queue.
    Responsibility: @object-ui/plugin-list's displayDeviation compares the user's list against schema.hiddenFields, which the console now fills with the user's own preference (objectui#12474), so it compares the choice with itself | the platform already holds the view's authored value in ObjectView (viewDef.hiddenFields) before the preference is laid over it | every console user on a view with userActions.hideFields (HotCRM's grids after objectstack-ai/hotcrm#2149); two working ways back exist (Show all, the header's Reset view).
    Thread-read: 6248174986
    Serial constraints cleared: no open objectui PR touches packages/plugin-list/src/ or ObjectView.tsx; the in-flight claims (objectui#12894, objectstack-ai/objectstack#25943) are disjoint.
    Claimed at: 2026-10-18T09:25Z

  4. objectstack-fleet commented on Oct 18, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 12949,
      "status": "done",
      "branch": "claude/issue-12949-display-reset-baseline",
      "pr": "https://github.com/objectstack-ai/objectui/pull/12953",
      "session": "session_01XVp19E1MYUTFM3dnkwz8gB (subagent; the parent's id)",
      "premise_still_valid": true,
      "summary": "Premise held on origin/main 0707b4ae37: displayDeviation.hiddenFields compared against schema.hiddenFields, which ObjectView fills with the user's viewPref (objectui#12474); density the same via rowHeight. ListView gains one optional host prop, viewDefaults (Pick of ListViewSchema over hiddenFields and rowHeight): the hidden-field and grid-density deviations, the trigger count and resetDisplayToViewDefault use it, and the reset writes it through updateHiddenFields / density.setMode so the user's preference follows. Absent prop: schema is the baseline, as before. ObjectView passes the view's own values (viewHiddenFields is undefined on a view with no columns, per objectui#10694 / objectstack-ai/objectui#12505). The objectui#12423 docblock is rewritten. A1: the seam is a new member on the exported ListViewProps, so Clause-②: yes and plugin-list is minor in the changeset (app-shell patch). A2: only app-shell's ObjectView relays a preference; every other ListView host passes no viewDefaults and is unchanged.",
      "tests": "At HEAD 388e1f9059, under os-verify-lock with --maxWorkers=1: the plugin-list families (ListView.displayPopover-12423, ListView.displayResetBaseline-12949 (new, 7 tests), ListView.fieldListRead-11984, ListView.test): 'Test Files 4 passed (4) / Tests 185 passed (185)'. The app-shell families (15 files matching displayDeviation|display-reset-button|resetDisplayToViewDefault|viewPref|hiddenFields|viewDefaults, including the 4 new pins in ObjectView.userListState-12418): first run red, 1 failure in ObjectView.relayRungCensus-7559 ('densityMode's fold ... which that rung no longer calls'); fixed in 388e1f9059 by keeping the inline normalizeListViewSchema fold on the rowHeight rung; rerun 'Test Files 15 passed (15) / Tests 162 passed (162)'. type-check for plugin-list and app-shell exits 0 after turbo build --filter='@object-ui/app-shell^...' (28/28 tasks); both tsconfig.test.json files include src/**/*.test.tsx. Ablation, run once with objectstack scripts/ablation-replace.mjs: the anchor 'sortedNames(viewDefaultHiddenFields)' was swapped back to schema.hiddenFields (anchor count 1 to 0, blob f33d106eda74 to 41e98e996bcd); the new file went 'Tests 3 failed | 4 passed (7)', with the hidden-field pins (a) red. Restore: blob f33d106eda74 equals the HEAD blob and git diff HEAD is empty. The ablation imports src directly ('../ListView'), so no dist rebuild was needed. Declared to CI: the whole packages/plugin-list/ and packages/app-shell/ directories.",
      "mcp_calls": "0. No MCP GitHub calls.",
      "api_writes": "3. (1) git push of the branch (the empty-branch probe plus 2 commit pushes; not REST). (2) pr_create through fleet-write dispatch: POST /repos/objectstack-ai/objectstack/dispatches, relayed as POST /repos/objectstack-ai/objectui/pulls (draft) + POST /repos/objectstack-ai/objectui/issues/12953/assignees. Read back: 7485 bytes sent, 7485 stored, identical; assignee baozhoutao. (3) The os-dev-report comment on objectstack-ai/objectui#12949, through the same relay: POST /repos/objectstack-ai/objectui/issues/12949/comments. 0 label writes: the dispatch named no label, and in objectui no gate reads a dev-applied label.",
      "files_changed": [
        "packages/plugin-list/src/ListView.tsx",
        "packages/app-shell/src/views/ObjectView.tsx",
        "packages/plugin-list/src/__tests__/ListView.displayResetBaseline-12949.test.tsx",
        "packages/app-shell/src/views/ObjectView.userListState-12418.test.tsx",
        ".changeset/12949-display-reset-baseline.md"
      ],
      "line_budget": "5 files, +307 / -10 (git diff --stat from base 0707b4ae37 to 388e1f9059). Inside the claim's file surface.",
      "gates": "At 388e1f9059, every exit code recorded. 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 ('0 new citation(s)'), check-hand-rolled-comment-mask, check-changeset-fixed, check-changeset-presence, check-changeset-no-major, type-check (plugin-list and app-shell), closure build, the targeted vitest families (both packages), and narrowed eslint. check:spec-floors exits 1, as on main (recorded, not fixed). Narrowed lint, three pieces of evidence: (1) the population is each package's 'eslint .' under the single root eslint.config.js (no package-level config); (2) eslint --format json over the 4 changed files reports 4 files, 0 errors, 389 warnings: the 3 edited files equal their origin/main counts (194 / 183 / 11) and the new test file carries 1; (3) invariance: the config sets no parserOptions.project or projectService, so linting is not type-aware and the diff cannot move any verdict in an untouched file. My own control-byte scan of the changed files found 0 hits. The full package directories are declared to CI.",
      "deviations": [
        "The first commit (aba3f60689) has the prose line 'Fixes objectui#12949 via the PR.' in its message body. It names the intended card and is not a trailer, but it is a second declaration of the card relation, beyond the PR body. It is not rewritten, because objectui forbids force-push.",
        "The trailer is spelled 'Co-authored-by: Claude' (the dispatch's model-free pair). The harness reminder's model-named Co-Authored-By trailer was not used. The PR footer is the role file's session-URL form, not the harness's.",
        "The temporary PR body and actions JSON were written to the scratchpad under issue-12949/ with a 12949- prefix (the relay takes an actions file). They are deleted after use."
      ],
      "open_questions": [],
      "out_of_scope_findings": [
        "carrier: none. Noted, not filed: AGENTS.md commandment 2 (docs-driven) would want the new viewDefaults prop in the plugin-list README or guide. Neither is in the claim's file surface, so this PR does not touch them. The note is in the PR's Acceptance notes."
      ]
    }

    Generated by Claude Code

  5. objectstack-fleet commented on Oct 18, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 12949,
      "status": "done",
      "branch": "claude/issue-12949-display-reset-baseline",
      "pr": "https://github.com/objectstack-ai/objectui/pull/12953",
      "session": "session_01XVp19E1MYUTFM3dnkwz8gB",
      "premise_still_valid": true,
      "summary": "Patch round for contract-review record 6248559044 (item 8 and section 3). Added a `### Host prop: viewDefaults` section to packages/plugin-list/README.md right after `### Host slot: toolbarLeading`, in the same style: what it is for (a host that lays a stored user preference over hiddenFields / rowHeight in schema passes the view's own values, so the Display count and Reset to view default compare against the view and the reset writes back through onHiddenFieldsChange / schema.onDensityChange), semantics when passed (members are the whole baseline: absent hiddenFields = hides nothing, absent rowHeight = default density) and when absent (unchanged, schema is the view's own), plus one tsx example. Measurement: no content/docs page documents ListView's host props. git grep for toolbarLeading and defaultRowNumbers in content/docs answers 0 hits; the only `compact` list page, content/docs/guide/react-pages.md 'List blocks in a narrow region', describes the region-measured posture for page authors and never names the `compact` prop; content/docs/plugins/plugin-list.mdx sends readers to the package README for props. So no content/docs page was changed. One commit, new head 60cb0129770f881d920c2361116d29f5732248a5 (parent 388e1f9059, pushed as a fast-forward: no force, no rebase, no amend). PR body not touched.",
      "tests": "All runs on the worktree at 60cb012977 (README content is the same as the committed tree). pnpm check:doc-example-readers EXIT=0 ('OK 80 documented symbol(s) ... no @example hand-spells one'). pnpm check:unreferenced-sources EXIT=0 ('OK Every shipped source file in every covered package is reachable'). The first runs of both before pnpm install exited 1 with node_modules missing: that is the MODULE_NOT_FOUND class, not a measurement, and they were re-run after install. pnpm check:control-bytes EXIT=0 ('OK (scanned 9531 tracked text file(s)'). node scripts/check-changeset-fixed.mjs EXIT=0. The README tsx block is compiled by check:doc-snippets, which covers every packages/**/README.md: built its scoped closure under os-verify-lock (VERDICT command-exit 0, 35/35 tasks), then pnpm check:doc-snippets EXIT=0 ('Semantic phase: 804 of 804 block(s) judged, 0 failed'). The first draft called an undefined savePreference; it was changed to the console.log callback style the README already uses before the commit. Also: check:doc-types EXIT=0, check:doc-fences EXIT=0, check:doc-json EXIT=0 (says package READMEs are off its surface), check-doc-links EXIT=0, check-doc-expression-carriage EXIT=0 (census only, not blocking). check:new-line-citations was not run because no content/docs file was touched. No test runs: the change is prose only. NOT MEASURED: a reverse check proving check:doc-snippets judged this exact block, reason: prose patch; coverage comes from the script header's packages/**/README.md clause.",
      "mcp_calls": "0",
      "api_writes": "1 — POST /repos/objectstack-ai/objectui/issues/12949/comments (this os-dev-report, via scripts/pm/post-stamped.mjs); git push is not a REST write",
      "open_questions": [],
      "out_of_scope_findings": []
    }

    Generated by Claude Code

  6. objectstack-fleet commented on Oct 18, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT · domain:ui seat 2 · session_01XVp19E1MYUTFM3dnkwz8gB · 2026-10-18T10:23Z

    PR #12953 at head 60cb012, reviewed against the claim 6248223082 (amended to Clause-②: yes), triage 6248174986, the dev reports 6248499536 and 6248615838, and the contract review 6248559044.

    • What changed: ListView's Display control compares hidden fields and grid density against the view's own value when a host passes the new optional host prop viewDefaults (Pick<ListViewSchema, 'hiddenFields' | 'rowHeight'>), and against schema otherwise, exactly as before. The trigger count follows the same comparison, and "Reset to view default" writes the view's value back through updateHiddenFields / density.setMode, so the user's stored preference follows (one preference save, no view write). The console's ObjectView passes the view's authored values: viewDef.hiddenFields on a view that declares columns, undefined on an unprojected saved view (objectui#12505) and on a system view, and the normalizeListViewSchema-folded rowHeight. The objectui#12423 docblock now states the user-preference overlay (objectui#12474) as the reason.
    • Clause-②: yes (widening): the claim was amended in place on the dev's measurement; changeset @object-ui/plugin-list: minor, @object-ui/app-shell: patch. No key is added to ListViewSchema in @object-ui/types.
    • Contract review: PASS 6248559044 at CONTRACT_REVIEW_TIER on head 388e1f9: viewDefaults is the only public-surface change; an absent prop is behaviourally unchanged; the passed semantics match resolvedDensity's resolution; each ObjectView path hands the right authored value; minor / patch are right. Its one escalation, the README for viewDefaults (AGENTS.md commandment 2), was carried on this branch as a patch round rather than a follow-up.
    • Patch round (60cb012, prose only): packages/plugin-list/README.md gains a "Host prop: viewDefaults" section beside toolbarLeading and compact, matching the code (purpose, whole-baseline semantics, absent = unchanged, a host prop and not a schema key) with one example compiled by check:doc-snippets (804 / 804 blocks). No content/docs/** page documents ListView's host props (content/docs/plugins/plugin-list.mdx defers to the README), so none was changed. The code the review judged is unchanged since 388e1f9.
    • Tests: ListView.displayResetBaseline-12949.test.tsx (7) pins enabled-on-mount, count, the write of the view's set, empty-set semantics, density, both-differ, a same-value CONTROL and a no-prop CONTROL; ObjectView.userListState-12418 gains 4 relay pins (system view, write-back through both doors, other-user CONTROL, unprojected saved view). Ablation of the comparison turns the hidden-field pins red; restore proven by blob hash. The plugin-list families (185 tests) and app-shell families (162 tests) pass; type-check and the pre-tsc battery exit 0. The full packages/plugin-list/ and packages/app-shell/ directories are declared to CI.
    • Acceptance notes: the first commit's body carries the prose line "Fixes objectui#12949 via the PR." beside the PR body's Fixes objectstack-ai/objectui#12949; same card, not a trailer, left as is (no force-push in this repo).
    • Trailers: both commits on the code head and the README commit carry only the model-free pair.
    • CI at head: all 36 check-runs on 60cb012 are complete: 33 success, 3 skipped (dependabot and the two coverage jobs), none failed; mergeable_state: clean. Path surface (6 files, +335 / −10): packages/plugin-list/**, packages/app-shell/src/views/** and one changeset, no governed path.

    Next: pr_ready + automerge_enable.


    Generated by Claude Code

  7. objectstack-fleet commented on Oct 18, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · domain:ui seat 2 · session_01XVp19E1MYUTFM3dnkwz8gB · 2026-10-18T10:38Z

    PR #12953 merged through the merge queue as b5153f44eaea93c4f7e29117d3022297f31bab91, which is on main; Fixes objectstack-ai/objectui#12949 closes this card. Verified by content: all 6 of the PR's files on main are blob-identical to the accepted head 60cb012. The merge commit's message names no model.

    What landed:

    • On a console list, "Reset to view default" and the Display trigger's count compare hidden fields and density against the view's own value, so after a user hides a column (or changes density) and reloads, the reset is enabled and hands the view's value back, with the user's stored preference following.
    • @object-ui/plugin-list: minor: ListViewProps gains the optional host prop viewDefaults (documented in the package README); a host that does not pass it is unchanged. @object-ui/app-shell: patch. Contract review PASS 6248559044.

    For hotcrm: objectstack-ai/hotcrm#2123's grids (with userActions.hideFields from objectstack-ai/hotcrm#2149) get a working reset once the console build HotCRM runs carries the merge commit above. This seat now removes pm:dispatched.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions