refactor(frontend) : extract StructureSkeletonPreview shared component
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
157
app/shared/utils/structureDisplayUtils.ts
Normal file
157
app/shared/utils/structureDisplayUtils.ts
Normal file
@@ -0,0 +1,157 @@
|
||||
/**
|
||||
* 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,
|
||||
})
|
||||
Reference in New Issue
Block a user