frontend cleanup
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import { formatFileSize } from '../utils/format';
|
||||
import { DownloadIcon, TextScanIcon, AnalyzeIcon, CloseIcon } from '../ui/icons';
|
||||
import { openOcrTextInNewTab } from '../utils/ocr';
|
||||
import { describeDocumentSummary } from '../documents/documentSummary';
|
||||
import { createDocumentActionState } from '../documents/documentActions';
|
||||
|
||||
const PreviewWorkspace = ({
|
||||
document,
|
||||
@@ -12,53 +12,43 @@ const PreviewWorkspace = ({
|
||||
}
|
||||
|
||||
const title = document.title;
|
||||
const mime = document.content_type;
|
||||
const sizeBytes = Number(document.current_version?.size_bytes) || 0;
|
||||
const sizeLabel = sizeBytes > 0 ? formatFileSize(sizeBytes) : null;
|
||||
const summary = describeDocumentSummary(document);
|
||||
const baseSummaryRows = summary.summaryRows.filter((row) => {
|
||||
if (row.key === 'pages') {
|
||||
return Number.isFinite(summary.pageCount);
|
||||
}
|
||||
if (row.key === 'folder') {
|
||||
return Boolean(summary.folderLabel);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
const summaryRows = [
|
||||
...baseSummaryRows,
|
||||
{
|
||||
key: 'original-name',
|
||||
label: 'Original filename',
|
||||
value: document.original_name || '—',
|
||||
},
|
||||
];
|
||||
const metadata =
|
||||
document.metadata && Object.keys(document.metadata).length > 0 ? document.metadata : null;
|
||||
const folderName = document.folder_path || document.folder_name || null;
|
||||
const issuedAt = document.issued_at || null;
|
||||
const createdAt = document.created_at || null;
|
||||
const updatedAt = document.updated_at || null;
|
||||
const tags = Array.isArray(document.tags) ? document.tags : [];
|
||||
const correspondents = Array.isArray(document.correspondents) ? document.correspondents : [];
|
||||
|
||||
const metadataSummary = (() => {
|
||||
const rows = [];
|
||||
if (mime) rows.push(['Type', mime]);
|
||||
if (sizeLabel) rows.push(['Size', sizeLabel]);
|
||||
if (issuedAt) rows.push(['Issued', new Date(issuedAt).toLocaleString()]);
|
||||
if (createdAt) rows.push(['Created', new Date(createdAt).toLocaleString()]);
|
||||
if (updatedAt) rows.push(['Updated', new Date(updatedAt).toLocaleString()]);
|
||||
if (folderName) rows.push(['Folder', folderName]);
|
||||
if (tags.length) {
|
||||
rows.push(['Tags', tags.map((tag) => tag.label).filter(Boolean).join(', ')]);
|
||||
}
|
||||
if (correspondents.length) {
|
||||
rows.push([
|
||||
'Correspondents',
|
||||
correspondents
|
||||
.map((entry) => entry.name)
|
||||
.filter(Boolean)
|
||||
.join(', '),
|
||||
]);
|
||||
}
|
||||
return rows;
|
||||
})();
|
||||
|
||||
return (
|
||||
<section className="preview-workspace">
|
||||
<aside className="preview-workspace__sidebar">
|
||||
<div className="preview-workspace__info">
|
||||
{metadataSummary.length ? (
|
||||
{summaryRows.length ? (
|
||||
<dl className="preview-workspace__summary">
|
||||
{metadataSummary.map(([label, value]) => (
|
||||
<div className="preview-workspace__summary-row" key={label}>
|
||||
<dt>{label}</dt>
|
||||
<dd>{value || '—'}</dd>
|
||||
</div>
|
||||
))}
|
||||
{summaryRows.map(({ key, label, value }) => {
|
||||
const displayValue =
|
||||
value === null || value === undefined || value === '' ? '—' : value;
|
||||
return (
|
||||
<div className="preview-workspace__summary-row" key={key}>
|
||||
<dt>{label}</dt>
|
||||
<dd>{displayValue}</dd>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</dl>
|
||||
) : null}
|
||||
</div>
|
||||
@@ -89,6 +79,7 @@ export default PreviewWorkspace;
|
||||
export const createPreviewWorkspaceHeaderActions = ({
|
||||
document,
|
||||
ensureAssetUrl,
|
||||
ensurePreviewData,
|
||||
getDocumentAsset,
|
||||
resolveApiPath,
|
||||
notifyApiError,
|
||||
@@ -98,27 +89,15 @@ export const createPreviewWorkspaceHeaderActions = ({
|
||||
return null;
|
||||
}
|
||||
|
||||
const downloadHref = document.current_version?.download_path
|
||||
? resolveApiPath(document.current_version.download_path)
|
||||
: null;
|
||||
|
||||
const ocrAsset = getDocumentAsset(document, 'ocr-text');
|
||||
const hasOcr = Boolean(ocrAsset);
|
||||
|
||||
const handleOcrClick = async () => {
|
||||
try {
|
||||
const success = await openOcrTextInNewTab({
|
||||
document,
|
||||
getDocumentAsset,
|
||||
ensureAssetUrl,
|
||||
});
|
||||
if (!success) {
|
||||
throw new Error('OCR text URL unavailable.');
|
||||
}
|
||||
} catch (error) {
|
||||
notifyApiError(error, 'Unable to open OCR text.');
|
||||
}
|
||||
};
|
||||
const { downloadHref, hasOcr, openOcr } = createDocumentActionState({
|
||||
document,
|
||||
resolveApiPath,
|
||||
ensurePreviewData,
|
||||
ensureAssetUrl,
|
||||
getDocumentAsset,
|
||||
notifyApiError,
|
||||
ocrErrorMessage: 'Unable to open OCR text.',
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -138,7 +117,9 @@ export const createPreviewWorkspaceHeaderActions = ({
|
||||
<button
|
||||
type="button"
|
||||
className="icon-button"
|
||||
onClick={handleOcrClick}
|
||||
onClick={() => {
|
||||
openOcr().catch(() => {});
|
||||
}}
|
||||
aria-label="View OCR text"
|
||||
title="View OCR text"
|
||||
>
|
||||
@@ -162,6 +143,7 @@ export const createPreviewSurface = ({
|
||||
document,
|
||||
previewEntry,
|
||||
ensureAssetUrl,
|
||||
ensurePreviewData,
|
||||
getDocumentAsset,
|
||||
resolveApiPath,
|
||||
notifyApiError,
|
||||
@@ -174,7 +156,6 @@ export const createPreviewSurface = ({
|
||||
}
|
||||
|
||||
const title = document.title;
|
||||
const sidebarToggle = renderSidebarToggle ? renderSidebarToggle() : null;
|
||||
const closeButton = onClose
|
||||
? (
|
||||
<button
|
||||
@@ -188,7 +169,8 @@ export const createPreviewSurface = ({
|
||||
</button>
|
||||
)
|
||||
: null;
|
||||
const leading = sidebarToggle || closeButton
|
||||
const sidebarToggle = renderSidebarToggle ? renderSidebarToggle() : null;
|
||||
const leading = closeButton || sidebarToggle
|
||||
? (
|
||||
<>
|
||||
{sidebarToggle}
|
||||
@@ -203,6 +185,7 @@ export const createPreviewSurface = ({
|
||||
actions: createPreviewWorkspaceHeaderActions({
|
||||
document,
|
||||
ensureAssetUrl,
|
||||
ensurePreviewData,
|
||||
getDocumentAsset,
|
||||
resolveApiPath,
|
||||
notifyApiError,
|
||||
|
||||
Reference in New Issue
Block a user