feat: ajouter les miniatures de documents dans les catalogues

This commit is contained in:
Matthieu
2025-10-24 15:25:40 +02:00
parent d011e58030
commit e9c7a3d1a7
3 changed files with 188 additions and 0 deletions

View File

@@ -91,6 +91,7 @@
<table class="table table-sm md:table-md">
<thead>
<tr>
<th class="w-24">Aperçu</th>
<th>Nom</th>
<th>Catégorie</th>
<th>Référence</th>
@@ -99,6 +100,12 @@
</thead>
<tbody>
<tr v-for="component in visibleComposants" :key="component.id">
<td class="align-middle">
<DocumentThumbnail
:document="resolvePrimaryDocument(component)"
:alt="resolvePreviewAlt(component)"
/>
</td>
<td>{{ component.name || 'Composant sans nom' }}</td>
<td>{{ component.typeComposant?.name || '—' }}</td>
<td>{{ component.reference || '—' }}</td>
@@ -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<string, any>) => {
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<string, any>) => {
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<string, any>) => {
const toComparable = (value?: string | null) =>
(value ?? '').toString().trim().toLowerCase()

View File

@@ -90,6 +90,7 @@
<table class="table table-sm md:table-md">
<thead>
<tr>
<th class="w-24">Aperçu</th>
<th>Nom</th>
<th>Catégorie</th>
<th>Référence</th>
@@ -98,6 +99,12 @@
</thead>
<tbody>
<tr v-for="piece in visiblePieces" :key="piece.id">
<td class="align-middle">
<DocumentThumbnail
:document="resolvePrimaryDocument(piece)"
:alt="resolvePreviewAlt(piece)"
/>
</td>
<td>{{ piece.name || 'Pièce sans nom' }}</td>
<td>{{ piece.typePiece?.name || '—' }}</td>
<td>{{ piece.reference || '—' }}</td>
@@ -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<string, any>) => {
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<string, any>) => {
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<string, any>) => {
const normalise = (value?: string | null) =>
(value ?? '').toString().trim().toLowerCase()