/** * Type definitions and pure label/description helpers for structure assignments. * * Extracted from composables/useStructureAssignmentFetch.ts to keep files * under 500 lines. These are stateless utilities that do not depend on Vue * reactivity or API fetching. */ import type { ComponentModelPiece, ComponentModelProduct, ComponentModelStructureNode, } from '~/shared/types/inventory' // --------------------------------------------------------------------------- // Option types // --------------------------------------------------------------------------- export interface ComponentOption { id: string name?: string | null reference?: string | null typeComposantId?: string | null typeComposant?: { id: string name?: string | null code?: string | null } | null } export interface PieceOption { id: string name?: string | null reference?: string | null typePieceId?: string | null typePiece?: { id: string name?: string | null code?: string | null } | null } export interface ProductOption { id: string name?: string | null reference?: string | null typeProductId?: string | null typeProduct?: { id: string name?: string | null code?: string | null } | null } // --------------------------------------------------------------------------- // Assignment node types // --------------------------------------------------------------------------- export interface StructurePieceAssignment { path: string definition: ComponentModelPiece selectedPieceId: string } export interface StructureProductAssignment { path: string definition: ComponentModelProduct selectedProductId: string } export interface StructureAssignmentNode { path: string definition: ComponentModelStructureNode selectedComponentId: string pieces: StructurePieceAssignment[] products: StructureProductAssignment[] subcomponents: StructureAssignmentNode[] } // --------------------------------------------------------------------------- // Component label helpers // --------------------------------------------------------------------------- export const componentOptionLabel = (component?: ComponentOption | null): string => { if (!component) { return 'Composant sans nom' } const name = component.name || 'Composant sans nom' return component.reference ? `${name} — ${component.reference}` : name } export const componentOptionDescription = (component?: ComponentOption | null): string => { if (!component) { return '' } const parts: string[] = [] const typeLabel = component.typeComposant?.name || component.typeComposant?.code || null if (typeLabel) { parts.push(typeLabel) } if (component.reference) { parts.push(`Ref. ${component.reference}`) } return parts.join(' \u2022 ') } // --------------------------------------------------------------------------- // Piece label helpers // --------------------------------------------------------------------------- export const pieceOptionLabel = (piece?: PieceOption | null): string => { if (!piece) { return 'Pièce' } const name = piece.name || 'Pièce' return piece.reference ? `${name} — ${piece.reference}` : name } export const pieceOptionDescription = (piece?: PieceOption | null): string => { if (!piece) { return '' } const parts: string[] = [] const typeLabel = piece.typePiece?.name || piece.typePiece?.code || null if (typeLabel) { parts.push(typeLabel) } if (piece.reference) { parts.push(`Ref. ${piece.reference}`) } return parts.join(' \u2022 ') } // --------------------------------------------------------------------------- // Product label helpers // --------------------------------------------------------------------------- export const productOptionLabel = (product?: ProductOption | null): string => { if (!product) { return 'Produit' } const name = product.name || 'Produit' return product.reference ? `${name} — ${product.reference}` : name } export const productOptionDescription = (product?: ProductOption | null): string => { if (!product) { return '' } const parts: string[] = [] const typeLabel = product.typeProduct?.name || product.typeProduct?.code || null if (typeLabel) { parts.push(typeLabel) } if (product.reference) { parts.push(`Ref. ${product.reference}`) } return parts.join(' \u2022 ') } // --------------------------------------------------------------------------- // Requirement description helpers // --------------------------------------------------------------------------- export const describePieceRequirement = ( assignment: StructurePieceAssignment, options: PieceOption[], pieceTypeLabelMap: Record, ): string => { const definition = assignment.definition const parts: string[] = [] const addPart = (value?: string | null) => { const trimmed = typeof value === 'string' ? value.trim() : '' if (trimmed && !parts.includes(trimmed)) { parts.push(trimmed) } } const fallbackPiece = options[0] || null const fallbackType = fallbackPiece?.typePiece || null addPart(definition.role) const explicitLabel = definition.typePieceLabel || definition.typePiece?.name || (definition.typePieceId ? pieceTypeLabelMap[definition.typePieceId] : null) || fallbackType?.name addPart(explicitLabel) const family = definition.familyCode || definition.typePiece?.code || fallbackType?.code || null if (family) { addPart(`Famille ${family}`) } if (parts.length === 0) { addPart(fallbackType?.name) if (fallbackType?.code) { addPart(`Famille ${fallbackType.code}`) } } if (parts.length === 0 && definition.typePieceId) { addPart(`#${definition.typePieceId}`) } return parts.length ? parts.join(' \u2022 ') : 'Pi\u00e8ce du squelette' } export const describeProductRequirement = ( assignment: StructureProductAssignment, options: ProductOption[], productTypeLabelMap: Record, ): string => { const definition = assignment.definition const parts: string[] = [] const addPart = (value?: string | null) => { const trimmed = typeof value === 'string' ? value.trim() : '' if (trimmed && !parts.includes(trimmed)) { parts.push(trimmed) } } const fallbackProduct = options[0] || null const fallbackType = fallbackProduct?.typeProduct || null addPart(definition.role) const explicitLabel = definition.typeProductLabel || definition.typeProduct?.name || (definition.typeProductId ? productTypeLabelMap[definition.typeProductId] : null) || fallbackType?.name addPart(explicitLabel) const family = definition.familyCode || definition.typeProduct?.code || fallbackType?.code || null if (family) { addPart(`Famille ${family}`) } if (parts.length === 0) { addPart(fallbackType?.name) if (fallbackType?.code) { addPart(`Famille ${fallbackType.code}`) } } if (parts.length === 0 && definition.typeProductId) { addPart(`#${definition.typeProductId}`) } return parts.length ? parts.join(' \u2022 ') : 'Produit du squelette' }