hydration

This commit is contained in:
2025-11-11 10:50:57 +01:00
parent 6ae497323e
commit 2dd786ce14
4 changed files with 160 additions and 475 deletions
@@ -0,0 +1,105 @@
import React, { useMemo } from 'react';
import DocumentInfoPanel from '../documents/DocumentInfoPanel';
import { DownloadIcon } from '../ui/icons';
const DocumentViewerLayout = ({
document,
previewEntry,
summaryProps,
metadataPayload,
contentTabConfig,
resetKey,
classNamePrefix = 'document-viewer',
defaultTabId = 'details',
infoPanelProps = {},
previewLoadingMessage = 'Preparing preview…',
}) => {
const previewContent = useMemo(() => {
if (!document || !previewEntry?.url) {
return null;
}
const normalizedContentType = (previewEntry.contentType
|| document.content_type
|| '')
.toLowerCase();
const isImage = normalizedContentType.startsWith('image/');
const isPdf = normalizedContentType === 'application/pdf'
|| normalizedContentType === 'application/x-pdf';
if (isImage) {
return (
<img
src={previewEntry.url}
alt={`Preview of ${document.title}`}
className="document-viewer__object document-viewer__object--image"
draggable={false}
/>
);
}
if (isPdf) {
return (
<iframe
src={previewEntry.url}
title={`Preview of ${document.title}`}
className="document-viewer__object"
/>
);
}
const displayContentType = document.content_type || previewEntry.contentType || 'this file type';
const displayFilename = previewEntry.filename
|| document.filename
|| document.original_name
|| 'download';
return (
<div className="document-viewer__unsupported">
<div className="document-viewer__unsupported-message">
Preview is not available for {displayContentType} files.
</div>
<div className="document-viewer__unsupported-filename">{displayFilename}</div>
<a
className="button-link document-viewer__unsupported-download"
href={previewEntry.url}
download={displayFilename}
target="_blank"
rel="noopener noreferrer"
>
<DownloadIcon />
<span>Download</span>
</a>
</div>
);
}, [previewEntry, document]);
return (
<>
<div className="document-viewer__details-pane">
<div className="document-viewer__details">
<DocumentInfoPanel
document={document}
summaryProps={summaryProps}
metadataPayload={metadataPayload}
contentConfig={contentTabConfig}
defaultTabId={defaultTabId}
classNamePrefix={classNamePrefix}
hideTabNavWhenSingle={false}
resetKey={resetKey || document?.id}
{...infoPanelProps}
/>
</div>
</div>
<div className="document-viewer__viewport">
{!previewEntry?.url ? (
<div className="document-viewer__message">{previewLoadingMessage}</div>
) : (
previewContent
)}
</div>
</>
);
};
export default DocumentViewerLayout;
+9 -82
View File
@@ -11,10 +11,10 @@ import {
buildCorrespondentOptions,
sortCorrespondents,
} from '../documents/DocumentSummarySection';
import DocumentInfoPanel from '../documents/DocumentInfoPanel';
import { extractDocumentMetadataPayload } from '../documents/documentMetadata';
import { createDocumentActionState } from '../documents/documentActions';
import { resolveDocumentAssetUrl } from '../asset_manager';
import DocumentViewerLayout from './DocumentViewerLayout';
const PORTRAIT_WIDTH_TO_HEIGHT = 1 / Math.sqrt(2); // ≈0.707 (A-series aspect ratio)
const DOCUMENT_VIEWER_PORTRAIT_HEIGHT_RATIO = 0.6;
@@ -83,66 +83,6 @@ const DocumentViewerPanel = ({
[correspondents],
);
const previewContent = useMemo(() => {
if (!document || !previewEntry?.url) {
return null;
}
const normalizedContentType = (previewEntry.contentType
|| document.content_type
|| '')
.toLowerCase();
const isImage = normalizedContentType.startsWith('image/');
const isPdf = normalizedContentType === 'application/pdf'
|| normalizedContentType === 'application/x-pdf';
if (isImage) {
return (
<img
src={previewEntry.url}
alt={`Preview of ${document.title}`}
className="document-viewer__object document-viewer__object--image"
draggable={false}
/>
);
}
if (isPdf) {
return (
<iframe
src={previewEntry.url}
title={`Preview of ${document.title}`}
className="document-viewer__object"
/>
);
}
const displayContentType = document.content_type || previewEntry.contentType || 'this file type';
const displayFilename = previewEntry.filename
|| document.filename
|| document.original_name
|| 'download';
return (
<div className="document-viewer__unsupported">
<div className="document-viewer__unsupported-message">
Preview is not available for {displayContentType} files.
</div>
<div className="document-viewer__unsupported-filename">{displayFilename}</div>
<a
className="button-link document-viewer__unsupported-download"
href={previewEntry.url}
download={displayFilename}
target="_blank"
rel="noopener noreferrer"
>
<DownloadIcon />
<span>Download</span>
</a>
</div>
);
}, [previewEntry, document]);
const metadataPayload = useMemo(
() => extractDocumentMetadataPayload(document),
[document],
@@ -316,27 +256,14 @@ const DocumentViewerPanel = ({
return (
<section className={viewerClassName} ref={viewerRef}>
<div className="document-viewer__details-pane">
<div className="document-viewer__details">
<DocumentInfoPanel
document={document}
summaryProps={summaryProps}
metadataPayload={metadataPayload}
contentConfig={contentTabConfig}
defaultTabId="details"
classNamePrefix="document-viewer"
hideTabNavWhenSingle={false}
resetKey={document?.id}
/>
</div>
</div>
<div className="document-viewer__viewport">
{!previewEntry?.url ? (
<div className="document-viewer__message">Loading preview</div>
) : (
previewContent
)}
</div>
<DocumentViewerLayout
document={document}
previewEntry={previewEntry}
summaryProps={summaryProps}
metadataPayload={metadataPayload}
contentTabConfig={contentTabConfig}
previewLoadingMessage="Loading preview…"
/>
</section>
);
};