Repository navigation
Commit 68edbcf
refactor(plugin-grid): move ObjectGrid's grouping and column summaries into sibling hooks (slice 6) (#26574)
<!-- claude-projects-attribution: {"github_login":"os-steve"} -->
_Requested by **Steve** · [project
thread](https://claude.ai/code/project/chan_01FdL1XeUyvVNxLreh3F4Qi9?thread=cmsg_01FdL1XeUyvVNxLreh3F4Qi94Cr2fbhp665MVvsYFfqYFe)_
Part of #25994 (slice 6 of the move-only split; slices 1–5 landed as
#26323, #26354, #26364, #26499 and #26537, and the card stays open for
the slices listed below).
Clause-②: no
Metadata-protocol: none
## What moved
Base `f48aa451` (`main` with slice 5).
`ui/packages/plugin-grid/src/ObjectGrid.tsx` is 5639 lines there. This
slice moves concerns **N**, **O** and **P** of the seam table in #26364,
as re-planned in #26499. They are adjacent and above the first early
return. Each block becomes a custom hook called where its lines stood:
| # | Concern | Lines on `f48aa451` | New home |
|---|---|---|---|
| N | The group value formatter and the date-family group faces
(`temporalGroupFaces`) | 1343–1451 | `useObjectGridGrouping` in
`objectGridGrouping.ts` |
| O | The render grouping, then server grouping: header and row-page
queries, option ranks, the grouped data (`groups`, `isGrouped`,
`toggleGroup`), the server leaves' rows and the match total | 1453–1612
| the same hook (N feeds O directly) |
| — | `TemporalGroupFace` and `temporalGroupHeading` (module level, with
their docblocks) | 592–644 | `objectGridGrouping.ts` |
| P | The query the cross-page fan-out replays (`bulkFanoutParams`), the
resolved match total, and the column summaries (`summaries`,
`hasSummary`) | 1614–1694 | `useObjectGridSummaries` in
`objectGridSummaries.ts` |
`TemporalGroupFace` is the type N builds its faces with, so it moves
with N, and `temporalGroupHeading`'s docblock is about that type, so the
two stay together. `temporalGroupHeading` gains the `export` keyword,
and `ObjectGrid.tsx` imports it back for the one call in the grouped
table's band (line 4879 there). #26341, which last edited these two, has
landed.
Hook inputs are passed explicitly and typed from their source; no
context is added and no `any` is introduced:
- Values from slices 4 and 5 are typed as `ReturnType<typeof
useObjectGridQueryInputs>[name]`, `ReturnType<typeof
useObjectGridGroupingDecisions>[name]`, `ReturnType<typeof
useObjectGridRowLoad>['invalidationNonce']`, and P's `isGrouped` as
`ReturnType<typeof useObjectGridGrouping>['isGrouped']`.
- `t` and `translateOptions` are `ReturnType<typeof
useGridTranslation>['t']` and `ReturnType<typeof
useSafeFieldLabel>['translateOptions']`.
- `objectFields` is `Record<string, any>` in the component. The hook
types it as what it reads: `GridCellFieldLike` (the cell face's own
input type) plus `type?: string` and `options?:
Parameters<translateOptions>[2]`.
- `data` is `unknown[]` in the grouping hook and `Parameters<typeof
useScopedColumnSummary>[1]` in the summaries hook. `objectSchema` is `{
fields?: Parameters<typeof useScopedColumnSummary>[2] } | null`. Setters
are `React.Dispatch<React.SetStateAction<…>>` of their state's type
(`unknown[]` for `data`).
The grouping hook returns the 7 names the rest of the component reads,
and the summaries hook returns 4. The component destructures them under
the same names. No identifier is renamed. Nothing new is exported from
`ObjectGrid.tsx`, and the package entry is untouched. Seventeen import
specifiers move with their only readers (four whole import lines among
them). `ObjectGrid.tsx` goes from 5639 to 5250 lines. The diff is 965
changed lines.
Move-only proof: the multiset of non-blank lines of the base
`ObjectGrid.tsx` equals the new `ObjectGrid.tsx` plus the two modules.
Nothing is missing except the 3 edited import lines, which differ only
by the removed specifiers, and `function temporalGroupHeading(`, which
now reads `export function temporalGroupHeading(`. The only added lines
are the module headers and imports, the `ReturnType` aliases and the
`GroupingFieldDef` type, the two hook signatures and `return { … }`
lists, and in `ObjectGrid.tsx` the two imports plus the two calls with
their two-line comments.
## Open PRs on `ObjectGrid.tsx`
None. I checked all 17 open PRs at the claim (07:55Z): none touches
`ObjectGrid.tsx` or its `objectGrid*` siblings.
## Source pins and test edits
None. I matched every string literal of every test that reads
`ObjectGrid.tsx` against the moved lines (the hooks and the two
module-level declarations), and the only hits were generic phrases in
prose. `groupDateHeading-13234.test.tsx`, which holds each date heading
to the cell under it, is a behavioural test and needs no edit.
`iconOnlyButtonCensus-12143` counts the two icon-only pagers that stay
in `ObjectGrid.tsx`.
## Remaining slices
As re-planned in #26499: **7 — C + D + E** (row-height sync,
column-state persistence, pull to refresh; re-points
`gridNonAuthorKeys`' `columnState` reads), and **8 — R + U + V** (closes
the card; re-points the five `generateColumns` pins).
## Verification
Run on `39923d86`. The head is now `67836999`, which only renames the
grouping hook's local field type from `ObjectFieldLike` to
`GroupingFieldDef`: Type Check UI's `check:spec-symbols` refused the
first name because `@objectstack/spec/system` exports it. On `67836999`
I re-ran `type-check` (exit 0) and all 16 `check:*` steps of the Type
Check UI job (`check:phantom-deps` through `check:i18n-designer-parity`,
every one exit 0).
- `pnpm --dir ui exec vitest run packages/plugin-grid/ --maxWorkers=2`,
the whole package suite, under the verification lock: 253 of 253 files,
2256 of 2256 tests. The before reading is the same count on slice 5
(#26537, CI green on `5345a340`).
- The 52 test files outside plugin-grid that read sources (the list
slices 1–5 used): 52 of 52 files, 2258 of 2258 tests.
- `pnpm --filter @object-ui/plugin-grid type-check` exit 0.
- `turbo run build --filter=@object-ui/console`: 70 of 70 tasks.
- `pnpm --dir ui run check:doc-example-readers` exit 0 (the newly
exported `temporalGroupHeading` is not a shared reader).
- eslint on the three files: 0 errors. Warnings go from 206 to 198, and
no dependency array changed. Three `react-hooks/exhaustive-deps`
messages now name the setters `setData`, `setTotalMatching` and
`setGroupedPage`, because a setter that arrives as a hook parameter is
not known to be stable. Three `react-hooks/set-state-in-effect` warnings
and eight `react-hooks/refs` warnings ("Cannot access refs during
render", on `lastFindParamsRef.current` feeding `bulkFanoutParams`) are
no longer raised, for the same reason: the rules recognise a setter or a
ref only where `useState` / `useRef` declares it. Those eleven are not
fixed, only out of the rules' sight; the reads are byte-identical.
- `node scripts/pm/dispatch-gates.mjs --commands`: 29 derived gates, all
exit 0 (the `vitest run scripts/` gate ran under the lock: 178 files,
5097 tests); `--ran` reconciles 29 of 29 (0 NOT-MEASURED, 0 UNRUN).
## Landing
No other open PR touches these files, so this can land as soon as CI is
green.
Changeset: `.changeset/25994-objectgrid-grouping-summaries-hooks.md`
(patch, `@object-ui/plugin-grid`).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01Bdrd2yH4eqnz2QobtN3haE
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 2dd332d commit 68edbcf
4 files changed
Lines changed: 554 additions & 411 deletions
File tree
- .changeset
- ui/packages/plugin-grid/src
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
0 commit comments