Repository navigation
refactor(app-shell): move ObjectView's page header and record overlay into sibling sub-components (slice 10) - #26434
Conversation
…tViewOptions.ts (slice 2) The timeline/calendar/gantt/gallery/kanban ViewOptions, storedLegacyOptions, isSameOptionsValue and dispatchViewPatches move verbatim out of views/ObjectView.tsx into views/objectViewOptions.ts. ObjectView.tsx imports them back and re-exports every name it exported before. Test edits forced by the move: the four source scans that read the ObjectView face (calendarBinding-7029, galleryBinding-7547, ganttBinding-7070, titleFieldConvergence) now read ObjectView.tsx plus objectViewOptions.ts, and the writeRefusalCensus-11583 LEDGER row for dispatchViewPatches is keyed by its new file. Claude-Session: https://claude.ai/code/session_01QciHBvFJXnhZqXmdqpDtpz Co-authored-by: Claude <noreply@anthropic.com>
…ome.tsx (slice 3) ObjectNotFoundState, the saved-view tab strip's viewport check (VIEW_TABS_MIN_WIDTH, viewTabsFitNow, useViewTabsFit) and keepInlineEditModeForTheSession move verbatim out of views/ObjectView.tsx into views/objectViewChrome.tsx. ObjectView.tsx imports them back and re-exports ObjectNotFoundState, the one name it exported. No test edits. Claude-Session: https://claude.ai/code/session_01QciHBvFJXnhZqXmdqpDtpz Co-authored-by: Claude <noreply@anthropic.com>
…unt into a sibling hook Slice 4 of the move-only ObjectView split. The realtime subscription, the reconnection conflict resolution and the footer record-count fetch move verbatim from ObjectViewInner into useObjectViewLiveData in views/objectViewLiveData.ts. The component calls the hook at the same position (hook order unchanged) and passes its inputs explicitly; the recordCount state stays in the component. No test edits. Claude-Session: https://claude.ai/code/session_01QciHBvFJXnhZqXmdqpDtpz Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QciHBvFJXnhZqXmdqpDtpz Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QciHBvFJXnhZqXmdqpDtpz Co-authored-by: Claude <noreply@anthropic.com>
…igation into sibling hooks Slices 5 and 6 of the move-only ObjectView split, paired in one PR. - The identity-import gate, its password-policy state and data source, and the managed-environment Users marker move verbatim into useObjectViewIdentity in views/objectViewIdentity.tsx. - The record navigation overlay (detail navigation config, drawer recordId URL state, row click, expand to page, list record links) moves verbatim into useObjectViewRecordNavigation in views/objectViewRecordNavigation.ts. The URL equality filters and the user-filter selections between its two blocks stay in the component. Inputs are passed explicitly; the component destructures the returned values under their original names. No test edits. Claude-Session: https://claude.ai/code/session_01QciHBvFJXnhZqXmdqpDtpz Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QciHBvFJXnhZqXmdqpDtpz Co-authored-by: Claude <noreply@anthropic.com>
…m their sources activeView, objectDef and objects were written as `any` in the new hook's parameter type. They now name where the component gets each value: the element of buildViewTabs' result, and ConsoleObjectViewProps['objects'] and its element. No new no-explicit-any warning; the moved bodies are unchanged. Claude-Session: https://claude.ai/code/session_01QciHBvFJXnhZqXmdqpDtpz Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QciHBvFJXnhZqXmdqpDtpz Co-authored-by: Claude <noreply@anthropic.com>
…a sibling hook Slice 7 of the move-only ObjectView split. The environment list's entitlements, the list actions and their localized toolbar copies, and the create and import buttons' toolbar-scope predicates move verbatim into useObjectViewToolbarAffordances in views/objectViewToolbarAffordances.ts. The resolveAffordance verdict memo stays in the component (the affordance grant census reads it there) and is passed in with the other inputs, typed from their sources. No test edits. Claude-Session: https://claude.ai/code/session_01QciHBvFJXnhZqXmdqpDtpz Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QciHBvFJXnhZqXmdqpDtpz Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QciHBvFJXnhZqXmdqpDtpz Co-authored-by: Claude <noreply@anthropic.com>
…ate into sibling hooks Slice 8 of the move-only ObjectView split. - The header's list_toolbar actions (less the record-scoped ones the selection bar carries), the nav runAction deep link and the action:bar node move verbatim into useObjectViewHeaderToolbar in views/objectViewHeaderToolbar.ts. - The list's uf_ URL state (seed, write-back, Reset view) moves into useObjectViewListUrlState, and the filter[...] equality filters with the restored user-filter selections into useObjectViewUrlFilters, both in views/objectViewListUrlState.ts. Hook parameters are typed from their sources. One test edit, path only: ObjectView.urlFilterSuffix-9196 reads objectViewListUrlState.ts, where the scanned block now lives. Claude-Session: https://claude.ai/code/session_01QciHBvFJXnhZqXmdqpDtpz Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QciHBvFJXnhZqXmdqpDtpz Co-authored-by: Claude <noreply@anthropic.com>
…and header chrome into sibling hooks Move-only split of ObjectViewInner: the view tab items, ViewTabBar and its own-row face go to objectViewTabBar.tsx; the merged views and the plugin ObjectViewSchema go to objectViewPluginSchema.ts; the create button, folded header actions menu and refused-view face go to objectViewHeaderChrome.tsx. Each hook is called where its block stood. Claude-Session: https://claude.ai/code/session_01QciHBvFJXnhZqXmdqpDtpz Co-authored-by: Claude <noreply@anthropic.com>
… into sibling sub-components Move-only split of ObjectViewInner's JSX: the PageHeader block goes to ObjectViewPageHeader in objectViewPageHeader.tsx, and the non-split NavigationOverlay with its RecordDetailView goes to ObjectViewRecordOverlay in objectViewRecordOverlay.tsx. Every value is passed in as a prop; the rendered DOM is unchanged. Claude-Session: https://claude.ai/code/session_01QciHBvFJXnhZqXmdqpDtpz Co-authored-by: Claude <noreply@anthropic.com>
|
I merged Generated by Claude Code |
席位核对 · ACCEPT · seat
|
Requested by Steve · project thread
Part of #25992 (slice 10 of the move-only split; slices 1 to 9 landed as #26152, #26233, #26310, #26336, #26353, #26374, #26396 and #26412, and the card stays open for slice 11).
Clause-②: no
Metadata-protocol: none
What moved
Base
4ef75053(slice 9 merged, latestmainmerged in;mainhas not touchedObjectView.tsxsince).ui/packages/app-shell/src/views/ObjectView.tsxis 2374 lines there. Two blocks ofObjectViewInner's JSX return move verbatim into sub-components in two new sibling modules. In each, every value the block read is passed as a prop, typed from its source (noany), the props keep the names the block used, no identifier is renamed, no context is added, and the rendered DOM is the same.Q-header: the page header →
objectViewPageHeader.tsxLines 1987–2100 (the
hidden sm:blockwrapper and itsPageHeader) move intoObjectViewPageHeader, mounted in their place with the propsobjectDef,objectPluralLabel,objectDesc,createButton,importShown,setShowImport,importDisabled,t,listActions,isEnvironmentList,headerToolbarActions,environmentEntitlements,toolbarBar,listFavorite,activeViewHasPreference,handleResetViewandfoldedHeaderActions. That covers the plural title (objectui#11696), the managed-by badge (objectui#12194, #12606), thecreateElementicon, the create button, Import, the schema-driven toolbar orEnvironmentListToolbar, the overflow menu with favorites and "Reset view" (objectui#12427, #12418), and the folded face (objectui#12705). The "1. Header with breadcrumb + description" comment above it stays in place.Q-overlay: the record detail overlay →
objectViewRecordOverlay.tsxLines 2347–2368 (the
NavigationOverlaydrawn for every mode butsplit, with itsRecordDetailViewrender function) move intoObjectViewRecordOverlay, with the propsnavOverlay,handleDrawerClose,objectLabel,objectDef,handleExpandDrawer,t,dataSource,objectsandonEdit. ThenavOverlay.mode !== 'split' &&guard around it stays in the component.What stays in the return, and why
plugin-form/src/affordanceGrantMap-12082.test.tsxfinds theImportWizardmounts by walking JSX element names per file, and requires each mount to sit in a file thelistImportsite names (CONSOLE_LIST=ObjectView.tsx, which also reads thelistImportrow). A mount in a new file would fail that pin. Re-pointing it would change the site'sreadBylist rather than a path, so the block stays.splitface of the overlay. It wraps the list itself (mainContentholds thePluginObjectView), so moving it would mean passing that subtree in as a prop, which changes lines.ManageViewsDialog, the managed-users invite line, the list area,MetadataPanel,ViewConfigPanelandCreateViewDialogstay. They are short, or they are the views' own config surface, which slice 11's handlers feed.Imports
Each import moves with its only readers.
createElement,Button, the fourDropdownMenu*parts,Upload,MoreHorizontal,RotateCcw,SchemaRenderer,FavoriteMenuItem,getIcon,PageHeader,ManagedByBadgeandEnvironmentListToolbargo to the header module.NavigationOverlayandRecordDetailVieware still drawn by thesplitface, so the overlay module imports them too. Nothing new is exported fromObjectView.tsx, and the package entry is untouched.ObjectView.tsxgoes from 2374 to 2263 lines.Move-only proof: the multiset of non-blank lines of the base
ObjectView.tsxis contained in newObjectView.tsxplus the two modules. The only base lines missing are four import lines that lost a moved name: thereact,lucide-react,../layout/SidebarItemMenu.jsand@object-ui/reactimports. Each is replaced by its trimmed form. Removed outright are theButtonandDropdownMenu*entries of the@object-ui/componentslist and thegetIcon,PageHeader,ManagedByBadgeandEnvironmentListToolbarimports, whose lines reappear verbatim in the header module. The added lines are the trimmed imports and the two new imports, the module headers and imports, the component signatures and prop types,return (/);, and inObjectView.tsxthe two mounts with their props and one-line comments.Test edits
None. No source reader of
ObjectView.tsxnames a moved line. The readers that mentionPageHeader,NavigationOverlay,RecordDetailVieworEnvironmentListToolbarread other files, mock the module, or assert an absence (navRunAction.privateConventionRetired: norunActionliteral, which holds in every file). TheaffordanceGrantMap-12082mount walk sees no host-gated component mounted in either new module.Seam table rows this PR changes (measured on
4ef75053)The full table (regions A to Q) is in #26336.
4ef75053PageHeader: title, badge, icon, create, Import, toolbar, overflow menu, folded facesetShowImport), G, H, PNavigationOverlayfor every mode butsplitsplitoverlay, config panelRemaining slice (closes the card)
renderListViewand the column flags only it reads. ThewriteRefusalCensus-11583rows, therelayRungCensus-7559read, thecheck-i18n-call-site-keys.test.tsdeleteViewConfirmrow and thetree-view-config-readers-8253CONSOLE_COMPOSITIONread of the treelabelFieldrung are re-pointed (path and file-key changes only).Verification
See the os-dev-report comment on the card for the full readings: app-shell
type-checkafter rebuilding its dependency closure, everyObjectView.*test inviews/(header fold, favorites entry, list title plural, managed-by badge, setup list chrome, import and create predicates, record navigation and overlay tests among them), theAppContent*tests, every other test that readsObjectView.tsxas source, eslint on the 3 touched files, the derived dispatch gates, and a Console build.Acceptance notes
ObjectView.tsxalone; the twoexhaustive-depswarnings onhandleViewChangeonly moved lines.Changeset:
.changeset/25992-objectview-page-header-overlay-split.md(patch,@object-ui/app-shell).🤖 Generated with Claude Code
https://claude.ai/code/session_01QciHBvFJXnhZqXmdqpDtpz