Corrige les manques signalés: champ technicien (congés) → autosuggest typeahead; compétences (demande de shift + éditeur équipe) → chips au lieu de texte libre. Composants réutilisables pour une UX cohérente partout (et le copilote/réassignation à venir). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
38 lines
1.4 KiB
Vue
38 lines
1.4 KiB
Vue
<template>
|
|
<!-- Sélecteur de technicien avec autosuggest (typeahead). Réutilisable partout
|
|
où on choisit un tech, pour une UX cohérente. options = [{label, value}]. -->
|
|
<q-select
|
|
dense outlined
|
|
:model-value="modelValue"
|
|
@update:model-value="v => $emit('update:modelValue', v)"
|
|
:options="filtered"
|
|
use-input input-debounce="200" fill-input hide-selected
|
|
emit-value map-options clearable
|
|
:label="label" :style="style" behavior="menu"
|
|
@filter="onFilter">
|
|
<template #no-option>
|
|
<q-item><q-item-section class="text-grey-6">Aucun technicien</q-item-section></q-item>
|
|
</template>
|
|
</q-select>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, watch } from 'vue'
|
|
const props = defineProps({
|
|
modelValue: { type: [String, null], default: null },
|
|
options: { type: Array, default: () => [] }, // [{label, value}]
|
|
label: { type: String, default: 'Technicien' },
|
|
style: { type: String, default: 'min-width:200px' },
|
|
})
|
|
defineEmits(['update:modelValue'])
|
|
const filtered = ref(props.options)
|
|
watch(() => props.options, (v) => { filtered.value = v }, { immediate: true })
|
|
function onFilter (val, update) {
|
|
update(() => {
|
|
const n = (val || '').toLowerCase()
|
|
filtered.value = !n ? props.options
|
|
: props.options.filter(o => (o.label || '').toLowerCase().includes(n) || String(o.value || '').toLowerCase().includes(n))
|
|
})
|
|
}
|
|
</script>
|