Merge pull request 'feat(VnSelect): refs #7136 add scroll' (!890) from 7136-vnSelect_paginate_simplify_2 into dev
gitea/salix-front/pipeline/head This commit looks good Details

Reviewed-on: #890
Reviewed-by: Javier Segarra <jsegarra@verdnatura.es>
This commit is contained in:
Alex Moreno 2024-11-15 10:24:46 +00:00
commit e8f0bc9965
2 changed files with 36 additions and 20 deletions

View File

@ -1,7 +1,7 @@
<script setup>
import { ref, toRefs, computed, watch, onMounted, useAttrs } from 'vue';
import { useI18n } from 'vue-i18n';
import FetchData from 'src/components/FetchData.vue';
import { useArrayData } from 'src/composables/useArrayData';
import { useRequired } from 'src/composables/useRequired';
import dataByOrder from 'src/utils/dataByOrder';
@ -90,6 +90,10 @@ const $props = defineProps({
type: Boolean,
default: false,
},
dataKey: {
type: String,
default: null,
},
});
const mixinRules = [requiredFieldRule, ...($attrs.rules ?? [])];
@ -98,14 +102,14 @@ const { optionLabel, optionValue, optionFilter, optionFilterValue, options, mode
const myOptions = ref([]);
const myOptionsOriginal = ref([]);
const vnSelectRef = ref();
const dataRef = ref();
const lastVal = ref();
const noOneText = t('globals.noOne');
const noOneOpt = ref({
[optionValue.value]: false,
[optionLabel.value]: noOneText,
});
const isLoading = ref(false);
const useURL = computed(() => $props.url);
const value = computed({
get() {
return $props.modelValue;
@ -129,11 +133,18 @@ watch(modelValue, async (newValue) => {
onMounted(() => {
setOptions(options.value);
if ($props.url && $props.modelValue && !findKeyInOptions())
if (useURL.value && $props.modelValue && !findKeyInOptions())
fetchFilter($props.modelValue);
if ($props.focusOnMount) setTimeout(() => vnSelectRef.value.showPopup(), 300);
});
defineExpose({ opts: myOptions });
const arrayDataKey =
$props.dataKey ?? ($props.url?.length > 0 ? $props.url : $attrs.name ?? $attrs.label);
const arrayData = useArrayData(arrayDataKey, { url: $props.url, searchUrl: false });
function findKeyInOptions() {
if (!$props.options) return;
return filter($props.modelValue, $props.options)?.length;
@ -168,7 +179,7 @@ function filter(val, options) {
}
async function fetchFilter(val) {
if (!$props.url || !dataRef.value) return;
if (!$props.url) return;
const { fields, include, sortBy, limit } = $props;
const key =
@ -190,8 +201,8 @@ async function fetchFilter(val) {
const fetchOptions = { where, include, limit };
if (fields) fetchOptions.fields = fields;
if (sortBy) fetchOptions.order = sortBy;
return dataRef.value.fetch(fetchOptions);
arrayData.reset(['skip', 'filter.skip', 'page']);
return (await arrayData.applyFilter({ filter: fetchOptions }))?.data;
}
async function filterHandler(val, update) {
@ -231,20 +242,23 @@ function nullishToTrue(value) {
const getVal = (val) => ($props.useLike ? { like: `%${val}%` } : val);
defineExpose({ opts: myOptions });
async function onScroll({ to, direction, from, index }) {
const lastIndex = myOptions.value.length - 1;
if (from === 0 && index === 0) return;
if (!useURL.value && !$props.fetchRef) return;
if (direction === 'decrease') return;
if (to === lastIndex && arrayData.store.hasMoreData && !isLoading.value) {
isLoading.value = true;
await arrayData.loadMore();
setOptions(arrayData.store.data);
vnSelectRef.value.scrollTo(lastIndex);
isLoading.value = false;
}
}
</script>
<template>
<FetchData
ref="dataRef"
:url="$props.url"
@on-fetch="(data) => setOptions(data)"
:where="where || { [optionValue]: value }"
:limit="limit"
:sort-by="sortBy"
:fields="fields"
:params="params"
/>
<QSelect
v-model="value"
:options="myOptions"
@ -263,6 +277,9 @@ defineExpose({ opts: myOptions });
:rules="mixinRules"
virtual-scroll-slice-size="options.length"
hide-bottom-space
:input-debounce="useURL ? '300' : '0'"
:loading="isLoading"
@virtual-scroll="onScroll"
>
<template v-if="isClearable" #append>
<QIcon

View File

@ -53,7 +53,7 @@ defineProps({
<QItemSection>
<VnSelect
url="Workers/activeWithInheritedRole"
:filter="{ where: { role: 'salesPerson' } }"
:where="{ role: 'salesPerson' }"
auto-load
:label="t('Salesperson')"
v-model="params.salesPersonFk"
@ -67,7 +67,6 @@ defineProps({
dense
outlined
rounded
:input-debounce="0"
/>
</QItemSection>
</QItem>