feat: Remove documentLink prop and onNavigatorSnapshot logic, and add openDetailPanel and closeDetailPanel to document shell.

This commit is contained in:
2025-12-04 01:32:28 +01:00
parent 8bb9f9950a
commit 3f7c294948
9 changed files with 129 additions and 183 deletions
+56 -33
View File
@@ -1,5 +1,5 @@
import React, { useCallback, useEffect, useMemo } from 'react';
import type { ReactNode } from 'react';
import type { ReactNode, ComponentProps } from 'react';
import { useNavigate } from 'react-router-dom';
import {
DocumentsFilterProvider,
@@ -13,25 +13,24 @@ import { PanelManagerProvider, usePanelManager } from './PanelManagerContext';
import Sidebar from '../sidebar/Sidebar';
import useDocumentsShell from './useDocumentsShell';
const DocumentsRouteContent: React.FC = () => {
const {
sidebarProps,
surfaceConfig,
documentsFilter,
} = useDocumentsShell();
const navigate = useNavigate();
const DocumentsInner: React.FC<{
sidebarProps: ComponentProps<typeof Sidebar> | null;
surfaceConfig: any;
onNavigate: (documentId: string) => void;
}> = ({ sidebarProps, surfaceConfig, onNavigate }) => {
const { openPreview } = usePreviewContext();
const { collapsed: sidebarCollapsed } = useSidebarContext();
const {
sidebarSuppressed,
expandSidebar,
openDetailPanel,
} = usePanelManager();
const { openPreview } = usePreviewContext();
const { openDetailPanel } = surfaceConfig;
const sidebarHidden = sidebarCollapsed || sidebarSuppressed;
const handleHeaderBreadcrumbClick = useCallback((crumb: DocumentsHeaderBreadcrumb) => {
const navigate = useNavigate();
const handleBreadcrumbNavigate = useCallback((crumb: DocumentsHeaderBreadcrumb) => {
if (!crumb || !crumb.id) {
return;
}
@@ -39,10 +38,6 @@ const DocumentsRouteContent: React.FC = () => {
navigate(target);
}, [navigate]);
const handleDocumentNavigate = useCallback((documentId: string) => {
navigate(`/documents/${documentId}`);
}, [navigate]);
const handleOpenSidepanel = useCallback((docId: string) => {
if (openDetailPanel) {
openDetailPanel({ documentIds: [docId] });
@@ -51,9 +46,9 @@ const DocumentsRouteContent: React.FC = () => {
const documentsTablePropsWithNav = useMemo(() => (
surfaceConfig.documentsTableProps
? { ...surfaceConfig.documentsTableProps, onBreadcrumbNavigate: handleHeaderBreadcrumbClick }
? { ...surfaceConfig.documentsTableProps, onBreadcrumbNavigate: handleBreadcrumbNavigate }
: null
), [surfaceConfig.documentsTableProps, handleHeaderBreadcrumbClick]);
), [surfaceConfig.documentsTableProps, handleBreadcrumbNavigate]);
const { surface } = useWorkspaceSurface({
sidebarHidden,
@@ -87,30 +82,58 @@ const DocumentsRouteContent: React.FC = () => {
);
};
const content = renderSurface();
return (
<DocumentOpenProvider
onOpenViewer={onNavigate}
onOpenPreview={openPreview}
onOpenSidepanel={handleOpenSidepanel}
>
{renderSurface()}
</DocumentOpenProvider>
);
};
const DocumentsRouteContent: React.FC = () => {
const {
sidebarProps,
surfaceConfig,
documentsFilter,
} = useDocumentsShell();
const navigate = useNavigate();
const handleDocumentNavigate = useCallback((documentId: string) => {
navigate(`/documents/${documentId}`);
}, [navigate]);
return (
<DocumentsFilterProvider value={documentsFilter}>
<PreviewProvider
onNavigate={handleDocumentNavigate}
>
<DocumentOpenProvider
onOpenViewer={handleDocumentNavigate}
onOpenPreview={openPreview}
onOpenSidepanel={handleOpenSidepanel}
>
{content}
</DocumentOpenProvider>
<DocumentsInner
sidebarProps={sidebarProps}
surfaceConfig={surfaceConfig}
onNavigate={handleDocumentNavigate}
/>
</PreviewProvider>
</DocumentsFilterProvider>
);
};
const DocumentsRoute: React.FC = () => (
<SidebarProvider>
<PanelManagerProvider>
<DocumentsRouteContent />
</PanelManagerProvider>
</SidebarProvider>
);
const DocumentsRoute: React.FC = () => {
const { surfaceConfig } = useDocumentsShell();
const { detailPanelOpen, closeDetailPanel } = surfaceConfig;
return (
<SidebarProvider>
<PanelManagerProvider
isOpen={detailPanelOpen}
onClose={closeDetailPanel}
>
<DocumentsRouteContent />
</PanelManagerProvider>
</SidebarProvider>
);
};
export default DocumentsRoute;
+26 -9
View File
@@ -89,9 +89,11 @@ const applyPanelWidthToRoot = (panel: PanelKey, width: number, active: boolean):
interface PanelManagerProviderProps {
children: ReactNode;
isOpen?: boolean;
onClose?: () => void;
}
export const PanelManagerProvider: React.FC<PanelManagerProviderProps> = ({ children }) => {
export const PanelManagerProvider: React.FC<PanelManagerProviderProps> = ({ children, isOpen, onClose }) => {
const { collapsed, setCollapsed } = useSidebarContext();
const initialSidebarWidth = readStoredWidth('sidebar', DEFAULT_SIDEBAR_WIDTH);
const initialDetailWidth = readStoredWidth('detail', DEFAULT_DETAIL_WIDTH);
@@ -100,7 +102,13 @@ export const PanelManagerProvider: React.FC<PanelManagerProviderProps> = ({ chil
const [detailWidth, setDetailWidthState] = useState(() => clampPanelWidth('detail', initialDetailWidth));
const [resizingPanel, setResizingPanel] = useState(null);
const [sidebarSuppressed, setSidebarSuppressed] = useState(false);
const [detailPanelOpen, setDetailPanelOpen] = useState(false);
const [detailPanelOpen, setDetailPanelOpen] = useState(Boolean(isOpen));
useEffect(() => {
if (isOpen !== undefined) {
setDetailPanelOpen(isOpen);
}
}, [isOpen]);
const detailCloseHandlerRef = useRef(null);
const panelWidthsRef = useRef({ sidebar: sidebarWidth, detail: detailWidth });
@@ -109,7 +117,11 @@ export const PanelManagerProvider: React.FC<PanelManagerProviderProps> = ({ chil
const closeDetailPanel = useCallback(() => {
const handler = detailCloseHandlerRef.current;
handler?.();
}, []);
onClose?.();
if (isOpen === undefined) {
setDetailPanelOpen(false);
}
}, [onClose, isOpen]);
useEffect(() => {
panelWidthsRef.current.sidebar = sidebarWidth;
@@ -228,11 +240,16 @@ export const PanelManagerProvider: React.FC<PanelManagerProviderProps> = ({ chil
}, []);
const setDetailActive = useCallback(
(isOpen) => {
setDetailPanelOpen(Boolean(isOpen));
handlePanelLayoutChange('detail', isOpen ? 'opened' : 'closed');
(active) => {
if (isOpen === undefined) {
setDetailPanelOpen(Boolean(active));
}
if (!active) {
onClose?.();
}
handlePanelLayoutChange('detail', active ? 'opened' : 'closed');
},
[handlePanelLayoutChange],
[handlePanelLayoutChange, isOpen, onClose],
);
const expandSidebar = useCallback(() => {
@@ -394,8 +411,8 @@ export const usePanelResizeBindings = (
const handleProps = enabled
? {
onPointerDown: handlePointerDown,
}
onPointerDown: handlePointerDown,
}
: {};
return {
+6 -2
View File
@@ -6,7 +6,10 @@ import type Sidebar from '../sidebar/Sidebar';
import type { UseWorkspaceSurfaceArgs } from './useWorkspaceSurface';
import type { Identifier } from '../types/identifiers';
type WorkspaceSurfaceConfig = Omit<UseWorkspaceSurfaceArgs, 'sidebarHidden' | 'onExpandSidebar'>;
type WorkspaceSurfaceConfig = Omit<UseWorkspaceSurfaceArgs, 'sidebarHidden' | 'onExpandSidebar'> & {
openDetailPanel?: (args: { documentIds?: Identifier[] }) => void;
closeDetailPanel?: () => void;
};
interface DocumentsShellView {
sidebarProps: ComponentProps<typeof Sidebar> | null;
@@ -23,8 +26,9 @@ const useDocumentsShell = (): DocumentsShellView => {
documentsTableProps: (shell.documentsTableProps ?? null) as WorkspaceSurfaceConfig['documentsTableProps'],
detailPanelProps: (shell.detailPanelProps ?? null) as WorkspaceSurfaceConfig['detailPanelProps'],
detailPanelOpen: Boolean(shell.detailPanelOpen),
openDetailPanel: shell.openDetailPanel as WorkspaceSurfaceConfig['openDetailPanel'],
closeDetailPanel: shell.closeDetailPanel as WorkspaceSurfaceConfig['closeDetailPanel'],
previewWorkspaceDocument: shell.previewWorkspaceDocument,
documentLink: shell.documentLink,
previewDocumentId: (shell.previewDocumentId as Identifier | null | undefined) ?? null,
closeDocumentPreview: shell.closeDocumentPreview as WorkspaceSurfaceConfig['closeDocumentPreview'],
ensurePreviewData: shell.ensurePreviewData as WorkspaceSurfaceConfig['ensurePreviewData'],
-4
View File
@@ -36,7 +36,6 @@ export interface UseWorkspaceSurfaceArgs {
detailPanelProps?: DetailPanelProps;
detailPanelOpen?: boolean;
previewWorkspaceDocument?: unknown;
documentLink?: unknown;
previewDocumentId?: Identifier | null;
ensureAssetUrl?: EnsureAssetUrl;
ensurePreviewData?: EnsurePreviewData;
@@ -56,7 +55,6 @@ export const useWorkspaceSurface = ({
detailPanelProps,
detailPanelOpen = false,
previewWorkspaceDocument,
documentLink,
previewDocumentId,
ensureAssetUrl,
ensurePreviewData,
@@ -181,7 +179,6 @@ export const useWorkspaceSurface = ({
const viewer = (
<DocumentViewerPanel
document={previewWorkspaceDocument || null}
documentLink={documentLink}
hydrateDocument={ensurePreviewData}
tagLookupById={tagLookupById}
tagOptions={tagOptions}
@@ -214,7 +211,6 @@ export const useWorkspaceSurface = ({
}, [
showPreviewWorkspace,
previewWorkspaceDocument,
documentLink,
ensurePreviewData,
ensureAssetUrl,
getDocumentAsset,