Files
papercrate/frontend/src/app/useWorkspaceSurface.js
T
2025-11-12 15:06:04 +01:00

169 lines
4.2 KiB
JavaScript

import React, { useCallback, useEffect, useMemo } 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';
export const useWorkspaceSurface = ({
sidebarHidden,
onExpandSidebar,
documentsTableProps,
detailPanelProps,
detailPanelOpen,
viewMode,
deskWorkspaceProps,
previewWorkspaceDocument,
previewWorkspaceEntry,
previewDocumentId,
ensureAssetUrl,
ensurePreviewData,
getDocumentAsset,
resolveApiPath,
notifyApiError,
closeDocumentPreview,
parentBreadcrumb,
onNavigateParent,
}) => {
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(() => {
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(() => {
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(() => {
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(() => {
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(() => {
if (showPreviewWorkspace) {
return previewSurface;
}
if (viewMode === 'desk') {
return workspaceSurface;
}
return documentsSurface;
}, [showPreviewWorkspace, viewMode, previewSurface, workspaceSurface, documentsSurface]);
return { surface };
};