This commit is contained in:
2025-11-18 13:16:35 +01:00
parent 0b0a1a88fd
commit 0c37ef5578
20 changed files with 434 additions and 417 deletions
+22 -69
View File
@@ -2,17 +2,14 @@ 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 { DocumentsHeaderBreadcrumb } from '../documents/panel/DocumentsPanelHeader';
import { SidebarProvider, useSidebarContext } from '../sidebar/SidebarContext';
import { PanelManagerProvider, usePanelManager } from './PanelManagerContext';
import Sidebar from '../sidebar/Sidebar';
type Identifier = string | number;
type Breadcrumb = { id?: Identifier; name?: string; label?: string; title?: string };
type EnsureAssetUrl = (
docId: Identifier,
asset: unknown,
@@ -25,7 +22,8 @@ type ResolveApiPath = (path: string) => string;
type NotifyApiError = (error: unknown, fallbackMessage?: string) => void;
interface DocumentsTableProps {
breadcrumbs?: Breadcrumb[] | null;
breadcrumbs?: DocumentsHeaderBreadcrumb[] | null;
onBreadcrumbNavigate?: (crumb: DocumentsHeaderBreadcrumb) => void;
[key: string]: unknown;
}
@@ -88,7 +86,7 @@ const DocumentsRouteContent: React.FC = () => {
const sidebarHidden = sidebarCollapsed || sidebarSuppressed;
const handleHeaderBreadcrumbClick = useCallback((crumb: Breadcrumb) => {
const handleHeaderBreadcrumbClick = useCallback((crumb: DocumentsHeaderBreadcrumb) => {
if (!crumb || !crumb.id) {
return;
}
@@ -96,10 +94,16 @@ const DocumentsRouteContent: React.FC = () => {
navigate(target);
}, [navigate]);
const documentsTablePropsWithNav = useMemo(() => (
documentsTableProps
? { ...documentsTableProps, onBreadcrumbNavigate: handleHeaderBreadcrumbClick }
: null
), [documentsTableProps, handleHeaderBreadcrumbClick]);
const { surface } = useWorkspaceSurface({
sidebarHidden,
onExpandSidebar: expandSidebar,
documentsTableProps,
documentsTableProps: documentsTablePropsWithNav,
detailPanelProps,
detailPanelOpen,
previewWorkspaceDocument,
@@ -122,75 +126,24 @@ const DocumentsRouteContent: React.FC = () => {
if (!surface) {
return (
<DocumentsLayout sidebarProps={sidebarPropsWithActions}>
<div className="main-content main-content--documents">
<div className="main-content__body main-content__body--documents" />
<main className={`documents-main${sidebarHidden ? ' documents-main--sidebar-hidden' : ''}`}>
{!sidebarHidden ? <Sidebar {...sidebarPropsWithActions} /> : null}
<div className="main-content">
<div className="main-content__body" />
</div>
</DocumentsLayout>
</main>
);
}
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 = (
<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">
<PanelHeader
className="main-content__header"
leading={header.leading}
title={headerTitle}
titleTag="h2"
actions={header.actions}
/>
</div>
{(header.floatingActions)}
</>
) : null}
<div className={bodyClass}>{surface.content}</div>
<main className={`documents-main${sidebarHidden ? ' documents-main--sidebar-hidden' : ''}`}>
{!sidebarHidden ? <Sidebar {...sidebarPropsWithActions} /> : null}
<div className="main-content">
<div className="main-content__body">{surface.content}</div>
{surfaceDetail}
</div>
</DocumentsLayout>
</main>
);
};