guts
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
import React, { useCallback, useEffect, useMemo } from 'react';
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import {
|
||||
DownloadIcon,
|
||||
DetailPanelCollapseIcon,
|
||||
WindowMaximizeIcon,
|
||||
IconZoomInArea,
|
||||
} from '../ui/icons';
|
||||
import PanelHeader from '../ui/PanelHeader';
|
||||
import { resolveDocumentAssetUrl } from '../asset_manager';
|
||||
@@ -12,6 +13,8 @@ import { sortCorrespondents, buildCorrespondentOptions } from '../documents/Docu
|
||||
import BreadcrumbTrail from '../ui/BreadcrumbTrail';
|
||||
import { extractDocumentMetadataPayload } from '../documents/documentMetadata';
|
||||
import DocumentViewerLayout from '../preview/DocumentViewerLayout';
|
||||
import PreviewZoomOverlay from './PreviewZoomOverlay';
|
||||
import { useAssetNavigator } from '../hooks/useAssetNavigator';
|
||||
|
||||
const DetailPanel = ({
|
||||
document = null,
|
||||
@@ -35,6 +38,19 @@ const DetailPanel = ({
|
||||
onClose = () => {},
|
||||
}) => {
|
||||
const singleDoc = document || null;
|
||||
const [zoomOverlayOpen, setZoomOverlayOpen] = useState(false);
|
||||
const previewNavigator = useAssetNavigator({
|
||||
document: singleDoc,
|
||||
assetType: 'preview',
|
||||
ensureAssetUrl,
|
||||
getAsset: getDocumentAsset,
|
||||
prefetch: 3,
|
||||
});
|
||||
const navigatorUrl = previewNavigator?.currentUrl;
|
||||
const navigatorCanGoPrev = Boolean(previewNavigator?.canGoPrev);
|
||||
const navigatorCanGoNext = Boolean(previewNavigator?.canGoNext);
|
||||
const navigatorGoPrev = previewNavigator?.goPrev;
|
||||
const navigatorGoNext = previewNavigator?.goNext;
|
||||
|
||||
const { downloadHref: singleDownloadHref } = useMemo(
|
||||
() =>
|
||||
@@ -199,15 +215,19 @@ const DetailPanel = ({
|
||||
}
|
||||
|
||||
return (
|
||||
<section className="document-viewer document-viewer--stacked">
|
||||
<DocumentViewerLayout
|
||||
document={singleDoc}
|
||||
previewEntry={previewEntry}
|
||||
summaryProps={singleSummaryProps}
|
||||
metadataPayload={singleMetadataPayload}
|
||||
contentTabConfig={singleContentConfig}
|
||||
previewLoadingMessage="Loading preview…"
|
||||
/>
|
||||
<section className="document-viewer-panel document-viewer-panel--stacked">
|
||||
<div className="document-viewer-panel__body">
|
||||
<section className="document-viewer document-viewer--stacked">
|
||||
<DocumentViewerLayout
|
||||
document={singleDoc}
|
||||
previewEntry={previewEntry}
|
||||
summaryProps={singleSummaryProps}
|
||||
metadataPayload={singleMetadataPayload}
|
||||
contentTabConfig={singleContentConfig}
|
||||
previewLoadingMessage="Loading preview…"
|
||||
/>
|
||||
</section>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
@@ -264,27 +284,83 @@ const DetailPanel = ({
|
||||
);
|
||||
}
|
||||
|
||||
const zoomDisplay = useMemo(() => {
|
||||
if (navigatorUrl && singleDoc) {
|
||||
return {
|
||||
url: navigatorUrl,
|
||||
alt: singleDoc.title,
|
||||
canGoPrev: navigatorCanGoPrev,
|
||||
canGoNext: navigatorCanGoNext,
|
||||
goPrev: navigatorCanGoPrev ? navigatorGoPrev : undefined,
|
||||
goNext: navigatorCanGoNext ? navigatorGoNext : undefined,
|
||||
};
|
||||
}
|
||||
if (singleDoc && previewEntry?.url) {
|
||||
return {
|
||||
url: previewEntry.url,
|
||||
alt: singleDoc.title,
|
||||
canGoPrev: false,
|
||||
canGoNext: false,
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}, [
|
||||
navigatorUrl,
|
||||
navigatorCanGoPrev,
|
||||
navigatorCanGoNext,
|
||||
navigatorGoPrev,
|
||||
navigatorGoNext,
|
||||
singleDoc,
|
||||
previewEntry?.url,
|
||||
]);
|
||||
|
||||
if (singleDoc && zoomDisplay) {
|
||||
headerActions.push(
|
||||
<button
|
||||
key="zoom"
|
||||
type="button"
|
||||
className="icon-button"
|
||||
onClick={() => setZoomOverlayOpen(true)}
|
||||
aria-label="Open zoom preview"
|
||||
title="Open zoom preview"
|
||||
>
|
||||
<IconZoomInArea />
|
||||
</button>,
|
||||
);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
setZoomOverlayOpen(false);
|
||||
}, [previewEntry?.url, singleDoc?.id]);
|
||||
|
||||
return (
|
||||
<aside className="detail-panel panel">
|
||||
<PanelHeader
|
||||
leading={headerLeading}
|
||||
title={
|
||||
headerBreadcrumbs ? (
|
||||
<BreadcrumbTrail
|
||||
entries={headerBreadcrumbs}
|
||||
separator="/"
|
||||
className="panel-header__breadcrumbs"
|
||||
truncateFromStart
|
||||
/>
|
||||
) : (
|
||||
headerTitle
|
||||
)
|
||||
}
|
||||
titleTag="h3"
|
||||
actions={headerActions.length ? headerActions : null}
|
||||
<>
|
||||
<aside className="detail-panel panel">
|
||||
<PanelHeader
|
||||
leading={headerLeading}
|
||||
title={
|
||||
headerBreadcrumbs ? (
|
||||
<BreadcrumbTrail
|
||||
entries={headerBreadcrumbs}
|
||||
separator="/"
|
||||
className="panel-header__breadcrumbs"
|
||||
truncateFromStart
|
||||
/>
|
||||
) : (
|
||||
headerTitle
|
||||
)
|
||||
}
|
||||
titleTag="h3"
|
||||
actions={headerActions.length ? headerActions : null}
|
||||
/>
|
||||
<div className="panel-body detail-panel__content">{renderContent()}</div>
|
||||
</aside>
|
||||
<PreviewZoomOverlay
|
||||
open={Boolean(zoomOverlayOpen && zoomDisplay)}
|
||||
display={zoomDisplay}
|
||||
onClose={() => setZoomOverlayOpen(false)}
|
||||
/>
|
||||
<div className="panel-body">{renderContent()}</div>
|
||||
</aside>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ import {
|
||||
const useDetailWorkspace = ({
|
||||
documents,
|
||||
searchResults,
|
||||
focusedDocumentId,
|
||||
selectionOrder,
|
||||
selectedDocumentIds,
|
||||
documentLookup,
|
||||
@@ -37,14 +36,6 @@ const useDetailWorkspace = ({
|
||||
tags,
|
||||
tagLookupById,
|
||||
}) => {
|
||||
const selectedDocument = useMemo(() => {
|
||||
if (!focusedDocumentId) {
|
||||
return null;
|
||||
}
|
||||
const pool = searchResults ?? documents;
|
||||
return pool.find((doc) => doc.id === focusedDocumentId) || null;
|
||||
}, [focusedDocumentId, searchResults, documents]);
|
||||
|
||||
const orderedSelectedDocuments = useMemo(() => {
|
||||
const ordered = [];
|
||||
const seen = new Set();
|
||||
@@ -185,12 +176,12 @@ const useDetailWorkspace = ({
|
||||
[folderNodes],
|
||||
);
|
||||
|
||||
const selectedPreviewEntry = useMemo(() => {
|
||||
if (!selectedDocument) {
|
||||
const detailPanelPreviewEntry = useMemo(() => {
|
||||
if (!detailPanelDocument) {
|
||||
return null;
|
||||
}
|
||||
return previewEntries.get(selectedDocument.id) || null;
|
||||
}, [selectedDocument, previewEntries]);
|
||||
return previewEntries.get(detailPanelDocument.id) || null;
|
||||
}, [detailPanelDocument, previewEntries]);
|
||||
|
||||
const previewWorkspaceEntry = useMemo(() => {
|
||||
if (!previewDocumentId) {
|
||||
@@ -239,7 +230,7 @@ const useDetailWorkspace = ({
|
||||
tagLookupById,
|
||||
onTagAdd: handleDocumentTagAdd,
|
||||
onTagRemove: handleTagRemove,
|
||||
previewEntry: selectedPreviewEntry,
|
||||
previewEntry: detailPanelPreviewEntry,
|
||||
onOpenPreview: openDocumentPreview,
|
||||
activePreviewId,
|
||||
onUpdateTitle: handleDocumentTitleUpdate,
|
||||
@@ -273,7 +264,7 @@ const useDetailWorkspace = ({
|
||||
resolveApiPath,
|
||||
resolveFolderPath,
|
||||
selectFolder,
|
||||
selectedPreviewEntry,
|
||||
detailPanelPreviewEntry,
|
||||
tags,
|
||||
tagLookupById,
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user