Skip to content

Commit e677770

Browse files
refactor(app-shell): move ObjectView's header toolbar and list URL state into sibling hooks (slice 8) (#26396)
<!-- 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 8 of the move-only split; slices 1 to 7 landed as #26152, #26233, #26310, #26336, #26353 and #26374, and the card stays open for the slices listed below). Clause-②: no Metadata-protocol: none ## What moved Base `fa5d72e1` (slice 7 merged). `ui/packages/app-shell/src/views/ObjectView.tsx` is 2796 lines there. Three concerns of `ObjectViewInner` move verbatim into custom hooks in two new sibling modules. In each, every input is passed as an argument, typed from its source (no `any`), the component destructures the returned values under their original names, no identifier is renamed and no context is added. ### G: the header toolbar → `objectViewHeaderToolbar.ts` Lines 798–874 move into `useObjectViewHeaderToolbar({ activeView, localizedToolbarActions, isEnvironmentList })`: `bulkWiredNamesKey`, `headerToolbarActions` (the `list_toolbar` actions less the record-scoped ones the selection bar carries, objectui#12462), the nav `runAction` deep link (`useOfferedNavRunAction`, `toolbarActionsWithDeepLink`) and the `toolbarBar` `action:bar` node. It returns `headerToolbarActions`, `toolbarActionsWithDeepLink` and `toolbarBar`. The column-declaration flags right after it (lines 875–899: `activeTabDeclaresColumns`, `draftColumnsEdited`, `activeViewDeclaresColumns`, `activeViewIsSaved`) stay. Only `renderListView` reads them, so they go with it in slice 11. ### H: the list's toolbar state in the URL → `objectViewListUrlState.ts` Lines 900–1015 move into `useObjectViewListUrlState({ objectName, objectDef, activeView, listPrefs, perms, user, searchParams, setSearchParams })`. That covers the objectui#11860 docblock, `listResetGeneration`, `listIdentityKey`, the seed refs and the render-time seed, the write-back effect, `writeListUrlState`, `activeViewHasPreference` and `handleResetView`. It returns `listIdentityKey`, `listSeedRef`, `ownListParamsRef`, `writeListUrlState`, `activeViewHasPreference` and `handleResetView`. `handleViewUpdate`, which follows, stays: it writes the config panel's draft. ### L-filter: URL equality filters and user-filter selections → `objectViewListUrlState.ts` Lines 1289–1359 move into `useObjectViewUrlFilters({ searchParams, setSearchParams, listIdentityKey, ownListParamsRef })`, in the same module: `filterParams`, `filterParamsKey`, `urlFilters` (through `parseUrlEqualityFilterTriples`), `ufSelectionsRef`, `initialUfSelections` and `handleUserFilterSelectionsChange`. It returns `urlFilters`, `initialUfSelections` and `handleUserFilterSelectionsChange`. It takes `listIdentityKey` and `ownListParamsRef` from the list URL state hook, which is the same coupling the block had with H inside the component. Each hook is called where its block stood, so the order of React hooks in the component is unchanged. ### Imports Each import moves with its only readers. `isRecordScopedAction`, `actionRendersAt`, `useOfferedNavRunAction` and `bulkWiredActionNamesKey` go to the header module. The whole `./userFilterUrlState.js` import, `readListFilterState`, `parseUrlEqualityFilterTriples` and `selectFilterParams` go to the list URL module. `selectFilterParams` is still re-exported from `ObjectView.tsx`, line unchanged. Nothing new is exported from `ObjectView.tsx`, and the package entry is untouched. `ObjectView.tsx` goes from 2796 to 2554 lines. Move-only proof: the multiset of non-blank lines of the base `ObjectView.tsx` is contained in new `ObjectView.tsx` plus the two modules. The only base lines missing are five import lines or import-list entries that lost a moved name: the `@object-ui/core`, `./listFilterStorage.js` and `@object-ui/types` (`actionRendersAt`) imports, and the `selectFilterParams` and `bulkWiredActionNamesKey` entries. The `@object-ui/core` and `./listFilterStorage.js` lines are replaced by their trimmed forms. The added lines are the trimmed imports and the two new imports, the module headers and imports, the hook signatures and parameter types, the `return` objects, and in `ObjectView.tsx` the three calls with their destructuring and two-line comments. ## Test edits One, path only, as the seat allowed: 1. `ObjectView.urlFilterSuffix-9196.test.ts`, describe "objectui#9196 — `ObjectView` no longer keeps a private reader of this family": `readFileSync(path.join(here, 'ObjectView.tsx'), 'utf8')` → `readFileSync(path.join(here, 'objectViewListUrlState.ts'), 'utf8')`. The block it scans (`const urlFilters`, `parseUrlEqualityFilterTriples`, the `./drillUrlFilters.js` import, no `filter\[` regex literal) now lives there. No assertion changed. No other source reader of `ObjectView.tsx` names a moved line. ## Seam table rows this PR changes (measured on `fa5d72e1`) The full table (regions A to Q) is in #26336. | # | Concern | Lines on `fa5d72e1` | Reads | Read by | Slice | |---|---|---|---|---|---| | G | Header toolbar actions, nav `runAction` deep link, `action:bar` node | 798–874 | D (`localizedToolbarActions`, `isEnvironmentList`), F (`activeView`) | P, Q | **8, this PR** | | G-columns | Column-declaration flags of the active view | 875–899 | B (`viewDraft`), F | O | 11, with O | | H | List toolbar state in the URL: seed, write-back, Reset view | 900–1015 | A, C (`objectDef`, `perms`, `user`), F (`activeView`, `listPrefs`) | L-filter, O, P, Q | **8, this PR** | | L-filter | `filter[...]` equality filters, `uf_*` user-filter selections | 1289–1359 | A, H (`listIdentityKey`, `ownListParamsRef`) | O | **8, this PR** | ## Remaining slices (the last closes the card) - **Slice 9 — N + P:** the view tab bar and the plugin schema plus header chrome. - **Slice 10 — Q:** the JSX return's `PageHeader`, import wizard and `NavigationOverlay` blocks into sub-components with explicit props. - **Slice 11 — B + I + O + G-columns (closes the card):** the view-config and view-tab CRUD handlers, `renderListView` and the column flags only it reads. The `writeRefusalCensus-11583` rows and the `relayRungCensus-7559` read are re-pointed (path and file-key changes only). `check-i18n-call-site-keys.test.ts` also reads `ObjectView.tsx` for the `deleteViewConfirm` call site in `handleDeleteView`, and is re-pointed the same way. ## 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 `AppContent*` tests, every other test that reads `ObjectView.tsx` as source, the app-shell tests that touch the list URL state, list filter storage, list preferences, `drillUrlFilters` or the nav `runAction`, eslint on the 4 touched files, the derived dispatch gates, and a Console build. ## Acceptance notes - eslint: 0 errors and no new `no-explicit-any`. The hook boundary adds three warnings that the same code did not raise inside one component, with dependency arrays kept verbatim because the slice is move-only: - `react-hooks/exhaustive-deps` on `handleUserFilterSelectionsChange`: `ownListParamsRef` now arrives as a parameter, and the rule only treats a `useRef` as stable inside the hook that declares it. It is the same ref object, so leaving it out of the deps changes nothing. - `react-hooks/refs` twice, on the `return` of `useObjectViewUrlFilters` (at `urlFilters` and `initialUfSelections`). `initialUfSelections` is read from `ufSelectionsRef` during render, as it was in the component, and the rule flags the values a hook returns from a render that reads a ref. The four files report 132 warnings, against 129 for the base `ObjectView.tsx` alone. Changeset: `.changeset/25992-objectview-header-list-url-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 0e7be7e commit e677770

5 files changed

Lines changed: 413 additions & 281 deletions

File tree

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
'@object-ui/app-shell': patch
3+
---
4+
5+
refactor(app-shell): the Console `ObjectView`'s header toolbar and list URL state move into sibling hooks
6+
7+
Clause-②: no
8+
Metadata-protocol: none
9+
10+
Three concerns move verbatim out of `ObjectViewInner` in `views/ObjectView.tsx`. The header's `list_toolbar` actions, the nav `runAction` deep link and the `action:bar` node move into `useObjectViewHeaderToolbar` in `objectViewHeaderToolbar.ts`. The list's toolbar state in the URL (the seed, its write-back and "Reset view") moves into `useObjectViewListUrlState`, and the `filter[...]` equality filters with the restored user-filter selections into `useObjectViewUrlFilters`, both in `objectViewListUrlState.ts`. The component passes every input in and reads the returned values. No logic, name or rendered output changes, and the package entry is unchanged.
11+
12+
What to do: nothing.

0 commit comments

Comments
 (0)