From 9319eb8171d3e68fc7133e9f00ea9eff13d7b4f4 Mon Sep 17 00:00:00 2001 From: lizerk Date: Wed, 3 Jun 2026 10:05:31 +0300 Subject: [PATCH] Add document preview support --- frontend/src/app/documents/page.tsx | 110 ++- .../documents/DocumentDetailModal.tsx | 41 +- .../components/documents/DocumentPreview.tsx | 869 ++++++++++-------- 3 files changed, 602 insertions(+), 418 deletions(-) diff --git a/frontend/src/app/documents/page.tsx b/frontend/src/app/documents/page.tsx index 48e5bbd9..aa6f263c 100644 --- a/frontend/src/app/documents/page.tsx +++ b/frontend/src/app/documents/page.tsx @@ -62,6 +62,99 @@ function formatDate(value?: string): string { }); } +const DOCUMENT_PREVIEW_EXTENSIONS = new Set([ + "pdf", + "jpg", + "jpeg", + "png", + "gif", + "webp", + "svg", + "bmp", + "ico", + "avif", + "docx", + "xls", + "xlsx", + "xlsm", + "xlsb", + "ods", + "csv", + "tsv", + "txt", + "text", + "md", + "markdown", + "json", + "xml", + "html", + "htm", + "css", + "scss", + "sass", + "less", + "js", + "jsx", + "ts", + "tsx", + "mjs", + "cjs", + "yml", + "yaml", + "ini", + "conf", + "cfg", + "log", + "sql", + "py", + "java", + "c", + "cpp", + "h", + "hpp", + "cs", + "go", + "rs", + "php", + "rb", + "kt", + "kts", + "swift", + "sh", + "bash", + "zsh", + "ps1", + "bat", + "cmd", + "properties", + "env", + "rtf", + "mp4", + "webm", + "ogg", + "ogv", + "mov", + "m4v", + "mp3", + "wav", + "oga", + "m4a", + "aac", + "flac", +]); +const DOCUMENT_PREVIEW_FILE_NAMES = new Set(["dockerfile", "makefile", "readme", "license", ".gitignore", ".env"]); + +function getDocumentFileExtension(fileName?: string | null): string { + const cleanName = (fileName || "").toLowerCase().split("?")[0].split("#")[0]; + return cleanName.match(/\.([^.]+)$/)?.[1] || ""; +} + +function canPreviewDocument(fileName?: string | null): boolean { + const lowerName = (fileName || "").toLowerCase(); + const extension = getDocumentFileExtension(fileName); + return DOCUMENT_PREVIEW_EXTENSIONS.has(extension) || DOCUMENT_PREVIEW_FILE_NAMES.has(lowerName); +} + function formatFileSize(value?: number): string { if (!value || value <= 0) return ""; if (value < 1024) return `${value} Б`; @@ -549,12 +642,17 @@ function DocumentsPageContent() { setDocumentMenuOpenId(null); }; - const openDocumentPdfFromMenu = (documentItem: Document) => { + const openDocumentPreviewFromMenu = (documentItem: Document) => { if (!documentItem.file_url) return; - setPdfViewerFile({ + const previewFile = { url: documentItem.file_url, name: documentItem.file_name || documentItem.title, - }); + }; + if (getDocumentFileExtension(documentItem.file_name) === "pdf") { + setPdfViewerFile(previewFile); + } else { + setPreviewFile(previewFile); + } setDocumentMenuOpenId(null); }; @@ -1129,7 +1227,7 @@ function DocumentsPageContent() { const fileSize = formatFileSize(doc.file_size); const recipientsCount = doc.recipients?.length || 0; const departmentsCount = doc.departments?.length || 0; - const hasPreview = Boolean(doc.file_url && doc.file_name?.toLowerCase().endsWith(".pdf")); + const hasPreview = Boolean(doc.file_url && canPreviewDocument(doc.file_name || doc.title)); // DEBUG: Проверка данных документа if (!authorName || !createdDate) { @@ -1309,11 +1407,11 @@ function DocumentsPageContent() { {hasPreview && ( )} diff --git a/frontend/src/components/documents/DocumentDetailModal.tsx b/frontend/src/components/documents/DocumentDetailModal.tsx index 8370dd33..606f69a7 100644 --- a/frontend/src/components/documents/DocumentDetailModal.tsx +++ b/frontend/src/components/documents/DocumentDetailModal.tsx @@ -28,13 +28,13 @@ import { import { DocumentAcknowledgement } from "./DocumentAcknowledgement"; import { DocumentComments } from "./DocumentComments"; import { DocumentRelated } from "./DocumentRelated"; +import { DocumentPreviewPane } from "./DocumentPreview"; interface DocumentDetailModalProps { document: Document | null; isOpen: boolean; onClose: () => void; onUpdate?: () => void; - onPreview?: (url: string, name: string) => void; onEditMetadata?: () => void; onViewReport?: () => void; onNavigateToRelated?: (docId: number) => void; @@ -47,7 +47,6 @@ export function DocumentDetailModal({ isOpen, onClose, onUpdate, - onPreview, onEditMetadata, onViewReport, onNavigateToRelated, @@ -94,41 +93,11 @@ export function DocumentDetailModal({ ); } - const fileExt = document.file_name?.toLowerCase().split(".").pop() || ""; - const isImage = ["jpg", "jpeg", "png", "gif", "webp", "svg", "bmp"].includes(fileExt); - const isPDF = fileExt === "pdf"; - - if (isImage) { - return ( -
- {document.file_name -
- ); - } - - if (isPDF) { - return ( -