Normalize machine link responses

This commit is contained in:
MatthieuTD
2025-10-09 09:21:40 +02:00
parent f89364d04e
commit 95c2a82689
3 changed files with 1028 additions and 216 deletions

View File

@@ -5,6 +5,45 @@ import { useApi } from './useApi'
const machines = ref([]) const machines = ref([])
const loading = ref(false) const loading = ref(false)
const resolveLinkCollection = (source, keys) => {
if (!source || typeof source !== 'object') {
return undefined
}
for (const key of keys) {
const value = source[key]
if (Array.isArray(value)) {
return value
}
}
return undefined
}
const normalizeMachineResponse = (payload) => {
if (!payload || typeof payload !== 'object') {
return null
}
const container = payload.machine && typeof payload.machine === 'object'
? payload.machine
: payload
const normalized = { ...container }
const componentLinks = resolveLinkCollection(payload, ['componentLinks', 'machineComponentLinks']) ??
resolveLinkCollection(container, ['componentLinks', 'machineComponentLinks']) ??
[]
const pieceLinks = resolveLinkCollection(payload, ['pieceLinks', 'machinePieceLinks']) ??
resolveLinkCollection(container, ['pieceLinks', 'machinePieceLinks']) ??
[]
normalized.componentLinks = componentLinks
normalized.pieceLinks = pieceLinks
return normalized
}
export function useMachines () { export function useMachines () {
const { showSuccess, showError, showInfo } = useToast() const { showSuccess, showError, showInfo } = useToast()
const { get, post, patch, delete: del } = useApi() const { get, post, patch, delete: del } = useApi()
@@ -14,8 +53,18 @@ export function useMachines () {
try { try {
const result = await get('/machines') const result = await get('/machines')
if (result.success) { if (result.success) {
machines.value = result.data const machineList = Array.isArray(result.data)
showInfo(`Chargement de ${machines.value.length} machine(s) réussi`) ? result.data
: Array.isArray(result.data?.machines)
? result.data.machines
: Array.isArray(result.data?.data)
? result.data.data
: []
const normalized = machineList
.map((item) => normalizeMachineResponse(item))
.filter(Boolean)
machines.value = normalized
showInfo(`Chargement de ${normalized.length} machine(s) réussi`)
} }
} catch (error) { } catch (error) {
console.error('Erreur lors du chargement des machines:', error) console.error('Erreur lors du chargement des machines:', error)
@@ -29,8 +78,14 @@ export function useMachines () {
try { try {
const result = await post('/machines', machineData) const result = await post('/machines', machineData)
if (result.success) { if (result.success) {
machines.value.push(result.data) const createdMachine = normalizeMachineResponse(result.data) ||
showSuccess(`Machine "${machineData.name}" créée avec succès`) normalizeMachineResponse(result.data?.machine) ||
null
if (createdMachine) {
machines.value.push(createdMachine)
}
const displayName = createdMachine?.name || machineData?.name || ''
showSuccess(`Machine "${displayName}" créée avec succès`)
} }
return result return result
} catch (error) { } catch (error) {
@@ -58,11 +113,17 @@ export function useMachines () {
try { try {
const result = await patch(`/machines/${id}`, machineData) const result = await patch(`/machines/${id}`, machineData)
if (result.success) { if (result.success) {
const updatedMachine = normalizeMachineResponse(result.data) ||
normalizeMachineResponse(result.data?.machine) ||
null
const index = machines.value.findIndex(machine => machine.id === id) const index = machines.value.findIndex(machine => machine.id === id)
if (index !== -1) { if (index !== -1 && updatedMachine) {
machines.value[index] = result.data machines.value[index] = {
...machines.value[index],
...updatedMachine,
}
} }
showSuccess(`Machine "${result.data?.name || machineData.name || ''}" mise à jour avec succès`) showSuccess(`Machine "${updatedMachine?.name || machineData.name || ''}" mise à jour avec succès`)
} }
return result return result
} catch (error) { } catch (error) {
@@ -84,7 +145,13 @@ export function useMachines () {
if (result.success) { if (result.success) {
const index = machines.value.findIndex(machine => machine.id === machineId) const index = machines.value.findIndex(machine => machine.id === machineId)
if (index !== -1) { if (index !== -1) {
machines.value[index] = result.data?.machine || result.data const updatedMachine = normalizeMachineResponse(result.data) ||
normalizeMachineResponse(result.data?.machine) ||
machines.value[index]
machines.value[index] = {
...machines.value[index],
...(updatedMachine || {}),
}
} }
showSuccess('Structure de la machine mise à jour avec succès') showSuccess('Structure de la machine mise à jour avec succès')
} }

View File

@@ -858,18 +858,17 @@ const {
updateMachine: updateMachineApi, updateMachine: updateMachineApi,
reconfigureSkeleton: reconfigureMachineSkeleton, reconfigureSkeleton: reconfigureMachineSkeleton,
} = useMachines() } = useMachines()
const { const {
getComposantsByMachine, updateComposant: updateComposantApi
updateComposant: updateComposantApi
} = useComposants() } = useComposants()
const { const {
getPiecesByMachine,
updatePiece: updatePieceApi updatePiece: updatePieceApi
} = usePieces() } = usePieces()
const { componentTypes, loadComponentTypes } = useComponentTypes() const { componentTypes, loadComponentTypes } = useComponentTypes()
const { pieceTypes, loadPieceTypes } = usePieceTypes() const { pieceTypes, loadPieceTypes } = usePieceTypes()
const { upsertCustomFieldValue, updateCustomFieldValue: updateCustomFieldValueApi } = useCustomFields() const { upsertCustomFieldValue, updateCustomFieldValue: updateCustomFieldValueApi } = useCustomFields()
const { get } = useApi()
const { const {
uploadDocuments, uploadDocuments,
deleteDocument, deleteDocument,
@@ -884,6 +883,8 @@ const loading = ref(true)
const machine = ref(null) const machine = ref(null)
const components = ref([]) const components = ref([])
const pieces = ref([]) const pieces = ref([])
const machineComponentLinks = ref([])
const machinePieceLinks = ref([])
const printAreaRef = ref(null) const printAreaRef = ref(null)
const { constructeurs, loadConstructeurs } = useConstructeurs() const { constructeurs, loadConstructeurs } = useConstructeurs()
@@ -970,6 +971,67 @@ const pieceTypeLabelMap = computed(() => {
return map return map
}) })
const isPlainObject = (value) => Object.prototype.toString.call(value) === '[object Object]'
const resolveIdentifier = (...candidates) => {
for (const candidate of candidates) {
if (candidate !== undefined && candidate !== null && candidate !== '') {
return candidate
}
}
return null
}
const extractParentLinkIdentifiers = (source) => {
if (!source || typeof source !== 'object') {
return {}
}
const identifiers = {}
const idKeys = [
'parentRequirementId',
'parentComponentRequirementId',
'parentPieceRequirementId',
'parentMachineComponentRequirementId',
'parentMachinePieceRequirementId',
'parentLinkId',
'parentComponentLinkId',
'parentPieceLinkId',
'parentComponentId',
'parentPieceId',
]
idKeys.forEach((key) => {
if (Object.prototype.hasOwnProperty.call(source, key)) {
const value = source[key]
if (value !== undefined && value !== null && value !== '') {
identifiers[key] = value
}
}
})
const objectKeys = [
'parentRequirement',
'parentComponentRequirement',
'parentPieceRequirement',
'parentMachineComponentRequirement',
'parentMachinePieceRequirement',
]
objectKeys.forEach((key) => {
const value = source[key]
if (isPlainObject(value) && value.id !== undefined && value.id !== null && value.id !== '') {
const idKey = `${key}Id`
if (!Object.prototype.hasOwnProperty.call(identifiers, idKey)) {
identifiers[idKey] = value.id
}
}
})
return identifiers
}
const resolveComponentRequirementTypeLabel = (requirement, entry) => { const resolveComponentRequirementTypeLabel = (requirement, entry) => {
const typeId = entry?.typeComposantId || requirement?.typeComposantId || null const typeId = entry?.typeComposantId || requirement?.typeComposantId || null
if (!typeId) { if (!typeId) {
@@ -994,47 +1056,126 @@ const getPieceRequirementEntries = (requirementId) => {
return pieceRequirementSelections[requirementId] || [] return pieceRequirementSelections[requirementId] || []
} }
const createComponentSelectionEntry = (requirement, source = null) => ({ const createComponentSelectionEntry = (requirement, source = null) => {
typeComposantId: source?.typeMachineComponentRequirement?.typeComposantId const link = source?.machineComponentLink || null
|| source?.typeComposantId
|| source?.typeComposant?.id
|| requirement?.typeComposantId
|| null,
definition: {
name:
source?.name
|| source?.nom
|| requirement?.typeComposant?.name
|| '',
reference: source?.reference || '',
constructeurId: source?.constructeurId || source?.constructeur?.id || null,
prix:
source?.prix
?? source?.price
?? null,
},
})
const createPieceSelectionEntry = (requirement, source = null) => ({ const entry = {
typePieceId: source?.typeMachinePieceRequirement?.typePieceId linkId: resolveIdentifier(link?.id, source?.machineComponentLinkId, source?.linkId),
|| source?.typePieceId composantId: resolveIdentifier(source?.composantId, source?.componentId, source?.id),
|| source?.typePiece?.id parentLinkId: resolveIdentifier(
|| requirement?.typePieceId link?.parentLinkId,
|| null, link?.parentComponentLinkId,
definition: { source?.parentComponentLinkId,
name: source?.parentLinkId,
source?.name ),
|| source?.nom parentRequirementId: resolveIdentifier(
|| requirement?.typePiece?.name link?.parentRequirementId,
|| '', source?.parentRequirementId,
reference: source?.reference || '', requirement?.parentRequirementId,
constructeurId: source?.constructeurId || source?.constructeur?.id || null, ),
prix: parentMachineComponentRequirementId: resolveIdentifier(
source?.prix link?.parentMachineComponentRequirementId,
?? source?.price source?.parentMachineComponentRequirementId,
?? null, requirement?.parentMachineComponentRequirementId,
}, ),
}) parentMachinePieceRequirementId: resolveIdentifier(
link?.parentMachinePieceRequirementId,
source?.parentMachinePieceRequirementId,
requirement?.parentMachinePieceRequirementId,
),
parentComponentId: resolveIdentifier(link?.parentComponentId, source?.parentComponentId),
parentPieceId: resolveIdentifier(link?.parentPieceId, source?.parentPieceId),
typeComposantId:
source?.typeMachineComponentRequirement?.typeComposantId
|| source?.typeComposantId
|| source?.typeComposant?.id
|| requirement?.typeComposantId
|| null,
definition: {
name:
source?.name
|| source?.nom
|| requirement?.typeComposant?.name
|| '',
reference: source?.reference || '',
constructeurId: source?.constructeurId || source?.constructeur?.id || null,
prix:
source?.prix
?? source?.price
?? null,
},
}
if (link?.overrides && isPlainObject(link.overrides)) {
entry.definition = {
...entry.definition,
...link.overrides,
}
}
return entry
}
const createPieceSelectionEntry = (requirement, source = null) => {
const link = source?.machinePieceLink || null
const entry = {
linkId: resolveIdentifier(link?.id, source?.machinePieceLinkId, source?.linkId),
pieceId: resolveIdentifier(source?.pieceId, source?.id),
parentLinkId: resolveIdentifier(link?.parentLinkId, source?.parentLinkId),
parentComponentLinkId: resolveIdentifier(
link?.parentComponentLinkId,
source?.parentComponentLinkId,
source?.machineComponentLinkId,
),
parentRequirementId: resolveIdentifier(
link?.parentRequirementId,
source?.parentRequirementId,
requirement?.parentRequirementId,
),
parentMachineComponentRequirementId: resolveIdentifier(
link?.parentMachineComponentRequirementId,
source?.parentMachineComponentRequirementId,
requirement?.parentMachineComponentRequirementId,
),
parentMachinePieceRequirementId: resolveIdentifier(
link?.parentMachinePieceRequirementId,
source?.parentMachinePieceRequirementId,
requirement?.parentMachinePieceRequirementId,
),
parentComponentId: resolveIdentifier(link?.parentComponentId, source?.parentComponentId, source?.composantId),
parentPieceId: resolveIdentifier(link?.parentPieceId, source?.parentPieceId),
composantId: resolveIdentifier(source?.composantId, link?.composantId, link?.componentId),
typePieceId:
source?.typeMachinePieceRequirement?.typePieceId
|| source?.typePieceId
|| source?.typePiece?.id
|| requirement?.typePieceId
|| null,
definition: {
name:
source?.name
|| source?.nom
|| requirement?.typePiece?.name
|| '',
reference: source?.reference || '',
constructeurId: source?.constructeurId || source?.constructeur?.id || null,
prix:
source?.prix
?? source?.price
?? null,
},
}
if (link?.overrides && isPlainObject(link.overrides)) {
entry.definition = {
...entry.definition,
...link.overrides,
}
}
return entry
}
const resetSkeletonRequirementSelections = () => { const resetSkeletonRequirementSelections = () => {
Object.keys(componentRequirementSelections).forEach((key) => { Object.keys(componentRequirementSelections).forEach((key) => {
@@ -1225,8 +1366,8 @@ const changeMachineView = async (view) => {
const validateSkeletonSelections = (type) => { const validateSkeletonSelections = (type) => {
const errors = [] const errors = []
const componentSelectionsPayload = [] const componentLinksPayload = []
const pieceSelectionsPayload = [] const pieceLinksPayload = []
for (const requirement of type.componentRequirements || []) { for (const requirement of type.componentRequirements || []) {
const entries = getComponentRequirementEntries(requirement.id) const entries = getComponentRequirementEntries(requirement.id)
@@ -1254,17 +1395,32 @@ const validateSkeletonSelections = (type) => {
return return
} }
const payload = { requirementId: requirement.id } const payload = {
if (entry.typeComposantId && entry.typeComposantId !== requirement.typeComposantId) { requirementId: requirement.id,
payload.typeComposantId = entry.typeComposantId typeComposantId: resolvedTypeId,
}
if (entry.linkId) {
payload.id = entry.linkId
payload.linkId = entry.linkId
}
if (entry.composantId) {
payload.composantId = entry.composantId
} }
const overrides = sanitizeDefinitionOverrides(entry.definition) const overrides = sanitizeDefinitionOverrides(entry.definition)
if (overrides) { if (overrides) {
payload.definition = overrides payload.overrides = overrides
} }
componentSelectionsPayload.push(payload) Object.assign(
payload,
extractParentLinkIdentifiers(requirement),
extractParentLinkIdentifiers(entry),
)
componentLinksPayload.push(payload)
}) })
} }
@@ -1294,17 +1450,36 @@ const validateSkeletonSelections = (type) => {
return return
} }
const payload = { requirementId: requirement.id } const payload = {
if (entry.typePieceId && entry.typePieceId !== requirement.typePieceId) { requirementId: requirement.id,
payload.typePieceId = entry.typePieceId typePieceId: resolvedTypeId,
}
if (entry.linkId) {
payload.id = entry.linkId
payload.linkId = entry.linkId
}
if (entry.pieceId) {
payload.pieceId = entry.pieceId
}
if (entry.composantId) {
payload.composantId = entry.composantId
} }
const overrides = sanitizeDefinitionOverrides(entry.definition) const overrides = sanitizeDefinitionOverrides(entry.definition)
if (overrides) { if (overrides) {
payload.definition = overrides payload.overrides = overrides
} }
pieceSelectionsPayload.push(payload) Object.assign(
payload,
extractParentLinkIdentifiers(requirement),
extractParentLinkIdentifiers(entry),
)
pieceLinksPayload.push(payload)
}) })
} }
@@ -1314,8 +1489,8 @@ const validateSkeletonSelections = (type) => {
return { return {
valid: true, valid: true,
componentSelections: componentSelectionsPayload, componentLinks: componentLinksPayload,
pieceSelections: pieceSelectionsPayload, pieceLinks: pieceLinksPayload,
} }
} }
@@ -1333,6 +1508,16 @@ const applySkeletonReconfigurationResult = async (data) => {
machineDocumentsLoaded.value = !!(machine.value.documents?.length) machineDocumentsLoaded.value = !!(machine.value.documents?.length)
} }
const linksApplied = applyMachineLinks(data) || applyMachineLinks(updatedMachine)
if (linksApplied) {
if (machine.value) {
machine.value.componentLinks = machineComponentLinks.value
machine.value.pieceLinks = machinePieceLinks.value
}
collapseAllComponents()
return
}
const newComponents = data.components ?? updatedMachine?.components ?? null const newComponents = data.components ?? updatedMachine?.components ?? null
if (Array.isArray(newComponents)) { if (Array.isArray(newComponents)) {
components.value = transformComponentCustomFields(newComponents) components.value = transformComponentCustomFields(newComponents)
@@ -1352,7 +1537,7 @@ const saveSkeletonConfiguration = async () => {
} }
const type = machineType.value const type = machineType.value
let payload = { componentSelections: [], pieceSelections: [] } let payload = { componentLinks: [], pieceLinks: [] }
if (type && machineHasSkeletonRequirements.value) { if (type && machineHasSkeletonRequirements.value) {
const validation = validateSkeletonSelections(type) const validation = validateSkeletonSelections(type)
@@ -1361,8 +1546,8 @@ const saveSkeletonConfiguration = async () => {
return return
} }
payload = { payload = {
componentSelections: validation.componentSelections, componentLinks: validation.componentLinks,
pieceSelections: validation.pieceSelections, pieceLinks: validation.pieceLinks,
} }
} }
@@ -1436,8 +1621,17 @@ const getMachineFieldId = (fieldName) => {
// Computed // Computed
const machinePieces = computed(() => { const machinePieces = computed(() => {
const filteredPieces = pieces.value.filter(piece => !piece.composantId) const filteredPieces = pieces.value.filter((piece) => {
console.log('machinePieces computed:', filteredPieces) const parentLinkId = resolveIdentifier(
piece.parentComponentLinkId,
piece.machinePieceLink?.parentComponentLinkId,
piece.parentLinkId,
)
if (parentLinkId) {
return false
}
return !piece.composantId
})
return filteredPieces return filteredPieces
}) })
@@ -2081,96 +2275,319 @@ function mergeComponentTrees(existing = [], updates = []) {
return merged return merged
} }
const buildMachineHierarchyFromLinks = (componentLinks = [], pieceLinks = []) => {
const componentMap = new Map()
const componentRoots = []
componentLinks.forEach((link, index) => {
if (!isPlainObject(link)) {
return
}
const baseComponent = isPlainObject(link.composant)
? link.composant
: isPlainObject(link.component)
? link.component
: isPlainObject(link.targetComponent)
? link.targetComponent
: {}
const linkId = resolveIdentifier(link.id, link.linkId, link.machineComponentLinkId)
const node = {
...baseComponent,
machineComponentLink: link,
machineComponentLinkId: linkId,
linkId,
componentLinkId: linkId,
composantId: resolveIdentifier(
baseComponent.composantId,
baseComponent.componentId,
link.composantId,
link.componentId,
baseComponent.id,
),
parentComponentLinkId: resolveIdentifier(
link.parentComponentLinkId,
link.parentLinkId,
link.parentMachineComponentLinkId,
baseComponent.parentComponentLinkId,
baseComponent.parentLinkId,
),
parentComposantId: resolveIdentifier(
baseComponent.parentComposantId,
link.parentComponentId,
),
parentRequirementId: resolveIdentifier(
baseComponent.parentRequirementId,
link.parentRequirementId,
),
parentMachineComponentRequirementId: resolveIdentifier(
baseComponent.parentMachineComponentRequirementId,
link.parentMachineComponentRequirementId,
),
parentMachinePieceRequirementId: resolveIdentifier(
baseComponent.parentMachinePieceRequirementId,
link.parentMachinePieceRequirementId,
),
typeMachineComponentRequirement:
link.requirement
|| link.typeMachineComponentRequirement
|| baseComponent.typeMachineComponentRequirement
|| null,
typeMachineComponentRequirementId: resolveIdentifier(
link.requirementId,
link.typeMachineComponentRequirementId,
(link.requirement || link.typeMachineComponentRequirement)?.id,
baseComponent.typeMachineComponentRequirementId,
),
definition: baseComponent.definition || {},
pieces: [],
subComponents: [],
sousComposants: [],
}
if (!node.id) {
node.id = resolveIdentifier(
baseComponent.id,
node.composantId,
link.composantId,
link.componentId,
`component-${index}`,
)
}
node.requirementId = node.typeMachineComponentRequirementId
node.machineComponentLinkOverrides = link.overrides || null
node.overrides = link.overrides || null
node.definitionOverrides = link.overrides || null
node.subcomponents = node.subComponents
componentMap.set(node.machineComponentLinkId || node.id, node)
})
componentMap.forEach((node) => {
const parentLinkId = resolveIdentifier(node.parentComponentLinkId)
if (parentLinkId && componentMap.has(parentLinkId)) {
const parent = componentMap.get(parentLinkId)
parent.subComponents.push(node)
parent.sousComposants = parent.subComponents
parent.subcomponents = parent.subComponents
node.parentComposantId = resolveIdentifier(
node.parentComposantId,
parent.composantId,
parent.id,
)
} else {
componentRoots.push(node)
}
})
const machinePieces = []
pieceLinks.forEach((link, index) => {
if (!isPlainObject(link)) {
return
}
const basePiece = isPlainObject(link.piece)
? link.piece
: isPlainObject(link.targetPiece)
? link.targetPiece
: isPlainObject(link.pieceModel)
? link.pieceModel
: {}
const linkId = resolveIdentifier(link.id, link.linkId, link.machinePieceLinkId)
const parentComponentLinkId = resolveIdentifier(
link.parentComponentLinkId,
link.parentLinkId,
link.parentMachineComponentLinkId,
basePiece.parentComponentLinkId,
)
const pieceEntry = {
...basePiece,
id: resolveIdentifier(basePiece.id, link.pieceId, linkId, `piece-${index}`),
pieceId: resolveIdentifier(basePiece.id, link.pieceId),
machinePieceLink: link,
machinePieceLinkId: linkId,
linkId,
parentComponentLinkId,
parentLinkId: resolveIdentifier(
link.parentLinkId,
link.parentMachinePieceLinkId,
basePiece.parentLinkId,
),
parentPieceLinkId: resolveIdentifier(
link.parentPieceLinkId,
basePiece.parentPieceLinkId,
),
parentPieceId: resolveIdentifier(
basePiece.parentPieceId,
link.parentPieceId,
),
parentComponentId: resolveIdentifier(
basePiece.parentComponentId,
link.parentComponentId,
),
composantId: resolveIdentifier(
basePiece.composantId,
basePiece.componentId,
link.composantId,
link.componentId,
),
typeMachinePieceRequirement:
link.requirement
|| link.typeMachinePieceRequirement
|| basePiece.typeMachinePieceRequirement
|| null,
}
pieceEntry.typeMachinePieceRequirementId = resolveIdentifier(
link.requirementId,
link.typeMachinePieceRequirementId,
pieceEntry.typeMachinePieceRequirement?.id,
basePiece.typeMachinePieceRequirementId,
)
pieceEntry.parentMachineComponentRequirementId = resolveIdentifier(
basePiece.parentMachineComponentRequirementId,
link.parentMachineComponentRequirementId,
)
pieceEntry.parentMachinePieceRequirementId = resolveIdentifier(
basePiece.parentMachinePieceRequirementId,
link.parentMachinePieceRequirementId,
)
pieceEntry.definition = basePiece.definition || {}
pieceEntry.overrides = link.overrides || null
if (!pieceEntry.name && link.overrides?.name) {
pieceEntry.name = link.overrides.name
}
if (parentComponentLinkId && componentMap.has(parentComponentLinkId)) {
const parent = componentMap.get(parentComponentLinkId)
parent.pieces.push(pieceEntry)
pieceEntry.parentComponentName = parent.name || parent.nom || null
} else {
machinePieces.push(pieceEntry)
}
})
componentMap.forEach((node) => {
node.sousComposants = node.subComponents
node.subcomponents = node.subComponents
})
return {
components: componentRoots,
machinePieces,
}
}
const resolveLinkArray = (source, keys) => {
if (!source || typeof source !== 'object') {
return null
}
for (const key of keys) {
const value = source[key]
if (Array.isArray(value)) {
return value
}
}
return null
}
const applyMachineLinks = (source) => {
const container = source?.machine ?? null
const componentLinks =
resolveLinkArray(source, ['componentLinks', 'machineComponentLinks']) ??
resolveLinkArray(container, ['componentLinks', 'machineComponentLinks'])
const pieceLinks =
resolveLinkArray(source, ['pieceLinks', 'machinePieceLinks']) ??
resolveLinkArray(container, ['pieceLinks', 'machinePieceLinks'])
if (componentLinks === null && pieceLinks === null) {
return false
}
const normalizedComponentLinks = componentLinks ?? []
const normalizedPieceLinks = pieceLinks ?? []
machineComponentLinks.value = normalizedComponentLinks
machinePieceLinks.value = normalizedPieceLinks
const { components: hierarchy, machinePieces: machineLevelPieces } =
buildMachineHierarchyFromLinks(normalizedComponentLinks, normalizedPieceLinks)
components.value = transformComponentCustomFields(hierarchy)
pieces.value = transformCustomFields(machineLevelPieces)
return true
}
// Methods // Methods
const loadMachineData = async () => { const loadMachineData = async () => {
loading.value = true loading.value = true
try { try {
console.log('Début du chargement des données pour machineId:', machineId) const machineResult = await get(`/machines/${machineId}`)
// Load specific machine directly from API
const { apiCall } = useApi()
console.log('Appel API pour machine:', machineId)
const machineResult = await apiCall(`/machines/${machineId}`, { method: 'GET' })
console.log('Résultat machine complet:', machineResult)
console.log('machineResult.success:', machineResult.success)
console.log('machineResult.data:', machineResult.data)
console.log('machineResult.error:', machineResult.error)
console.log('Machine customFieldValues:', machineResult.data?.customFieldValues)
console.log('Nombre de champs personnalisés:', machineResult.data?.customFieldValues?.length)
if (machineResult.success) {
machine.value = machineResult.data
machine.value.documents = machine.value.documents || []
machine.value.customFieldValues = machine.value.customFieldValues || []
machineDocumentsLoaded.value = !!(machine.value.documents?.length)
console.log('Machine trouvée et assignée:', machine.value)
syncMachineCustomFields() if (!machineResult.success) {
} else { console.error('Machine non trouvée:', machineId, machineResult.error)
console.error('Machine non trouvée:', machineId) machine.value = null
console.error('Erreur API:', machineResult.error) components.value = []
loading.value = false pieces.value = []
return return
} }
// Initialize machine fields const machinePayload = machineResult.data?.machine && typeof machineResult.data.machine === 'object'
? machineResult.data.machine
: machineResult.data
if (!machinePayload || typeof machinePayload !== 'object') {
console.error('Réponse machine invalide pour', machineId)
machine.value = null
components.value = []
pieces.value = []
return
}
machine.value = {
...machinePayload,
documents: machinePayload.documents || [],
customFieldValues: machinePayload.customFieldValues || [],
}
machineDocumentsLoaded.value = machine.value.documents.length > 0
syncMachineCustomFields()
initMachineFields() initMachineFields()
console.log('Champs machine initialisés')
console.log('Machine après initialisation:', machine.value) const linksApplied = applyMachineLinks(machineResult.data)
console.log('Machine name:', machineName.value)
console.log('Machine reference:', machineReference.value) if (machine.value) {
machine.value.componentLinks = machineComponentLinks.value
// Load components with hierarchy machine.value.pieceLinks = machinePieceLinks.value
console.log('Chargement des composants avec hiérarchie...')
const componentsResult = await apiCall(`/composants/hierarchy/${machineId}`, { method: 'GET' })
console.log('Résultat composants:', componentsResult)
console.log('Structure des données reçues:', JSON.stringify(componentsResult.data, null, 2))
if (componentsResult.success) {
console.log('Transformation des composants...')
components.value = transformComponentCustomFields(componentsResult.data)
console.log('Composants chargés:', components.value.length)
console.log('Composants transformés:', components.value)
collapseAllComponents()
// Debug: afficher la hiérarchie
console.log('=== HIÉRARCHIE DES COMPOSANTS ===')
components.value.forEach(comp => {
console.log(`Composant: ${comp.name} (ID: ${comp.id}, Parent: ${comp.parentComposantId})`)
if (comp.subComponents && comp.subComponents.length > 0) {
console.log(` Sous-composants: ${comp.subComponents.map(sc => sc.name).join(', ')}`)
}
})
console.log('=== FIN HIÉRARCHIE ===')
} else {
console.error('Erreur lors du chargement des composants:', componentsResult.error)
} }
// Load pieces from machine response instead of separate API call if (!linksApplied) {
if (machine.value && machine.value.pieces) { components.value = transformComponentCustomFields(machinePayload.components || [])
// Transformer les champs personnalisés pieces.value = transformCustomFields(machinePayload.pieces || [])
pieces.value = transformCustomFields(machine.value.pieces)
console.log('Pièces transformées:', pieces.value)
console.log('Pièces chargées:', pieces.value.length)
} else {
console.log('Aucune pièce trouvée dans la réponse de la machine')
} }
collapseAllComponents()
if (!machineDocumentsLoaded.value) { if (!machineDocumentsLoaded.value) {
await refreshMachineDocuments() await refreshMachineDocuments()
} }
console.log('Chargement terminé avec succès')
} catch (error) { } catch (error) {
console.error('Erreur lors du chargement des données:', error) console.error('Erreur lors du chargement des données:', error)
} finally { } finally {
loading.value = false loading.value = false
console.log('Loading terminé, loading.value =', loading.value)
} }
} }
const updateMachineInfo = async () => { const updateMachineInfo = async () => {
if (!machine.value) return if (!machine.value) return
try { try {
const result = await updateMachineApi(machine.value.id, { const result = await updateMachineApi(machine.value.id, {
name: machineName.value, name: machineName.value,
@@ -2178,8 +2595,25 @@ const updateMachineInfo = async () => {
constructeurId: machineConstructeurId.value || null constructeurId: machineConstructeurId.value || null
}) })
if (result.success) { if (result.success) {
machine.value = result.data const machinePayload = result.data?.machine && typeof result.data.machine === 'object'
machineConstructeurId.value = result.data.constructeurId || result.data.constructeur?.id || null ? result.data.machine
: result.data
if (machinePayload && typeof machinePayload === 'object') {
machine.value = {
...machine.value,
...machinePayload,
documents: machinePayload.documents || machine.value.documents || [],
customFieldValues: machinePayload.customFieldValues || machine.value.customFieldValues || [],
}
machineConstructeurId.value = machine.value.constructeurId || machine.value.constructeur?.id || null
const linksApplied = applyMachineLinks(result.data)
if (linksApplied && machine.value) {
machine.value.componentLinks = machineComponentLinks.value
machine.value.pieceLinks = machinePieceLinks.value
}
}
} }
} catch (error) { } catch (error) {
console.error('Erreur lors de la mise à jour de la machine:', error) console.error('Erreur lors de la mise à jour de la machine:', error)
@@ -2348,14 +2782,12 @@ const updatePieceCustomField = async (fieldUpdate) => {
} }
} }
const editComponent = (component) => { const editComponent = () => {
// TODO: Implement edit modal toast.showInfo('La modification des composants sera bientôt disponible')
console.log('Edit component:', component)
} }
const editPiece = (piece) => { const editPiece = () => {
// TODO: Implement edit modal toast.showInfo('La modification des pièces sera bientôt disponible')
console.log('Edit piece:', piece)
} }
const toggleEditMode = () => { const toggleEditMode = () => {
@@ -2415,7 +2847,6 @@ onMounted(() => {
const route = useRoute() const route = useRoute()
if (route.query.edit === 'true') { if (route.query.edit === 'true') {
isEditMode.value = true isEditMode.value = true
console.log('Mode édition activé depuis l\'URL')
} }
}) })
</script> </script>

View File

@@ -203,16 +203,18 @@
Constructeur : Constructeur :
{{ findComponentById(entry.composantId)?.constructeur?.name || findComponentById(entry.composantId)?.constructeurName || "—" }} {{ findComponentById(entry.composantId)?.constructeur?.name || findComponentById(entry.composantId)?.constructeurName || "—" }}
</div> </div>
<div> <div>
Machine actuelle : Machines liées :
{{ findComponentById(entry.composantId)?.machine?.name || findComponentById(entry.composantId)?.machineId || "Non affecté" }} {{ formatAssignmentList(getComponentMachineAssignments(findComponentById(entry.composantId))) || 'Aucune' }}
</div> </div>
<div <div
v-if="findComponentById(entry.composantId)?.machine?.name" v-if="formatAssignmentList(getComponentMachineAssignments(findComponentById(entry.composantId)))"
class="text-warning mt-1" class="text-warning mt-1"
> >
La réaffectation détachera ce composant de sa machine actuelle lors de la création. Ce composant est déjà lié à
</div> {{ formatAssignmentList(getComponentMachineAssignments(findComponentById(entry.composantId))) }}.
La création ajoutera un nouveau lien.
</div>
</div> </div>
</div> </div>
</div> </div>
@@ -319,20 +321,20 @@
Constructeur : Constructeur :
{{ findPieceById(entry.pieceId)?.constructeur?.name || findPieceById(entry.pieceId)?.constructeurName || "—" }} {{ findPieceById(entry.pieceId)?.constructeur?.name || findPieceById(entry.pieceId)?.constructeurName || "—" }}
</div> </div>
<div> <div>
Machine actuelle : Machines liées :
{{ findPieceById(entry.pieceId)?.machine?.name || findPieceById(entry.pieceId)?.machineId || "Non affecté" }} {{ formatAssignmentList(getPieceMachineAssignments(findPieceById(entry.pieceId))) || 'Aucune' }}
</div> </div>
<div> <div>
Composant actuel : Composants liés :
{{ findPieceById(entry.pieceId)?.composant?.name || findPieceById(entry.pieceId)?.composantId || "Non affecté" }} {{ formatAssignmentList(getPieceComponentAssignments(findPieceById(entry.pieceId))) || 'Aucun' }}
</div> </div>
<div <div
v-if="findPieceById(entry.pieceId)?.machine?.name || findPieceById(entry.pieceId)?.composant?.name" v-if="formatAssignmentList(getPieceMachineAssignments(findPieceById(entry.pieceId))) || formatAssignmentList(getPieceComponentAssignments(findPieceById(entry.pieceId)))"
class="text-warning mt-1" class="text-warning mt-1"
> >
Cette pièce sera détachée de son affectation actuelle pendant la création. Cette pièce dispose déjà de liaisons existantes. La création ajoutera un nouveau lien.
</div> </div>
</div> </div>
</div> </div>
</div> </div>
@@ -583,6 +585,7 @@ import { useMachineTypesApi } from '~/composables/useMachineTypesApi'
import { useComposants } from '~/composables/useComposants' import { useComposants } from '~/composables/useComposants'
import { usePieces } from '~/composables/usePieces' import { usePieces } from '~/composables/usePieces'
import { useToast } from '~/composables/useToast' import { useToast } from '~/composables/useToast'
import { sanitizeDefinitionOverrides } from '~/shared/modelUtils'
import IconLucidePlus from '~icons/lucide/plus' import IconLucidePlus from '~icons/lucide/plus'
import IconLucideX from '~icons/lucide/x' import IconLucideX from '~icons/lucide/x'
import IconLucideEye from '~icons/lucide/eye' import IconLucideEye from '~icons/lucide/eye'
@@ -639,6 +642,215 @@ const pieceById = computed(() => {
const componentInventory = computed(() => composants.value || []) const componentInventory = computed(() => composants.value || [])
const pieceInventory = computed(() => pieces.value || []) const pieceInventory = computed(() => pieces.value || [])
const isPlainObject = value => value !== null && typeof value === 'object' && !Array.isArray(value)
const toTrimmedString = (value) => {
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
}
const dedupeAssignments = (assignments) => {
const seen = new Set()
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
})
}
const normalizeMachineAssignment = (input) => {
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.machine || input.machineData || input
if (!isPlainObject(container)) {
return null
}
const id = container.id ?? input.machineId ?? input.id ?? null
const name =
container.name
|| input.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,
}
}
const collectMachineAssignments = (source) => {
if (!isPlainObject(source)) {
return []
}
const candidates = [
source.machines,
source.machineLinks,
source.machineAssignments,
source.machinesAssignments,
source.linkedMachines,
]
const assignments = []
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)
}
const normalizeComponentAssignment = (input) => {
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.component || input.composant || input
if (!isPlainObject(container)) {
return null
}
const id = container.id ?? input.componentId ?? input.composantId ?? input.id ?? null
const name =
container.name
|| input.componentName
|| input.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,
}
}
const collectComponentAssignments = (source) => {
if (!isPlainObject(source)) {
return []
}
const candidates = [
source.components,
source.composants,
source.componentLinks,
source.linkedComponents,
]
const assignments = []
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)
}
const getComponentMachineAssignments = component => collectMachineAssignments(component || {})
const getPieceMachineAssignments = piece => collectMachineAssignments(piece || {})
const getPieceComponentAssignments = piece => collectComponentAssignments(piece || {})
const formatAssignmentList = (assignments) => {
if (!Array.isArray(assignments) || assignments.length === 0) {
return ''
}
return assignments
.map((assignment) => assignment?.name || assignment?.id)
.filter(Boolean)
.join(', ')
}
const selectedComponentIds = computed(() => { const selectedComponentIds = computed(() => {
const ids = [] const ids = []
Object.values(componentRequirementSelections).forEach((entries) => { Object.values(componentRequirementSelections).forEach((entries) => {
@@ -715,10 +927,9 @@ const formatComponentOption = (component) => {
if (constructeurName) { if (constructeurName) {
parts.push(constructeurName) parts.push(constructeurName)
} }
if (component.machine?.name) { const machineAssignments = getComponentMachineAssignments(component)
parts.push(`Machine: ${component.machine.name}`) if (machineAssignments.length) {
} else if (component.machineId) { parts.push(`Machines: ${formatAssignmentList(machineAssignments)}`)
parts.push(`Machine: ${component.machineId}`)
} }
return parts.join(' • ') return parts.join(' • ')
} }
@@ -735,15 +946,13 @@ const formatPieceOption = (piece) => {
if (constructeurName) { if (constructeurName) {
parts.push(constructeurName) parts.push(constructeurName)
} }
if (piece.machine?.name) { const machineAssignments = getPieceMachineAssignments(piece)
parts.push(`Machine: ${piece.machine.name}`) if (machineAssignments.length) {
} else if (piece.machineId) { parts.push(`Machines: ${formatAssignmentList(machineAssignments)}`)
parts.push(`Machine: ${piece.machineId}`)
} }
if (piece.composant?.name) { const componentAssignments = getPieceComponentAssignments(piece)
parts.push(`Composant: ${piece.composant.name}`) if (componentAssignments.length) {
} else if (piece.composantId) { parts.push(`Composants: ${formatAssignmentList(componentAssignments)}`)
parts.push(`Composant: ${piece.composantId}`)
} }
return parts.join(' • ') return parts.join(' • ')
} }
@@ -877,10 +1086,58 @@ const removePieceSelectionEntry = (requirementId, index) => {
pieceRequirementSelections[requirementId] = entries.filter((_, i) => i !== index) pieceRequirementSelections[requirementId] = entries.filter((_, i) => i !== index)
} }
const extractParentIdentifiers = (source) => {
if (!isPlainObject(source)) {
return {}
}
const identifiers = {}
const idKeys = [
'parentRequirementId',
'parentComponentRequirementId',
'parentPieceRequirementId',
'parentMachineComponentRequirementId',
'parentMachinePieceRequirementId',
'parentLinkId',
'parentComponentId',
'parentPieceId',
]
idKeys.forEach((key) => {
if (Object.prototype.hasOwnProperty.call(source, key)) {
const value = source[key]
if (value !== undefined && value !== null && value !== '') {
identifiers[key] = value
}
}
})
const objectKeys = [
'parentRequirement',
'parentComponentRequirement',
'parentPieceRequirement',
'parentMachineComponentRequirement',
'parentMachinePieceRequirement',
]
objectKeys.forEach((key) => {
const value = source[key]
if (isPlainObject(value) && value.id !== undefined && value.id !== null && value.id !== '') {
const idKey = `${key}Id`
if (!Object.prototype.hasOwnProperty.call(identifiers, idKey)) {
identifiers[idKey] = value.id
}
}
})
return identifiers
}
const validateRequirementSelections = (type) => { const validateRequirementSelections = (type) => {
const errors = [] const errors = []
const componentSelectionsPayload = [] const componentLinksPayload = []
const pieceSelectionsPayload = [] const pieceLinksPayload = []
for (const requirement of type.componentRequirements || []) { for (const requirement of type.componentRequirements || []) {
const entries = getComponentRequirementEntries(requirement.id) const entries = getComponentRequirementEntries(requirement.id)
@@ -907,16 +1164,6 @@ const validateRequirementSelections = (type) => {
return return
} }
if (component.machineId) {
errors.push(`Le composant "${component.name || component.id}" est déjà affecté à une machine.`)
return
}
if (component.parentComposantId) {
errors.push(`Le composant "${component.name || component.id}" est déjà rattaché à un autre composant.`)
return
}
const requiredTypeId = requirement.typeComposantId || requirement.typeComposant?.id || null const requiredTypeId = requirement.typeComposantId || requirement.typeComposant?.id || null
if ( if (
requiredTypeId && requiredTypeId &&
@@ -927,10 +1174,19 @@ const validateRequirementSelections = (type) => {
return return
} }
componentSelectionsPayload.push({ const payload = {
requirementId: requirement.id, requirementId: requirement.id,
composantId: entry.composantId, composantId: entry.composantId,
}) }
const overrides = sanitizeDefinitionOverrides(entry.definition)
if (overrides) {
payload.overrides = overrides
}
Object.assign(payload, extractParentIdentifiers(requirement), extractParentIdentifiers(entry))
componentLinksPayload.push(payload)
}) })
} }
@@ -959,11 +1215,6 @@ const validateRequirementSelections = (type) => {
return return
} }
if (piece.machineId || piece.composantId) {
errors.push(`La pièce "${piece.name || piece.id}" est déjà affectée.`)
return
}
const requiredTypeId = requirement.typePieceId || requirement.typePiece?.id || null const requiredTypeId = requirement.typePieceId || requirement.typePiece?.id || null
if ( if (
requiredTypeId && requiredTypeId &&
@@ -974,10 +1225,19 @@ const validateRequirementSelections = (type) => {
return return
} }
pieceSelectionsPayload.push({ const payload = {
requirementId: requirement.id, requirementId: requirement.id,
pieceId: entry.pieceId, pieceId: entry.pieceId,
}) }
const overrides = sanitizeDefinitionOverrides(entry.definition)
if (overrides) {
payload.overrides = overrides
}
Object.assign(payload, extractParentIdentifiers(requirement), extractParentIdentifiers(entry))
pieceLinksPayload.push(payload)
}) })
} }
@@ -987,8 +1247,8 @@ const validateRequirementSelections = (type) => {
return { return {
valid: true, valid: true,
componentSelections: componentSelectionsPayload, componentLinks: componentLinksPayload,
pieceSelections: pieceSelectionsPayload, pieceLinks: pieceLinksPayload,
} }
} }
@@ -1059,6 +1319,11 @@ const machinePreview = computed(() => {
if (constructeurName) { if (constructeurName) {
subtitleParts.push(constructeurName) subtitleParts.push(constructeurName)
} }
const machineAssignments = selectedComponent ? getComponentMachineAssignments(selectedComponent) : []
const assignmentLabel = formatAssignmentList(machineAssignments)
if (assignmentLabel) {
subtitleParts.push(`Liée à ${assignmentLabel}`)
}
const status = entry.composantId ? 'complete' : 'pending' const status = entry.composantId ? 'complete' : 'pending'
return { return {
@@ -1066,6 +1331,8 @@ const machinePreview = computed(() => {
status, status,
title: displayName, title: displayName,
subtitle: subtitleParts.join(' • ') || null, subtitle: subtitleParts.join(' • ') || null,
assignmentLabel,
assignments: machineAssignments,
} }
}) })
@@ -1086,9 +1353,22 @@ const machinePreview = computed(() => {
issues.push({ message: 'Sélectionner un composant pour chaque entrée.', kind: 'error', anchor: `component-group-${requirement.id}` }) issues.push({ message: 'Sélectionner un composant pour chaque entrée.', kind: 'error', anchor: `component-group-${requirement.id}` })
} }
const status = issues.some(issue => issue.kind === 'error') normalizedEntries.forEach((entrySummary) => {
if (entrySummary.assignmentLabel) {
issues.push({
message: `Le composant "${entrySummary.title}" est déjà lié à ${entrySummary.assignmentLabel}.`,
kind: 'warning',
anchor: `component-group-${requirement.id}`,
})
}
})
const hasErrors = issues.some(issue => issue.kind === 'error')
const hasWarnings = issues.some(issue => issue.kind === 'warning') || completed < entries.length
const status = hasErrors
? 'error' ? 'error'
: completed < entries.length : hasWarnings
? 'warning' ? 'warning'
: 'ready' : 'ready'
@@ -1120,6 +1400,16 @@ const machinePreview = computed(() => {
if (constructeurName) { if (constructeurName) {
subtitleParts.push(constructeurName) subtitleParts.push(constructeurName)
} }
const machineAssignments = selectedPiece ? getPieceMachineAssignments(selectedPiece) : []
const machineAssignmentLabel = formatAssignmentList(machineAssignments)
if (machineAssignmentLabel) {
subtitleParts.push(`Machines: ${machineAssignmentLabel}`)
}
const componentAssignments = selectedPiece ? getPieceComponentAssignments(selectedPiece) : []
const componentAssignmentLabel = formatAssignmentList(componentAssignments)
if (componentAssignmentLabel) {
subtitleParts.push(`Composants: ${componentAssignmentLabel}`)
}
const status = entry.pieceId ? 'complete' : 'pending' const status = entry.pieceId ? 'complete' : 'pending'
return { return {
@@ -1127,6 +1417,10 @@ const machinePreview = computed(() => {
status, status,
title: displayName, title: displayName,
subtitle: subtitleParts.join(' • ') || null, subtitle: subtitleParts.join(' • ') || null,
machineAssignmentLabel,
componentAssignmentLabel,
machineAssignments,
componentAssignments,
} }
}) })
@@ -1147,9 +1441,29 @@ const machinePreview = computed(() => {
issues.push({ message: 'Sélectionner une pièce pour chaque entrée.', kind: 'error', anchor: `piece-group-${requirement.id}` }) issues.push({ message: 'Sélectionner une pièce pour chaque entrée.', kind: 'error', anchor: `piece-group-${requirement.id}` })
} }
const status = issues.some(issue => issue.kind === 'error') normalizedEntries.forEach((entrySummary) => {
if (entrySummary.machineAssignmentLabel) {
issues.push({
message: `La pièce "${entrySummary.title}" est déjà liée aux machines ${entrySummary.machineAssignmentLabel}.`,
kind: 'warning',
anchor: `piece-group-${requirement.id}`,
})
}
if (entrySummary.componentAssignmentLabel) {
issues.push({
message: `La pièce "${entrySummary.title}" est déjà rattachée aux composants ${entrySummary.componentAssignmentLabel}.`,
kind: 'warning',
anchor: `piece-group-${requirement.id}`,
})
}
})
const hasErrors = issues.some(issue => issue.kind === 'error')
const hasWarnings = issues.some(issue => issue.kind === 'warning') || completed < entries.length
const status = hasErrors
? 'error' ? 'error'
: completed < entries.length : hasWarnings
? 'warning' ? 'warning'
: 'ready' : 'ready'
@@ -1293,8 +1607,8 @@ const finalizeMachineCreation = async () => {
const hasRequirements = (type.componentRequirements?.length || 0) > 0 || (type.pieceRequirements?.length || 0) > 0 const hasRequirements = (type.componentRequirements?.length || 0) > 0 || (type.pieceRequirements?.length || 0) > 0
let componentSelections = [] let componentLinks = []
let pieceSelections = [] let pieceLinks = []
if (hasRequirements) { if (hasRequirements) {
const validationResult = validateRequirementSelections(type) const validationResult = validateRequirementSelections(type)
@@ -1302,16 +1616,16 @@ const finalizeMachineCreation = async () => {
toast.showError(validationResult.error) toast.showError(validationResult.error)
return return
} }
componentSelections = validationResult.componentSelections componentLinks = validationResult.componentLinks
pieceSelections = validationResult.pieceSelections pieceLinks = validationResult.pieceLinks
} }
const payload = { const payload = {
...baseMachineData, ...baseMachineData,
...(hasRequirements ...(hasRequirements
? { ? {
componentSelections, componentLinks,
pieceSelections pieceLinks
} }
: {}) : {})
} }