feat: Add model feature for piece and component
This commit is contained in:
@@ -293,29 +293,7 @@
|
||||
:key="`${requirement.id}-piece-${entryIndex}`"
|
||||
class="bg-base-200/60 rounded-md p-3 space-y-3"
|
||||
>
|
||||
<div class="flex flex-wrap items-center gap-2 text-xs">
|
||||
<label class="inline-flex items-center gap-1">
|
||||
<input
|
||||
type="radio"
|
||||
class="radio radio-xs"
|
||||
:checked="entry.mode === 'model'"
|
||||
@change="setPieceSelectionMode(requirement.id, entryIndex, 'model')"
|
||||
/>
|
||||
Modèle existant
|
||||
</label>
|
||||
<label class="inline-flex items-center gap-1">
|
||||
<input
|
||||
type="radio"
|
||||
class="radio radio-xs"
|
||||
:checked="entry.mode === 'manual'"
|
||||
@change="setPieceSelectionMode(requirement.id, entryIndex, 'manual')"
|
||||
:disabled="!requirement.allowNewModels"
|
||||
/>
|
||||
Définir manuellement
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div v-if="entry.mode === 'model'" class="grid grid-cols-1 md:grid-cols-2 gap-3">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-3">
|
||||
<div class="form-control">
|
||||
<label class="label">
|
||||
<span class="label-text text-xs">Modèle de pièce</span>
|
||||
@@ -344,32 +322,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-else class="grid grid-cols-1 md:grid-cols-2 gap-3">
|
||||
<div class="form-control">
|
||||
<label class="label">
|
||||
<span class="label-text text-xs">Nom de la pièce</span>
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
class="input input-bordered input-sm"
|
||||
:value="entry.name"
|
||||
placeholder="Nom de la pièce"
|
||||
@input="updatePieceSelectionEntry(requirement.id, entryIndex, { name: $event.target.value })"
|
||||
/>
|
||||
</div>
|
||||
<div class="form-control">
|
||||
<label class="label">
|
||||
<span class="label-text text-xs">Référence (optionnel)</span>
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
class="input input-bordered input-sm"
|
||||
placeholder="(Non géré pour l'instant)"
|
||||
disabled
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<button
|
||||
type="button"
|
||||
@@ -482,7 +434,6 @@
|
||||
</p>
|
||||
<p v-if="entry.subtitle" class="text-xs text-gray-500">{{ entry.subtitle }}</p>
|
||||
</div>
|
||||
<span v-if="entry.mode === 'manual'" class="badge badge-ghost badge-xs">manuel</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -903,23 +854,12 @@ const machinePreview = computed(() => {
|
||||
const entriesSource = getPieceRequirementEntries(requirement.id)
|
||||
const entriesList = entriesSource ? [...entriesSource] : []
|
||||
const normalizedEntries = entriesList.map((entry, index) => {
|
||||
if (entry.mode === 'model') {
|
||||
const model = resolvePieceModel(requirement, entry.pieceModelId)
|
||||
return {
|
||||
key: `${requirement.id}-${index}`,
|
||||
mode: 'model',
|
||||
status: model ? 'complete' : 'pending',
|
||||
title: model ? model.name : 'Sélectionner un modèle',
|
||||
subtitle: model?.description || null,
|
||||
}
|
||||
}
|
||||
const manualName = (entry.name || '').trim()
|
||||
const model = resolvePieceModel(requirement, entry.pieceModelId)
|
||||
return {
|
||||
key: `${requirement.id}-${index}`,
|
||||
mode: 'manual',
|
||||
status: manualName ? 'complete' : 'pending',
|
||||
title: manualName || 'Nom à renseigner',
|
||||
subtitle: manualName ? null : null,
|
||||
status: model ? 'complete' : 'pending',
|
||||
title: model ? model.name : 'Sélectionner un modèle',
|
||||
subtitle: model?.description || null,
|
||||
}
|
||||
})
|
||||
|
||||
@@ -936,10 +876,6 @@ const machinePreview = computed(() => {
|
||||
issues.push({ message: `Maximum ${max} dépassé`, kind: 'error', anchor: `piece-group-${requirement.id}` })
|
||||
}
|
||||
|
||||
if (!requirement.allowNewModels && normalizedEntries.some((entry) => entry.mode === 'manual' && entry.status === 'complete')) {
|
||||
issues.push({ message: "Ce groupe n'autorise que les modèles existants.", kind: 'error', anchor: `piece-group-${requirement.id}` })
|
||||
}
|
||||
|
||||
if (normalizedEntries.some((entry) => entry.status !== 'complete')) {
|
||||
issues.push({ message: 'Compléter les sélections restantes.', kind: 'warning', anchor: `piece-group-${requirement.id}` })
|
||||
}
|
||||
@@ -1056,9 +992,7 @@ const createComponentSelectionEntry = () => ({
|
||||
})
|
||||
|
||||
const createPieceSelectionEntry = () => ({
|
||||
mode: 'model',
|
||||
pieceModelId: '',
|
||||
name: '',
|
||||
})
|
||||
|
||||
const addComponentSelectionEntry = (requirement) => {
|
||||
@@ -1109,17 +1043,6 @@ const removePieceSelectionEntry = (requirementId, index) => {
|
||||
pieceRequirementSelections[requirementId] = entries.filter((_, i) => i !== index)
|
||||
}
|
||||
|
||||
const setPieceSelectionMode = (requirementId, index, mode) => {
|
||||
const entries = getPieceRequirementEntries(requirementId)
|
||||
pieceRequirementSelections[requirementId] = entries.map((entry, i) => {
|
||||
if (i !== index) return entry
|
||||
if (mode === 'model') {
|
||||
return { ...entry, mode: 'model', pieceModelId: entry.pieceModelId || '', name: '' }
|
||||
}
|
||||
return { ...entry, mode: 'manual', pieceModelId: '', name: entry.name || '' }
|
||||
})
|
||||
}
|
||||
|
||||
const updatePieceSelectionEntry = (requirementId, index, patch) => {
|
||||
const entries = getPieceRequirementEntries(requirementId)
|
||||
pieceRequirementSelections[requirementId] = entries.map((entry, i) =>
|
||||
@@ -1175,12 +1098,7 @@ const validateRequirementSelections = (type) => {
|
||||
|
||||
for (const requirement of type.pieceRequirements || []) {
|
||||
const entries = getPieceRequirementEntries(requirement.id)
|
||||
const usableEntries = entries.filter((entry) => {
|
||||
if (entry.mode === 'model') {
|
||||
return !!entry.pieceModelId
|
||||
}
|
||||
return !!entry.name && entry.name.trim().length > 0
|
||||
})
|
||||
const usableEntries = entries.filter((entry) => !!entry.pieceModelId)
|
||||
|
||||
const min = requirement.minCount ?? (requirement.required ? 1 : 0)
|
||||
const max = requirement.maxCount ?? null
|
||||
@@ -1193,24 +1111,11 @@ const validateRequirementSelections = (type) => {
|
||||
errors.push(`Le groupe "${requirement.label || requirement.typePiece?.name || 'Pièces'}" ne peut dépasser ${max} élément(s).`)
|
||||
}
|
||||
|
||||
if (!requirement.allowNewModels && usableEntries.some((entry) => entry.mode === 'manual')) {
|
||||
errors.push(`Le groupe "${requirement.label || requirement.typePiece?.name || 'Pièces'}" n'autorise que les modèles existants.`)
|
||||
}
|
||||
|
||||
usableEntries.forEach((entry) => {
|
||||
if (entry.mode === 'model') {
|
||||
pieceSelectionsPayload.push({
|
||||
requirementId: requirement.id,
|
||||
pieceModelId: entry.pieceModelId,
|
||||
})
|
||||
} else {
|
||||
pieceSelectionsPayload.push({
|
||||
requirementId: requirement.id,
|
||||
definition: {
|
||||
name: entry.name.trim(),
|
||||
},
|
||||
})
|
||||
}
|
||||
pieceSelectionsPayload.push({
|
||||
requirementId: requirement.id,
|
||||
pieceModelId: entry.pieceModelId,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1322,10 +1227,9 @@ const submitCreatePieceModel = async () => {
|
||||
if (result.success) {
|
||||
await loadPieceModels(createPieceModelModal.requirement.typePieceId)
|
||||
const entries = getPieceRequirementEntries(createPieceModelModal.requirement.id)
|
||||
const targetIndex = entries.findIndex((entry) => entry.mode === 'model' && !entry.pieceModelId)
|
||||
const targetIndex = entries.findIndex((entry) => !entry.pieceModelId)
|
||||
if (targetIndex !== -1) {
|
||||
updatePieceSelectionEntry(createPieceModelModal.requirement.id, targetIndex, {
|
||||
mode: 'model',
|
||||
pieceModelId: result.data.id,
|
||||
})
|
||||
} else {
|
||||
@@ -1334,7 +1238,6 @@ const submitCreatePieceModel = async () => {
|
||||
createPieceModelModal.requirement.id,
|
||||
getPieceRequirementEntries(createPieceModelModal.requirement.id).length - 1,
|
||||
{
|
||||
mode: 'model',
|
||||
pieceModelId: result.data.id,
|
||||
},
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user