diff --git a/src/components/shared/select-muliple/SelectOffice.vue b/src/components/shared/select-muliple/SelectOffice.vue new file mode 100644 index 00000000..24437cd1 --- /dev/null +++ b/src/components/shared/select-muliple/SelectOffice.vue @@ -0,0 +1,104 @@ + + diff --git a/src/components/shared/select-muliple/select-multiple.ts b/src/components/shared/select-muliple/select-multiple.ts new file mode 100644 index 00000000..f1f31bf7 --- /dev/null +++ b/src/components/shared/select-muliple/select-multiple.ts @@ -0,0 +1,110 @@ +import { QSelect } from 'quasar'; +import { ref, Ref, watch } from 'vue'; + +export type SelectProps any> = { + params?: Parameters[0]; + creatable?: boolean; + label?: string; + placeholder?: string; + readonly?: boolean; + required?: boolean; + disabled?: boolean; + clearable?: boolean; + autoSelectOnSingle?: boolean; +}; + +export const createSelect = >( + state: { + value: Ref; + valueOption: Ref; + selectOptions: Ref; + getByValue: (id: string) => Promise | T | void; + getList: (query?: string) => Promise | T[] | void; + }, + opts?: { + valueField?: keyof T; + }, +) => { + const { value, valueOption, selectOptions, getList, getByValue } = state; + + const valueField = opts?.valueField || 'value'; + + let cache: T[]; + let previousSearch = ''; + + watch(value, (v) => { + console.log('UPDATED'); + if ( + !v || + (cache && cache.find((opt) => v.find((val) => val === opt[valueField]))) + ) { + return; + } + getSelectedOption(); + }); + + async function getOptions(query?: string) { + if (cache && selectOptions.value.length > 0 && previousSearch === query) { + selectOptions.value = JSON.parse(JSON.stringify(cache)); + return; + } + const ret = await getList(query); + if (ret) { + cache = ret; + selectOptions.value = JSON.parse(JSON.stringify(cache)); + previousSearch = query || previousSearch; + } + } + + async function setFirstValue() { + if (value.value) return; + const first = selectOptions.value.at(0); + if (first) value.value = first[valueField]; + } + + async function getSelectedOption() { + const currentValue = value.value; + + if (!currentValue) return; + if (selectOptions.value.find((v) => v[valueField] === currentValue)) return; + + const newValueOptions = currentValue.map(async (a) => { + const findValue = valueOption.value?.find((b) => b[valueField] === a); + + if (findValue) { + selectOptions.value.unshift(findValue); + return findValue; + } + + const ret = await getByValue(a); + + if (ret) { + selectOptions.value.unshift(ret); + return ret; + } + }); + + const retValueOptions = await Promise.all(newValueOptions); + + valueOption.value = retValueOptions.flatMap((v) => (!!v ? v : [])); + } + + type QuasarSelectUpdate = ( + callback: () => void, + afterFn?: ((ref: QSelect) => void) | undefined, + ) => void; + + function filter(value: string, update: QuasarSelectUpdate) { + update( + () => getOptions(value), + (ref) => { + if (!!value && ref.options && ref.options.length > 0) { + ref.setOptionIndex(-1); + ref.moveOptionSelection(1, true); + } + }, + ); + } + + return { getOptions, setFirstValue, getSelectedOption, filter }; +};