This commit is contained in:
2025-10-31 01:26:24 +01:00
parent fa43bc749e
commit 722c2f9a5c
14 changed files with 6497 additions and 6377 deletions
+204
View File
@@ -0,0 +1,204 @@
import React, { useCallback, useMemo, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { ChevronsRightIcon } from '../ui/icons';
import { createDocumentsSurface } from '../documents/DocumentsTable';
import { createPreviewSurface } from '../preview/PreviewWorkspace';
import { createDesktopSurface } from '../DesktopWorkspace';
import { useAppShell } from '../appShellContext';
import DocumentsLayout from './DocumentsLayout';
const DocumentsRoute = () => {
const {
sidebarProps,
documentsTableProps,
detailPanelProps,
detailPanelOpen,
workspaceMode,
skeuoWorkspaceProps,
openTagsModal,
openCorrespondentsModal,
openDocumentTypesModal,
previewWorkspaceDocument,
previewWorkspaceEntry,
closeDocumentPreview,
handleThumbnailRegeneration,
ensurePreviewData,
resolveApiPath,
ensureAssetUrl,
getDocumentAsset,
notifyApiError,
} = useAppShell();
const navigate = useNavigate();
const [sidebarCollapsed, setSidebarCollapsed] = useState(false);
const collapseSidebar = useCallback(() => setSidebarCollapsed(true), []);
const expandSidebar = useCallback(() => setSidebarCollapsed(false), []);
const sidebarPropsWithActions = useMemo(
() => ({
...sidebarProps,
onManageTags: openTagsModal,
onManageCorrespondents: openCorrespondentsModal,
onManageDocumentTypes: openDocumentTypesModal,
onCollapse: collapseSidebar,
}),
[sidebarProps, openTagsModal, openCorrespondentsModal, openDocumentTypesModal, collapseSidebar],
);
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 isWorkspace = workspaceMode === 'skeuo';
const isPreviewWorkspace = Boolean(previewWorkspaceDocument);
const showPreviewWorkspace = !isWorkspace && isPreviewWorkspace;
const renderSidebarToggle = useCallback(() => {
if (!sidebarCollapsed) {
return null;
}
return (
<button
type="button"
className="icon-button"
onClick={expandSidebar}
aria-label="Expand sidebar"
title="Expand sidebar"
>
<ChevronsRightIcon />
</button>
);
}, [sidebarCollapsed, expandSidebar]);
const documentsSurface = useMemo(() => {
if (!documentsTableProps) {
return null;
}
return createDocumentsSurface({
tableProps: documentsTableProps,
parentBreadcrumb,
onNavigateParent: parentBreadcrumb ? handleNavigateParent : null,
renderSidebarToggle,
detailProps: detailPanelProps,
detailOpen: detailPanelOpen,
});
}, [
documentsTableProps,
parentBreadcrumb,
handleNavigateParent,
renderSidebarToggle,
detailPanelProps,
detailPanelOpen,
]);
const previewSurface = useMemo(() => {
if (!showPreviewWorkspace || !previewWorkspaceDocument) {
return null;
}
return createPreviewSurface({
document: previewWorkspaceDocument,
previewEntry: previewWorkspaceEntry,
ensureAssetUrl,
ensurePreviewData,
getDocumentAsset,
resolveApiPath,
notifyApiError,
onRegenerate: handleThumbnailRegeneration,
onClose: closeDocumentPreview,
renderSidebarToggle,
});
}, [
showPreviewWorkspace,
previewWorkspaceDocument,
previewWorkspaceEntry,
ensureAssetUrl,
ensurePreviewData,
getDocumentAsset,
resolveApiPath,
notifyApiError,
handleThumbnailRegeneration,
closeDocumentPreview,
renderSidebarToggle,
]);
const workspaceSurface = useMemo(() => {
if (!isWorkspace) {
return null;
}
return createDesktopSurface({
workspaceProps: skeuoWorkspaceProps,
renderSidebarToggle,
});
}, [isWorkspace, skeuoWorkspaceProps, renderSidebarToggle]);
const surface = showPreviewWorkspace
? previewSurface
: isWorkspace
? workspaceSurface
: documentsSurface;
if (!surface) {
return (
<DocumentsLayout
sidebarProps={sidebarPropsWithActions}
sidebarCollapsed={sidebarCollapsed}
>
<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;
return (
<DocumentsLayout
sidebarProps={sidebarPropsWithActions}
sidebarCollapsed={sidebarCollapsed}
>
<div className={mainContentClass}>
{header ? (
<div className="panel-header main-content__header">
{header.leading}
<h2 className="main-content__title">
{header.title}
{header.subtitle ? (
<span className="main-content__subtitle">{header.subtitle}</span>
) : null}
</h2>
<div className="panel-actions__spacer" />
{header.actions}
</div>
) : null}
<div className={bodyClass}>{surface.content}</div>
{surface.detail || null}
</div>
</DocumentsLayout>
);
};
export default DocumentsRoute;