feat(models): align component model editing with type selection~

This commit is contained in:
Matthieu
2025-09-30 17:32:00 +02:00
parent 84bc99d8ec
commit 25d2aa1bcc
3 changed files with 149 additions and 27 deletions

View File

@@ -8,25 +8,32 @@
{{ isRoot ? 'Famille de composant racine' : 'Famille de composant' }}
</span>
</label>
<select
v-model="node.typeComposantId"
class="select select-bordered select-sm w-full"
@change="handleComponentTypeSelect(node)"
>
<option value="">
Sélectionner une famille de composant
</option>
<option
v-for="type in componentTypes"
:key="type.id"
:value="type.id"
<template v-if="!lockType">
<select
v-model="node.typeComposantId"
class="select select-bordered select-sm w-full"
@change="handleComponentTypeSelect(node)"
>
{{ formatComponentTypeOption(type) }}
</option>
</select>
<p class="text-[11px] text-gray-500">
{{ node.typeComposantId ? `Sélection : ${getComponentTypeLabel(node.typeComposantId) || 'Inconnue'}` : 'Aucune famille sélectionnée' }}
</p>
<option value="">
Sélectionner une famille de composant
</option>
<option
v-for="type in componentTypes"
:key="type.id"
:value="type.id"
>
{{ formatComponentTypeOption(type) }}
</option>
</select>
<p class="text-[11px] text-gray-500">
{{ node.typeComposantId ? `Sélection : ${getComponentTypeLabel(node.typeComposantId) || 'Inconnue'}` : 'Aucune famille sélectionnée' }}
</p>
</template>
<template v-else>
<div class="input input-bordered input-sm bg-base-200 flex items-center">
{{ lockedTypeDisplay }}
</div>
</template>
</div>
<button
v-if="!isRoot"
@@ -202,11 +209,15 @@ const props = withDefaults(defineProps<{
componentTypes?: ModelTypeOption[]
pieceTypes?: ModelTypeOption[]
isRoot?: boolean
lockType?: boolean
lockedTypeLabel?: string
}>(), {
depth: 0,
componentTypes: () => [],
pieceTypes: () => [],
isRoot: false,
lockType: false,
lockedTypeLabel: '',
})
const emit = defineEmits(['remove'])
@@ -222,6 +233,12 @@ const containerClass = computed(() => {
})
const headingClass = computed(() => (props.isRoot ? 'text-sm font-semibold' : 'text-xs font-semibold'))
const lockedTypeDisplay = computed(() => {
if (props.lockedTypeLabel) {
return props.lockedTypeLabel
}
return getComponentTypeLabel(props.node?.typeComposantId) || 'Famille non définie'
})
const formatModelTypeOption = (type: ModelTypeOption | undefined | null) => {
if (!type) return ''
@@ -274,6 +291,15 @@ const syncComponentType = (component: any) => {
if (!component) {
return
}
if (props.lockType && props.isRoot) {
if (props.lockedTypeLabel) {
component.typeComposantLabel = props.lockedTypeLabel
if (!component.name || component.name === component.typeComposantLabel) {
component.name = props.lockedTypeLabel
}
}
return
}
const id = typeof component.typeComposantId === 'string'
? component.typeComposantId
: ''
@@ -430,4 +456,18 @@ watch(
},
{ deep: true }
)
watch(
() => [props.lockedTypeLabel, props.lockType],
() => {
if (props.lockType && props.isRoot) {
const label = props.lockedTypeLabel || lockedTypeDisplay.value
props.node.typeComposantLabel = label
if (label && (!props.node.name || props.node.name === lockedTypeDisplay.value)) {
props.node.name = label
}
}
},
{ immediate: true }
)
</script>