Add new dropdown search

This commit is contained in:
Matthieu
2025-10-16 08:51:18 +02:00
parent e297d1bb39
commit 62b5c9b297
10 changed files with 197 additions and 80 deletions

View File

@@ -29,21 +29,17 @@
<span class="label-text">{{ labels.typeSelectLabel }}</span>
<span class="label-text-alt text-error">*</span>
</label>
<select
:value="requirement[typeField] ?? ''"
class="select select-bordered select-sm"
required
@change="updateRequirement(index, { [typeField]: normalizeTypeValue($event.target.value) })"
>
<option value="">{{ labels.typePlaceholder }}</option>
<option
v-for="type in typeOptions"
:key="type.id"
:value="type.id"
>
{{ type.name }}
</option>
</select>
<SearchSelect
:model-value="normalizeTypeModel(requirement[typeField])"
:options="typeOptions"
:loading="typeLoading"
size="sm"
:placeholder="labels.typePlaceholder"
:empty-text="typeOptions.length ? 'Aucun résultat' : 'Aucune option disponible'"
:option-label="optionLabel"
:option-description="optionDescription"
@update:modelValue="(value) => updateRequirement(index, { [typeField]: normalizeTypeValue(value) })"
/>
</div>
<div class="form-control">
@@ -128,10 +124,12 @@ import { computed } from 'vue'
import type { PropType } from 'vue'
import IconLucidePlus from '~icons/lucide/plus'
import IconLucideTrash2 from '~icons/lucide/trash-2'
import SearchSelect from '~/components/common/SearchSelect.vue'
type Option = {
id: string | number
name: string
description?: string | null
}
type Requirement = Record<string, unknown> & {
@@ -193,6 +191,10 @@ const props = defineProps({
type: Number,
default: 0,
},
typeLoading: {
type: Boolean,
default: false,
},
})
const emit = defineEmits(['update:modelValue'])
@@ -202,6 +204,23 @@ const requirements = computed({
set: (value) => emit('update:modelValue', value),
})
const optionLabel = (option: Option) => {
if (!option) {
return ''
}
return option.name || ''
}
const optionDescription = (option: Option) => {
if (!option) {
return ''
}
if (typeof option.description === 'string' && option.description.trim()) {
return option.description.trim()
}
return ''
}
const addRequirement = () => {
requirements.value = [
...requirements.value,
@@ -232,8 +251,18 @@ const parseOptionalNumber = (value: string) => {
return Number.isFinite(parsed) ? parsed : null
}
const normalizeTypeValue = (value: string) => {
if (!value) {
const normalizeTypeModel = (value: unknown) => {
if (value === null || value === undefined) {
return ''
}
if (typeof value === 'string' || typeof value === 'number') {
return value
}
return ''
}
const normalizeTypeValue = (value: string | number | null | undefined) => {
if (value === '' || value === null || value === undefined) {
return null
}
return value