From 3705b8daedbf66f8319751efd066ecad6fe9eafe Mon Sep 17 00:00:00 2001 From: matthieu Date: Thu, 29 Jan 2026 19:53:56 +0100 Subject: [PATCH] feat(model-types): allow adding custom fields in restricted mode When a category has linked items (pieces, components, products), enable restricted mode instead of blocking all edits: - Allow adding new custom fields - Lock existing fields from modification or deletion - Hide add buttons for products, pieces, and subcomponents - Display informative message about restricted mode Co-Authored-By: Claude Opus 4.5 --- .../ComponentModelStructureEditor.vue | 5 + app/components/PieceModelStructureEditor.vue | 47 ++++++++- app/components/StructureNodeEditor.vue | 97 +++++++++++++++++-- app/components/model-types/ModelTypeForm.vue | 27 +++++- app/composables/useCategoryEditGuard.ts | 27 ++++-- app/pages/component-category/[id]/edit.vue | 4 + app/pages/piece-category/[id]/edit.vue | 4 + app/pages/product-category/[id]/edit.vue | 4 + 8 files changed, 194 insertions(+), 21 deletions(-) diff --git a/app/components/ComponentModelStructureEditor.vue b/app/components/ComponentModelStructureEditor.vue index f69c3a0..14869e2 100644 --- a/app/components/ComponentModelStructureEditor.vue +++ b/app/components/ComponentModelStructureEditor.vue @@ -10,6 +10,7 @@ :locked-type-label="displayedRootTypeLabel" :allow-subcomponents="allowSubcomponents" :max-subcomponent-depth="maxSubcomponentDepth" + :restricted-mode="restrictedMode" is-root /> @@ -55,6 +56,10 @@ const props = defineProps({ type: Number, default: Infinity, }, + restrictedMode: { + type: Boolean, + default: false, + }, }) const emit = defineEmits(['update:modelValue']) diff --git a/app/components/PieceModelStructureEditor.vue b/app/components/PieceModelStructureEditor.vue index 599f053..27e2a82 100644 --- a/app/components/PieceModelStructureEditor.vue +++ b/app/components/PieceModelStructureEditor.vue @@ -7,10 +7,10 @@ Produits inclus par défaut

- Ces produits s’afficheront lors de la création d’une pièce basée sur cette catégorie. + Ces produits s'afficheront lors de la création d'une pièce basée sur cette catégorie.

- @@ -35,6 +35,7 @@ + + Obligatoire @@ -137,16 +149,27 @@ v-model="field.optionsText" class="textarea textarea-bordered textarea-xs h-20" placeholder="Option 1 Option 2" + :disabled="isFieldLocked(field)" /> +
+ +
@@ -181,6 +204,7 @@ type EditorProduct = { const props = defineProps<{ modelValue?: PieceModelStructure | null + restrictedMode?: boolean }>() const emit = defineEmits<{ @@ -330,6 +354,19 @@ const fields = ref(hydrateFields(props.modelValue)) const products = ref(hydrateProducts(props.modelValue)) const restState = ref>(extractRest(props.modelValue)) +const initialFieldUids = ref>(new Set(fields.value.map(f => f.uid))) +const initialProductUids = ref>(new Set(products.value.map(p => p.uid))) + +const isFieldLocked = (field: EditorField): boolean => { + return props.restrictedMode === true && initialFieldUids.value.has(field.uid) +} + +const isProductLocked = (product: EditorProduct): boolean => { + return props.restrictedMode === true && initialProductUids.value.has(product.uid) +} + +const restrictedMode = computed(() => props.restrictedMode === true) + const applyOrderIndex = (list: EditorField[]): EditorField[] => list.map((field, index) => ({ ...field, @@ -438,6 +475,8 @@ watch( products.value = hydrateProducts(value) products.value.forEach((product) => updateProductTypeMetadata(product)) lastEmitted = incomingSerialized + initialFieldUids.value = new Set(fields.value.map(f => f.uid)) + initialProductUids.value = new Set(products.value.map(p => p.uid)) }, { deep: true }, ) diff --git a/app/components/StructureNodeEditor.vue b/app/components/StructureNodeEditor.vue index f520923..bce8a43 100644 --- a/app/components/StructureNodeEditor.vue +++ b/app/components/StructureNodeEditor.vue @@ -17,6 +17,7 @@ +
- + Obligatoire
+
+ +
@@ -144,7 +163,7 @@

{{ isRoot ? 'Produits inclus par défaut' : 'Produits' }}

- @@ -179,6 +198,7 @@ - +
+ +
@@ -207,7 +236,7 @@

{{ isRoot ? 'Pièces incluses par défaut' : 'Pièces' }}

- @@ -243,6 +272,7 @@