Normalize machine link responses
This commit is contained in:
@@ -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')
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
: {})
|
: {})
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user