feat: show product thumbnails in catalogue list
Display the primary product document (image/pdf) as the leading column in the catalogue table for quicker visual identification.
This commit is contained in:
@@ -91,6 +91,7 @@
|
||||
<table class="table table-sm md:table-md">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="w-16">Aperçu</th>
|
||||
<th>Nom</th>
|
||||
<th>Référence</th>
|
||||
<th>Type de produit</th>
|
||||
@@ -101,6 +102,12 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="product in filteredProducts" :key="product.id">
|
||||
<td class="align-middle">
|
||||
<DocumentThumbnail
|
||||
:document="resolvePrimaryDocument(product)"
|
||||
:alt="resolvePreviewAlt(product)"
|
||||
/>
|
||||
</td>
|
||||
<td class="font-medium">{{ product.name }}</td>
|
||||
<td>{{ product.reference || '—' }}</td>
|
||||
<td>{{ product.typeProduct?.name || '—' }}</td>
|
||||
@@ -142,6 +149,8 @@ import { computed, onMounted, ref } from 'vue'
|
||||
import { useHead } from '#imports'
|
||||
import { useProducts } from '~/composables/useProducts'
|
||||
import { useToast } from '~/composables/useToast'
|
||||
import DocumentThumbnail from '~/components/DocumentThumbnail.vue'
|
||||
import { isImageDocument, isPdfDocument } from '~/utils/documentPreview'
|
||||
|
||||
useHead(() => ({
|
||||
title: 'Catalogue des produits',
|
||||
@@ -230,6 +239,35 @@ const formatConstructeurs = (constructeurs: Array<Record<string, any>>) =>
|
||||
.filter((name): name is string => Boolean(name))
|
||||
.join(', ')
|
||||
|
||||
const resolvePrimaryDocument = (product: Record<string, any>) => {
|
||||
const documents = Array.isArray(product?.documents) ? product.documents : []
|
||||
if (!documents.length) {
|
||||
return null
|
||||
}
|
||||
const normalized = documents.filter((doc) => doc && typeof doc === 'object')
|
||||
const withPath = normalized.filter((doc) => doc?.path)
|
||||
if (!withPath.length) {
|
||||
return normalized[0] ?? null
|
||||
}
|
||||
const images = withPath.filter((doc) => isImageDocument(doc))
|
||||
if (images.length) {
|
||||
return images[0]
|
||||
}
|
||||
const pdf = withPath.find((doc) => isPdfDocument(doc))
|
||||
if (pdf) {
|
||||
return pdf
|
||||
}
|
||||
return withPath[0]
|
||||
}
|
||||
|
||||
const resolvePreviewAlt = (product: Record<string, any>) => {
|
||||
const parts = [product?.name, product?.reference].filter(Boolean)
|
||||
if (parts.length) {
|
||||
return `Aperçu du document de ${parts.join(' – ')}`
|
||||
}
|
||||
return 'Aperçu du document'
|
||||
}
|
||||
|
||||
const reload = async () => {
|
||||
await loadProducts({ force: true })
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user