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">
|
<table class="table table-sm md:table-md">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
<th class="w-16">Aperçu</th>
|
||||||
<th>Nom</th>
|
<th>Nom</th>
|
||||||
<th>Référence</th>
|
<th>Référence</th>
|
||||||
<th>Type de produit</th>
|
<th>Type de produit</th>
|
||||||
@@ -101,6 +102,12 @@
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr v-for="product in filteredProducts" :key="product.id">
|
<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 class="font-medium">{{ product.name }}</td>
|
||||||
<td>{{ product.reference || '—' }}</td>
|
<td>{{ product.reference || '—' }}</td>
|
||||||
<td>{{ product.typeProduct?.name || '—' }}</td>
|
<td>{{ product.typeProduct?.name || '—' }}</td>
|
||||||
@@ -142,6 +149,8 @@ import { computed, onMounted, ref } from 'vue'
|
|||||||
import { useHead } from '#imports'
|
import { useHead } from '#imports'
|
||||||
import { useProducts } from '~/composables/useProducts'
|
import { useProducts } from '~/composables/useProducts'
|
||||||
import { useToast } from '~/composables/useToast'
|
import { useToast } from '~/composables/useToast'
|
||||||
|
import DocumentThumbnail from '~/components/DocumentThumbnail.vue'
|
||||||
|
import { isImageDocument, isPdfDocument } from '~/utils/documentPreview'
|
||||||
|
|
||||||
useHead(() => ({
|
useHead(() => ({
|
||||||
title: 'Catalogue des produits',
|
title: 'Catalogue des produits',
|
||||||
@@ -230,6 +239,35 @@ const formatConstructeurs = (constructeurs: Array<Record<string, any>>) =>
|
|||||||
.filter((name): name is string => Boolean(name))
|
.filter((name): name is string => Boolean(name))
|
||||||
.join(', ')
|
.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 () => {
|
const reload = async () => {
|
||||||
await loadProducts({ force: true })
|
await loadProducts({ force: true })
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user