Skip to content

Leads, Accounts and Opportunities grid views: no column chooser in Display because userActions.hideFields is unset — declare it once the objectui Hide Fields persistence fixes (objectui#12474, objectui#12505) are released #2123

Closed

Description

@objectstack-fleet

Filing gate ③, on the maintainer's word (chat, 2026-10-15, session session_019YFzJp4o8Ck4NsT1toC4UP, seat account os-bill): the seat ran a functional audit of the HotCRM console on objectui main 720f6d4 and hotcrm main 63db83e (report, private to the maintainer: https://claude.ai/artifact/XPrn5eZMsQaKUgasMJEMmR, finding F12, figure 20), listed this as a card to file at whichever side owns the default, and the maintainer answered 「同意开卡,使用 pm-dispatch 创建卡片」. The reading below settles the side: the console's default is deliberate, so the fix is HotCRM view metadata. Quota note: the audit's cards exceed the filing gate's three-per-fire quota on that word, which approved the report's card list as a set.

Blocked-by: objectstack-ai/objectui#12474
Blocked-by: objectstack-ai/objectui#12505

Tracked with objectstack-ai/objectstack#25945 (the console layout parent) as a HotCRM-side item of the audit. Unlock criterion (the hotcrm lane's rule: an upstream fix counts when it is published, not merged): the @object-ui/* release that carries the fixes of the two cards above is the one this repo depends on, so that a user's Hide Fields click no longer rewrites the shared view and persists for that user.

Reader who acts: the repo:hotcrm seat, once the Blocked-by: lines clear: one dev round in src/sales/views/*.view.ts, size S.

Dedupe (MCP search_issues, scope objectstack-ai/hotcrm, all states, read 2026-10-15T14:14Z): "lead kanban card title first name only gallery cards first_name last_name full_name view columns hide fields userActions" → 0. objectui side, same read: "view description … tooltip" → objectstack-ai/objectui#12474 (open: Hide Fields and density still write the shared view), objectstack-ai/objectui#12505 (open: Hide Fields session-only on a view with no columns), objectstack-ai/objectui#12504 (open). None is this card; the two open ones are what it waits on.

What happens (console on objectui 720f6d4, HotCRM 63db83e, 1440)

On the Leads, Accounts and Opportunities grids the Display popover offers Group, Density, Row numbers, Edit inline and Reset, and no column chooser: a user who wants to hide the empty "Need Type" column, or show a column the view does not list, has no control for it. The design reference on objectstack-ai/objectstack#25945 puts the column chooser as Display's first group.

Readings (read 2026-10-15T14:15Z)

  1. objectui packages/plugin-list/src/ListView.tsx lines 1480–1510: the toolbar flags are per-toggle; showHideFields: ua?.hideFields === true and showColor: ua?.rowColor === true are off unless the view turns them on, kept so deliberately ("flipping it would grow two buttons on every existing view"); the other affordances are on unless turned off. userActions on a view is the toolbar policy (UserActionsConfigSchema).
  2. hotcrm src/sales/views/lead.view.ts lines 125–128 (all_leads), 404–406, 454–456, 474–476, 499–501: every grid view declares userActions: { editInline: true } and nothing else; the account and opportunity view files declare the same shape.
  3. objectui console list toolbar: the density toggle and Hide Fields still write the shared view, so one user's click changes the list for everyone and a walled tenant is refused (the rest of objectui#12418's family) objectui#12474 and console list toolbar: Hide Fields on a user's saved view that declares no columns is session-only after objectui#12474 (it used to persist by writing the shared view) objectui#12505 (open): Hide Fields today writes the shared view (one user's click changes everyone's list, a walled tenant is refused) or stays session-only; turning the control on in an exhibit app before that lands would demonstrate the wrong behaviour.

What to build

  1. Every grid view of Leads, Accounts and Opportunities declares userActions: { editInline: true, hideFields: true } (and rowColor only where the view has a colour field worth it).
  2. pnpm objectstack validate (or the repo's validate script) green; the console's Display popover shows the column chooser as its first group on those views.

Acceptance

  • Browser reading at 1440 on the console with the released @object-ui/* that carries the fixes above: Display on the Leads grid lists Hide fields first; hiding "Need Type" persists for the user across a reload and does not change another user's list.
  • The changeset the repo's changeset-check.yml requires (or the skip-changeset label if the maintainer treats view metadata as unreleased).

Out of scope

Attribution: written by the domain:ui seat in session session_019YFzJp4o8Ck4NsT1toC4UP (account os-bill) on the maintainer's words quoted above.

Screenshots (added 2026-10-15T14:44Z, on the maintainer's word 「专用分支存图,卡里嵌 raw 链接」)

The images live on the attachment branch claude/ui-audit-2026-10-15-shots of objectstack-ai/objectui (commit 918a251, never merged; index at https://github.com/objectstack-ai/objectui/blob/918a2510a54bd6875b90eb6996d098c3ec0451dd/docs/design/console-audit-2026-10-15/README.md). Full set and figure numbers: the audit report linked above.

The Display popover on the Leads grid: Group, Density, Row numbers, Edit inline, Reset; no column chooser

display-popover.png

Activity

  1. objectstack-fleet commented on Oct 18, 2026

    @objectstack-fleet
    ContributorAuthor

    Unlock scan · repo:hotcrm seat · os-project-manager · session session_01BDgipbNowaGa139em8Fhoq · 2026-10-18T04:32Z

    pm:blocked → pm:queue (p2). Both named fixes are in the console that HotCRM's pin installs.


    Generated by Claude Code

  2. added
    pm:queueReady for the PM dispatch loop
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Oct 18, 2026
  3. objectstack-fleet commented on Oct 18, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 88
    Session: session_01BDgipbNowaGa139em8Fhoq
    Account: os-project-manager (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-2123-grid-hide-fields
    Worktree: hotcrm-issue-2123
    Domain: repo:hotcrm (single-lane repo, no domain:* taxonomy)
    Seat: repo:hotcrm#1 (seat post objectstack-ai/objectui#1353)
    File surface: src/sales/views/lead.view.ts, src/sales/views/account.view.ts, src/sales/views/opportunity.view.ts (each grid view's userActions only); the content/docs/** pages that describe a grid's Display menu, if any; tests under test/; one new .changeset/2123-*.md (stop on breach; explain in the report)
    Container & model: S, mode:subagent, model: default (dispatch-gates --tier --repo objectstack-ai/hotcrm: no path-derived mandate; default rather than floor because the persistence reading in the browser is a judgment, not a gate)
    Clause-②: no
    Responsibility: n/a — not a defect card
    Thread-read: 6245680334
    Serial constraints cleared: src/sales/views/lead.view.ts: free since PR objectstack-ai/objectui#2145 landed (3fd939d). The account and opportunity view files: no other claim or open PR. In-flight hotcrm#2146 is read-only; PRs objectstack-ai/objectui#2147 and objectstack-ai/objectui#2148 touch none of these files.


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 18, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 2123,
      "status": "done",
      "branch": "claude/issue-2123-grid-hide-fields",
      "pr": "https://github.com/objectstack-ai/hotcrm/pull/2149",
      "session": "session_01BDgipbNowaGa139em8Fhoq (subagent: the parent's id, as the relay envelope resolved it)",
      "premise_still_valid": true,
      "summary": "All 15 type:'grid' views of crm_lead (5), crm_account (4) and crm_opportunity (6) now declare userActions: { editInline: true, hideFields: true }. rowColor is untouched under the objectstack-ai/objectui#2107 ruling. Kanban, calendar, gallery, map and timeline views are untouched. Assumption 1 holds: the pin is 18.0.0-next.3, console .objectui-sha 5e15928b4631, where the ListView flag is ua?.hideFields === true and ObjectView persistHiddenFields writes listPrefs.patchView, i.e. the user's own sys_user_preference row ui.list.OBJECT. Assumption 2 holds in the browser at 1440. User A (admin) hid Need Type on All Leads with one POST /api/v1/data/sys_user_preference ({key: ui.list.crm_lead, perView: {crm_lead.all_leads: {hiddenFields: [need_type]}}}). The column stayed hidden after a reload and in a second fresh browser context. User B (sales.manager, own session) still saw Need Type. There were 0 writes to /api/v1/meta/* in the whole run. Show all and the header's Reset view both bring the column back, and each persists. Assumption 3: 15 grid views. Each shows Hide Fields in Display, with no Row Color section. The controls (Contacts grid, both kanbans, account_gallery) show no Hide Fields. One card acceptance clause measures false: 'Display lists Hide fields first'. Hide Fields is the second section, under Group, because the console's ViewSettingsPopover declares that order (objectui#12423). No view key can move it; see open_questions. No content/docs page describes the Display menu, so no doc changed.",
      "tests": "New test/view-hide-fields.test.ts, 4 pins: the walk reaches each object; every grid view declares hideFields: true; every grid view declares columns (the per-user path needs them); no grid view sets userActions.rowColor. Targeted run: 'pnpm exec vitest run --maxWorkers=2 test/view-hide-fields.test.ts test/view-inline-edit.test.ts' gave 'Test Files 2 passed (2) / Tests 7 passed (7)', VERDICT command-exit 0. Ablation, one leg (the hideFields behaviour): scripts/ablation-replace.mjs in WRAP mode on lead.view.ts all_leads, anchor count 1 to 0, blob 662052f0b07d to 5279e7b9f347. Result: 'AssertionError: ... expected [ crm_lead.all_leads ] to deeply equal []', 1 failed | 3 passed, red as expected. Restore was proven: 'blob == HEAD (662052f0b07d) and git diff HEAD is empty'. No dist/ is in the path, because the suite reads src via objectstack.composition. Full suite on head 88754d0 (the merge of origin/main 5224ed7): 'pnpm test' gave 'Test Files 188 passed (188) / Tests 3734 passed | 1 skipped (3735)', VERDICT command-exit 0, lock held 587s.",
      "gates": "Local, through os-verify-lock, slot hotcrm-2123-verify, on head 88754d0. (1) 'pnpm validate && pnpm typecheck && pnpm lint && pnpm lint:i18n-gate && pnpm hygiene && pnpm hygiene:tokens && pnpm build' gave VERDICT command-exit 0 ('Validation passed'; lint 18 suggestions, none on a view; 'i18n lint gate: 0 i18n/missing-* issues'; 'source hygiene clean'; 'source token ratchet clean'; 'Build complete'). (2) 'pnpm test' gave VERDICT command-exit 0. Together these are the whole pnpm verify chain, split in two to stay under the foreground cap. hotcrm has no dispatch-gates families, so there is no --ran reconciliation. PR check-runs at report time on 88754d0: Check Changeset success; Label Pull Request success; Vercel Preview Comments success; Build and Test (22.x) in_progress; Analyze Code (javascript) in_progress; Playwright in_progress; Quality Checks in_progress; link-check in_progress.",
      "mcp_calls": "0",
      "api_writes": "2 relay strokes. Each is one POST /repos/objectstack-ai/objectstack/dispatches, executed as objectstack-fleet[bot]. (1) pr_create became POST /repos/objectstack-ai/hotcrm/pulls (draft) + POST /repos/objectstack-ai/hotcrm/issues/2149/assignees [os-project-manager]; the read-back shows 7374 bytes sent and identical, assignee listed. (2) comment became POST /repos/objectstack-ai/hotcrm/issues/2123/comments (this report). Also one git push (not REST).",
      "files_changed": [
        "src/sales/views/lead.view.ts",
        "src/sales/views/account.view.ts",
        "src/sales/views/opportunity.view.ts",
        "test/view-hide-fields.test.ts",
        ".changeset/2123-grid-hide-fields.md"
      ],
      "line_budget": "n/a. No skills/** file and no ratcheted ledger was touched. hygiene:tokens on the final head: src/sales authored total ~103,476 tokens (ceiling ~160,500), clean.",
      "deviations": [
        "The card acceptance clause 'Display on the Leads grid lists Hide fields first' measured false: Hide Fields is second, under Group, in the console's declared order. PR objectstack-ai/objectui#2149 keeps 'Fixes objectstack-ai/objectui#2123'; see open_questions.",
        "origin/main moved to 5224ed7 (#2147, objectstack-ai/objectui#2148) after the branch point, so it was merged in with a merge commit (88754d0) and verify ran on the merged head. No file overlaps the branch.",
        "For the source reading, the console commit 5e15928b4631 was fetched (depth 1) into the shared /home/user/objectui object store. Its working tree was not touched.",
        "The first dev-server boot was refused on a nonexistent --home flag, so nothing started. The second boot used OS_HOME in the scratchpad, on port 4123 with a scratch database. The first kill hit the setsid wrapper pid. The server's own process group 25265 was then stopped and port 4123 confirmed closed.",
        "Commit trailers are model-free per the dispatch. The PR footer uses the agent-definition session-URL form, not the harness reminder's form."
      ],
      "open_questions": [
        {
          "question": "The card's acceptance says Display 'lists Hide fields first'. On next.3 it is the second section, under Group, by the console's own declared order (ViewSettingsPopover header, objectui#12423), and no view key reorders it. Should PR objectstack-ai/objectui#2149 close the card with that clause unmet?",
          "options": [
            "A: keep 'Fixes objectstack-ai/objectui#2123'. The deliverable (column chooser on every grid view, per-user persistence, isolation) is measured. The order is the console's, and its design reference is carried by the open objectui#12444.",
            "B: change the body to 'Part of objectstack-ai/objectui#2123' and leave the card open for the order. It would wait on an objectui decision that no hotcrm change can make."
          ],
          "recommendation": "A. The card's own Out of scope gives the console's Hide Fields behaviour to objectui, and the order is the same kind of console-side choice. Keeping a hotcrm card open for it would block nothing but this card."
        }
      ],
      "out_of_scope_findings": [
        "class: a · reach: public door, the console UI, measured at 1440 on 18.0.0-next.3. Hide Need Type on All Leads, then reload: Display shows Hide Fields with badge 1, but 'Reset to view default' (data-testid display-reset-button) reads disabled=true, so the label tells the user there is nothing to reset. The working ways back are Show all and the header's Reset view, both measured. Seam: renderer: objectui plugin-list ListView displayDeviation.hiddenFields compares against schema.hiddenFields, which app-shell ObjectView relays from viewPref.hiddenFields. ObjectView documents the same split for sort. Density (viewPref.rowHeight relayed as rowHeight) has the same shape by source reading; that was not measured. Dedupe words: 'Reset to view default disabled', 'displayDeviation hiddenFields', 'Display reset after reload', 'viewPref relay reset'.",
        "carrier: objectui#12444 · The Display order puts Hide Fields after Group. The 2026-10-15 design reference on that parent puts the column chooser first. Noted, not filed.",
        "carrier: none · The header of test/view-inline-edit.test.ts says the spec declares editInline .default(false). The 18.0.0-next.3 spec reads .default(true) ('On by default'). This is a stale comment, recorded in the PR's Acceptance notes only."
      ]
    }

    Generated by Claude Code

  5. objectstack-fleet commented on Oct 18, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT → PR objectstack-ai/objectui#2149 comment 6247545434 · repo:hotcrm seat · session session_01BDgipbNowaGa139em8Fhoq · 2026-10-18T08:17Z

    Thread-read: 6247507018

    All 15 grid views of Leads, Accounts and Opportunities turn on Hide Fields, and rowColor stays off (ruling on objectstack-ai/objectui#2107). The choice is kept per user and touches no one else's list, measured with two users. The order clause ("Hide fields first") is the console's, so it is carried by objectstack-ai/objectstack#25945, and Fixes objectstack-ai/objectui#2123 stays. "Reset to view default" being disabled after a reload is filed as objectstack-ai/objectui#12949. Landing waits on CI.

  6. objectstack-fleet commented on Oct 18, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · repo:hotcrm seat · session session_01BDgipbNowaGa139em8Fhoq · 2026-10-18T08:25Z

    Reading Probe Result
    PR objectstack-ai/objectui#2149 GET /pulls/2149 merged 2026-10-18T08:24:58Z through the merge queue (added_to_merge_queue → merged in the timeline), on its reviewed head 88754d0 with all 9 checks success and its base equal to main's tip 5224ed7
    Queue branch git ls-remote origin 'refs/heads/gh-readonly-queue/*' empty
    origin/main GET /commits/main 149f201 feat(views): Hide fields on the Leads, Accounts and Opportunities grids (#2149). The merge message carries 0 model-identifier lines

    State: Fixes objectstack-ai/objectui#2123 closed this card (completed). pm:dispatched is removed and os-project-manager is unassigned with this note. "Reset to view default" being disabled after a reload continues on objectstack-ai/objectui#12949; the Display order on objectstack-ai/objectstack#25945.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions