typescript
This commit is contained in:
@@ -0,0 +1,189 @@
|
||||
import React, { useCallback, useEffect, useMemo } 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 Breadcrumb = { id?: string | number; name?: string; label?: string; title?: string };
|
||||
|
||||
const DocumentsRouteContent: React.FC = () => {
|
||||
const {
|
||||
sidebarProps,
|
||||
documentsTableProps,
|
||||
detailPanelProps,
|
||||
detailPanelOpen,
|
||||
documentsViewMode,
|
||||
deskWorkspaceProps,
|
||||
openTagsModal,
|
||||
openCorrespondentsModal,
|
||||
previewWorkspaceDocument,
|
||||
previewWorkspaceEntry,
|
||||
previewDocumentId,
|
||||
closeDocumentPreview,
|
||||
ensurePreviewData,
|
||||
resolveApiPath,
|
||||
ensureAssetUrl,
|
||||
getDocumentAsset,
|
||||
notifyApiError,
|
||||
} = useAppShell();
|
||||
const navigate = useNavigate();
|
||||
const { collapsed: sidebarCollapsed } = useSidebarContext();
|
||||
const {
|
||||
sidebarSuppressed,
|
||||
expandSidebar,
|
||||
} = usePanelManager();
|
||||
|
||||
const sidebarPropsWithActions = useMemo(
|
||||
() => ({
|
||||
...sidebarProps,
|
||||
onManageTags: openTagsModal,
|
||||
onManageCorrespondents: openCorrespondentsModal,
|
||||
}),
|
||||
[sidebarProps, openTagsModal, openCorrespondentsModal],
|
||||
);
|
||||
|
||||
const sidebarHidden = sidebarCollapsed || sidebarSuppressed;
|
||||
|
||||
const breadcrumbs = documentsTableProps?.breadcrumbs || null;
|
||||
const parentBreadcrumb = useMemo(() => {
|
||||
if (!Array.isArray(breadcrumbs) || breadcrumbs.length <= 1) {
|
||||
return null;
|
||||
}
|
||||
return breadcrumbs[breadcrumbs.length - 2];
|
||||
}, [breadcrumbs]);
|
||||
|
||||
const handleNavigateParent = useCallback(() => {
|
||||
if (!parentBreadcrumb) {
|
||||
return;
|
||||
}
|
||||
const target = parentBreadcrumb.id === 'root'
|
||||
? '/documents'
|
||||
: `/documents/folder/${parentBreadcrumb.id}`;
|
||||
navigate(target);
|
||||
}, [navigate, parentBreadcrumb]);
|
||||
|
||||
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,
|
||||
parentBreadcrumb,
|
||||
onNavigateParent: handleNavigateParent,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
document.body.classList.add('has-main-content');
|
||||
return () => {
|
||||
document.body.classList.remove('has-main-content');
|
||||
};
|
||||
}, []);
|
||||
|
||||
if (!surface) {
|
||||
return (
|
||||
<DocumentsLayout sidebarProps={sidebarPropsWithActions}>
|
||||
<div className="main-content main-content--documents">
|
||||
<div className="main-content__body main-content__body--documents" />
|
||||
</div>
|
||||
</DocumentsLayout>
|
||||
);
|
||||
}
|
||||
|
||||
const variant = surface.variant || 'documents';
|
||||
|
||||
const mainContentClass = `main-content main-content--${variant}${
|
||||
surface.detail ? ' main-content--has-detail' : ''
|
||||
}`;
|
||||
const bodyClass = `main-content__body main-content__body--${variant}${
|
||||
surface.detail ? ' 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 = (
|
||||
<h2 className="main-content__title">
|
||||
<BreadcrumbTrail
|
||||
entries={trailEntries}
|
||||
className="main-content__breadcrumbs"
|
||||
separator="/"
|
||||
/>
|
||||
{header.subtitle ? (
|
||||
<span className="main-content__subtitle">{header.subtitle}</span>
|
||||
) : null}
|
||||
</h2>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<DocumentsLayout sidebarProps={sidebarPropsWithActions}>
|
||||
<div className={mainContentClass}>
|
||||
{header ? (
|
||||
<div className="main-content__header-wrapper">
|
||||
{(header.selectionLabel || header.floatingActions) ? (
|
||||
<div className="panel-floating" aria-live="polite" aria-atomic="true">
|
||||
{header.selectionLabel ? (
|
||||
<span className="panel-floating__label">{header.selectionLabel}</span>
|
||||
) : null}
|
||||
{header.floatingActions || null}
|
||||
</div>
|
||||
) : null}
|
||||
<PanelHeader
|
||||
className="main-content__header"
|
||||
leading={header.leading}
|
||||
title={headerTitle}
|
||||
titleTag="h2"
|
||||
actions={header.actions}
|
||||
/>
|
||||
</div>
|
||||
) : null}
|
||||
<div className={bodyClass}>{surface.content}</div>
|
||||
{surface.detail || null}
|
||||
</div>
|
||||
</DocumentsLayout>
|
||||
);
|
||||
};
|
||||
|
||||
const DocumentsRoute: React.FC = () => (
|
||||
<SidebarProvider>
|
||||
<PanelManagerProvider>
|
||||
<DocumentsRouteContent />
|
||||
</PanelManagerProvider>
|
||||
</SidebarProvider>
|
||||
);
|
||||
|
||||
export default DocumentsRoute;
|
||||
Reference in New Issue
Block a user