frontend cleanup

This commit is contained in:
2025-10-30 18:17:01 +01:00
parent bb34a47fa8
commit 85f3d90329
7 changed files with 510 additions and 292 deletions
+75
View File
@@ -0,0 +1,75 @@
import { openOcrTextInNewTab } from '../utils/ocr';
const asyncFalse = async () => false;
const resolveDocumentDownloadHref = (document, resolveApiPath) => {
if (!document || typeof resolveApiPath !== 'function') {
return null;
}
const downloadPath = document.current_version?.download_path;
if (!downloadPath) {
return null;
}
return resolveApiPath(downloadPath);
};
const hasDocumentOcrAsset = (document, getDocumentAsset) => {
if (!document || typeof getDocumentAsset !== 'function') {
return false;
}
return Boolean(getDocumentAsset(document, 'ocr-text'));
};
export const createDocumentActionState = ({
document,
resolveApiPath,
ensurePreviewData,
ensureAssetUrl,
getDocumentAsset,
notifyApiError,
ocrErrorMessage = 'Unable to open OCR text.',
}) => {
if (!document) {
return {
downloadHref: null,
hasOcr: false,
openOcr: asyncFalse,
};
}
const downloadHref = resolveDocumentDownloadHref(document, resolveApiPath);
const hasOcr = hasDocumentOcrAsset(document, getDocumentAsset);
const openOcr = hasOcr
? async () => {
try {
const success = await openOcrTextInNewTab({
document,
ensurePreviewData,
getDocumentAsset,
ensureAssetUrl,
});
if (!success && typeof notifyApiError === 'function') {
notifyApiError(new Error('OCR text URL unavailable.'), ocrErrorMessage);
}
return success;
} catch (error) {
if (typeof notifyApiError === 'function') {
notifyApiError(error, ocrErrorMessage);
}
throw error;
}
}
: asyncFalse;
return {
downloadHref,
hasOcr,
openOcr,
};
};
export const documentActionsTestExports = {
resolveDocumentDownloadHref,
hasDocumentOcrAsset,
};
+140
View File
@@ -0,0 +1,140 @@
import { formatFileSize } from '../utils/format';
const defaultFormatDateTime = (value) => {
if (!value) {
return '—';
}
const date = new Date(value);
if (Number.isNaN(date.getTime())) {
return '—';
}
return date.toLocaleString();
};
const coercePageCount = (metadata) => {
const raw = metadata?.page_count;
if (typeof raw === 'number') {
return Number.isFinite(raw) && raw >= 0 ? raw : null;
}
if (raw != null && raw !== '') {
const parsed = Number.parseInt(raw, 10);
if (Number.isFinite(parsed) && parsed >= 0) {
return parsed;
}
}
return null;
};
const sanitizeTags = (tags) => {
if (!Array.isArray(tags)) {
return [];
}
return tags
.filter((tag) => tag && (tag.label || tag.id))
.map((tag) => ({
id: tag.id,
label: tag.label || '',
color: tag.color || null,
}));
};
const sanitizeCorrespondents = (entries) => {
if (!Array.isArray(entries)) {
return [];
}
return entries
.filter((entry) => entry && (entry.name || entry.id))
.map((entry) => ({
id: entry.id,
name: entry.name || '',
count: entry.count,
}));
};
export const describeDocumentSummary = (document, options = {}) => {
if (!document) {
return {
title: '',
originalName: '',
mimeTypeLabel: '—',
sizeLabel: '—',
uploadedAtLabel: '—',
issuedAtLabel: '—',
createdAtLabel: '—',
updatedAtLabel: '—',
pageCount: null,
pageCountLabel: '—',
folderLabel: null,
tags: [],
correspondents: [],
tagsSummary: '—',
correspondentsSummary: '—',
summaryRows: [],
};
}
const {
formatDateTime = defaultFormatDateTime,
} = options;
const title = document.title || '';
const originalName = document.original_name || '';
const mimeTypeLabel = document.content_type || 'Unknown';
const sizeBytes = Number(document.current_version?.size_bytes);
const sizeLabel = Number.isFinite(sizeBytes) && sizeBytes > 0 ? formatFileSize(sizeBytes) : '—';
const metadata = document.current_version?.metadata || null;
const pageCount = coercePageCount(metadata);
const pageCountLabel = Number.isFinite(pageCount) ? String(pageCount) : '—';
const uploadedAtLabel = formatDateTime(document.uploaded_at);
const issuedAtLabel = formatDateTime(document.issued_at);
const createdAtLabel = formatDateTime(document.created_at);
const updatedAtLabel = formatDateTime(document.updated_at);
const folderLabel = document.folder_path || document.folder_name || null;
const tags = sanitizeTags(document.tags);
const correspondents = sanitizeCorrespondents(document.correspondents);
const tagLabels = tags.map((tag) => tag.label).filter(Boolean);
const correspondentLabels = correspondents.map((entry) => entry.name).filter(Boolean);
const tagsSummary = tagLabels.length ? tagLabels.join(', ') : '—';
const correspondentsSummary = correspondentLabels.length
? correspondentLabels.join(', ')
: '—';
const summaryRows = [
{ key: 'uploaded', label: 'Uploaded', value: uploadedAtLabel },
{ key: 'size', label: 'Size', value: sizeLabel },
{ key: 'type', label: 'Type', value: mimeTypeLabel },
{ key: 'issued', label: 'Issued', value: issuedAtLabel },
{ key: 'pages', label: 'Pages', value: pageCountLabel },
{ key: 'created', label: 'Created', value: createdAtLabel },
{ key: 'updated', label: 'Updated', value: updatedAtLabel },
{ key: 'folder', label: 'Folder', value: folderLabel || '—' },
{ key: 'tags', label: 'Tags', value: tagsSummary },
{ key: 'correspondents', label: 'Correspondents', value: correspondentsSummary },
];
return {
title,
originalName,
mimeTypeLabel,
sizeLabel,
uploadedAtLabel,
issuedAtLabel,
createdAtLabel,
updatedAtLabel,
pageCount,
pageCountLabel,
folderLabel,
tags,
correspondents,
tagsSummary,
correspondentsSummary,
summaryRows,
};
};