typescript
This commit is contained in:
@@ -0,0 +1,214 @@
|
||||
import { useCallback, useEffect, useMemo } from 'react';
|
||||
import type { ReactNode } from 'react';
|
||||
import { SidebarExpandIcon } from '../ui/icons';
|
||||
import { createDocumentsSurface } from '../documents/DocumentsPanel';
|
||||
import { createDocumentViewerSurface } from '../preview/DocumentViewerPanel';
|
||||
import createDesktopSurface from '../desktop/createDesktopSurface';
|
||||
import { usePanelManager } from './PanelManagerContext';
|
||||
|
||||
type Identifier = string | number;
|
||||
|
||||
type EnsureAssetUrl = (docId: Identifier, asset: unknown, options?: Record<string, unknown>) => Promise<unknown> | void;
|
||||
type EnsurePreviewData = (docId: Identifier, options?: Record<string, unknown>) => Promise<unknown>;
|
||||
type GetDocumentAsset = (document: unknown, assetType: string) => unknown;
|
||||
type ResolveApiPath = (path: string) => string;
|
||||
type NotifyApiError = (error: unknown, fallbackMessage?: string) => void;
|
||||
|
||||
type DocumentsSurface = ReturnType<typeof createDocumentsSurface> | null;
|
||||
type PreviewSurface = ReturnType<typeof createDocumentViewerSurface> | null;
|
||||
type DesktopSurface = ReturnType<typeof createDesktopSurface> | null;
|
||||
type WorkspaceSurface = DocumentsSurface | PreviewSurface | DesktopSurface | null;
|
||||
|
||||
interface Breadcrumb {
|
||||
id?: Identifier;
|
||||
name?: string;
|
||||
label?: string;
|
||||
title?: string;
|
||||
}
|
||||
|
||||
interface UseWorkspaceSurfaceArgs {
|
||||
sidebarHidden?: boolean;
|
||||
onExpandSidebar?: () => void;
|
||||
documentsTableProps?: Record<string, any> | null;
|
||||
detailPanelProps?: (Record<string, any> & { onClose?: () => void }) | null;
|
||||
detailPanelOpen?: boolean;
|
||||
viewMode?: string;
|
||||
deskWorkspaceProps?: Record<string, any> | null;
|
||||
previewWorkspaceDocument?: unknown;
|
||||
previewWorkspaceEntry?: unknown;
|
||||
previewDocumentId?: Identifier | null;
|
||||
ensureAssetUrl?: EnsureAssetUrl;
|
||||
ensurePreviewData?: EnsurePreviewData;
|
||||
getDocumentAsset?: GetDocumentAsset;
|
||||
resolveApiPath?: ResolveApiPath;
|
||||
notifyApiError?: NotifyApiError;
|
||||
closeDocumentPreview?: () => void;
|
||||
parentBreadcrumb?: Breadcrumb | null;
|
||||
onNavigateParent?: () => void;
|
||||
}
|
||||
|
||||
interface UseWorkspaceSurfaceResult {
|
||||
surface: WorkspaceSurface;
|
||||
}
|
||||
|
||||
export const useWorkspaceSurface = ({
|
||||
sidebarHidden = false,
|
||||
onExpandSidebar,
|
||||
documentsTableProps,
|
||||
detailPanelProps,
|
||||
detailPanelOpen = false,
|
||||
viewMode = 'list',
|
||||
deskWorkspaceProps,
|
||||
previewWorkspaceDocument,
|
||||
previewWorkspaceEntry,
|
||||
previewDocumentId,
|
||||
ensureAssetUrl,
|
||||
ensurePreviewData,
|
||||
getDocumentAsset,
|
||||
resolveApiPath,
|
||||
notifyApiError,
|
||||
closeDocumentPreview,
|
||||
parentBreadcrumb,
|
||||
onNavigateParent,
|
||||
}: 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 (
|
||||
<button
|
||||
type="button"
|
||||
className="icon-button"
|
||||
onClick={onExpandSidebar}
|
||||
aria-label="Expand sidebar"
|
||||
title="Expand sidebar"
|
||||
>
|
||||
<SidebarExpandIcon />
|
||||
</button>
|
||||
);
|
||||
}, [sidebarHidden, onExpandSidebar]);
|
||||
|
||||
const documentsSurface = useMemo<DocumentsSurface>(() => {
|
||||
if (!documentsTableProps) {
|
||||
return null;
|
||||
}
|
||||
return createDocumentsSurface({
|
||||
tableProps: documentsTableProps,
|
||||
parentBreadcrumb,
|
||||
onNavigateParent: parentBreadcrumb ? onNavigateParent : null,
|
||||
renderSidebarToggle,
|
||||
detailProps: detailPanelProps,
|
||||
detailOpen: detailPanelOpen,
|
||||
});
|
||||
}, [
|
||||
documentsTableProps,
|
||||
parentBreadcrumb,
|
||||
onNavigateParent,
|
||||
renderSidebarToggle,
|
||||
detailPanelProps,
|
||||
detailPanelOpen,
|
||||
]);
|
||||
|
||||
const showPreviewWorkspace = Boolean(previewDocumentId);
|
||||
|
||||
const previewSurface = useMemo<PreviewSurface>(() => {
|
||||
if (!showPreviewWorkspace) {
|
||||
return null;
|
||||
}
|
||||
const detailExtras = detailPanelProps || {};
|
||||
const {
|
||||
tagLookupById,
|
||||
tags: tagOptions,
|
||||
onTagAdd,
|
||||
onTagRemove,
|
||||
correspondents,
|
||||
onCorrespondentAdd,
|
||||
onCorrespondentRemove,
|
||||
onUpdateTitle,
|
||||
onUpdateIssued,
|
||||
resolveFolderPath,
|
||||
onFolderNavigate,
|
||||
} = detailExtras;
|
||||
return createDocumentViewerSurface({
|
||||
document: previewWorkspaceDocument,
|
||||
previewEntry: previewWorkspaceEntry,
|
||||
ensureAssetUrl,
|
||||
ensurePreviewData,
|
||||
getDocumentAsset,
|
||||
resolveApiPath,
|
||||
notifyApiError,
|
||||
onClose: closeDocumentPreview,
|
||||
renderSidebarToggle,
|
||||
tagLookupById,
|
||||
tagOptions,
|
||||
onTagAdd,
|
||||
onTagRemove,
|
||||
correspondents,
|
||||
onCorrespondentAdd,
|
||||
onCorrespondentRemove,
|
||||
onUpdateTitle,
|
||||
onUpdateIssued,
|
||||
resolveFolderPath,
|
||||
onFolderNavigate,
|
||||
});
|
||||
}, [
|
||||
showPreviewWorkspace,
|
||||
previewWorkspaceDocument,
|
||||
previewWorkspaceEntry,
|
||||
ensureAssetUrl,
|
||||
ensurePreviewData,
|
||||
getDocumentAsset,
|
||||
resolveApiPath,
|
||||
notifyApiError,
|
||||
closeDocumentPreview,
|
||||
renderSidebarToggle,
|
||||
detailPanelProps,
|
||||
]);
|
||||
|
||||
const workspaceSurface = useMemo<DesktopSurface>(() => {
|
||||
if (viewMode !== 'desk') {
|
||||
return null;
|
||||
}
|
||||
return createDesktopSurface({
|
||||
workspaceProps: deskWorkspaceProps,
|
||||
renderSidebarToggle,
|
||||
parentBreadcrumb,
|
||||
onNavigateParent: parentBreadcrumb ? onNavigateParent : null,
|
||||
detailProps: detailPanelProps,
|
||||
detailOpen: detailPanelOpen,
|
||||
});
|
||||
}, [
|
||||
viewMode,
|
||||
deskWorkspaceProps,
|
||||
renderSidebarToggle,
|
||||
parentBreadcrumb,
|
||||
onNavigateParent,
|
||||
detailPanelProps,
|
||||
detailPanelOpen,
|
||||
]);
|
||||
|
||||
const surface = useMemo<WorkspaceSurface>(() => {
|
||||
if (showPreviewWorkspace) {
|
||||
return previewSurface;
|
||||
}
|
||||
if (viewMode === 'desk') {
|
||||
return workspaceSurface;
|
||||
}
|
||||
return documentsSurface;
|
||||
}, [showPreviewWorkspace, viewMode, previewSurface, workspaceSurface, documentsSurface]);
|
||||
|
||||
return { surface };
|
||||
};
|
||||
Reference in New Issue
Block a user