fix(piece) : rendre les slots produit optionnels en création et édition
Some checks failed
Auto Tag Develop / tag (push) Has been cancelled

Les sélections de produits liés ne bloquent plus la soumission du
formulaire de création ou d'édition de pièce. Les slots vides restent
visibles et peuvent être remplis ultérieurement.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-06 17:18:05 +02:00
parent 041a04f0e9
commit 9fc88df3ff
3 changed files with 13 additions and 28 deletions

View File

@@ -20,7 +20,6 @@ import {
buildProductRequirementDescriptions,
buildProductRequirementEntries,
resizeProductSelections,
areProductSelectionsFilled,
applyProductSelection,
collectNormalizedProductIds,
} from '~/shared/utils/pieceProductSelectionUtils'
@@ -199,13 +198,7 @@ export function usePieceEdit(pieceId: string) {
buildProductRequirementEntries(structureProducts.value, 'piece-product-requirement'),
)
const productSelectionsFilled = computed(() =>
areProductSelectionsFilled(
requiresProductSelection.value,
productRequirementEntries.value,
productSelections.value,
),
)
const productSelectionsFilled = computed(() => true)
const setProductSelection = (index: number, value: string | null) => {
productSelections.value = applyProductSelection(productSelections.value, index, value)
@@ -355,11 +348,6 @@ export function usePieceEdit(pieceId: string) {
return
}
if (!productSelectionsFilled.value) {
toast.showError('Sélectionnez un produit conforme au squelette.')
return
}
const rawPrice = typeof editionForm.prix === 'string'
? editionForm.prix.trim()
: editionForm.prix === null || editionForm.prix === undefined

View File

@@ -261,7 +261,7 @@
:model-value="productSelections[entry.index] || null"
:disabled="!canEdit || saving"
:type-product-id="entry.typeProductId"
helper-text="Un produit valide est requis pour cette pièce."
helper-text="Sélectionnez un produit (optionnel)."
@update:model-value="(value) => setProductSelection(entry.index, value)"
/>
</div>
@@ -359,6 +359,9 @@
</header>
<template v-if="isEditMode">
<CustomFieldInputGrid :fields="customFieldInputs" :disabled="!canEdit || saving" />
<p v-if="hasRequiredCustomFields && !requiredCustomFieldsFilled" class="text-xs text-warning">
Certains champs personnalisés sont obligatoires. Veuillez les renseigner avant de valider.
</p>
</template>
<template v-else>
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
@@ -420,6 +423,9 @@
Enregistrer les modifications
</button>
</div>
<p v-if="isEditMode && hasRequiredCustomFields && !requiredCustomFieldsFilled" class="text-xs text-error text-right">
Merci de renseigner tous les champs personnalisés obligatoires.
</p>
</div>
</section>
</main>
@@ -460,6 +466,7 @@ const {
constructeurLinks,
productSelections,
customFieldInputs,
requiredCustomFieldsFilled,
pieceTypeList,
selectedType,
resolvedStructure,
@@ -481,6 +488,8 @@ const {
formatPieceStructurePreview,
} = usePieceEdit(String(route.params.id))
const hasRequiredCustomFields = computed(() => customFieldInputs.value.some(f => f.required))
const entityTabs = computed(() => [
{ key: 'general', label: 'Général' },
{ key: 'products', label: 'Produits liés', count: structureProducts.value.length },

View File

@@ -168,7 +168,7 @@
:model-value="productSelections[entry.index] || null"
:disabled="!canEdit || submitting || !selectedType"
:type-product-id="entry.typeProductId"
helper-text="Un produit est requis pour cette pièce."
helper-text="Sélectionnez un produit (optionnel)."
@update:model-value="(value) => setProductSelection(entry.index, value)"
/>
</div>
@@ -273,7 +273,6 @@ import {
buildProductRequirementDescriptions,
buildProductRequirementEntries,
resizeProductSelections,
areProductSelectionsFilled,
applyProductSelection,
collectNormalizedProductIds,
} from '~/shared/utils/pieceProductSelectionUtils'
@@ -379,13 +378,7 @@ const productRequirementEntries = computed(() =>
buildProductRequirementEntries(structureProducts.value, 'piece-create-product-requirement'),
)
const productSelectionsFilled = computed(() =>
areProductSelectionsFilled(
requiresProductSelection.value,
productRequirementEntries.value,
productSelections.value,
),
)
const productSelectionsFilled = computed(() => true)
const setProductSelection = (index: number, value: string | null) => {
productSelections.value = applyProductSelection(productSelections.value, index, value)
@@ -444,11 +437,6 @@ const submitCreation = async () => {
return
}
if (!productSelectionsFilled.value) {
toast.showError('Sélectionnez un produit conforme au squelette.')
return
}
const payload: Record<string, any> = {
name: creationForm.name.trim(),
typePieceId: selectedType.value.id,