import { isImageDocument, isPdfDocument } from '~/utils/documentPreview' /** * Selects the best document for thumbnail preview from an entity's documents array. * Default priority: PDF first, then images. Use `preferImages` to reverse. */ export const resolvePrimaryDocument = (entity: Record, preferImages = false): any | null => { const documents = Array.isArray(entity?.documents) ? entity.documents : [] if (!documents.length) return null const normalized = documents.filter((doc: any) => doc && typeof doc === 'object') const withPath = normalized.filter((doc: any) => doc?.fileUrl || doc?.path) if (!withPath.length) return normalized[0] ?? null const first = preferImages ? isImageDocument : isPdfDocument const second = preferImages ? isPdfDocument : isImageDocument const a = withPath.find((doc: any) => first(doc)) if (a) return a const b = withPath.find((doc: any) => second(doc)) if (b) return b return withPath[0] } /** * Builds alt text for a document preview thumbnail. */ export const resolvePreviewAlt = (entity: Record): string => { const parts = [entity?.name, entity?.reference].filter(Boolean) return parts.length ? `Aperçu du document de ${parts.join(' – ')}` : 'Aperçu du document' } /** * Supplier name resolution: extracts unique supplier names from entity relations. */ export const resolveSupplierNames = (entity: Record, nestedKey?: string): string[] => { const names: string[] = [] const seen = new Set() const pushName = (maybeName: unknown) => { if (typeof maybeName !== 'string') return const normalized = maybeName.trim().replace(/\s+/g, ' ') if (!normalized.length) return const key = normalized.toLowerCase() if (seen.has(key)) return seen.add(key) names.push(normalized) } const collectConstructeurs = (value: unknown): void => { if (!value) return if (Array.isArray(value)) { value.forEach(collectConstructeurs); return } if (typeof value === 'string') { pushName(value); return } if (typeof value === 'object') { const record = value as Record pushName(record?.name ?? record?.label ?? record?.companyName ?? record?.company ?? null) if (record?.constructeur) collectConstructeurs(record.constructeur) if (Array.isArray(record?.constructeurs)) collectConstructeurs(record.constructeurs) } } const collectFromLabel = (value: unknown): void => { if (typeof value !== 'string') return value.split(/[,;\\/•·|]+/).map(part => part.trim()).filter(Boolean).forEach(pushName) } collectConstructeurs(entity?.constructeurs) collectConstructeurs(entity?.constructeur) collectFromLabel(entity?.constructeursLabel) collectFromLabel(entity?.supplierLabel) collectFromLabel(entity?.suppliers) if (nestedKey && entity?.[nestedKey]) { const nested = entity[nestedKey] collectConstructeurs(nested?.constructeurs) collectConstructeurs(nested?.constructeur) collectFromLabel(nested?.constructeursLabel) collectFromLabel(nested?.supplierLabel) } return names } const MAX_VISIBLE_SUPPLIERS = 3 export const buildSuppliersDisplay = (suppliers: string[]) => { const visible = suppliers.slice(0, MAX_VISIBLE_SUPPLIERS) const overflow = Math.max(suppliers.length - visible.length, 0) return { suppliers, visible, overflow, tooltip: suppliers.length ? suppliers.join(', ') : '' } }