diff --git a/app/components/DocumentThumbnail.vue b/app/components/DocumentThumbnail.vue
new file mode 100644
index 0000000..d35516b
--- /dev/null
+++ b/app/components/DocumentThumbnail.vue
@@ -0,0 +1,115 @@
+
+
+
![]()
+
+
+
+
+ —
+
+
+
+
diff --git a/app/pages/component-catalog.vue b/app/pages/component-catalog.vue
index cc73db3..f653435 100644
--- a/app/pages/component-catalog.vue
+++ b/app/pages/component-catalog.vue
@@ -91,6 +91,7 @@
+ | Aperçu |
Nom |
Catégorie |
Référence |
@@ -99,6 +100,12 @@
+ |
+
+ |
{{ component.name || 'Composant sans nom' }} |
{{ component.typeComposant?.name || '—' }} |
{{ component.reference || '—' }} |
@@ -134,6 +141,8 @@
import { computed, onMounted, ref } from 'vue'
import { useComposants } from '~/composables/useComposants'
import { useToast } from '~/composables/useToast'
+import DocumentThumbnail from '~/components/DocumentThumbnail.vue'
+import { isImageDocument, isPdfDocument } from '~/utils/documentPreview'
const { showError } = useToast()
const { composants, loadComposants, loading: loadingComposantsRef, deleteComposant } = useComposants()
@@ -145,6 +154,32 @@ const searchTerm = ref('')
const sortField = ref<'name' | 'createdAt'>('name')
const sortDirection = ref<'asc' | 'desc'>('asc')
+const resolvePrimaryDocument = (component: Record) => {
+ const documents = Array.isArray(component?.documents) ? component.documents : []
+ if (!documents.length) {
+ return null
+ }
+ const normalized = documents.filter((doc) => doc && typeof doc === 'object')
+ const withPath = normalized.filter((doc) => doc?.path)
+ const pdf = withPath.find((doc) => isPdfDocument(doc))
+ if (pdf) {
+ return pdf
+ }
+ const image = withPath.find((doc) => isImageDocument(doc))
+ if (image) {
+ return image
+ }
+ return withPath[0] ?? normalized[0] ?? null
+}
+
+const resolvePreviewAlt = (component: Record) => {
+ const parts = [component?.name, component?.reference].filter(Boolean)
+ if (parts.length) {
+ return `Aperçu du document de ${parts.join(' – ')}`
+ }
+ return 'Aperçu du document'
+}
+
const resolveComparableName = (component: Record) => {
const toComparable = (value?: string | null) =>
(value ?? '').toString().trim().toLowerCase()
diff --git a/app/pages/pieces-catalog.vue b/app/pages/pieces-catalog.vue
index 95265a1..6530c14 100644
--- a/app/pages/pieces-catalog.vue
+++ b/app/pages/pieces-catalog.vue
@@ -90,6 +90,7 @@
+ | Aperçu |
Nom |
Catégorie |
Référence |
@@ -98,6 +99,12 @@
+ |
+
+ |
{{ piece.name || 'Pièce sans nom' }} |
{{ piece.typePiece?.name || '—' }} |
{{ piece.reference || '—' }} |
@@ -133,6 +140,8 @@
import { computed, onMounted, ref } from 'vue'
import { usePieces } from '~/composables/usePieces'
import { useToast } from '~/composables/useToast'
+import DocumentThumbnail from '~/components/DocumentThumbnail.vue'
+import { isImageDocument, isPdfDocument } from '~/utils/documentPreview'
const { showError } = useToast()
const { pieces, loadPieces, loading: loadingPiecesRef, deletePiece } = usePieces()
@@ -144,6 +153,35 @@ const searchTerm = ref('')
const sortField = ref<'name' | 'createdAt'>('name')
const sortDirection = ref<'asc' | 'desc'>('asc')
+const resolvePrimaryDocument = (piece: Record) => {
+ const documents = Array.isArray(piece?.documents) ? piece.documents : []
+ if (!documents.length) {
+ return null
+ }
+ const normalized = documents.filter((doc) => doc && typeof doc === 'object')
+ const withPath = normalized.filter((doc) => doc?.path)
+
+ const pdf = withPath.find((doc) => isPdfDocument(doc))
+ if (pdf) {
+ return pdf
+ }
+
+ const image = withPath.find((doc) => isImageDocument(doc))
+ if (image) {
+ return image
+ }
+
+ return withPath[0] ?? normalized[0] ?? null
+}
+
+const resolvePreviewAlt = (piece: Record) => {
+ const parts = [piece?.name, piece?.reference].filter(Boolean)
+ if (parts.length) {
+ return `Aperçu du document de ${parts.join(' – ')}`
+ }
+ return 'Aperçu du document'
+}
+
const resolveComparableName = (piece: Record) => {
const normalise = (value?: string | null) =>
(value ?? '').toString().trim().toLowerCase()