import { useCallback, useEffect, useMemo } from 'react'; import type { ComponentProps, ReactNode } from 'react'; import { SidebarExpandIcon } from '../ui/icons'; import DocumentsPanel from '../documents/panel/DocumentsPanel'; import DocumentViewerPanel from '../preview/DocumentViewerPanel'; import { usePanelManager } from './PanelManagerContext'; import { FolderManagerProvider } from '../folders/FolderManagerContext'; import type { Identifier } from '../types/identifiers'; export type EnsureAssetUrl = ( docId: Identifier, asset: unknown, options?: Record, ) => Promise | void; export type EnsurePreviewData = (docId: Identifier, options?: Record) => Promise; export type GetDocumentAsset = (document: unknown, assetType: string) => unknown; export type NotifyApiError = (error: unknown, fallbackMessage?: string) => void; export type DocumentsTableProps = ComponentProps | null; export type DetailPanelProps = (ComponentProps & { onClose?: () => void; onOpenPreview?: (args: { documentIds: Array }) => void; folderNodes?: Map; ensureFolderData?: ( folderId: Identifier | 'root', options?: { force?: boolean; includeDocuments?: boolean }, ) => Promise; }) | null; export type WorkspaceSurface = { content: ReactNode; detail?: ReactNode | null; detailMode?: 'overlay' | 'inline' | null } | null; export interface UseWorkspaceSurfaceArgs { sidebarHidden?: boolean; onExpandSidebar?: () => void; documentsTableProps?: DocumentsTableProps; detailPanelProps?: DetailPanelProps; detailPanelOpen?: boolean; previewWorkspaceDocument?: unknown; documentLink?: unknown; previewDocumentId?: Identifier | null; ensureAssetUrl?: EnsureAssetUrl; ensurePreviewData?: EnsurePreviewData; getDocumentAsset?: GetDocumentAsset; notifyApiError?: NotifyApiError; closeDocumentPreview?: () => void; } export interface UseWorkspaceSurfaceResult { surface: WorkspaceSurface; } export const useWorkspaceSurface = ({ sidebarHidden = false, onExpandSidebar, documentsTableProps, detailPanelProps, detailPanelOpen = false, previewWorkspaceDocument, documentLink, previewDocumentId, ensureAssetUrl, ensurePreviewData, getDocumentAsset, notifyApiError, closeDocumentPreview, }: UseWorkspaceSurfaceArgs): UseWorkspaceSurfaceResult => { const { registerDetailCloseHandler, setDetailActive } = usePanelManager(); useEffect(() => { const handler = detailPanelProps?.onClose || null; registerDetailCloseHandler(handler); return () => registerDetailCloseHandler(null); }, [registerDetailCloseHandler, detailPanelProps?.onClose]); useEffect(() => { setDetailActive(Boolean(detailPanelOpen)); return () => setDetailActive(false); }, [detailPanelOpen, setDetailActive]); const renderSidebarToggle = useCallback<() => ReactNode>(() => { if (!sidebarHidden) { return null; } return ( ); }, [sidebarHidden, onExpandSidebar]); const documentsSurface = useMemo(() => { if (!documentsTableProps) { return null; } const sidebarToggle = renderSidebarToggle ? renderSidebarToggle() : null; const viewMode = documentsTableProps.viewMode; const sidebarMode = viewMode === 'desk' ? 'overlay' : 'inline'; const detailMode: 'overlay' | 'inline' | null = detailPanelOpen && detailPanelProps ? sidebarMode : null; const detail = detailPanelOpen && detailPanelProps ? (() => { const { onClose, onOpenPreview, tags: tagOptions, folderNodes, ensureFolderData, ...restDetailProps } = detailPanelProps; const viewer = ( ); if (folderNodes && ensureFolderData) { return ( {viewer} ); } return ( <>{viewer} ); })() : null; return { content: ( ), detail, detailMode, }; }, [ documentsTableProps, renderSidebarToggle, detailPanelOpen, detailPanelProps, ]); const showPreviewWorkspace = Boolean(previewDocumentId); const previewSurface = useMemo(() => { if (!showPreviewWorkspace) { return null; } const sidebarToggle = renderSidebarToggle ? renderSidebarToggle() : null; const detailExtras = detailPanelProps || {}; const { tagLookupById, tags: tagOptions, onTagAdd, onTagRemove, correspondents, onCorrespondentAdd, onCorrespondentRemove, onUpdateTitle, onUpdateIssued, resolveFolderPath, folderNodes, ensureFolderData, } = detailExtras; const viewer = ( ); const content = folderNodes && ensureFolderData ? ( {viewer} ) : viewer; return { content, detail: null, detailMode: null }; }, [ showPreviewWorkspace, previewWorkspaceDocument, documentLink, ensurePreviewData, ensureAssetUrl, getDocumentAsset, notifyApiError, renderSidebarToggle, closeDocumentPreview, detailPanelProps, ]); const surface = useMemo(() => { if (showPreviewWorkspace) { return previewSurface; } return documentsSurface; }, [showPreviewWorkspace, previewSurface, documentsSurface]); return { surface }; };