Repository navigation
Commit eeaa827
refactor(plugin-grid): move ObjectGrid's authored-input diagnostics into a sibling hook (slice 3) (#26364)
<!-- 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 3 of the move-only split, the first slice inside
the `ObjectGrid` component body; slices 1 and 2 landed as #26323 and
#26354, and the card stays open for the slices listed below).
Clause-②: no
Metadata-protocol: none
## What moved
Base `222755eb` (slice 2 merged).
`ui/packages/plugin-grid/src/ObjectGrid.tsx` is 6637 lines there:
imports and re-exports, the module-level code that tests pin in place,
and the `ObjectGrid` component from line 673 to the end.
This slice moves concern **Q** of the seam table below, verbatim, into a
custom hook `useObjectGridDiagnostics` in a new sibling module
`ui/packages/plugin-grid/src/objectGridDiagnostics.ts`. Q is the three
authored-input diagnostics, each a `useEffect` with one `console.warn`,
with their whole comment blocks:
- a `columns` entry the renderer cannot read (objectui#5349), through
`describeUnresolvedColumns`;
- an unusable `bulkActionDefs` member (objectui#8730), through
`describeUnusableBulkActionDefs`;
- a `pagination.pageSize` or flat `pageSize` that is not a positive
integer (objectui#9853), through `describeNonPositivePageSize`.
Q reads only `schema` and declares nothing any other region reads, so
the hook takes `schema: ObjectGridSchema` and nothing else. It declares
no state, adds no context and returns nothing. `ObjectGrid` calls
`useObjectGridDiagnostics(schema)` at the exact place the moved lines
stood (after the column summaries, before `generateColumns`), so the
order of the component's hooks does not change. The three `describe*`
import specifiers move with their only readers. No identifier is
renamed. Nothing new is exported from `ObjectGrid.tsx`, and the package
entry is untouched. `ObjectGrid.tsx` goes from 6637 to 6563 lines.
Move-only proof: the multiset of non-blank lines of the base
`ObjectGrid.tsx` equals the new `ObjectGrid.tsx` plus
`objectGridDiagnostics.ts`. Nothing is missing. The only added lines are
the new module's header comment, its five imports, the hook's docblock,
signature and closing brace, and in `ObjectGrid.tsx` the new import plus
the call with its two-line comment. The three edited import lines differ
only by the removed specifiers.
Kept away from #26341 (#25884): its `ObjectGrid.tsx` edits are
`temporalGroupHeading` and the seven column-cell call sites inside
`generateColumns` (region R). This slice touches neither, and its only
hunk in the component body ends above `generateColumns`.
## Test edits
None. No test reads the moved lines as source: I checked every test that
reads `ObjectGrid.tsx` (the nine in `plugin-grid/src/__tests__` and the
fourteen elsewhere that key a census row by that path), and none names
`describeUnresolvedColumns`, `describeUnusableBulkActionDefs`,
`describeNonPositivePageSize` or the three diagnostic slices. The
behavioural tests that spy on `console.warn` render the real
`ObjectGrid`, so they cover the hook.
## Seam table of the `ObjectGrid` component (measured on `222755eb`)
Lines are in the base file. "Reads" names inputs from other regions; the
props and `schema` are left out. "Read by" names the regions that use
what a region declares. A region after the first early return (line
3758) cannot become a hook, because a hook may not run after a
conditional return; it can become a plain function or a sub-component
with explicit props.
| # | Concern | Lines | Declares (main) | Reads | Read by | Slice |
|---|---|---|---|---|---|---|
| A | Props destructure | 673–709 | the host props | — | all | stays |
| B | Core state: rows, loading, error, i18n, metadata, object schema,
card view, refresh key, row versions, row conflict, export flags, row
height, selection, bulk dialog, grouped paging | 710–763 | `data`,
`loading`, `objectSchema`, `refreshKey`, `selectedRows`, `rowConflict`,
… and setters | — | all | stays (shared state) |
| C | Row-height sync effect | 765–776 | — | B | — | 8 (with AD) |
| D | Column state persistence | 778–849 | `columnStorageKey`,
`columnState`, `saveColumnState` | — | U, AA | 11 (pinned:
`gridNonAuthorKeys` reads the `NON-AUTHOR SURFACE — columnState` block
here) |
| E | Pull to refresh, card-view breakpoint | 851–870 | `pullRef`,
`isRefreshing`, `pullDistance` | B | AC, AH | 4 |
| F | Record source: bound data, data config, inline data, host paging
mode, object name and fields | 873–950 | `dataConfig`, `hasInlineData`,
`externalManualPagination`, `objectName`, `objectFields` | B | most |
stays (shared; `base-bind-declared` keys the `bind` read to this file) |
| G | Permissions, row affordances, operations, row actions, CRUD
verdicts | 951–1171 | `perms`, `operations`, `canEdit`, `canDelete`,
`resolvedRowActionDefs`, `recordVerdict`, … | B, F | K, V, X, Y, AF | 11
(pinned: `NON-AUTHOR SURFACE — rowActionDefs` block) |
| H | Projection keys (grouping, predicates, row colour, concurrency
token) | 1172–1264 | `groupingProjectionKey`, `predicateProjectionKey`,
`carriesConcurrencyToken`, `rowColorField` | B, F | K | 5 (with I) |
| I | Filter, sort, search and server paging state | 1265–1390 |
`schemaFilter`, `headerSort`, `searchTerm`, `querySearchTerm`,
`serverPage`, `searchFieldsKey` | B, F | K, Z, AF | 5 (with H) |
| J | Grouping decisions: masked grouping refusal, server-grouped fetch,
header-query and whole-rows refusals, fetch window | 1391–1548 |
`serverGroupedFetch`, `groupingNeedsHeaderQuery`,
`groupingNeedsWholeRows`, `fetchWindow`, `groupRowQuery` | B, F, I | K,
O, T | 6 (with O) |
| K | The row load effect | 1549–2168 | `invalidationNonce` (the effect
sets B's state) | B, F, G, H, I, J | O | 7 (largest effect; one hook
with typed inputs) |
| L | Host `findParams` sync | 2169–2187 | — | B | — | 4 (with E) |
| M | Navigation overlay, action runtime, row colour, predicate scope,
capability gate, row style | 2188–2276 | `navigation`, `executeAction`,
`getRowClassName`, `mayInvokeRowAction`, `getRowStyle` | B, F | R, V,
AA, AB, AC | stays (shared; pinned: `NON-AUTHOR SURFACE — onNavigate`
block and the `onNavigate: onNavigate ?? schema.onNavigate` read) |
| N | Group value formatter and temporal group faces | 2277–2381 |
`groupValueFormatter`, `temporalGroupFaces` | B, F | O, AE | after
#26341 lands (it edits `temporalGroupHeading`, which N calls) |
| O | Server grouping: headers, rows, grouped data, grouped totals |
2382–2557 | `groups`, `isGrouped`, `toggleGroup`, `groupHeaders`,
`serverGroupTotal` | B, F, I, J, K, N | P, T, W, Z, AA, AE | 6 (with J)
|
| P | Bulk fan-out params, column summaries | 2558–2624 |
`bulkFanoutParams`, `summaries`, `hasSummary` | B, F, O | X, AE | 9
(with X) |
| **Q** | **Authored-input diagnostics** | **2625–2702** | (nothing
anyone reads) | (`schema` only) | none | **3, this PR** |
| R | `generateColumns` | 2704–3590 | `generateColumns` | B, F, G, M | U
| 12, after #26341 (it edits the seven cell call sites here; pinned by
`columnReadBoundary-6458`, `relationalMetaCopySet`,
`cellRendererResolutionBoundary-8920`, `percent-storage-callers-11475`,
`column-identity.ratchet`) |
| S | Export: formats, format warning, `handleExport` | 3591–3755 |
`exportableFormats`, `handleExport` | B, F | AD | 8 (pinned:
`ObjectGrid.exportOptionsKeys` reads the `schema.exportOptions` reads
here) |
| T | Early returns: filter refusal, whole-rows refusal, load error,
loading, header-query refusal | 3756–3853 | — | B, I, J, O | — | 10
(sub-components) |
| U | Column post-processing: persisted widths and order | 3854–4040 |
`columns`, `persistedColumns` | D, R | V, W | 12 (with R) |
| V | Actions column and pinning | 4041–4213 | `columnsWithActions`,
pinned column sets | G, M, U | W, AA | 12 (pinned: `NON-AUTHOR SURFACE —
maxInlineRowActions`) |
| W | Density, sortability, column chrome, frozen columns, manual paging
flags | 4214–4406 | `orderedColumns`, `manualPaginationOn`,
`manualSearchOn`, `effectiveFrozenColumns` | B, F, O, U, V | Z, AA, AF |
12 |
| X | Bulk actions and selection | 4407–4783 | `bulkActionDefs`,
`selectionMode`, `dispatchBulkAction`, `handleBulkDialogClose`, … | B,
F, G, P | AA, AG | 9 (with P) |
| Y | Row save and optimistic-concurrency conflict | 4784–5012 |
`defaultRowSave`, `defaultBatchSave`, `settleRowConflict` | B, F, G |
AA, AG | 11 (pinned: `affordanceGrantMap-12082` keys `ObjectGrid >
writeRowGuarded` and `ObjectGrid > resolveRowConflict` to this file) |
| Z | Pagination, sort and search wiring | 5013–5118 | `pageSize`,
`manualPage`, `manualSort`, `manualOnSortChange`, `manualSearch` | B, F,
I, W | AA | 12 (with AA) |
| AA | `dataTableSchema`, grouped table schema | 5119–5466 |
`tableColumns`, `dataTableSchema`, `buildGroupedTableSchema` | most |
AE, AH | 12 |
| AB | Record detail overlay | 5467–5692 | `recordOverlayShellProps`,
`renderRecordDetail` | B, F, M | AC, AH | 10 |
| AC | Mobile card view (an early return) | 5693–6025 | — | B, E, M, AB
| — | 10 (pinned: `clickableNonControlCensus-13461` keys its clickable
`div` to this file) |
| AD | Toolbar: row height toggle, export menu | 6026–6128 |
`gridToolbar` | B, C, S | AH | 8 (with C, S) |
| AE | Summary footer, group headers and footers, group bands, grouped
pager, grid content | 6129–6408 | `summaryFooter`, `groupedPager`,
`gridContent` | B, N, O, P, AA | AF | 10 (pinned:
`iconOnlyButtonCensus-12143` counts two icon-only pagers in this file) |
| AF | Empty states | 6409–6514 | `renderedGridContent` | B, G, I, W, AE
| AH | 10 |
| AG | Bulk and row-conflict dialogs | 6515–6553 | `bulkDialog`,
`rowConflictDialog` | B, X, Y | AH | 9 (with X) |
| AH | The final return | 6554–6637 | — | everything | — | stays |
## Remaining slices (one PR each; the last closes the card)
- **Slice 4 — E + L:** pull to refresh, the card-view breakpoint effect
and the host `findParams` sync into a sibling hook.
- **Slice 5 — H + I:** the projection keys and the filter, sort, search
and server-paging state into a sibling hook.
- **Slice 6 — J + O:** the grouping decisions and server grouping into a
sibling hook.
- **Slice 7 — K:** the row load effect into a sibling hook, every input
typed from its source.
- **Slice 8 — C + S + AD:** the row-height sync, export and the toolbar
into a hook plus a toolbar sub-component. S is pinned by
`ObjectGrid.exportOptionsKeys`; this slice needs that test to read the
new module too.
- **Slice 9 — P + X + AG:** bulk fan-out, bulk actions, selection and
the bulk dialog into a hook (above the early returns) plus plain
functions or a sub-component (below them).
- **Slice 10 — T + AB + AC + AE + AF:** the early-return panels, the
record detail overlay, the mobile card view, the grouped content and the
empty states into sub-components with explicit props. AC and AE carry
census rows keyed to `ObjectGrid.tsx`.
- **Slice 11 — D + G + Y:** the column-state persistence, the row
affordances and the row save handlers. They are pinned by file and
symbol (`gridNonAuthorKeys`, `affordanceGrantMap-12082`); moving them
needs those rows re-keyed to the new file, which is more than the
import-path edits the card allows. If the seat does not grant that, they
stay in `ObjectGrid.tsx` as the component's core.
- **Slice 12 — R + U + V + W + Z + AA (closes the card):**
`generateColumns` and the column pipeline into the table schema, after
#26341 lands. Five source-reading tests pin R, so this slice needs the
same allowance as slice 11, or these regions stay and slice 11 or 10
closes the card.
A, B, F and M stay in the component in every plan: they are the shared
state most other concerns read. Each later slice re-measures the line
spans and the source-scan pins at its claim, because the file moves
daily.
## Verification
Run on head `fb3f7f50`:
- `pnpm --dir ui exec vitest run packages/plugin-grid/ --maxWorkers=2`,
the whole package suite, under the verification lock: 251 of 251 files
and 2247 of 2247 tests passed after the move. The before reading is the
same suite on slice 2's tested tree (the package tree of `main`
`222755eb`): 251 of 251 files, 2247 of 2247 tests, locally and in CI on
#26354.
- The 52 test files outside plugin-grid that read sources (the list
slices 1 and 2 used): 52 of 52 files, 2258 of 2258 tests passed.
- `pnpm --filter @object-ui/plugin-grid type-check` exit 0.
- eslint on the two touched files: 0 errors. `objectGridDiagnostics.ts`
draws no warning at all, so the hook's dependency arrays raise no
`react-hooks/exhaustive-deps` finding.
- `pnpm --dir ui run check:doc-example-readers` exit 0.
- `node scripts/gen-sdui-manifest-node.mjs`: the manifest is
byte-identical (sha256 `1f6e1ccb…`). Only
`scripts/sdui-manifest.sources/plugin-grid.json` is re-recorded. `node
scripts/check-sdui-manifest.mjs` exit 0.
- `node scripts/pm/dispatch-gates.mjs --commands`: 41 derived gates, all
exit 0; `--ran` reconciles 41 of 41 (0 NOT-MEASURED, 0 UNRUN).
## Acceptance notes
- The moved comments still say "`resolvesToDataColumn` above" and "the
export format warning below", about code that stays in `ObjectGrid.tsx`.
They are kept verbatim because the slice is move-only.
## Landing
On the plugin-grid line this goes after #26358 and #26341, so it stays a
draft. Expect a merge of `main` and a re-record of `plugin-grid.json`
before it lands.
Changeset: `.changeset/25994-objectgrid-diagnostics-hook.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>
Co-authored-by: objectstack-fleet[bot] <332303061+objectstack-fleet[bot]@users.noreply.github.com>1 parent a7f4b99 commit eeaa827
3 files changed
Lines changed: 117 additions & 81 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 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
79 | 79 | | |
80 | 80 | | |
81 | 81 | | |
82 | | - | |
| 82 | + | |
83 | 83 | | |
84 | | - | |
| 84 | + | |
85 | 85 | | |
86 | 86 | | |
87 | 87 | | |
| |||
91 | 91 | | |
92 | 92 | | |
93 | 93 | | |
94 | | - | |
| 94 | + | |
95 | 95 | | |
96 | 96 | | |
97 | 97 | | |
| 98 | + | |
98 | 99 | | |
99 | 100 | | |
100 | 101 | | |
| |||
2624 | 2625 | | |
2625 | 2626 | | |
2626 | 2627 | | |
2627 | | - | |
2628 | | - | |
2629 | | - | |
2630 | | - | |
2631 | | - | |
2632 | | - | |
2633 | | - | |
2634 | | - | |
2635 | | - | |
2636 | | - | |
2637 | | - | |
2638 | | - | |
2639 | | - | |
2640 | | - | |
2641 | | - | |
2642 | | - | |
2643 | | - | |
2644 | | - | |
2645 | | - | |
2646 | | - | |
2647 | | - | |
2648 | | - | |
2649 | | - | |
2650 | | - | |
2651 | | - | |
2652 | | - | |
2653 | | - | |
2654 | | - | |
2655 | | - | |
2656 | | - | |
2657 | | - | |
2658 | | - | |
2659 | | - | |
2660 | | - | |
2661 | | - | |
2662 | | - | |
2663 | | - | |
2664 | | - | |
2665 | | - | |
2666 | | - | |
2667 | | - | |
2668 | | - | |
2669 | | - | |
2670 | | - | |
2671 | | - | |
2672 | | - | |
2673 | | - | |
2674 | | - | |
2675 | | - | |
2676 | | - | |
2677 | | - | |
2678 | | - | |
2679 | | - | |
2680 | | - | |
2681 | | - | |
2682 | | - | |
2683 | | - | |
2684 | | - | |
2685 | | - | |
2686 | | - | |
2687 | | - | |
2688 | | - | |
2689 | | - | |
2690 | | - | |
2691 | | - | |
2692 | | - | |
2693 | | - | |
2694 | | - | |
2695 | | - | |
2696 | | - | |
2697 | | - | |
2698 | | - | |
2699 | | - | |
2700 | | - | |
2701 | | - | |
2702 | | - | |
2703 | | - | |
2704 | | - | |
| 2628 | + | |
| 2629 | + | |
| 2630 | + | |
2705 | 2631 | | |
2706 | 2632 | | |
2707 | 2633 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
0 commit comments