200 lines
6.6 KiB
Vue
200 lines
6.6 KiB
Vue
<template>
|
||
<div :class="['space-y-4', depth > 0 ? 'border-l border-base-200 pl-4 ml-2' : '']">
|
||
<div class="bg-base-100 border border-base-200 rounded-lg p-4 space-y-4">
|
||
<div class="flex flex-col gap-2">
|
||
<div class="flex items-start justify-between gap-3">
|
||
<div class="space-y-1">
|
||
<h4 class="font-semibold text-sm">
|
||
{{ node.alias || node.typeComposantLabel || 'Composant' }}
|
||
</h4>
|
||
<p class="text-xs text-gray-500">
|
||
{{
|
||
node.typeComposantLabel
|
||
? `Famille : ${node.typeComposantLabel}`
|
||
: node.typeComposantId
|
||
? `Famille : ${node.typeComposantId}`
|
||
: 'Famille non définie'
|
||
}}
|
||
</p>
|
||
</div>
|
||
|
||
<div v-if="!showSelfSelector && selectedComponentModelLabel" class="badge badge-outline badge-sm">
|
||
Modèle : {{ selectedComponentModelLabel }}
|
||
</div>
|
||
</div>
|
||
|
||
<div v-if="showSelfSelector" class="form-control max-w-xs">
|
||
<label class="label">
|
||
<span class="label-text text-xs">Modèle de composant</span>
|
||
</label>
|
||
<select
|
||
class="select select-bordered select-xs"
|
||
:value="selectedComponentModelId"
|
||
@change="onComponentModelSelect($event.target.value)"
|
||
>
|
||
<option value="">Sélectionner un modèle</option>
|
||
<option v-for="model in componentModels" :key="model.id" :value="model.id">
|
||
{{ model.name }}
|
||
</option>
|
||
</select>
|
||
<p v-if="loadingComponentModels" class="text-[10px] text-gray-500 mt-1">
|
||
Chargement des modèles…
|
||
</p>
|
||
<p v-else-if="!componentModels.length" class="text-[10px] text-gray-500 mt-1">
|
||
Aucun modèle disponible pour cette famille.
|
||
</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div v-if="hasPieces" class="space-y-2">
|
||
<h5 class="text-[11px] font-semibold uppercase text-gray-500">Pièces associées</h5>
|
||
<div
|
||
v-for="(piece, pieceIndex) in node.pieces"
|
||
:key="pieceIndex"
|
||
class="bg-base-200/60 border border-base-200 rounded-md p-3 space-y-2"
|
||
>
|
||
<div class="space-y-1">
|
||
<span class="font-medium text-sm">{{ piece.typePieceLabel || 'Pièce' }}</span>
|
||
<p class="text-[11px] text-gray-500">
|
||
{{
|
||
piece.typePieceLabel
|
||
? `Famille : ${piece.typePieceLabel}`
|
||
: piece.typePieceId
|
||
? `Famille : ${piece.typePieceId}`
|
||
: 'Famille non définie'
|
||
}}
|
||
</p>
|
||
</div>
|
||
<div class="form-control max-w-xs">
|
||
<label class="label">
|
||
<span class="label-text text-xs">Modèle de pièce</span>
|
||
</label>
|
||
<select
|
||
class="select select-bordered select-xs"
|
||
:value="piece.__pieceModelId || ''"
|
||
@change="onPieceModelSelect(piece, $event.target.value)"
|
||
>
|
||
<option value="">Sélectionner un modèle</option>
|
||
<option v-for="model in getPieceModels(piece.typePieceId)" :key="model.id" :value="model.id">
|
||
{{ model.name }}
|
||
</option>
|
||
</select>
|
||
<p v-if="loadingPieceModels" class="text-[10px] text-gray-500 mt-1">
|
||
Chargement des modèles…
|
||
</p>
|
||
<p
|
||
v-else-if="getPieceModels(piece.typePieceId).length === 0"
|
||
class="text-[10px] text-gray-500 mt-1"
|
||
>
|
||
Aucun modèle disponible pour cette famille.
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div v-if="hasSubComponents" class="space-y-3">
|
||
<h5 class="text-[11px] font-semibold uppercase text-gray-500">Sous-composants</h5>
|
||
<SkeletonComponentNodeSelector
|
||
v-for="(subComponent, index) in (node.subcomponents || node.subComponents || [])"
|
||
:key="index"
|
||
:node="subComponent"
|
||
:depth="depth + 1"
|
||
:get-component-models-for-type="getComponentModelsForType"
|
||
:get-piece-models-for-type="getPieceModelsForType"
|
||
:loading-component-models="loadingComponentModels"
|
||
:loading-piece-models="loadingPieceModels"
|
||
@component-model-change="forwardComponentModelChange"
|
||
@piece-model-change="forwardPieceModelChange"
|
||
/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { computed } from 'vue'
|
||
|
||
defineOptions({ name: 'SkeletonComponentNodeSelector' })
|
||
|
||
const props = defineProps({
|
||
node: {
|
||
type: Object,
|
||
required: true,
|
||
},
|
||
depth: {
|
||
type: Number,
|
||
default: 0,
|
||
},
|
||
getComponentModelsForType: {
|
||
type: Function,
|
||
required: true,
|
||
},
|
||
getPieceModelsForType: {
|
||
type: Function,
|
||
required: true,
|
||
},
|
||
loadingComponentModels: {
|
||
type: Boolean,
|
||
default: false,
|
||
},
|
||
loadingPieceModels: {
|
||
type: Boolean,
|
||
default: false,
|
||
},
|
||
showSelfSelector: {
|
||
type: Boolean,
|
||
default: true,
|
||
},
|
||
})
|
||
|
||
const emit = defineEmits(['component-model-change', 'piece-model-change'])
|
||
|
||
const componentModels = computed(() => {
|
||
if (!props.node?.typeComposantId) {
|
||
return []
|
||
}
|
||
const models = props.getComponentModelsForType(props.node.typeComposantId)
|
||
return Array.isArray(models) ? models : []
|
||
})
|
||
|
||
const selectedComponentModelId = computed(() => props.node?.__componentModelId || '')
|
||
|
||
const selectedComponentModelLabel = computed(() => {
|
||
if (!selectedComponentModelId.value) {
|
||
return ''
|
||
}
|
||
const match = componentModels.value.find((model) => model.id === selectedComponentModelId.value)
|
||
return match?.name || ''
|
||
})
|
||
|
||
const hasPieces = computed(() => Array.isArray(props.node?.pieces) && props.node.pieces.length > 0)
|
||
const hasSubComponents = computed(() => {
|
||
const list = props.node?.subcomponents || props.node?.subComponents || []
|
||
return Array.isArray(list) && list.length > 0
|
||
})
|
||
|
||
const getPieceModels = (typePieceId) => {
|
||
if (!typePieceId) {
|
||
return []
|
||
}
|
||
const models = props.getPieceModelsForType(typePieceId)
|
||
return Array.isArray(models) ? models : []
|
||
}
|
||
|
||
const onComponentModelSelect = (value) => {
|
||
emit('component-model-change', props.node, props.node?.typeComposantId || '', value || '')
|
||
}
|
||
|
||
const onPieceModelSelect = (piece, value) => {
|
||
emit('piece-model-change', piece, piece?.typePieceId || '', value || '')
|
||
}
|
||
|
||
const forwardComponentModelChange = (...args) => {
|
||
emit('component-model-change', ...args)
|
||
}
|
||
|
||
const forwardPieceModelChange = (...args) => {
|
||
emit('piece-model-change', ...args)
|
||
}
|
||
</script>
|