feat: apply vnSelectPaginate_simplify proposal

This commit is contained in:
Javier Segarra 2024-07-22 10:42:15 +02:00
parent b00f955913
commit cf721bf5a7
3 changed files with 39 additions and 57 deletions

View File

@ -79,6 +79,7 @@ const { optionLabel, optionValue, optionFilter, options, modelValue } = toRefs($
const myOptions = ref([]);
const myOptionsOriginal = ref([]);
const vnSelectRef = ref();
const lastVal = ref();
const isLoading = ref(false);
@ -87,11 +88,8 @@ const selectValue = computed({
return $props.modelValue;
},
set(value) {
isFiltered = false;
filterValue.value = !!value;
arrayData.store.page = 0;
arrayData.store.hasMoreData = true;
emit('update:modelValue', value);
},
});
@ -101,48 +99,31 @@ const useURL = computed(() => $props.url);
const $attrs = useAttrs();
const arrayDataKey =
$props.dataKey ?? ($props.url.length > 0 ? $props.url : $attrs.label);
const arrayDataOptions = {
url: $props.url,
where: $props.where,
limit: $props.limit,
sortBy: $props.sortBy,
fields: $props.fields,
};
const filterValue = ref(null);
const arrayData = useArrayData(arrayDataKey, arrayDataOptions);
let isFiltered = false;
onMounted(async () => {
if ($props.focusOnMount) setTimeout(() => vnSelectRef.value.showPopup(), 300);
setOptions(options.value);
if (!$props.options) fetchFilter($props.modelValue);
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(filterValue, (newVal, oldVal) => {
const _isFiltered = oldVal?.length < newVal?.length;
if (!_isFiltered && isFiltered) {
arrayData.store.hasMoreData = true;
arrayData.store.userFilter = $props.where;
arrayData.store.filter.where = $props.where;
arrayData.store.data = myOptions.value;
}
isFiltered = _isFiltered;
});
const arrayData = useArrayData(arrayDataKey, { url: $props.url });
watch(modelValue, (newValue) => {
if (useURL.value) return;
if (!myOptions.value.some((option) => option[optionValue.value] == newValue))
fetchFilter(newValue);
});
onMounted(() => {
setOptions(options.value);
if ($props.url && $props.modelValue && !findKeyInOptions())
fetchFilter($props.modelValue);
if ($props.focusOnMount) setTimeout(() => vnSelectRef.value.showPopup(), 300);
});
function findKeyInOptions() {
if (!$props.options) return;
return filter($props.modelValue, $props.options)?.length;
}
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();
@ -167,36 +148,35 @@ async function fetchFilter(val) {
if (!useURL.value) return;
const { fields, sortBy, limit } = $props;
let key = new RegExp(/\d/g).test(val)
? optionFilter.value ?? optionValue.value
: optionValue.value;
? optionValue.value
: optionFilter.value ?? optionLabel.value;
const defaultWhere = $props.useLike
? { [key]: { like: `%${val}%` } }
: { [key]: val };
const where = { ...defaultWhere, ...$props.where };
const fetchOptions = { where, fields, order: sortBy, limit };
const where = { ...(val ? defaultWhere : {}), ...$props.where };
const fetchOptions = { where, order: sortBy, limit };
if (fields) fetchOptions.fields = fields;
arrayData.store.userFilter = fetchOptions;
return arrayData.fetch({ append: false, updateRouter: false });
arrayData.store.skip = 0;
arrayData.store.filter.skip = 0;
const { data } = await arrayData.fetch({ append: true, updateRouter: false });
setOptions(data);
return data;
}
async function filterHandler(val, update) {
if (!val && lastVal.value === val) {
lastVal.value = val;
return update();
}
lastVal.value = val;
let newOptions;
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, isFiltered ? myOptions.value : myOptionsOriginal.value);
}
if (useURL.value && isFiltered && arrayData.store.hasMoreData) {
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, updateRouter: false });
newOptions = data;
myOptions.value = data;
}
if ($props.url) {
newOptions = await fetchFilter(val);
} else newOptions = filter(val, myOptionsOriginal.value);
update(
() => {
myOptions.value = newOptions;
@ -228,6 +208,7 @@ async function onScroll({ to, direction, from, index }) {
<template>
<QSelect
:input-debounce="$attrs.url ? 300 : 0"
:loading="isLoading"
@virtual-scroll="onScroll"
v-model="selectValue"

View File

@ -175,7 +175,7 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
async function addOrder(field, direction = 'ASC') {
const newOrder = field + ' ' + direction;
let order = store.order ?? [];
let order = store.order || [];
if (typeof order == 'string') order = [order];
let index = order.findIndex((o) => o.split(' ')[0] === field);

View File

@ -110,6 +110,7 @@ const contactChannels = ref([]);
option-filter="firstName"
use-input
v-model="data.salesPersonFk"
:use-like="false"
>
<template #prepend>
<QAvatar color="orange">