feat: enrich piece assignment labels and document previews

This commit is contained in:
Matthieu
2025-10-23 09:01:38 +02:00
parent 553600c34b
commit 417b34b45e
11 changed files with 364 additions and 51 deletions

View File

@@ -276,13 +276,22 @@
class="flex items-center justify-between rounded border border-base-200 bg-base-100 px-3 py-2"
>
<div class="flex items-center gap-3 text-sm">
<div class="h-14 w-14 flex-shrink-0 overflow-hidden rounded-md border border-base-200 bg-base-200/70 flex items-center justify-center">
<div
class="flex-shrink-0 overflow-hidden rounded-md border border-base-200 bg-base-200/70 flex items-center justify-center"
:class="documentThumbnailClass(document)"
>
<img
v-if="isImageDocument(document) && document.path"
:src="document.path"
class="h-full w-full object-cover"
:alt="`Aperçu de ${document.name}`"
>
<iframe
v-else-if="shouldInlinePdf(document)"
:src="documentPreviewSrc(document)"
class="h-full w-full border-0 bg-white"
title="Aperçu PDF"
/>
<component
v-else
:is="documentIcon(document).component"
@@ -348,7 +357,7 @@ import { useCustomFields } from "~/composables/useCustomFields";
import { useToast } from "~/composables/useToast";
import { useDocuments } from "~/composables/useDocuments";
import { getFileIcon } from "~/utils/fileIcons";
import { canPreviewDocument, isImageDocument } from "~/utils/documentPreview";
import { canPreviewDocument, isImageDocument, isPdfDocument } from "~/utils/documentPreview";
import DocumentUpload from "~/components/DocumentUpload.vue";
import DocumentPreviewModal from "~/components/DocumentPreviewModal.vue";
import IconLucidePackage from "~icons/lucide/package";
@@ -388,6 +397,40 @@ const documentIcon = (doc) =>
getFileIcon({ name: doc.filename || doc.name, mime: doc.mimeType });
const previewDocument = ref(null);
const previewVisible = ref(false);
const PDF_PREVIEW_MAX_BYTES = 5 * 1024 * 1024;
const shouldInlinePdf = (document) => {
if (!document || !isPdfDocument(document) || !document.path) {
return false;
}
if (typeof document.size === "number" && document.size > PDF_PREVIEW_MAX_BYTES) {
return false;
}
return true;
};
const appendPdfViewerParams = (src) => {
if (!src || src.startsWith("data:")) {
return src || "";
}
if (src.includes("#")) {
return `${src}&toolbar=0&navpanes=0`;
}
return `${src}#toolbar=0&navpanes=0`;
};
const documentPreviewSrc = (document) => {
if (!document?.path) {
return "";
}
if (isPdfDocument(document)) {
return appendPdfViewerParams(document.path);
}
return document.path;
};
const documentThumbnailClass = (document) => {
if (shouldInlinePdf(document) || (isImageDocument(document) && document?.path)) {
return "h-24 w-20";
}
return "h-16 w-16";
};
const extractStructureCustomFields = (structure) => {
if (!structure || typeof structure !== "object") {
return [];