2024-09-18 14:29:32 +07:00
|
|
|
<script lang="ts" setup>
|
2024-09-23 15:03:54 +07:00
|
|
|
import { onMounted, ref, watch } from 'vue';
|
2024-09-18 14:29:32 +07:00
|
|
|
import { selectFilterOptionRefMod } from 'src/stores/utils';
|
2024-09-23 15:03:54 +07:00
|
|
|
import { QSelect } from 'quasar';
|
2024-09-18 14:29:32 +07:00
|
|
|
|
2024-09-27 15:21:31 +07:00
|
|
|
const model = defineModel<string | null>();
|
2024-09-18 14:29:32 +07:00
|
|
|
|
|
|
|
|
const options = ref<Record<string, unknown>[]>([]);
|
2024-09-23 15:03:54 +07:00
|
|
|
let defaultFilter: (
|
|
|
|
|
value: string,
|
|
|
|
|
update: (callbackFn: () => void, afterFn?: (ref: QSelect) => void) => void,
|
|
|
|
|
) => void;
|
|
|
|
|
|
|
|
|
|
const props = withDefaults(
|
|
|
|
|
defineProps<{
|
|
|
|
|
id?: string;
|
|
|
|
|
label?: string;
|
|
|
|
|
option: Record<string, unknown>[];
|
|
|
|
|
optionLabel?: string;
|
|
|
|
|
optionValue?: string;
|
2024-10-02 15:06:39 +07:00
|
|
|
placeholder?: string;
|
2024-09-23 15:03:54 +07:00
|
|
|
|
2024-10-02 15:06:39 +07:00
|
|
|
hideSelected?: boolean;
|
2024-09-23 15:03:54 +07:00
|
|
|
readonly?: boolean;
|
|
|
|
|
clearable?: boolean;
|
|
|
|
|
incremental?: boolean;
|
2024-10-02 15:06:39 +07:00
|
|
|
fillInput?: boolean;
|
2024-10-04 09:45:05 +07:00
|
|
|
disable?: boolean;
|
2024-09-23 15:03:54 +07:00
|
|
|
|
|
|
|
|
rules?: ((value: string) => string | true)[];
|
|
|
|
|
}>(),
|
2024-10-02 15:06:39 +07:00
|
|
|
{
|
|
|
|
|
option: () => [],
|
|
|
|
|
optionLabel: 'label',
|
|
|
|
|
optionValue: 'value',
|
|
|
|
|
hideSelected: true,
|
|
|
|
|
fillInput: true,
|
2024-10-04 09:45:05 +07:00
|
|
|
disable: false,
|
2024-10-02 15:06:39 +07:00
|
|
|
},
|
2024-09-23 15:03:54 +07:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
defineEmits<{
|
|
|
|
|
(e: 'filter', val: string, update: void): void;
|
|
|
|
|
}>();
|
|
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
defaultFilter = selectFilterOptionRefMod(
|
|
|
|
|
ref(props.option),
|
|
|
|
|
options,
|
|
|
|
|
props.optionLabel,
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
watch(
|
|
|
|
|
() => props.option,
|
|
|
|
|
() => {
|
|
|
|
|
defaultFilter = selectFilterOptionRefMod(
|
|
|
|
|
ref(props.option),
|
|
|
|
|
options,
|
|
|
|
|
props.optionLabel,
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
);
|
2024-09-18 14:29:32 +07:00
|
|
|
</script>
|
|
|
|
|
<template>
|
|
|
|
|
<q-select
|
2024-10-02 15:06:39 +07:00
|
|
|
:placeholder="placeholder"
|
2024-09-18 14:29:32 +07:00
|
|
|
outlined
|
2024-09-23 15:03:54 +07:00
|
|
|
:clearable
|
2024-10-04 09:45:05 +07:00
|
|
|
:disable
|
2024-09-18 14:29:32 +07:00
|
|
|
use-input
|
|
|
|
|
emit-value
|
|
|
|
|
map-options
|
2024-10-02 15:06:39 +07:00
|
|
|
:hideSelected
|
2024-09-18 14:29:32 +07:00
|
|
|
hide-bottom-space
|
2024-10-02 15:06:39 +07:00
|
|
|
:fill-input="fillInput && !!model"
|
2024-09-18 14:29:32 +07:00
|
|
|
:hide-dropdown-icon="readonly"
|
|
|
|
|
input-debounce="0"
|
2024-09-23 15:03:54 +07:00
|
|
|
:option-value="optionValue"
|
|
|
|
|
:option-label="optionLabel"
|
2024-09-18 14:29:32 +07:00
|
|
|
v-model="model"
|
|
|
|
|
dense
|
2024-09-23 15:03:54 +07:00
|
|
|
:readonly
|
2024-09-18 14:29:32 +07:00
|
|
|
:label="label"
|
2024-09-23 15:03:54 +07:00
|
|
|
:options="incremental ? option : options"
|
2024-10-02 15:06:39 +07:00
|
|
|
:for="`${id}`"
|
2024-09-23 15:03:54 +07:00
|
|
|
@filter="
|
|
|
|
|
(val, update) => {
|
|
|
|
|
incremental ? $emit('filter', val, update) : defaultFilter(val, update);
|
|
|
|
|
}
|
|
|
|
|
"
|
|
|
|
|
:rules
|
2024-09-18 14:29:32 +07:00
|
|
|
>
|
|
|
|
|
<template v-slot:no-option>
|
2024-09-30 11:37:18 +07:00
|
|
|
<slot name="noOption"></slot>
|
|
|
|
|
|
|
|
|
|
<q-item v-if="!$slots.noOption">
|
2024-09-18 14:29:32 +07:00
|
|
|
<q-item-section class="text-grey">
|
|
|
|
|
{{ $t('general.noData') }}
|
|
|
|
|
</q-item-section>
|
|
|
|
|
</q-item>
|
|
|
|
|
</template>
|
2024-09-23 15:03:54 +07:00
|
|
|
|
2024-10-02 15:06:39 +07:00
|
|
|
<template v-if="$slots.selectedItem" v-slot:selected-item="scope">
|
|
|
|
|
<slot name="selectedItem" :scope="scope"></slot>
|
2024-09-23 15:03:54 +07:00
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<template v-if="$slots.option" v-slot:option="scope">
|
|
|
|
|
<slot name="option" :scope="scope"></slot>
|
|
|
|
|
</template>
|
2024-09-18 14:29:32 +07:00
|
|
|
</q-select>
|
|
|
|
|
</template>
|