Files
Inventory/app/shared/utils/structureSelectionUtils.ts

108 lines
3.7 KiB
TypeScript

export type SelectionEntry = {
id: string
path: string
requirementLabel: string
resolvedName: string
}
export type StructureSelectionResult = {
pieces: SelectionEntry[]
products: SelectionEntry[]
components: SelectionEntry[]
}
type CatalogMap = Map<string, { name?: string, [key: string]: any }>
type LabelResolvers = {
resolvePieceLabel: (definition: Record<string, any>) => string
resolveProductLabel: (definition: Record<string, any>) => string
resolveSubcomponentLabel: (definition: Record<string, any>) => string
}
const isNonEmptyString = (value: unknown): value is string =>
typeof value === 'string' && value.trim().length > 0
export function collectStructureSelections(
root: any,
catalogs: {
pieceCatalogMap: CatalogMap
productCatalogMap: CatalogMap
componentCatalogMap: CatalogMap
},
resolvers: LabelResolvers,
): StructureSelectionResult {
const piecesSelected: SelectionEntry[] = []
const productsSelected: SelectionEntry[] = []
const componentsSelected: SelectionEntry[] = []
if (!root || typeof root !== 'object') {
return { pieces: piecesSelected, products: productsSelected, components: componentsSelected }
}
const visitNode = (node: any, fallbackPath = 'racine') => {
if (!node || typeof node !== 'object') {
return
}
const nodePath = isNonEmptyString(node.path) ? node.path : fallbackPath
const nodePieces = Array.isArray(node.pieces) ? node.pieces : []
nodePieces.forEach((entry: any, index: number) => {
const selectedId = entry?.selectedPieceId
if (!isNonEmptyString(selectedId)) {
return
}
const definition = entry?.definition ?? entry
const catalogPiece = catalogs.pieceCatalogMap.get(selectedId)
piecesSelected.push({
id: selectedId,
path: isNonEmptyString(entry?.path) ? entry.path : `${nodePath}:piece-${index + 1}`,
requirementLabel: resolvers.resolvePieceLabel(definition),
resolvedName: catalogPiece?.name || selectedId,
})
})
const nodeProducts = Array.isArray(node.products) ? node.products : []
nodeProducts.forEach((entry: any, index: number) => {
const selectedId = entry?.selectedProductId
if (!isNonEmptyString(selectedId)) {
return
}
const definition = entry?.definition ?? entry
const catalogProduct = catalogs.productCatalogMap.get(selectedId)
productsSelected.push({
id: selectedId,
path: isNonEmptyString(entry?.path) ? entry.path : `${nodePath}:product-${index + 1}`,
requirementLabel: resolvers.resolveProductLabel(definition),
resolvedName: catalogProduct?.name || selectedId,
})
})
const nodeChildren = Array.isArray(node.subcomponents)
? node.subcomponents
: Array.isArray(node.subComponents)
? node.subComponents
: []
nodeChildren.forEach((child: any, index: number) => {
const selectedId = child?.selectedComponentId
if (isNonEmptyString(selectedId)) {
const definition = child?.definition ?? child
const catalogComponent = catalogs.componentCatalogMap.get(selectedId)
componentsSelected.push({
id: selectedId,
path: isNonEmptyString(child?.path) ? child.path : `${nodePath}:subcomponent-${index + 1}`,
requirementLabel: resolvers.resolveSubcomponentLabel(definition),
resolvedName: catalogComponent?.name || selectedId,
})
}
visitNode(child, isNonEmptyString(child?.path) ? child.path : `${nodePath}:subcomponent-${index + 1}`)
})
}
visitNode(root, isNonEmptyString(root?.path) ? root.path : 'racine')
return { pieces: piecesSelected, products: productsSelected, components: componentsSelected }
}