Merges the full git history of Inventory_frontend into the monorepo under frontend/. Removes the submodule in favor of a unified repo. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
263 lines
7.0 KiB
TypeScript
263 lines
7.0 KiB
TypeScript
/**
|
|
* 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, string>,
|
|
): 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, string>,
|
|
): 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'
|
|
}
|