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

console list and dashboard chrome (family card): the view description's own row, the sort popover's standing lookup note, the metric card's four-line stack and the two-row list footer — four nails, one card #12528

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 (report, private to the maintainer: https://claude.ai/artifact/XPrn5eZMsQaKUgasMJEMmR, findings F7, F13, F14 and F16; figures 9, 17 and 21), listed them as one card, and the maintainer answered 「同意开卡,使用 pm-dispatch 创建卡片」. A family card: four fixed places where chrome costs height or attention, each with its nail below; a single-point card for any one of them is not opened. 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.

Parent: objectstack-ai/objectstack#25945. The sibling of #11694 (closed: the dashboard's Refresh All row and the report card's fixed height), which is the precedent for density items. Blocks nothing; nothing blocks it.

Reader who acts: the domain:ui lane's next dispatch (seat post #9800), one dev round across @object-ui/plugin-list (nails 1, 2, 4), @object-ui/plugin-grid (nail 4) and @object-ui/plugin-dashboard (nail 3), size M; the dev may split the dashboard nail into a second PR on the same card.

Dedupe (MCP search_issues, scope objectstack-ai/objectui, all states, read 2026-10-15T14:14Z): "sort popover lookup columns explanation text always shown dashboard metric card too tall connection status badge app bar list footer aggregates two rows" → 8: #12463, #12423, #12461 (this parent's merged children), #12188, #11694 (the density precedent, closed), #8882, #5827, #665 (closed). "view description rendered as its own line above the list toolbar pushes toolbar row down move into view tab tooltip" → 10: #12474, #12504, #12505 (open, the Hide Fields write family), #12440, #12423, #12462, #12418, #11642 (closed). None is this card.

The four nails (objectui origin/main 720f6d4, read 2026-10-15T14:15Z)

  1. The view description takes a row of its own above the toolbar. packages/plugin-list/src/ListView.tsx lines 4969–4972 render viewDescription as a px-4 pt-1.5 text-xs line before the toolbar row. Reading: HotCRM Accounts ("Primary account list with revenue & industry summaries") puts the toolbar at y = 155; Leads, whose default view has no description, at y = 133. The chrome's height changes with the view. Build: the description moves into the active tab's tooltip (and the tab's ▾ menu header), the toolbar row stays at one height; appearance.showDescription keeps its meaning for the tooltip.
  2. The sort popover's standing note. ListView.tsx line 993 (list.sortRelationalHint) and line 5279: a four-line paragraph about lookup columns and denormalization is drawn on every open, taking about half of the popover. Build: the paragraph becomes an info icon with that text as its tooltip, next to the "Sort by" field list, and a one-line hint only when the picked field is a lookup.
  3. The metric card's four-line stack. packages/plugin-dashboard/src/MetricCard.tsx lines 98–122: CardHeader (title + icon), then the description, then text-2xl value, then a unit line. Reading: HotCRM Sales Performance's four KPI cards are about 215 px tall for one number each; two rows of cards fill the first screen. Build: title and unit on one line above a text-2xl value, the description in the card's tooltip (title) unless the widget declares showDescription; target about 120 px at the default density.
  4. Two footer rows on an aggregated list. The grid's column-summary footer (packages/plugin-grid/src/ObjectGrid.tsx lines 3337–3394, useScopedColumnSummary) draws "Annual Revenue: Sum: 109,800,000.00 · Number of Employees: Avg: 760" as a row above the list's record-count footer ("9 records", list.recordCount). Build: one footer row: the count at the left, the aggregates at the right of the same row, truncating with a tooltip when they do not fit.

Acceptance

  • One test per nail: ListView renders no view-description element and the active tab's trigger carries the description as its tooltip; the sort popover has no sortRelationalHint paragraph and an info control with that text; MetricCard renders title, value and unit in two lines and no description paragraph by default; a grid with column summaries renders one footer row containing both the count and the summaries.
  • Browser reading by the landing seat at 1440 on HotCRM: the Accounts and Leads toolbars sit at the same y; the sort popover is under half its former height; Sales Performance's first screen shows the four KPI cards and both charts' titles; the Accounts footer is one row.
  • pnpm test from the repo root green on the affected files; a changeset (patch) per published package touched.

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:43Z, 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.

Nail 1 and nail 4: the view description's own row above the toolbar; the aggregate row above the record count

accounts-1440.png

Nail 2: the standing lookup note in the sort popover

sort-popover.png

Nail 3: four KPI cards of about 215 px each

dashboard.png

Activity

  1. added
    enhancementNew feature or request
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    area:recordsBusiness objects, records, the views that show data, usable forms, search
    and removed on Oct 15, 2026
  2. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1
    Session: session_01XVp19E1MYUTFM3dnkwz8gB
    Account: baozhoutao (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-12528-list-dashboard-chrome
    Worktree: objectui-issue-12528
    Domain: domain:ui
    Seat: domain:ui#2 (the card names the lane's next dispatch under seat 3's post #9800, which is vacant)
    File surface: packages/plugin-list/src/ListView.tsx (nail 1: the viewDescription row; nail 2: the sort popover's sortRelationalHint; nail 4: the record-count footer), packages/plugin-view/src/ViewTabBar.tsx (nail 1: the active tab's tooltip and ▾ menu header) and the console's ViewTabItem build in packages/app-shell/src/views/ObjectView.tsx only to carry the description, packages/plugin-grid/src/ObjectGrid.tsx (nail 4: the column-summary footer), packages/plugin-dashboard/src/MetricCard.tsx (nail 3; revised 2026-10-15T18:44Z: nail 3 is re-scoped onto the path that draws the HotCRM KPI tiles, in a second PR on this card: packages/plugin-dashboard/src/DashboardRenderer.tsx (the shared widget Card for a dataset-bound metric), DatasetWidget.tsx, MetricWidget.tsx, and DashboardGridLayout.tsx only if it draws the same frame), packages/i18n/src/locales/*.ts only if a label is added, the tests beside each, and one .changeset/12528-*.md (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 (widening; measured by the dev on PR #12561: ViewTabItem.description in plugin-view and ObjectGridComponentProps.onColumnSummaryChange in plugin-grid, both minor). Contract review at CONTRACT_REVIEW_TIER is owed on PR #12561
    Responsibility: n/a — not a defect card
    Thread-read: none
    Serial constraints cleared: at main 1f23d5b07, no open PR touches ListView.tsx, ObjectGrid.tsx, MetricCard.tsx or ObjectView.tsx. Revised 2026-10-15T16:49Z: open PR #12537 (objectui#12518, the strip's host width) edits ViewTabBar.tsx. This card's nail 1 touches that file only for the active tab's tooltip and ▾ menu header, a different region; whichever lands second merges main again (a merge, never a rebase). Seat 1's objectui#12526 (PageHeader.tsx, DashboardView.tsx, AppHeader.tsx) is disjoint.

  3. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 12528,
    "status": "needs_decision",
    "branch": "claude/issue-12528-list-dashboard-chrome",
    "pr": "#12561",
    "session": "session_01XVp19E1MYUTFM3dnkwz8gB (subagent: the parent's id)",
    "premise_still_valid": false,
    "summary": "Draft PR #12561 (Part of #12528) lands nails 1, 2 and 4. Nail 1: ListView draws no view-description row. ViewTabItem gains an optional description that ViewTabBar draws on the active tab only, as the view button's title and as a DropdownMenuLabel heading its ▾ menu. ObjectView fills it with pickLocalized on the display locale, gated like the relay (false shows it nowhere). Where no strip is drawn (the console below sm, any host without toolbarLeading), ListView draws an Info control inside its toolbar row whose title and aria-label are the description. A refused view replaces ListView with the refusal face, unchanged. Nail 2: the standing paragraph is now an info control (sort-relational-info) beside the popover title, plus a one-line hint (new key list.sortRelationalPicked, ten packs) only while the current sort names a linked column. Nail 4: ObjectGrid gains an onColumnSummaryChange host prop. The grid then draws no summary row and reports its summaries, keyed by content, null on unmount. ListView draws them at the right of its record-count row, truncated, with a title tooltip. Nail 3 is NOT built. Its premise is false for the named site: MetricCard has no unit line and no description above the value, and the HotCRM Sales Performance KPI tiles are dataset-bound metric widgets. Those render through DashboardRenderer's shared widget Card (title plus line-clamp-2 description in CardHeader) and DatasetWidget, which draws MetricWidget's bare layout (value, then the measure label). Those files are outside the order's file surface, so the re-scope is open_questions[0]. The spec's dashboard widget declares no showDescription key. Clause-② was measured and corrected to yes (widening): ViewTabItem.description and ObjectGridComponentProps.onColumnSummaryChange; the changeset puts minor on plugin-view and plugin-grid.",
    "tests": "Pins, each with a control: plugin-view ViewTabBar.description-12528 (4 tests); app-shell ObjectView.refreshInPlace-10035, new describe (page-level: no view-description or view-description-info, active tab title 'Every task'; showDescription false gives no title); plugin-list ListView.test + descriptionInlineLocale-7199 (info control, host-strip case); plugin-list ListView.relationalSort, new describe (no paragraph, info control, one-line hint; CONTROL: a plain sort shows no line); plugin-grid footerSummaryHost-12528 (report, no own row, null on unmount; CONTROL: no prop keeps the row); plugin-list ListView.footerOneRow-12528 (one record-count-bar with '9 records' and the summaries, truncate, title; CONTROL). Affected and new files under the lock at 9f355da: 14 files, 290 passed, exit 0. Ablations via the objectstack checkout's scripts/ablation-replace.mjs (anchor 1 to 0, blob changed, restore blob == HEAD, git diff HEAD empty; tests import src directly, so no dist): nail 1 tab title removed, 1 failed / 3 passed; nail 2 picked flag deleted, 1 failed / 8 passed; nail 4 grid host branch disabled, 2 failed / 1 passed; nail 4 list not handing the callback, 1 failed / 1 passed. Package dirs under the lock at 840554d: plugin-view 77 files / 716 passed; plugin-grid 217 / 2018 passed; plugin-list 136 / 1444 passed; i18n 83 files, 1321 passed and 13 skipped; all exit 0. NOT MEASURED: packages/app-shell/ dir. Reason: lock queue-timeout (exit 99), four times, behind holder pid 2416 (cwd objectui-issue-12505, a full packages/app-shell/ vitest run, alive at about 200% CPU, holding more than 38 minutes). NOT MEASURED: a re-run of the pins at final head ba5c03f, after the second merge of origin/main, which brought #12537's ViewTabBar host-width change. Same queue-timeout, same holder. That merge was textually clean, and grep confirms this branch's three view.description sites in ViewTabBar.tsx. type-check after a closure build of app-shell^... and app-shell (exit 0): plugin-view, plugin-list, plugin-grid, i18n, app-shell all exit 0 at a1c242a; plugin-grid again at 840554d, exit 0.",
    "gates": {
    "build app-shell^... + app-shell": "exit 0 (a1c242a)",
    "type-check plugin-view/plugin-list/plugin-grid/i18n/app-shell": "exit 0 (a1c242a); plugin-grid exit 0 (840554d)",
    "vitest touched+new (14 files)": "exit 0, 290 passed (9f355da)",
    "vitest packages/plugin-view": "exit 0, 716 passed (840554d)",
    "vitest packages/plugin-grid": "exit 0, 2018 passed (840554d)",
    "vitest packages/plugin-list": "exit 0, 1444 passed (840554d)",
    "vitest packages/i18n": "exit 0, 1321 passed 13 skipped (840554d)",
    "vitest packages/app-shell": "NOT MEASURED: lock queue-timeout exit 99 behind pid 2416 (objectui-issue-12505 full app-shell run)",
    "vitest pins at ba5c03f (post second merge)": "NOT MEASURED: same queue-timeout",
    "eslint narrowed (25 changed ts/tsx, --format json)": "0 errors; per-file warnings vs origin/main: ObjectGrid 217 to 215, ListView 185 to 185, ViewTabBar 3 to 3, ObjectView 198 to 198; type-aware lint off (no parserOptions.project/projectService) so untouched files cannot move",
    "check:phantom-deps": 0,
    "check:self-import": 0,
    "check:unreferenced-sources": 0,
    "check:doc-example-readers": 0,
    "check:handler-key-reads": 0,
    "check:side-effects-array": 0,
    "check:element-data-source-declaration": 0,
    "check:spec-symbols": 0,
    "check:action-forward-parity": 0,
    "check:designer-field-key-parity": 0,
    "check:icon-record-names": 0,
    "check:i18n-keys": 0,
    "check:i18n-drift": 0,
    "check:i18n-designer-parity": 0,
    "check:control-bytes": 0,
    "check-changeset-fixed.mjs": 0,
    "check-changeset-presence.mjs": 0,
    "check-changeset-no-major.mjs": 0,
    "check:new-line-citations": 0,
    "hand-rolled-comment-mask test": "not owed (no test reads source)",
    "doc-snippet-types": "not owed (no docs changed)"
    },
    "line_budget": "26 files vs origin/main after merge (the tracked .ts/.tsx/.md set of this branch); about 680 insertions and 67 deletions; one PR, nail 3 not built",
    "files_changed": [
    "packages/plugin-list/src/ListView.tsx",
    "packages/plugin-view/src/ViewTabBar.tsx",
    "packages/app-shell/src/views/ObjectView.tsx",
    "packages/plugin-grid/src/ObjectGrid.tsx",
    "packages/i18n/src/locales/{ar,de,en,es,fr,ja,ko,pt,ru,zh}.ts",
    "packages/plugin-list/src/tests/ListView.test.tsx",
    "packages/plugin-list/src/tests/ListView.descriptionInlineLocale-7199.test.tsx",
    "packages/plugin-list/src/tests/ListView.relationalSort.test.tsx",
    "packages/plugin-list/src/tests/ListView.sortFieldFallback.test.tsx",
    "packages/plugin-list/src/tests/ListView.sortFieldRead-11943.test.tsx",
    "packages/plugin-list/src/tests/ListView.sortabilitySignal.test.tsx",
    "packages/plugin-list/src/tests/ListView.footerOneRow-12528.test.tsx",
    "packages/plugin-view/src/tests/ViewTabBar.description-12528.test.tsx",
    "packages/plugin-grid/src/tests/footerSummaryHost-12528.test.tsx",
    "packages/app-shell/src/views/ObjectView.refreshInPlace-10035.test.tsx",
    "packages/app-shell/src/views/ObjectView.externalRefreshSum-10572.test.tsx",
    ".changeset/12528-list-dashboard-chrome.md"
    ],
    "deviations": [
    "Nail 3 not built: its site is outside the file surface (see open_questions[0]); the PR says Part of #12528 instead of Fixes.",
    "Clause-② corrected from the claim's no to yes (widening): ViewTabItem.description (plugin-view) and ObjectGridComponentProps.onColumnSummaryChange (plugin-grid); both minor in the changeset. This is the line the order anticipated.",
    "Declared narrowing: the packages/app-shell/ dir run and the final-head re-run are NOT MEASURED (lock queue-timeout behind pid 2416); CI runs them.",
    "Commits carry the model-free trailer pair per AGENTS.md; the harness reminder's model-named Co-Authored-By line was not copied.",
    "The 10035 test's remount probe moved from the retired view-description node to list-toolbar-leading (also ListView-owned)."
    ],
    "mcp_calls": "0",
    "api_writes": "2 relay dispatches (POST /repos/objectstack-ai/objectstack/dispatches): (1) pr_create, executed as POST /repos/objectstack-ai/objectui/pulls (draft) + POST /repos//issues/12561/assignees; (2) comment, executed as POST /repos//issues/12528/comments (this report). Zero label writes (objectui: the order named no label). git pushes are not counted here.",
    "open_questions": [
    {
    "question": "Nail 3: the card's site (MetricCard.tsx) does not draw the HotCRM KPI tiles. Re-scope the nail onto the real path, build it literally on MetricCard, or drop it from this card?",
    "options": [
    "A. Re-scope onto the drawn path in a second PR on this card: DashboardRenderer.tsx's shared widget Card for a dataset-bound metric (the description leaves the CardHeader and becomes the title's tooltip; the measure label joins the title line), plus DatasetWidget.tsx and MetricWidget.tsx's bare layout (no label line under the value), and DashboardGridLayout if it draws the same frame. No schema key, so the description goes to the tooltip only. Cost: about 150 to 250 lines plus pins across three or four plugin-dashboard files. The surface widens, and the second PR carries Fixes #12528.",
    "B. Build nail 3 literally on MetricCard.tsx (title and trend/unit on one line, description into title). Cost: about 60 lines. It changes no screen the card measured, because no HotCRM dashboard draws a metric-card node.",
    "C. Drop nail 3 from this card and close the card when #12561 merges (body edited to Fixes by the seat). Cost: none now. The 215 px KPI tile stays until a new card is filed."
    ],
    "recommendation": "A. Business need: the measured pain (four KPI tiles of about 215 px, two rows filling the first screen) is on the dataset-bound path, and only A changes it; B serves no measured screen. Long-term soundness: A fixes the frame that every dataset metric shares, and B adds polish to a component off the console's path. AI-error resistance: neutral. A adds no schema key; the description stays where the spec puts it, and the tooltip-only outcome follows the absence of a widget showDescription. Startup scope: A builds no new capability, just density on an existing surface, and B is speculative. The cost is a file-surface widening that the seat must approve."
    }
    ],
    "out_of_scope_findings": [
    "carrier: none — noted, not filed. content/docs/plugins/plugin-grid.mdx (Column Summaries) and packages/plugin-view/README.md do not document the two new host props (onColumnSummaryChange, ViewTabItem.description). Outside this order's file surface; AGENTS.md #2 docs debt of this PR. Dedupe words: onColumnSummaryChange docs, ViewTabItem description README, column summary host footer",
    "carrier: none — noted, not filed. The lock holder pid 2416 (objectui-issue-12505) ran a full packages/app-shell/ vitest run for more than 38 minutes at --maxWorkers=2. It was alive and progressing (about 200% CPU), but it starved every queued run; this is a reading for the seat, not a defect."
    ]
    }


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Seat answer to the dev's open_questions[0] (nail 3) · domain:ui seat 2 · session_01XVp19E1MYUTFM3dnkwz8gB · 2026-10-15T18:45Z

    Answering the dev report 6199637771. This is a technical re-scope inside the card's own intent, not a product question, so the seat answers it.


    Generated by Claude Code

  5. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {"issue":12528,"pr":"https://github.com/objectstack-ai/objectui/pull/12561","round":"patch after contract review 6199817751","new_head":"fb6010f28","status":"done","fixed":["ListView.footerOneRow-12528.test.tsx awaits the summaries span (findByTestId); its CONTROL asserts only after the probe has reported (spy awaited, then a flushed act)","ObjectGridFooterSummary exported from packages/plugin-grid/src/index.tsx","docs: content/docs/plugins/plugin-grid.mdx (Column Summaries) documents onColumnSummaryChange with a typed tsx snippet; packages/plugin-view/README.md documents ViewTabItem.description"],"reproduction":"Under the lock: a copy of the OLD test whose probe reports 40 ms late fails with the CI message (Unable to find [data-testid=record-count-summaries]); a copy of the NEW test under the same delay passes (1 failed / 3 passed across the two copies). Both copies were deleted and never committed.","gates":{"vitest packages/plugin-list + plugin-view + plugin-grid at fb6010f":"exit 0, 431 files / 4181 tests","check:doc-snippets":0,"check:doc-examples":0,"check:doc-json":0,"check:doc-example-readers":0,"check:doc-fences":0,"check:doc-example-ids":0,"check:doc-types":0,"vitest packages/app-shell":"NOT MEASURED: run started under the lock, stopped by me after 38 min to free the shared lock (full suite is 1404 files); CI runs it"},"merged":"origin/main merged before fb6010f; merge commits only"}


    Generated by Claude Code

  6. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed (part 1 of 2) · domain:ui seat 2 · session_01XVp19E1MYUTFM3dnkwz8gB · 2026-10-15T21:08Z

    PR #12561 (nails 1, 2 and 4, Part of objectstack-ai/objectui#12528) merged through the merge queue as 646caea, which is on main. Verified by content:

    What landed:

    • The view description moves from its own row to the active tab's tooltip and ▾ menu header, with an in-row Info control where no strip is drawn.
    • The sort popover's standing note becomes an info control, plus a one-line hint while a linked column is sorted.
    • The column summaries share the record-count row.
    • Two optional host props: ViewTabItem.description and onColumnSummaryChange, both minor bumps, both documented.

    The card stays open. Nail 3 is PR #12572 (Fixes objectstack-ai/objectui#12528), which lands next. pm:dispatched stays until then.


    Generated by Claude Code

  7. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed (part 2 of 2) · domain:ui seat 2 · session_01XVp19E1MYUTFM3dnkwz8gB · 2026-10-15T21:24Z

    PR #12572 (nail 3, Fixes objectstack-ai/objectui#12528) merged through the merge queue as d88e351, which is on main. Verified by content: all 5 of its files on origin/main are blob-identical to the accepted head 43c0b82.

    pm:dispatched leaves with this note. The card closed completed on merge.


    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

area:recordsBusiness objects, records, the views that show data, usable forms, searchdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatenhancementNew feature or requestpriority:p2

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions