import React, { useCallback, useEffect, useMemo } from 'react'; import type { ReactNode } from 'react'; import { useNavigate } from 'react-router-dom'; import { useAppShell } from '../appShellContext'; import DocumentsLayout from './DocumentsLayout'; import { useWorkspaceSurface } from './useWorkspaceSurface'; import PanelHeader from '../ui/PanelHeader'; import BreadcrumbTrail from '../ui/BreadcrumbTrail'; import { SidebarProvider, useSidebarContext } from '../sidebar/SidebarContext'; import { PanelManagerProvider, usePanelManager } from './PanelManagerContext'; type Identifier = string | number; type Breadcrumb = { id?: Identifier; name?: string; label?: string; title?: string }; type EnsureAssetUrl = ( docId: Identifier, asset: unknown, options?: Record, ) => Promise | void; type EnsurePreviewData = (docId: Identifier, options?: Record) => Promise; type GetDocumentAsset = (document: unknown, assetType: string) => unknown; type ResolveApiPath = (path: string) => string; type NotifyApiError = (error: unknown, fallbackMessage?: string) => void; interface DocumentsTableProps { breadcrumbs?: Breadcrumb[] | null; [key: string]: unknown; } interface DocumentsRouteAppShell { sidebarProps?: Record | null; documentsTableProps?: DocumentsTableProps | null; detailPanelProps?: Record | null; detailPanelOpen?: boolean; documentsViewMode?: string; deskWorkspaceProps?: Record | null; openTagsModal?: () => void; openCorrespondentsModal?: () => void; previewWorkspaceDocument?: unknown; previewWorkspaceEntry?: unknown; previewDocumentId?: Identifier | null; closeDocumentPreview?: () => void; ensurePreviewData?: EnsurePreviewData; resolveApiPath?: ResolveApiPath; ensureAssetUrl?: EnsureAssetUrl; getDocumentAsset?: GetDocumentAsset; notifyApiError?: NotifyApiError; } const DocumentsRouteContent: React.FC = () => { const { sidebarProps, documentsTableProps, detailPanelProps, detailPanelOpen, documentsViewMode, deskWorkspaceProps, openTagsModal, openCorrespondentsModal, previewWorkspaceDocument, previewWorkspaceEntry, previewDocumentId, closeDocumentPreview, ensurePreviewData, resolveApiPath, ensureAssetUrl, getDocumentAsset, notifyApiError, } = useAppShell() as DocumentsRouteAppShell; const navigate = useNavigate(); const { collapsed: sidebarCollapsed } = useSidebarContext(); const { sidebarSuppressed, expandSidebar, } = usePanelManager(); const safeSidebarProps = useMemo>( () => (sidebarProps && Object(sidebarProps) === sidebarProps ? sidebarProps : {}), [sidebarProps], ); const sidebarPropsWithActions = useMemo( () => ({ ...safeSidebarProps, onManageTags: openTagsModal, onManageCorrespondents: openCorrespondentsModal, }), [safeSidebarProps, openTagsModal, openCorrespondentsModal], ); const sidebarHidden = sidebarCollapsed || sidebarSuppressed; const handleHeaderBreadcrumbClick = useCallback((crumb: Breadcrumb) => { if (!crumb || !crumb.id) { return; } const target = crumb.id === 'root' ? '/documents' : `/documents/folder/${crumb.id}`; navigate(target); }, [navigate]); const { surface } = useWorkspaceSurface({ sidebarHidden, onExpandSidebar: expandSidebar, documentsTableProps, detailPanelProps, detailPanelOpen, viewMode: documentsViewMode, deskWorkspaceProps, previewWorkspaceDocument, previewWorkspaceEntry, previewDocumentId, ensureAssetUrl, ensurePreviewData, getDocumentAsset, resolveApiPath, notifyApiError, closeDocumentPreview, }); useEffect(() => { document.body.classList.add('has-main-content'); return () => { document.body.classList.remove('has-main-content'); }; }, []); if (!surface) { return (
); } const variant = surface.variant || 'documents'; const surfaceDetail = (surface as { detail?: ReactNode }).detail || null; const hasDetail = Boolean(surfaceDetail); const mainContentClass = `main-content main-content--${variant}${ hasDetail ? ' main-content--has-detail' : '' }`; const bodyClass = `main-content__body main-content__body--${variant}${ hasDetail ? ' main-content__body--has-detail' : '' }`; const header = surface.header || null; let headerTitle: React.ReactNode = null; if (header) { const breadcrumbEntries = Array.isArray(header.breadcrumbs) ? header.breadcrumbs.filter(Boolean) : []; const lastIndex = breadcrumbEntries.length - 1; const trailEntries = breadcrumbEntries.length ? breadcrumbEntries.map((crumb, index) => ({ id: crumb.id ?? index, label: crumb.name ?? crumb.label ?? crumb.title ?? '', onClick: index < lastIndex ? () => handleHeaderBreadcrumbClick(crumb) : null, })) : [{ id: 'current-location', label: header.title }]; headerTitle = (

{header.subtitle ? ( {header.subtitle} ) : null}

); } return (
{header ? ( <>
{(header.floatingActions)} ) : null}
{surface.content}
{surfaceDetail}
); }; const DocumentsRoute: React.FC = () => ( ); export default DocumentsRoute;