diff --git a/app/components/ComposantSelect.vue b/app/components/ComposantSelect.vue new file mode 100644 index 0000000..f63f449 --- /dev/null +++ b/app/components/ComposantSelect.vue @@ -0,0 +1,116 @@ + + + diff --git a/app/components/PieceSelect.vue b/app/components/PieceSelect.vue new file mode 100644 index 0000000..9f08cbf --- /dev/null +++ b/app/components/PieceSelect.vue @@ -0,0 +1,116 @@ + + + diff --git a/app/composables/useComponentEdit.ts b/app/composables/useComponentEdit.ts index 38408d1..674e0ec 100644 --- a/app/composables/useComponentEdit.ts +++ b/app/composables/useComponentEdit.ts @@ -270,6 +270,94 @@ export function useComponentEdit(componentId: string) { } }) + // --- Slot selection entries (for selectors) --- + + const pieceSlotEntries = computed(() => { + const structure = component.value?.structure + if (!structure?.pieces) return [] + return (structure.pieces as any[]).map((slot: any, i: number) => ({ + slotId: slot.slotId, + typePieceId: slot.typePieceId, + selectedPieceId: slot.selectedPieceId ?? null, + quantity: slot.quantity ?? 1, + position: slot.position ?? i, + label: pieceTypeLabelMap.value[slot.typePieceId] || `Pièce #${i + 1}`, + })) + }) + + const productSlotEntries = computed(() => { + const structure = component.value?.structure + if (!structure?.products) return [] + return (structure.products as any[]).map((slot: any, i: number) => ({ + slotId: slot.slotId, + typeProductId: slot.typeProductId, + selectedProductId: slot.selectedProductId ?? null, + familyCode: slot.familyCode, + position: slot.position ?? i, + label: productTypeLabelMap.value[slot.typeProductId] || `Produit #${i + 1}`, + })) + }) + + const subcomponentSlotEntries = computed(() => { + const structure = component.value?.structure + if (!structure?.subcomponents) return [] + return (structure.subcomponents as any[]).map((slot: any, i: number) => ({ + slotId: slot.slotId, + typeComposantId: slot.typeComposantId, + selectedComponentId: slot.selectedComponentId ?? null, + alias: slot.alias, + familyCode: slot.familyCode, + position: slot.position ?? i, + label: slot.alias || `Sous-composant #${i + 1}`, + })) + }) + + const savePieceSlotSelection = async (slotId: string, selectedPieceId: string | null) => { + try { + await patch(`/composant-piece-slots/${slotId}`, { selectedPieceId }) + // Update local structure + const structure = component.value?.structure + if (structure?.pieces) { + const slot = (structure.pieces as any[]).find((s: any) => s.slotId === slotId) + if (slot) slot.selectedPieceId = selectedPieceId + } + toast.showSuccess('Pièce mise à jour') + } + catch (error: any) { + toast.showError(error?.message || 'Erreur lors de la mise à jour') + } + } + + const saveProductSlotSelection = async (slotId: string, selectedProductId: string | null) => { + try { + await patch(`/composant-product-slots/${slotId}`, { selectedProductId }) + const structure = component.value?.structure + if (structure?.products) { + const slot = (structure.products as any[]).find((s: any) => s.slotId === slotId) + if (slot) slot.selectedProductId = selectedProductId + } + toast.showSuccess('Produit mis à jour') + } + catch (error: any) { + toast.showError(error?.message || 'Erreur lors de la mise à jour') + } + } + + const saveSubcomponentSlotSelection = async (slotId: string, selectedComposantId: string | null) => { + try { + await patch(`/composant-subcomponent-slots/${slotId}`, { selectedComposantId }) + const structure = component.value?.structure + if (structure?.subcomponents) { + const slot = (structure.subcomponents as any[]).find((s: any) => s.slotId === slotId) + if (slot) slot.selectedComponentId = selectedComposantId + } + toast.showSuccess('Sous-composant mis à jour') + } + catch (error: any) { + toast.showError(error?.message || 'Erreur lors de la mise à jour') + } + } + const saveSlotQuantity = async (entry: SelectionEntry) => { const slotId = entry.slotId const quantity = typeof entry._definition?.quantity === 'number' @@ -423,14 +511,12 @@ export function useComponentEdit(componentId: string) { ]) loading.value = false - // Defer bulk catalog loads — only needed when component has structure selections - if (component.value?.structure) { - Promise.allSettled([ - loadPieces({ itemsPerPage: 200 }), - loadProducts({ itemsPerPage: 200 }), - loadComposants({ itemsPerPage: 200 }), - ]).catch(() => {}) - } + // Load catalogs for slot selectors + Promise.allSettled([ + loadPieces({ itemsPerPage: 200 }), + loadProducts({ itemsPerPage: 200 }), + loadComposants({ itemsPerPage: 200 }), + ]).catch(() => {}) }) return { @@ -456,6 +542,9 @@ export function useComponentEdit(componentId: string) { selectedType, selectedTypeStructure, structureSelections, + pieceSlotEntries, + productSlotEntries, + subcomponentSlotEntries, // History history, @@ -470,6 +559,9 @@ export function useComponentEdit(componentId: string) { refreshDocuments, submitEdition, saveSlotQuantity, + savePieceSlotSelection, + saveProductSlotSelection, + saveSubcomponentSlotSelection, resolvePieceLabel, resolveProductLabel, resolveSubcomponentLabel, diff --git a/app/pages/component/[id]/edit.vue b/app/pages/component/[id]/edit.vue index fff3470..f0c340e 100644 --- a/app/pages/component/[id]/edit.vue +++ b/app/pages/component/[id]/edit.vue @@ -152,57 +152,76 @@ />
-

Sélections actuelles

+

Sélections du squelette

- Voici les pièces, produits et sous-composants réellement choisis pour ce composant. + Choisissez les pièces, produits et sous-composants pour chaque emplacement requis par la catégorie.

-
-
-

Pièces choisies

-
    -
  • - {{ entry.resolvedName }} - ×{{ entry.quantity }} - — {{ entry.requirementLabel }} - -
  • -
+
+

Pièces

+
+
+ + +
+
-
-

Produits choisis

-
    -
  • - {{ entry.resolvedName }} - — {{ entry.requirementLabel }} -
  • -
+
+

Produits

+
+
+ + +
+
-
-

Sous-composants choisis

-
    -
  • - {{ entry.resolvedName }} - — {{ entry.requirementLabel }} -
  • -
+
+

Sous-composants

+
+
+ + +
@@ -312,6 +331,9 @@ const { selectedType, selectedTypeStructure, structureSelections, + pieceSlotEntries, + productSlotEntries, + subcomponentSlotEntries, history, historyLoading, historyError, @@ -321,6 +343,9 @@ const { handleFilesAdded, submitEdition, saveSlotQuantity, + savePieceSlotSelection, + saveProductSlotSelection, + saveSubcomponentSlotSelection, resolvePieceLabel, resolveProductLabel, resolveSubcomponentLabel,