This commit is contained in:
Javier Segarra 2024-05-25 10:00:58 +02:00
parent e67c5e17f4
commit 1ca6bce7fe
6 changed files with 59 additions and 82 deletions

View File

@ -1,6 +1,6 @@
<script setup> <script setup>
import { onMounted, ref } from 'vue'; import { onMounted } from 'vue';
import { useArrayData } from 'composables/useArrayData'; import axios from 'axios';
const $props = defineProps({ const $props = defineProps({
autoLoad: { autoLoad: {
@ -24,12 +24,8 @@ const $props = defineProps({
default: '', default: '',
}, },
limit: { limit: {
type: Number, type: String,
default: 30, default: '',
},
skip: {
type: Number,
default: 0,
}, },
params: { params: {
type: Object, type: Object,
@ -37,27 +33,8 @@ const $props = defineProps({
}, },
}); });
const arrayData = useArrayData($props.url ?? $props.dataKey, {
autoLoad: $props.autoLoad,
url: $props.url,
filter: $props.filter,
where: $props.where,
sortBy: $props.sortBy,
limit: $props.limit,
params: $props.params,
});
const store = arrayData.store;
const pagination = ref({
sortBy: $props.sortBy,
skip: $props.skip,
rowsPerPage: +$props.limit,
page: 0,
hasMoreData: true,
});
const emit = defineEmits(['onFetch']); const emit = defineEmits(['onFetch']);
defineExpose({ fetch, pagination }); defineExpose({ fetch });
onMounted(async () => { onMounted(async () => {
if ($props.autoLoad) { if ($props.autoLoad) {
@ -71,17 +48,10 @@ async function fetch(fetchFilter = {}) {
if ($props.where && !fetchFilter.where) filter.where = $props.where; if ($props.where && !fetchFilter.where) filter.where = $props.where;
if ($props.sortBy) filter.order = $props.sortBy; if ($props.sortBy) filter.order = $props.sortBy;
if ($props.limit) filter.limit = $props.limit; if ($props.limit) filter.limit = $props.limit;
if ($props.skip) filter.skip = $props.skip;
else {
const skip = pagination.value.page * $props.limit;
pagination.value.skip = skip;
filter.skip = skip;
}
await arrayData.applyFilter({ filter });
const { data } = store; const { data } = await axios.get($props.url, {
pagination.value.hasMoreData = data.length === pagination.value.rowsPerPage; params: { filter: JSON.stringify(filter), ...$props.params },
pagination.value.page += 1; });
emit('onFetch', data); emit('onFetch', data);
return data; return data;

View File

@ -4,6 +4,7 @@ import { onMounted } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import FetchData from 'src/components/FetchData.vue'; import FetchData from 'src/components/FetchData.vue';
const emit = defineEmits(['update:modelValue', 'update:options']); const emit = defineEmits(['update:modelValue', 'update:options']);
import { useArrayData } from 'src/composables/useArrayData';
const $props = defineProps({ const $props = defineProps({
modelValue: { modelValue: {
@ -42,10 +43,10 @@ const $props = defineProps({
type: Boolean, type: Boolean,
default: true, default: true,
}, },
paginate: { // paginate: {
type: Boolean, // type: Boolean,
default: true, // default: true,
}, // },
fields: { fields: {
type: Array, type: Array,
default: null, default: null,
@ -58,18 +59,18 @@ const $props = defineProps({
type: String, type: String,
default: null, default: null,
}, },
orderBy: { // orderBy: {
type: String, // type: String,
default: null, // default: null,
}, // },
limit: { limit: {
type: [Number, String], type: [Number, String],
default: '30', default: '30',
}, },
fetchRef: { // fetchRef: {
type: Object, // type: Object,
default: null, // default: null,
}, // },
}); });
const { t } = useI18n(); const { t } = useI18n();
@ -90,13 +91,30 @@ const value = computed({
}, },
}); });
function setOptions(data) { function setOptions(data, append = false) {
if (isLoading.value) { if (isLoading.value) {
data.unshift(...myOptions.value); data.unshift(...myOptions.value);
} }
myOptions.value = JSON.parse(JSON.stringify(data)); if (arrayData.store) {
myOptionsOriginal.value = JSON.parse(JSON.stringify(data)); // arrayData.store.data = data;
arrayData.store.hasMoreData = data.length === +$props.limit;
append && myOptions.value.concat(data);
// myOptionsOriginal.value = JSON.parse(JSON.stringify(data));
} else {
myOptions.value = JSON.parse(JSON.stringify(data));
myOptionsOriginal.value = JSON.parse(JSON.stringify(data));
}
} }
const useURL = computed(() => $props.url?.length > 0);
const arrayData = useURL.value
? useArrayData($props.url, {
url: $props.url,
fields: $props.fields,
where: $props.where,
sortBy: $props.sortBy,
limit: $props.limit,
})
: ref(null);
onMounted(() => { onMounted(() => {
setOptions(options.value); setOptions(options.value);
if ($props.url && $props.modelValue) fetchFilter($props.modelValue); if ($props.url && $props.modelValue) fetchFilter($props.modelValue);
@ -166,15 +184,23 @@ watch(modelValue, (newValue) => {
const isLoading = ref(false); const isLoading = ref(false);
async function onScroll(scrollEv) { async function onScroll(scrollEv) {
const { to, direction } = scrollEv; const { to, direction, from, index } = scrollEv;
const lastIndex = myOptions.value.length - 1; const lastIndex = myOptions.value.length - 1;
if (from === 0 && index === 0) return;
if (!$props.url && !$props.fetchRef) return; if (!$props.url && !$props.fetchRef) return;
if (direction === 'decrease') return; if (direction === 'decrease') return;
if (to === lastIndex && dataRef.value.pagination.hasMoreData && !isLoading.value) { if (to === lastIndex && arrayData.store.hasMoreData && !isLoading.value) {
isLoading.value = true; isLoading.value = true;
!$props.url && (await $props.fetchRef.paginate()); !$props.url && (await $props.fetchRef.paginate());
$props.url && (await fetchFilter('')); $props.url && (await arrayData.loadMore());
setOptions(
arrayData.store.data.slice(
myOptions.value.length,
myOptions.value.length + 5
),
true
);
isLoading.value = false; isLoading.value = false;
} }
} }

View File

@ -79,7 +79,8 @@ export function useArrayData(key, userOptions) {
exprFilter = where ? { where } : null; exprFilter = where ? { where } : null;
} }
Object.assign(store.filter, filter, store.userFilter, exprFilter); Object.assign(filter, store.userFilter, exprFilter);
Object.assign(store.filter, filter);
const params = { const params = {
filter: JSON.stringify(store.filter), filter: JSON.stringify(store.filter),
}; };
@ -111,6 +112,8 @@ export function useArrayData(key, userOptions) {
return response; return response;
} }
function isHasMoreData() {}
function destroy() { function destroy() {
if (arrayDataStore.get(key)) { if (arrayDataStore.get(key)) {
arrayDataStore.clear(key); arrayDataStore.clear(key);

View File

@ -8,7 +8,7 @@ import FetchData from 'components/FetchData.vue';
import FormModel from 'components/FormModel.vue'; import FormModel from 'components/FormModel.vue';
import VnRow from 'components/ui/VnRow.vue'; import VnRow from 'components/ui/VnRow.vue';
import VnInput from 'src/components/common/VnInput.vue'; import VnInput from 'src/components/common/VnInput.vue';
import VnSelectFilter from 'src/components/common/VnSelectFilter.vue'; import VnSelect from 'src/components/common/VnSelect.vue';
const route = useRoute(); const route = useRoute();
const { t } = useI18n(); const { t } = useI18n();
@ -40,23 +40,6 @@ const filterOptions = {
}; };
</script> </script>
<template> <template>
<fetch-data
url="ContactChannels"
@on-fetch="(data) => (contactChannels = data)"
auto-load
/>
<fetch-data
url="BusinessTypes"
@on-fetch="(data) => (businessTypes = data)"
auto-load
/>
<fetch-data
:filter="filter"
@on-fetch="(data) => (clients = data)"
auto-load
url="Clients"
/>
<FormModel :url="`Clients/${route.params.id}`" auto-load model="customer"> <FormModel :url="`Clients/${route.params.id}`" auto-load model="customer">
<template #form="{ data, validate, filter }"> <template #form="{ data, validate, filter }">
<VnRow class="row q-gutter-md q-mb-md"> <VnRow class="row q-gutter-md q-mb-md">
@ -118,7 +101,7 @@ const filterOptions = {
/> />
</VnRow> </VnRow>
<VnRow class="row q-gutter-md q-mb-md"> <VnRow class="row q-gutter-md q-mb-md">
<QSelect <VnSelect
:input-debounce="0" :input-debounce="0"
:label="t('customer.basicData.salesPerson')" :label="t('customer.basicData.salesPerson')"
:options="workers" :options="workers"
@ -142,7 +125,7 @@ const filterOptions = {
/> />
</QAvatar> </QAvatar>
</template> </template>
</QSelect> </VnSelect>
<QSelect <QSelect
v-model="data.contactChannelFk" v-model="data.contactChannelFk"
:options="contactChannels" :options="contactChannels"

View File

@ -8,7 +8,6 @@ import CustomerFilter from '../CustomerFilter.vue';
data-key="Client" data-key="Client"
base-url="Clients" base-url="Clients"
:descriptor="CustomerDescriptor" :descriptor="CustomerDescriptor"
:filter-panel="CustomerFilter"
search-data-key="CustomerList" search-data-key="CustomerList"
search-url="Clients/filter" search-url="Clients/filter"
searchbar-label="Search customer" searchbar-label="Search customer"

View File

@ -27,7 +27,6 @@ function handleLocation(data, location) {
data.provinceFk = provinceFk; data.provinceFk = provinceFk;
data.countryFk = countryFk; data.countryFk = countryFk;
} }
const businessTypesRef = ref();
</script> </script>
<template> <template>
@ -37,10 +36,8 @@ const businessTypesRef = ref();
url="Workers/search?departmentCodes" url="Workers/search?departmentCodes"
/> />
<FetchData <FetchData
ref="businessTypesRef"
@on-fetch="(data) => (businessTypesOptions = data)" @on-fetch="(data) => (businessTypesOptions = data)"
auto-load auto-load
limit="10"
url="BusinessTypes" url="BusinessTypes"
/> />
<QPage> <QPage>
@ -70,7 +67,6 @@ const businessTypesRef = ref();
option-label="description" option-label="description"
option-value="code" option-value="code"
v-model="data.businessTypeFk" v-model="data.businessTypeFk"
:fetch-ref="businessTypesRef"
/> />
<QInput v-model="data.fi" :label="t('Tax number')" /> <QInput v-model="data.fi" :label="t('Tax number')" />
</VnRow> </VnRow>