+
+
![]()
+
+
@@ -317,7 +326,7 @@ import DocumentUpload from './DocumentUpload.vue'
import ConstructeurSelect from './ConstructeurSelect.vue'
import { useDocuments } from '~/composables/useDocuments'
import { getFileIcon } from '~/utils/fileIcons'
-import { canPreviewDocument, isImageDocument } from '~/utils/documentPreview'
+import { canPreviewDocument, isImageDocument, isPdfDocument } from '~/utils/documentPreview'
import DocumentPreviewModal from '~/components/DocumentPreviewModal.vue'
import IconLucideChevronRight from '~icons/lucide/chevron-right'
import { useCustomFields } from '~/composables/useCustomFields'
@@ -357,6 +366,40 @@ const componentDocuments = computed(() => props.component.documents || [])
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 childComponents = computed(() => {
const list = props.component.subcomponents || props.component.subComponents || []
diff --git a/app/components/ComponentStructureAssignmentNode.vue b/app/components/ComponentStructureAssignmentNode.vue
index fa9ed1d..15c3aab 100644
--- a/app/components/ComponentStructureAssignmentNode.vue
+++ b/app/components/ComponentStructureAssignmentNode.vue
@@ -228,16 +228,44 @@ watch(
const describePieceRequirement = (definition: ComponentModelPiece) => {
const parts: string[] = [];
- if (definition.role) {
- parts.push(definition.role);
+ const addPart = (value?: string | null) => {
+ const trimmed = typeof value === 'string' ? value.trim() : '';
+ if (trimmed && !parts.includes(trimmed)) {
+ parts.push(trimmed);
+ }
+ };
+
+ const options = getPieceOptions(definition);
+ const fallbackPiece = options[0] || null;
+ const fallbackType = fallbackPiece?.typePiece || null;
+
+ addPart(definition.role);
+ addPart(
+ definition.typePieceLabel ||
+ (definition as any).typePiece?.name ||
+ fallbackType?.name,
+ );
+
+ const family =
+ definition.familyCode ||
+ (definition as any).typePiece?.code ||
+ fallbackType?.code ||
+ null;
+ if (family) {
+ addPart(`Famille ${family}`);
}
- if (definition.typePieceLabel) {
- parts.push(definition.typePieceLabel);
- } else if ((definition as any).typePiece?.name) {
- parts.push((definition as any).typePiece.name);
- } else if (definition.familyCode) {
- parts.push(definition.familyCode);
+
+ if (parts.length === 0) {
+ addPart(fallbackType?.name);
+ if (fallbackType?.code) {
+ addPart(`Famille ${fallbackType.code}`);
+ }
}
+
+ if (parts.length === 0 && definition.typePieceId) {
+ addPart(`#${definition.typePieceId}`);
+ }
+
return parts.length ? parts.join(' • ') : 'Pièce du squelette';
};
diff --git a/app/components/PieceItem.vue b/app/components/PieceItem.vue
index f212b4f..9c709f5 100644
--- a/app/components/PieceItem.vue
+++ b/app/components/PieceItem.vue
@@ -276,13 +276,22 @@
class="flex items-center justify-between rounded border border-base-200 bg-base-100 px-3 py-2"
>
-
+
![]()
+
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 [];
diff --git a/app/components/StructureNodeEditor.vue b/app/components/StructureNodeEditor.vue
index 05433f7..1f15c9c 100644
--- a/app/components/StructureNodeEditor.vue
+++ b/app/components/StructureNodeEditor.vue
@@ -495,6 +495,8 @@ const addPiece = () => {
typePieceId: '',
typePieceLabel: '',
reference: '',
+ familyCode: '',
+ role: '',
})
}
diff --git a/app/pages/component/[id]/edit.vue b/app/pages/component/[id]/edit.vue
index b4ec582..e76a742 100644
--- a/app/pages/component/[id]/edit.vue
+++ b/app/pages/component/[id]/edit.vue
@@ -311,13 +311,22 @@
class="flex items-center justify-between rounded border border-base-200 bg-base-100 px-3 py-2"
>
-
+
![]()
+
{
const formatted = size / Math.pow(1024, index)
return `${formatted.toFixed(1)} ${units[index]}`
}
+const PDF_PREVIEW_MAX_BYTES = 5 * 1024 * 1024
+const shouldInlinePdf = (document: any) => {
+ 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: string) => {
+ 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: any) => {
+ if (!document?.path) {
+ return ''
+ }
+ if (isPdfDocument(document)) {
+ return appendPdfViewerParams(document.path)
+ }
+ return document.path
+}
+const documentThumbnailClass = (document: any) => {
+ if (shouldInlinePdf(document) || (isImageDocument(document) && document?.path)) {
+ return 'h-24 w-20'
+ }
+ return 'h-16 w-16'
+}
const openPreview = (doc: any) => {
if (!doc || !canPreviewDocument(doc)) {
return
@@ -944,8 +987,10 @@ const resolvePieceLabel = (piece: Record) => {
parts.push(piece.typePiece.name)
} else if (piece.typePieceLabel) {
parts.push(piece.typePieceLabel)
+ } else if (piece.typePiece?.code) {
+ parts.push(`Famille ${piece.typePiece.code}`)
} else if (piece.familyCode) {
- parts.push(piece.familyCode)
+ parts.push(`Famille ${piece.familyCode}`)
} else if (piece.typePieceId) {
parts.push(`#${piece.typePieceId}`)
}
diff --git a/app/pages/component/create.vue b/app/pages/component/create.vue
index 12ad6e8..92068c9 100644
--- a/app/pages/component/create.vue
+++ b/app/pages/component/create.vue
@@ -584,6 +584,7 @@ const sanitizePieceDefinition = (definition: ComponentModelPiece) =>
typePieceId: definition.typePieceId ?? null,
typePieceLabel: definition.typePieceLabel ?? null,
reference: definition.reference ?? null,
+ familyCode: (definition as any).familyCode ?? null,
})
const serializeStructureAssignments = (
@@ -697,8 +698,10 @@ const resolvePieceLabel = (piece: Record) => {
parts.push(piece.typePiece.name)
} else if (piece.typePieceLabel) {
parts.push(piece.typePieceLabel)
+ } else if (piece.typePiece?.code) {
+ parts.push(`Famille ${piece.typePiece.code}`)
} else if (piece.familyCode) {
- parts.push(piece.familyCode)
+ parts.push(`Famille ${piece.familyCode}`)
} else if (piece.typePieceId) {
parts.push(`#${piece.typePieceId}`)
}
diff --git a/app/pages/machine/[id].vue b/app/pages/machine/[id].vue
index f242297..a014807 100644
--- a/app/pages/machine/[id].vue
+++ b/app/pages/machine/[id].vue
@@ -86,9 +86,15 @@
rounded
>
-
{{ machine.typeMachine?.category || 'N/A' }}
-
{{ machine.site?.name }}
-
{{ machine.reference }}
+
+ {{ machine.typeMachine?.category }}
+
+
+ {{ machine.site?.name }}
+
+
+ {{ machine.reference }}
+
@@ -113,7 +119,7 @@
{{ machineName }}
-