This commit is contained in:
2025-11-11 15:23:07 +01:00
parent a8589a864a
commit 5333de0e89
5 changed files with 137 additions and 58 deletions
+8 -3
View File
@@ -83,12 +83,17 @@ const createDesktopSurface = ({
const sidebarToggle = renderSidebarToggle ? renderSidebarToggle() : null; const sidebarToggle = renderSidebarToggle ? renderSidebarToggle() : null;
const detail = detailOpen && detailProps const detail = detailOpen && detailProps
? ( ? (() => {
const { onClose, onOpenPreview, ...restDetailProps } = detailProps;
return (
<DocumentViewerPanel <DocumentViewerPanel
variant="sidebar" variant="sidebar"
{...detailProps} onCollapsePanel={onClose}
onMaximizePanel={onOpenPreview}
{...restDetailProps}
/> />
) );
})()
: null; : null;
const surfaceConfig = createWorkspaceSurfaceConfig({ const surfaceConfig = createWorkspaceSurfaceConfig({
key: 'workspace', key: 'workspace',
@@ -92,12 +92,17 @@ const createDocumentsSurface = ({
const sidebarToggle = renderSidebarToggle ? renderSidebarToggle() : null; const sidebarToggle = renderSidebarToggle ? renderSidebarToggle() : null;
const detail = detailOpen && detailProps const detail = detailOpen && detailProps
? ( ? (() => {
const { onClose, onOpenPreview, ...restDetailProps } = detailProps;
return (
<DocumentViewerPanel <DocumentViewerPanel
variant="sidebar" variant="sidebar"
{...detailProps} onCollapsePanel={onClose}
onMaximizePanel={onOpenPreview}
{...restDetailProps}
/> />
) );
})()
: null; : null;
return createWorkspaceSurfaceConfig({ return createWorkspaceSurfaceConfig({
+105 -36
View File
@@ -6,7 +6,13 @@ import React, {
useState, useState,
} from 'react'; } from 'react';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import { DownloadIcon, CloseIcon, IconZoomInArea } from '../ui/icons'; import {
DownloadIcon,
CloseIcon,
IconZoomInArea,
DetailPanelCollapseIcon,
WindowMaximizeIcon,
} from '../ui/icons';
import PreviewZoomOverlay from '../detail/PreviewZoomOverlay'; import PreviewZoomOverlay from '../detail/PreviewZoomOverlay';
import { import {
buildCorrespondentOptions, buildCorrespondentOptions,
@@ -79,7 +85,6 @@ const DocumentViewerPanel = ({
onCorrespondentRemove, onCorrespondentRemove,
onUpdateTitle, onUpdateTitle,
onUpdateIssued, onUpdateIssued,
hasOcr = false,
ensureAssetUrl, ensureAssetUrl,
getDocumentAsset, getDocumentAsset,
ensurePreviewData, ensurePreviewData,
@@ -88,8 +93,12 @@ const DocumentViewerPanel = ({
sidebarToggle = null, sidebarToggle = null,
onClosePanel, onClosePanel,
resolveFolderPath, resolveFolderPath,
variant = 'viewer',
onCollapsePanel,
onMaximizePanel,
}) => { }) => {
const navigate = useNavigate(); const navigate = useNavigate();
const isSidebarVariant = variant === 'sidebar';
const sortedCorrespondents = useMemo( const sortedCorrespondents = useMemo(
() => sortCorrespondents(document?.correspondents || []), () => sortCorrespondents(document?.correspondents || []),
[document], [document],
@@ -105,6 +114,13 @@ const DocumentViewerPanel = ({
[document], [document],
); );
const hasOcr = useMemo(() => {
if (!document || typeof getDocumentAsset !== 'function') {
return false;
}
return Boolean(getDocumentAsset(document, 'ocr-text'));
}, [document, getDocumentAsset]);
const summaryProps = useMemo( const summaryProps = useMemo(
() => ({ () => ({
tagLookupById, tagLookupById,
@@ -331,7 +347,38 @@ const DocumentViewerPanel = ({
canZoom: Boolean(zoomDisplay), canZoom: Boolean(zoomDisplay),
}); });
const closeButton = onClosePanel const collapseButton = isSidebarVariant && typeof onCollapsePanel === 'function'
? (
<button
type="button"
className="icon-button"
onClick={() => onCollapsePanel?.()}
aria-label="Close detail panel"
title="Close detail panel"
>
<DetailPanelCollapseIcon />
</button>
)
: null;
const maximizeButton = isSidebarVariant && typeof onMaximizePanel === 'function'
? (
<button
type="button"
className="icon-button"
onClick={(event) => {
event.stopPropagation();
onMaximizePanel?.(document?.id);
}}
aria-label="Maximize"
title="Maximize"
>
<WindowMaximizeIcon className="icon--flip-y" />
</button>
)
: null;
const closeButton = !isSidebarVariant && onClosePanel
? ( ? (
<button <button
type="button" type="button"
@@ -345,7 +392,9 @@ const DocumentViewerPanel = ({
) )
: null; : null;
const headerLeadingButtons = [sidebarToggle, closeButton].filter(Boolean); const headerLeadingButtons = isSidebarVariant
? [collapseButton, maximizeButton].filter(Boolean)
: [sidebarToggle, closeButton].filter(Boolean);
const headerLeadingContent = headerLeadingButtons.length const headerLeadingContent = headerLeadingButtons.length
? ( ? (
<> <>
@@ -354,10 +403,7 @@ const DocumentViewerPanel = ({
) )
: null; : null;
if (!document) { const loadingSection = (
return (
<section className="document-viewer-panel" ref={panelRef}>
<PanelHeader title="Document preview" />
<div className="document-viewer-panel__body"> <div className="document-viewer-panel__body">
<section className="document-viewer document-viewer--loading"> <section className="document-viewer document-viewer--loading">
<div className="document-viewer__details-pane"> <div className="document-viewer__details-pane">
@@ -370,30 +416,14 @@ const DocumentViewerPanel = ({
</div> </div>
</section> </section>
</div> </div>
</section>
);
}
const headerTitle = breadcrumbTrailEntries.length ? (
<BreadcrumbTrail
entries={breadcrumbTrailEntries}
separator="/"
className="panel-header__breadcrumbs"
/>
) : (
document?.title || 'Document preview'
); );
return ( const viewerSection = document ? (
<> <div
<section className="document-viewer-panel" ref={panelRef}> className={isStackedLayout
<PanelHeader ? 'document-viewer-panel__body document-viewer-panel__body--stacked'
leading={headerLeadingContent} : 'document-viewer-panel__body'}
title={headerTitle} >
titleTag="h3"
actions={headerActions}
/>
<div className="document-viewer-panel__body">
<section className={viewerClassName}> <section className={viewerClassName}>
<DocumentViewerLayout <DocumentViewerLayout
document={document} document={document}
@@ -405,12 +435,56 @@ const DocumentViewerPanel = ({
/> />
</section> </section>
</div> </div>
</section> ) : loadingSection;
const headerTitle = breadcrumbTrailEntries.length ? (
<BreadcrumbTrail
entries={breadcrumbTrailEntries}
separator="/"
className="panel-header__breadcrumbs"
truncateFromStart={isSidebarVariant}
/>
) : (
document?.title || 'Document preview'
);
const overlay = (
<PreviewZoomOverlay <PreviewZoomOverlay
open={Boolean(zoomOverlayOpen && zoomDisplay)} open={Boolean(zoomOverlayOpen && zoomDisplay)}
display={zoomDisplay} display={zoomDisplay}
onClose={handleZoomClose} onClose={handleZoomClose}
/> />
);
if (isSidebarVariant) {
return (
<>
<aside className="detail-panel panel" ref={panelRef}>
<PanelHeader
leading={headerLeadingContent}
title={headerTitle}
titleTag="h3"
actions={headerActions}
/>
<div className="panel-body detail-panel__content">{viewerSection}</div>
</aside>
{overlay}
</>
);
}
return (
<>
<section className="document-viewer-panel" ref={panelRef}>
<PanelHeader
leading={headerLeadingContent}
title={headerTitle}
titleTag="h3"
actions={headerActions}
/>
{viewerSection}
</section>
{overlay}
</> </>
); );
}; };
@@ -442,10 +516,6 @@ export const createDocumentViewerSurface = ({
return null; return null;
} }
const hasOcr = typeof getDocumentAsset === 'function'
? Boolean(getDocumentAsset(document, 'ocr-text'))
: false;
const sidebarToggle = typeof renderSidebarToggle === 'function' const sidebarToggle = typeof renderSidebarToggle === 'function'
? renderSidebarToggle() ? renderSidebarToggle()
: null; : null;
@@ -468,7 +538,6 @@ export const createDocumentViewerSurface = ({
onCorrespondentRemove={onCorrespondentRemove} onCorrespondentRemove={onCorrespondentRemove}
onUpdateTitle={onUpdateTitle} onUpdateTitle={onUpdateTitle}
onUpdateIssued={onUpdateIssued} onUpdateIssued={onUpdateIssued}
hasOcr={hasOcr}
ensureAssetUrl={ensureAssetUrl} ensureAssetUrl={ensureAssetUrl}
getDocumentAsset={getDocumentAsset} getDocumentAsset={getDocumentAsset}
ensurePreviewData={ensurePreviewData} ensurePreviewData={ensurePreviewData}
+2 -2
View File
@@ -347,8 +347,8 @@
display: flex; display: flex;
position: relative; position: relative;
overflow: hidden; overflow: hidden;
align-items: stretch; align-items: flex-start;
justify-content: center; justify-content: flex-start;
max-height: 100%; max-height: 100%;
grid-area: viewport; grid-area: viewport;
} }