Repository navigation
Commit 73683ee
refactor(app-shell): move ObjectView's renderListView into a sibling hook (slice 11a) (#26492)
<!-- claude-projects-attribution: {"github_login":"os-steve"} -->
_Requested by **Steve** · [project
thread](https://claude.ai/code/project/chan_01FdL1XeUyvVNxLreh3F4Qi9?thread=cmsg_01FdL1XeUyvVNxLreh3F4Qi9VtKf3F9dzJPJM4RRtABaEc)_
Part of #25992 (slice 11a of the move-only split; slices 1 to 10 landed
as #26152, #26233, #26310, #26336, #26353, #26374, #26396, #26412 and
#26434). Slice 11 is split in two, as the seat agreed: this PR moves
`renderListView`, and slice 11b (the view-config and view-tab CRUD
handlers) closes the card.
Clause-②: no
Metadata-protocol: none
## What moved
Base `8cac64f2` (slice 10 merged).
`ui/packages/app-shell/src/views/ObjectView.tsx` is 2263 lines there.
Three blocks of `ObjectViewInner` move verbatim into one custom hook,
`useObjectViewListRenderer`, in the new sibling module
`objectViewListRenderer.tsx`. Every input is passed as an argument,
typed from its source (no `any`), and the component destructures
`renderListView` under its original name. No identifier is renamed and
no context is added.
- **O: `renderListView`** (lines 1145–1910). The `useCallback` the
plugin `ObjectView` calls to draw a view. It covers the `type: 'chart'`
face through `ObjectChart`, the `ListView` face with the relay of the
view's keys onto `fullSchema`, the toolbar doors that write the user's
own list state through `listPrefs.patchView`, the held `options` and
`filter` identities, and the dependency list, all kept verbatim.
- **G-columns: the column-declaration flags** (lines 783–806).
`activeTabDeclaresColumns`, `draftColumnsEdited`,
`activeViewDeclaresColumns` and `activeViewIsSaved`, with their
docblocks. Only `renderListView` reads them.
- **M: the held list identity refs** (lines 1109–1119).
`heldListOptions` and `heldListFilter`, the two `useRef`s with their
docblocks (objectui#10046, #7237). Only `renderListView` reads them.
The hook is called where `renderListView` stood, after the view tab bar
hook. The block it returns is unchanged.
**Hook order.** The two `useRef` calls of M used to run before
`useObjectViewTabBar` (whose `useViewTabsFit` and `useDisplayLocale` run
in between). They now run after it, inside the new hook. Both are
independent refs initialised to `undefined`; nothing between their old
and new positions reads them. The seat's ruling allows this shift when
stated. G-columns are plain values, not hooks.
The module also takes the lazy `ObjectChart` declaration (`lazy(() =>
import('@object-ui/plugin-charts')…)`), verbatim. Its only mount is the
chart face of `renderListView`, so the chart chunk stays lazy and is
split exactly as before. The `ImportWizard` lazy declaration stays in
`ObjectView.tsx`.
### Imports
Each import moves with its only readers: `DENSITY_MODE_TO_ROW_HEIGHT`,
`normalizeListViewSchema`, `buildListFilterKey`, `writeListFilterState`,
`ListViewPreference`, `ListView`, `ListViewSchema`, `TreeViewConfig`,
`useRef`, `ReactNode`, `resolveManagedByEmptyState`,
`warnSuppressedListNav`, `substituteFilterTokens`,
`keepInlineEditModeForTheSession`, and the view-options family entries
(`timelineViewOptions`, `calendarViewOptions`, `ganttViewOptions`,
`galleryViewOptions`, `kanbanViewOptions`, `storedLegacyOptions`,
`isSameOptionsValue`). The view-options names are still re-exported from
`ObjectView.tsx`, lines unchanged. Names the component still reads
elsewhere (`useCallback`, `Suspense`, `lazy`, `isSavedViewId`,
`FilterTokenScope`) are imported by the module as well. Nothing new is
exported from `ObjectView.tsx`, and the package entry is untouched.
`ObjectView.tsx` goes from 2263 to 1480 lines.
Move-only proof: the multiset of non-blank lines of the base
`ObjectView.tsx` is contained in new `ObjectView.tsx` plus the module.
The only base lines missing are six import lines or entries that lost a
moved name: the `react`, `@object-ui/core`,
`../context/ListPreferencesProvider.js`, `@object-ui/types` and
`./objectViewChrome.js` imports, and the `substituteFilterTokens` entry
of the helpers list. Each import is replaced by its trimmed form.
Removed outright are the `./listFilterStorage.js`,
`@object-ui/plugin-list`, `../utils/managedByEmptyState.js` and
`../utils/warnSuppressedListNav.js` imports, the `ObjectChart` lazy
declaration, and the view-options entries of the
`./objectViewOptions.js` import list. Their lines reappear verbatim in
the module. The added lines are the trimmed imports and the new import,
the module header and imports, the hook signature and parameter types,
the `return`, and in `ObjectView.tsx` the call with its destructuring
and two-line comment.
## Test edits
Six source-scan readers move to the file that now holds what they read.
Each edit is a path or file-list change, and no assertion changed:
1. `ObjectView.relayRungCensus-7559.test.ts`: `RELAY_SOURCE` reads
`objectViewListRenderer.tsx` (both candidate paths), the parse name
follows, and so does the path in the anchor's error message. The census
anchors on `const fullSchema = { … }` in `renderListView`.
2. `packages/types/src/__tests__/tree-view-config-readers-8253.test.ts`:
`CONSOLE_COMPOSITION` →
`packages/app-shell/src/views/objectViewListRenderer.tsx`. It reads the
`viewDef` tree `labelField` rung.
3.
`packages/types/src/__tests__/object-view-unmirrored-keys-7779.test.ts`:
`APP_SHELL_OBJECT_VIEW` →
`packages/app-shell/src/views/objectViewListRenderer.tsx`. Its three
reads are the app-shell relay (`rowHeight` through the fold, `rowColor`,
and the absent `allowExport` / `prefixField` / `densityMode` reads).
4. `ObjectView.titleFieldConvergence.test.tsx`: the joined `SOURCE` list
`['ObjectView.tsx', 'objectViewOptions.ts']` gains
`'objectViewListRenderer.tsx'`. The seams it counts span all three.
5. `ObjectView.overlayPatchOnly.test.ts`: `objectViewCode` reads
`ObjectView.tsx` and `objectViewListRenderer.tsx` joined. The
retired-family absence covers both, `handleViewConfigSave` stays in
`ObjectView.tsx`, and the objectui#12474 doors (`onDensityChange`,
`persistHiddenFields`) are in the module.
6. `view-filter-fold.ratchet.test.ts`: `objectViewSrc` reads
`ObjectView.tsx` and `objectViewListRenderer.tsx` joined. The
`onFilterChange` handlers are in the module, and `handleViewConfigSave`
stays in `ObjectView.tsx`.
Slice 11b will add its module to the joined lists in 5 and 6, and
re-point the `writeRefusalCensus-11583` rows and
`check-i18n-call-site-keys`.
## Seam table rows this PR changes (measured on `8cac64f2`)
The full table (regions A to Q) is in #26336.
| # | Concern | Lines on `8cac64f2` | Reads | Read by | Slice |
|---|---|---|---|---|---|
| G-columns | Column-declaration flags of the active view | 783–806 | B
(`viewDraft`), F (`baseView`, `derivedColumnViewIds`, `savedViews`) | O
| **11a, this PR** |
| M | Held list identity refs | 1109–1119 | — | O | **11a, this PR** |
| O | `renderListView` | 1145–1910 | A, B, C, D, E, F, G-columns, H, J,
L, L-filter, M, N | Q | **11a, this PR** |
| B | View config panel and create dialog state, `handleViewConfigSave`,
`handleViewCreate` (and `handleViewUpdate`, 829–836) | 231–386 | A, C |
F, G-columns, H, I, N, P, Q | 11b |
| I | View switching, mobile switcher, view-tab CRUD callbacks |
837–1045 | A, B, C, F | N, Q | 11b (closes the card) |
## Verification
See the os-dev-report comment on the card for the full readings:
app-shell `type-check` after rebuilding its dependency closure, every
`ObjectView.*` test in `views/` (the calendar, gallery, gantt, timeline,
kanban and chart bindings, relays, density, column and filter tests
among them), the `AppContent*` tests, every other test that reads
`ObjectView.tsx` as source, including the six re-pointed ones, eslint on
the touched files, the derived dispatch gates, and a Console build.
## Acceptance notes
- eslint: 0 errors, no new `no-explicit-any`. The two files report 108
warnings against 107 for the base `ObjectView.tsx` alone. The one added
warning is `react-refresh/only-export-components` on
`objectViewListRenderer.tsx`: the module declares the lazy `ObjectChart`
component and exports a hook. The declaration is kept verbatim with its
only mount rather than reshaped. The two `exhaustive-deps` warnings on
`handleViewChange` only moved lines. The six test edits add no warning.
Changeset: `.changeset/25992-objectview-list-renderer-split.md` (patch,
`@object-ui/app-shell`).
---
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01QciHBvFJXnhZqXmdqpDtpz
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent f9ecf95 commit 73683ee
9 files changed
Lines changed: 975 additions & 831 deletions
File tree
- .changeset
- ui/packages
- app-shell/src/views
- types/src/__tests__
| 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 | |
|---|---|---|---|
| |||
308 | 308 | | |
309 | 309 | | |
310 | 310 | | |
311 | | - | |
| 311 | + | |
312 | 312 | | |
313 | 313 | | |
314 | 314 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
131 | 131 | | |
132 | 132 | | |
133 | 133 | | |
134 | | - | |
| 134 | + | |
135 | 135 | | |
136 | 136 | | |
137 | 137 | | |
| |||
225 | 225 | | |
226 | 226 | | |
227 | 227 | | |
228 | | - | |
| 228 | + | |
229 | 229 | | |
230 | 230 | | |
231 | 231 | | |
| |||
244 | 244 | | |
245 | 245 | | |
246 | 246 | | |
247 | | - | |
| 247 | + | |
248 | 248 | | |
249 | 249 | | |
250 | 250 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
314 | 314 | | |
315 | 315 | | |
316 | 316 | | |
317 | | - | |
| 317 | + | |
318 | 318 | | |
319 | 319 | | |
320 | 320 | | |
| |||
Large diffs are not rendered by default.
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
43 | 43 | | |
44 | 44 | | |
45 | 45 | | |
46 | | - | |
| 46 | + | |
47 | 47 | | |
48 | 48 | | |
49 | 49 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2050 | 2050 | | |
2051 | 2051 | | |
2052 | 2052 | | |
2053 | | - | |
| 2053 | + | |
2054 | 2054 | | |
2055 | 2055 | | |
2056 | 2056 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
77 | 77 | | |
78 | 78 | | |
79 | 79 | | |
80 | | - | |
| 80 | + | |
81 | 81 | | |
82 | 82 | | |
83 | 83 | | |
| |||
0 commit comments