Files
Inventory/frontend/app/shared/utils/assignmentUtils.ts
Matthieu 974a4a0781 refactor : merge Inventory_frontend submodule into frontend/ directory
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>
2026-04-01 14:17:57 +02:00

221 lines
6.7 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Entity assignment normalization and display utilities.
*
* Extracted from pages/machines/new.vue these pure functions resolve
* machine / component / piece assignments from nested API payloads.
*/
type AnyRecord = Record<string, unknown>
// ---------------------------------------------------------------------------
// Primitive helpers
// ---------------------------------------------------------------------------
const isPlainObject = (value: unknown): value is AnyRecord =>
value !== null && typeof value === 'object' && !Array.isArray(value)
const toTrimmedString = (value: unknown): string | null => {
if (typeof value === 'string') {
const trimmed = value.trim()
return trimmed.length > 0 ? trimmed : null
}
if (typeof value === 'number' && Number.isFinite(value)) {
return String(value)
}
return null
}
// ---------------------------------------------------------------------------
// Dedup
// ---------------------------------------------------------------------------
export const dedupeAssignments = (
assignments: AnyRecord[],
): AnyRecord[] => {
const seen = new Set<string>()
return assignments.filter((assignment) => {
if (!assignment) return false
const id = assignment.id != null ? String(assignment.id) : ''
const name = assignment.name != null ? String(assignment.name) : ''
const key = `${id}::${name}`
if (!id && !name) return false
if (seen.has(key)) return false
seen.add(key)
return true
})
}
// ---------------------------------------------------------------------------
// Machine assignments
// ---------------------------------------------------------------------------
export const normalizeMachineAssignment = (input: unknown): AnyRecord | null => {
if (!input) return null
if (typeof input === 'string') {
const name = toTrimmedString(input)
return name ? { id: name, name } : null
}
if (typeof input === 'number' && Number.isFinite(input)) {
const value = String(input)
return { id: value, name: value }
}
const container = (input as AnyRecord).machine || (input as AnyRecord).machineData || input
if (!isPlainObject(container)) return null
const id =
container.id ?? (input as AnyRecord).machineId ?? (input as AnyRecord).id ?? null
const name =
container.name ||
(input as AnyRecord).machineName ||
container.label ||
container.title ||
(typeof id === 'string' ? id : null) ||
(typeof id === 'number' ? String(id) : null)
if (id == null && name == null) return null
return {
id: id != null ? id : null,
name: name != null ? name : null,
}
}
export const collectMachineAssignments = (source: unknown): AnyRecord[] => {
if (!isPlainObject(source)) return []
const candidates = [
source.machines,
source.machineLinks,
source.machineAssignments,
source.machinesAssignments,
source.linkedMachines,
]
const assignments: AnyRecord[] = []
candidates.forEach((list) => {
if (Array.isArray(list)) {
list.forEach((item) => {
const normalized = normalizeMachineAssignment(item)
if (normalized) assignments.push(normalized)
})
}
})
if (!assignments.length) {
const direct = normalizeMachineAssignment(source.machine)
if (direct) assignments.push(direct)
}
if (!assignments.length) {
const idCandidate = source.machineId ?? source.machineID ?? null
const nameCandidate = source.machineName ?? null
const normalized = normalizeMachineAssignment(nameCandidate || idCandidate)
if (normalized) assignments.push(normalized)
}
return dedupeAssignments(assignments)
}
// ---------------------------------------------------------------------------
// Component assignments
// ---------------------------------------------------------------------------
export const normalizeComponentAssignment = (input: unknown): AnyRecord | null => {
if (!input) return null
if (typeof input === 'string') {
const value = toTrimmedString(input)
return value ? { id: value, name: value } : null
}
if (typeof input === 'number' && Number.isFinite(input)) {
const value = String(input)
return { id: value, name: value }
}
const container =
(input as AnyRecord).component || (input as AnyRecord).composant || input
if (!isPlainObject(container)) return null
const id =
container.id ??
(input as AnyRecord).componentId ??
(input as AnyRecord).composantId ??
(input as AnyRecord).id ??
null
const name =
container.name ||
(input as AnyRecord).componentName ||
(input as AnyRecord).composantName ||
container.label ||
(typeof id === 'string' ? id : null) ||
(typeof id === 'number' ? String(id) : null)
if (id == null && name == null) return null
return {
id: id != null ? id : null,
name: name != null ? name : null,
}
}
export const collectComponentAssignments = (source: unknown): AnyRecord[] => {
if (!isPlainObject(source)) return []
const candidates = [
source.components,
source.composants,
source.componentLinks,
source.linkedComponents,
]
const assignments: AnyRecord[] = []
candidates.forEach((list) => {
if (Array.isArray(list)) {
list.forEach((item) => {
const normalized = normalizeComponentAssignment(item)
if (normalized) assignments.push(normalized)
})
}
})
if (!assignments.length) {
const direct = normalizeComponentAssignment(source.component || source.composant)
if (direct) assignments.push(direct)
}
if (!assignments.length) {
const idCandidate = source.componentId ?? source.composantId ?? null
const normalized = normalizeComponentAssignment(idCandidate)
if (normalized) assignments.push(normalized)
}
return dedupeAssignments(assignments)
}
// ---------------------------------------------------------------------------
// Convenience wrappers
// ---------------------------------------------------------------------------
export const getComponentMachineAssignments = (component: unknown): AnyRecord[] =>
collectMachineAssignments(component || {})
export const getPieceMachineAssignments = (piece: unknown): AnyRecord[] =>
collectMachineAssignments(piece || {})
export const getPieceComponentAssignments = (piece: unknown): AnyRecord[] =>
collectComponentAssignments(piece || {})
// ---------------------------------------------------------------------------
// Display
// ---------------------------------------------------------------------------
export const formatAssignmentList = (assignments: AnyRecord[]): string => {
if (!Array.isArray(assignments) || assignments.length === 0) return ''
return assignments
.map((assignment) => (assignment?.name || assignment?.id) as string)
.filter(Boolean)
.join(', ')
}