diff --git a/src/components/common/VnSelect.vue b/src/components/common/VnSelect.vue index 976e949c8..2abac6f44 100644 --- a/src/components/common/VnSelect.vue +++ b/src/components/common/VnSelect.vue @@ -3,6 +3,7 @@ import { ref, toRefs, computed, watch, onMounted } from 'vue'; import { useI18n } from 'vue-i18n'; const emit = defineEmits(['update:modelValue', 'update:options']); import { useArrayData } from 'src/composables/useArrayData'; +import { useAttrs } from 'vue'; const $props = defineProps({ modelValue: { @@ -75,6 +76,8 @@ const myOptions = ref([]); const myOptionsOriginal = ref([]); const vnSelectRef = ref(); +const isLoading = ref(false); + const selectValue = computed({ get() { return $props.modelValue; @@ -85,12 +88,7 @@ const selectValue = computed({ }, }); -function setOptions(data, append = true) { - myOptions.value = JSON.parse(JSON.stringify(data)); - if (append) myOptionsOriginal.value = JSON.parse(JSON.stringify(data)); -} const useURL = computed(() => $props.url); -import { useAttrs } from 'vue'; const $attrs = useAttrs(); const arrayDataKey = $props.dataKey ?? ($props.url !== '' ? $props.url : $attrs.label); @@ -101,25 +99,33 @@ const arrayDataOptions = { sortBy: $props.sortBy, fields: $props.fields, }; +const filterValue = ref(null); const arrayData = useArrayData(arrayDataKey, arrayDataOptions); onMounted(async () => { + if ($props.focusOnMount) setTimeout(() => vnSelectRef.value.showPopup(), 300); setOptions(options.value); if (!$props.options) fetchFilter($props.modelValue); + await initSelect(); +}); + +async function initSelect() { if (useURL.value) { arrayData.store.userFilter = $props.where; arrayData.store.filter.where = $props.where; const { data } = await arrayData.fetch({ append: true, updateRouter: false }); setOptions(data); } -}); +} watch(modelValue, (newValue) => { if (useURL.value) return; if (!myOptions.value.some((option) => option[optionValue.value] == newValue)) fetchFilter(newValue); }); -const isLoading = ref(false); - +function setOptions(data, append = true) { + myOptions.value = JSON.parse(JSON.stringify(data)); + if (append) myOptionsOriginal.value = JSON.parse(JSON.stringify(data)); +} function filter(val, options) { const search = val.toString().toLowerCase(); @@ -139,10 +145,7 @@ function filter(val, options) { return id == search || optionLabel.includes(search); }); } - -async function fetchFilter(val) { - if (!useURL.value) return; - +function whereFn(val) { const { fields, sortBy, limit } = $props; let key = new RegExp(/\d/g).test(val) ? optionFilter.value ?? optionValue.value @@ -150,22 +153,33 @@ async function fetchFilter(val) { const where = { ...{ [key]: { like: `%${val}%` } }, ...$props.where }; const fetchOptions = { where, order: sortBy, limit }; - if (fields) fetchOptions.fields = fields; - return arrayData.value.fetch(fetchOptions); + return fetchOptions; } - +async function fetchFilter(val) { + if (!useURL.value) return; + const fetchOptions = whereFn(val); + arrayData.store.userFilter = fetchOptions; + return arrayData.fetch({ append: false, updateRouter: false }); +} +let isFiltered = false; +watch(filterValue, (newVal, oldVal) => { + isFiltered = oldVal?.length < newVal?.length; +}); async function filterHandler(val, update) { if (!$props.defaultFilter) return update(); let newOptions = []; + filterValue.value = val; if (myOptions.value.length > 0 && !useURL.value) { newOptions = filter(val, myOptions.value); myOptions.value = []; - } else newOptions = filter(val, myOptionsOriginal.value); - if (useURL.value && myOptions.value.length < 1) { + } else { + newOptions = filter(val, myOptionsOriginal.value); + } + if (useURL.value && isFiltered) { arrayData.store.skip = 0; arrayData.store.filter.skip = 0; arrayData.store.filter.where = { [optionFilter.value]: val, ...$props.where }; - const { data } = await arrayData.fetch({ append: false }); + const { data } = await arrayData.fetch({ append: false, updateRouter: false }); newOptions = data; myOptions.value = data; } @@ -189,7 +203,16 @@ async function onScroll(scrollEv) { if (from === 0 && index === 0) return; if (!useURL.value && !$props.fetchRef) return; if (direction === 'decrease') return; + console.log(arrayData.store.data.length, myOptions.value.length); + // const restoreFilter = +arrayData.store.limit === myOptions.value.length; if (to === lastIndex && arrayData.store.hasMoreData && !isLoading.value) { + if (isFiltered) { + arrayData.store.userFilter = $props.where; + arrayData.store.filter.where = $props.where; + arrayData.store.hasMoreData = true; + await initSelect(); + return; + } isLoading.value = true; await arrayData.loadMore(); setOptions(arrayData.store.data); @@ -197,10 +220,6 @@ async function onScroll(scrollEv) { isLoading.value = false; } } - -onMounted(async () => { - if ($props.focusOnMount) setTimeout(() => vnSelectRef.value.showPopup(), 300); -});