Add new dropdown search
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user