Skip to content

fix(plugin-grid): a grouped list on a phone draws group headers and cards instead of the desktop table - #27078

Merged
objectstack-fleet[bot] merged 3 commits into
mainfrom
claude/project-thread-869uzk
Oct 28, 2026
Merged

objectstack-fleet[bot] merged 3 commits into
mainfrom
claude/project-thread-869uzk

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Warren · project thread
Fixes #26896

Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么:手机宽度(小于 768px)下,分组列表不再沿用桌面表格,而是和普通列表一样显示卡片,分组标题夹在卡片之间。
  • 为什么改:分组列表在手机上标题被截断、其它列被固定的操作列挡住,完全没法读;普通列表早已是卡片。
  • 风险与回滚:只改 ObjectGrid 的渲染分支,桌面分组表格与普通卡片不变;回滚即 revert 本 PR。
  • 先看:ObjectGrid.tsx 里新的 isGrouped && useCardView 分支与 buildMobileCardRenderer;groupedMobileCards-26896.test.tsx;groupingNeedsHeaderQuery-10881.test.tsx 改写的那条旧断言。
  • 两分钟验证:pnpm --dir ui exec vitest run packages/plugin-grid/src/__tests__/groupedMobileCards-26896.test.tsx,预期 4 个测试全绿。
  • 需要你做的:无,席位落地。

What changes

  • ObjectGrid lifts the mobile card body out of the plain card branch into one renderer, buildMobileCardRenderer(), which returns the per-row card function. The plain card view (ungrouped, under 768px) draws through it unchanged: same scroller, same card markup.
  • A grouped view under the same card breakpoint (isGrouped && useCardView) now draws groupBandsOf(pagedGroups) as a vertical list instead of the grouped table: each band's GroupRow (toggle, label, count, aggregations), then that band's rows as cards, then its footer (a server-grouped group's pager or loading line). Collapse, counts, the whole-group pager (groupedPager) and server group paging keep working because they are the same bands the table draws.
  • At a desktop width the grouped table (one table, one header) is untouched.

Tests

  • New groupedMobileCards-26896.test.tsx (4 tests): at 390px a client-grouped view draws one band per group with that group's rows as cards under it and no table; collapsing a band removes its cards and keeps the band; the same on the server-grouped path (header query + per-group pages). CONTROL: at 1280px the same view still draws the one grouped table and no card.
  • groupingNeedsHeaderQuery-10881.test.tsx: its re-homed pin asserted that a grouped grid under 768px draws the table, which is exactly the behaviour this card replaces. It now asserts the five bands, their cards and no table; its ungrouped control is unchanged.
  • Ablation (one-off, not kept): with isGrouped && useCardView replaced by isGrouped && false (via scripts/ablation-replace.mjs, anchor hit 1 → 0, restored blob equal to HEAD, git diff HEAD empty), the new file goes 3 failed / 1 passed: the three phone tests red, the desktop control green.

Acceptance notes

  • The grouped phone view keeps the page's toolbar and bulk bar (it draws inside the grid's normal frame), while the plain card view keeps its existing early return. Cards carry no selection checkbox in either view, as before.
  • Group headers in the card view do not stick to the top while scrolling; the plain card list has no sticky header either.

Verification

Gates derived by node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack, run on the final head 8cfdb16a: 35 derived plus 5 extra (plugin-grid type-check, eslint on the touched files, check:changeset-fixed, check:new-line-citations, the touched test files), all 40 exit 0, exits captured before any pipe; --ran reconciles 35 derived / 35 run / 0 NOT-MEASURED. Details in the os-dev report on the card. The whole packages/plugin-grid/ suite ran once before the test update (253/254 files; the one red was the stale pin rewritten above) and the touched files were re-run on the final head.


Generated by Claude Code

… phone

Below the card breakpoint the grouped branch kept the desktop table. The
card body moves into one renderer (buildMobileCardRenderer) that the plain
card view and a new grouped card view both draw with; the grouped view
draws each band, its rows as cards and its footer.

Claude-Session: https://claude.ai/code/session_01JQwxbYnetNoLwkb9ksXxde
Co-authored-by: Claude <noreply@anthropic.com>
…s and cards

The re-homed pin asserted the grouped table under 768px, which is the
behaviour this card replaces; it now asserts the bands, their cards and
no table, keeping the ungrouped control.

Claude-Session: https://claude.ai/code/session_01JQwxbYnetNoLwkb9ksXxde
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added size/l documentation Improvements or additions to documentation tooling labels Oct 28, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

席位核对

ACCEPT · domain:ui#2 · session_01JQwxbXpF772qWJjojJvRXw · head 8cfdb16a02 · 2026-10-28T04:24Z

席位意见:手机上的分组列表现在逐组画出组头、卡片和组尾,与普通列表的卡片视图同一个渲染器;桌面分组表格不变。

  1. Shape: draft, base main; the body says Fixes #26896, which is right, because the PR covers the whole card. 4 files, +446/−188. Not governed (check-governed-merges --pr 27078). ≤ 3000 lines.
  2. Premise measured. Seat read at head:
    • The plain card branch's inline body is lifted into buildMobileCardRenderer() unchanged. It is a plain closure with no hook calls, so calling it inside a branch breaks no hook order.
    • The plain branch now runs only when !isGrouped. The new isGrouped && useCardView branch maps groupBandsOf(pagedGroups) to band, cards and footer, and keeps the whole-group pager (groupedPager) and the FAB clearance on the scroller.
    • The desktop grouped table (isGrouped && !useCardView) is the old branch untouched.
  3. Gate check-runs (pinned to head 8cfdb16a02). In progress at this record; landing waits for every check green. The dev's local reading: new groupedMobileCards-26896.test.tsx 4/4, and the derived gate families exit 0.
  4. Accepted deviations.
    • The existing pin groupingNeedsHeaderQuery-10881 asserted the old phone behaviour (a table under 768px). It is rewritten to expect 5 bands, the card titles and no table. That old behaviour is exactly the card's bug, so the rewrite is the fix, not a loosened gate.
    • The full plugin-grid suite ran before that rewrite (253/254, the one red being that pin) and was not re-run on the final head. CI's Test UI shards on this head cover it.
  5. Out of scope / serial. PR feat(app-shell,plugin-list,plugin-grid,i18n): the Display menu's Open records section writes the reader's drawer | split preference; the name cell's ↗ opens the record as the full page #27031 also edits ui/packages/plugin-grid/src/ObjectGrid.tsx. Whichever lands second merges main and re-runs the gates.
  6. Landing clause. Not governed. When every check on the current head is green, the seat lands it (pr_ready + automerge_enable), or asks the maintainer to click if the classifier refuses. On merge, Fixes #26896 closes the card.

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 28, 2026 08:06
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 28, 2026 08:06
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 28, 2026
Merged via the queue into main with commit 74133d9 Oct 28, 2026
54 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-869uzk branch October 28, 2026 08:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/l tooling

Projects

None yet

2 participants