158 lines
5.1 KiB
TypeScript
158 lines
5.1 KiB
TypeScript
/**
|
|
* Shared helpers for displaying component/machine structure skeleton details.
|
|
*
|
|
* Extracted from pages/component/create.vue and pages/component/[id]/edit.vue
|
|
* where these functions were duplicated verbatim.
|
|
*/
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Structure accessors
|
|
// ---------------------------------------------------------------------------
|
|
|
|
type StructureLike = Record<string, any> | null
|
|
|
|
export const getStructureCustomFields = (structure: StructureLike): any[] => {
|
|
return Array.isArray(structure?.customFields) ? structure.customFields : []
|
|
}
|
|
|
|
export const getStructurePieces = (structure: StructureLike): any[] => {
|
|
return Array.isArray(structure?.pieces) ? structure.pieces : []
|
|
}
|
|
|
|
export const getStructureProducts = (structure: StructureLike): any[] => {
|
|
return Array.isArray(structure?.products) ? structure.products : []
|
|
}
|
|
|
|
export const getStructureSubcomponents = (structure: StructureLike): any[] => {
|
|
if (Array.isArray(structure?.subcomponents)) {
|
|
return structure.subcomponents
|
|
}
|
|
const legacy = (structure as any)?.subComponents
|
|
return Array.isArray(legacy) ? legacy : []
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Label resolvers
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export const resolvePieceLabel = (
|
|
piece: Record<string, any>,
|
|
labelMap: Record<string, string> = {},
|
|
): string => {
|
|
const parts: string[] = []
|
|
if (piece.role) {
|
|
parts.push(piece.role)
|
|
}
|
|
if (piece.typePiece?.name) {
|
|
parts.push(piece.typePiece.name)
|
|
} else if (piece.typePieceLabel) {
|
|
parts.push(piece.typePieceLabel)
|
|
} else if (piece.typePieceId && labelMap[piece.typePieceId]) {
|
|
parts.push(labelMap[piece.typePieceId]!)
|
|
} else if (piece.typePiece?.code) {
|
|
parts.push(`Famille ${piece.typePiece.code}`)
|
|
} else if (piece.familyCode) {
|
|
parts.push(`Famille ${piece.familyCode}`)
|
|
} else if (piece.typePieceId) {
|
|
parts.push(`#${piece.typePieceId}`)
|
|
}
|
|
return parts.length ? parts.join(' • ') : 'Pièce'
|
|
}
|
|
|
|
export const resolveProductLabel = (
|
|
product: Record<string, any>,
|
|
labelMap: Record<string, string> = {},
|
|
): string => {
|
|
const parts: string[] = []
|
|
if (product.role) {
|
|
parts.push(product.role)
|
|
}
|
|
if (product.typeProduct?.name) {
|
|
parts.push(product.typeProduct.name)
|
|
} else if (product.typeProductLabel) {
|
|
parts.push(product.typeProductLabel)
|
|
} else if (product.typeProductId && labelMap[product.typeProductId]) {
|
|
parts.push(labelMap[product.typeProductId]!)
|
|
} else if (product.typeProduct?.code) {
|
|
parts.push(`Catégorie ${product.typeProduct.code}`)
|
|
} else if (product.familyCode) {
|
|
parts.push(`Catégorie ${product.familyCode}`)
|
|
} else if (product.typeProductId) {
|
|
parts.push(`#${product.typeProductId}`)
|
|
}
|
|
return parts.length ? parts.join(' • ') : 'Produit'
|
|
}
|
|
|
|
export const resolveSubcomponentLabel = (node: Record<string, any>): string => {
|
|
const parts: string[] = []
|
|
if (node.alias) {
|
|
parts.push(node.alias)
|
|
}
|
|
if (node.typeComposant?.name) {
|
|
parts.push(node.typeComposant.name)
|
|
} else if (node.typeComposantLabel) {
|
|
parts.push(node.typeComposantLabel)
|
|
} else if (node.familyCode) {
|
|
parts.push(node.familyCode)
|
|
} else if (node.typeComposantId) {
|
|
parts.push(`#${node.typeComposantId}`)
|
|
}
|
|
|
|
const childCount = Array.isArray(node.subcomponents)
|
|
? node.subcomponents.length
|
|
: Array.isArray(node.subComponents)
|
|
? node.subComponents.length
|
|
: 0
|
|
if (childCount) {
|
|
parts.push(`${childCount} sous-composant(s)`)
|
|
}
|
|
return parts.length ? parts.join(' • ') : 'Sous-composant'
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Generic model type name fetcher (replaces fetchPieceTypeNames / fetchProductTypeNames)
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export const fetchModelTypeNames = async (
|
|
ids: string[],
|
|
existingMap: Record<string, string>,
|
|
get: (url: string) => Promise<{ success?: boolean; data?: any }>,
|
|
): Promise<Record<string, string>> => {
|
|
const missing = ids.filter((id) => id && !existingMap[id])
|
|
if (!missing.length) {
|
|
return {}
|
|
}
|
|
const results = await Promise.allSettled(
|
|
missing.map((id) => get(`/model_types/${id}`)),
|
|
)
|
|
const additions: Record<string, string> = {}
|
|
results.forEach((result, index) => {
|
|
const key = missing[index]
|
|
if (!key || result.status !== 'fulfilled') {
|
|
return
|
|
}
|
|
const data = result.value?.data
|
|
const name = data?.name || data?.code
|
|
if (name) {
|
|
additions[key] = name
|
|
}
|
|
})
|
|
return additions
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Type label map builder
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export const buildTypeLabelMap = (
|
|
types: any[],
|
|
fetchedOverrides: Record<string, string> = {},
|
|
): Record<string, string> => ({
|
|
...Object.fromEntries(
|
|
(types || [])
|
|
.filter((type: any) => type?.id)
|
|
.map((type: any) => [type.id, type.name || type.code || '']),
|
|
),
|
|
...fetchedOverrides,
|
|
})
|