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

@@ -5,13 +5,15 @@
:depth="0"
:component-types="availableComponentTypes"
:piece-types="availablePieceTypes"
:lock-type="lockRootType"
:locked-type-label="displayedRootTypeLabel"
is-root
/>
</div>
</template>
<script setup lang="ts">
import { reactive, watch, computed, onMounted } from 'vue'
import { reactive, watch, computed, onMounted, ref } from 'vue'
import StructureNodeEditor from '~/components/StructureNodeEditor.vue'
import {
defaultStructure,
@@ -28,11 +30,62 @@ const props = defineProps({
type: Object,
default: () => defaultStructure(),
},
rootTypeId: {
type: String,
default: '',
},
rootTypeLabel: {
type: String,
default: '',
},
lockRootType: {
type: Boolean,
default: false,
},
})
const emit = defineEmits(['update:modelValue'])
const localStructure = reactive(hydrateStructureForEditor(props.modelValue))
const previousLockedLabel = ref(props.rootTypeLabel || '')
const { pieceTypes, loadPieceTypes } = usePieceTypes()
const { componentTypes, loadComponentTypes } = useComponentTypes()
const availablePieceTypes = computed(() => pieceTypes.value ?? [])
const availableComponentTypes = computed(() => componentTypes.value ?? [])
const fallbackRootTypeLabel = computed(() => {
if (!props.rootTypeId) {
return ''
}
const match = availableComponentTypes.value.find((type) => type?.id === props.rootTypeId)
return match?.name || ''
})
const displayedRootTypeLabel = computed(() => props.rootTypeLabel || fallbackRootTypeLabel.value)
const syncRootType = () => {
if (!props.lockRootType) {
previousLockedLabel.value = props.rootTypeLabel || ''
return
}
const newTypeId = props.rootTypeId || ''
const newLabel = displayedRootTypeLabel.value
localStructure.typeComposantId = newTypeId
localStructure.typeComposantLabel = newLabel
const previousLabel = previousLockedLabel.value
if (!localStructure.name || localStructure.name === previousLabel || localStructure.name === '') {
localStructure.name = newLabel || localStructure.name
}
previousLockedLabel.value = newLabel
}
let lastEmitted = JSON.stringify(cloneStructure(props.modelValue))
const syncFromProps = (value: any) => {
const hydrated = hydrateStructureForEditor(value)
@@ -40,6 +93,7 @@ const syncFromProps = (value: any) => {
localStructure.pieces = hydrated.pieces
localStructure.subComponents = hydrated.subComponents
lastEmitted = JSON.stringify(cloneStructure(value))
syncRootType()
}
watch(
@@ -50,7 +104,20 @@ watch(
{ deep: true }
)
let lastEmitted = JSON.stringify(cloneStructure(props.modelValue))
watch(
() => [props.rootTypeId, props.rootTypeLabel, props.lockRootType],
() => {
syncRootType()
},
{ immediate: true }
)
watch(
availableComponentTypes,
() => {
syncRootType()
}
)
watch(
localStructure,
@@ -65,12 +132,6 @@ watch(
{ deep: true }
)
const { pieceTypes, loadPieceTypes } = usePieceTypes()
const { componentTypes, loadComponentTypes } = useComponentTypes()
const availablePieceTypes = computed(() => pieceTypes.value ?? [])
const availableComponentTypes = computed(() => componentTypes.value ?? [])
onMounted(async () => {
const loaders: Promise<any>[] = []
if (!availablePieceTypes.value.length) {
@@ -82,5 +143,6 @@ onMounted(async () => {
if (loaders.length) {
await Promise.allSettled(loaders)
}
syncRootType()
})
</script>