feat: ajouter les miniatures de documents dans les catalogues
This commit is contained in:
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user