refactor: 04 => improve fetchWorkflowList for mobile handling and adjust pagination logic

This commit is contained in:
puriphatt 2025-01-31 11:57:52 +07:00
parent a61d2225f9
commit 17b527c078
2 changed files with 107 additions and 64 deletions

View file

@ -127,7 +127,7 @@ async function deleteWorkflow(id?: string) {
message: t('dialog.message.confirmDelete'), message: t('dialog.message.confirmDelete'),
action: async () => { action: async () => {
await workflowStore.deleteWorkflowTemplate(targetId); await workflowStore.deleteWorkflowTemplate(targetId);
await fetchWorkflowList(); await fetchWorkflowList($q.screen.xs);
resetForm(); resetForm();
}, },
@ -263,10 +263,12 @@ function resetForm() {
} }
async function fetchWorkflowList(mobileFetch?: boolean) { async function fetchWorkflowList(mobileFetch?: boolean) {
console.log(workflowData.value.length);
const res = await workflowStore.getWorkflowTemplateList({ const res = await workflowStore.getWorkflowTemplateList({
page: mobileFetch ? 1 : workflowPage.value, page: mobileFetch ? 1 : workflowPage.value,
pageSize: mobileFetch ? workflowData.value.length : workflowPageSize.value, pageSize: mobileFetch
? workflowData.value.length +
(pageState.total - workflowData.value.length === 0 ? 1 : 0)
: workflowPageSize.value,
query: pageState.inputSearch, query: pageState.inputSearch,
status: status:
statusFilter.value === 'all' statusFilter.value === 'all'
@ -515,7 +517,7 @@ watch([() => pageState.inputSearch, workflowPageSize], () => {
<article v-else class="col q-pa-md surface-2 scroll full-width"> <article v-else class="col q-pa-md surface-2 scroll full-width">
<q-infinite-scroll <q-infinite-scroll
:offset="100" :offset="10"
@load=" @load="
(_, done) => { (_, done) => {
if ($q.screen.gt.xs || workflowPage === workflowPageMax) return; if ($q.screen.gt.xs || workflowPage === workflowPageMax) return;
@ -789,7 +791,7 @@ watch([() => pageState.inputSearch, workflowPageSize], () => {
<PaginationComponent <PaginationComponent
v-model:current-page="workflowPage" v-model:current-page="workflowPage"
v-model:max-page="workflowPageMax" v-model:max-page="workflowPageMax"
:fetch-data="fetchWorkflowList" :fetch-data="() => fetchWorkflowList()"
/> />
</nav> </nav>
</footer> </footer>

View file

@ -274,6 +274,10 @@ const formProduct = ref<ProductCreate>({
code: '', code: '',
image: undefined, image: undefined,
shared: false, shared: false,
serviceChargeCalcVat: true,
serviceChargeVatIncluded: true,
agentPriceCalcVat: true,
agentPriceVatIncluded: true,
}); });
const currWorkflow = ref<WorkflowTemplate>(); const currWorkflow = ref<WorkflowTemplate>();
@ -596,10 +600,14 @@ function selectAllProduct(list: Product[]) {
}); });
} }
async function fetchListGroups() { async function fetchListGroups(mobileFetch?: boolean) {
const productGroupLength = productGroup.value?.length || 0;
const res = await fetchProductGroup({ const res = await fetchProductGroup({
page: currentPageGroup.value, page: mobileFetch ? 1 : currentPageGroup.value,
pageSize: pageSizeGroup.value, pageSize: mobileFetch
? productGroupLength +
(stat.value[0]?.count - productGroupLength === 1 ? 1 : 0)
: pageSizeGroup.value,
query: !!inputSearch.value ? inputSearch.value : undefined, query: !!inputSearch.value ? inputSearch.value : undefined,
status: status:
currentStatus.value === 'All' currentStatus.value === 'All'
@ -610,13 +618,14 @@ async function fetchListGroups() {
}); });
if (res) { if (res) {
currentPageGroup.value = res.page; // currentPageGroup.value = res.page;
totalGroup.value = res.total; totalGroup.value = res.total;
maxPageGroup.value = Math.ceil(res.total / pageSizeGroup.value); maxPageGroup.value = Math.ceil(res.total / pageSizeGroup.value);
if (!productGroup.value) productGroup.value = []; if (!productGroup.value) productGroup.value = [];
$q.screen.lt.md productGroup.value =
? productGroup.value.push(...res.result) $q.screen.xs && !mobileFetch
: (productGroup.value = res.result); ? [...productGroup.value, ...res.result]
: res.result;
} }
} }
@ -649,10 +658,13 @@ async function fetchListOfProductIsAdd(
} }
} }
async function fetchListOfProduct() { async function fetchListOfProduct(mobileFetch?: boolean) {
const productLength = product.value?.length || 0;
const res = await fetchListProduct({ const res = await fetchListProduct({
page: currentPageServiceAndProduct.value, page: mobileFetch ? 1 : currentPageServiceAndProduct.value,
pageSize: pageSizeServiceAndProduct.value, pageSize: mobileFetch
? productLength + (stat.value[2]?.count - productLength === 1 ? 1 : 0)
: pageSizeServiceAndProduct.value,
query: !!inputSearchProductAndService.value query: !!inputSearchProductAndService.value
? inputSearchProductAndService.value ? inputSearchProductAndService.value
: undefined, : undefined,
@ -666,14 +678,14 @@ async function fetchListOfProduct() {
}); });
if (res) { if (res) {
// currentPageServiceAndProduct.value = res.page;
total.value = res.total; total.value = res.total;
totalProduct.value = res.total; totalProduct.value = res.total;
currentPageServiceAndProduct.value = res.page;
maxPageServiceAndProduct.value = Math.ceil( maxPageServiceAndProduct.value = Math.ceil(
res.total / pageSizeServiceAndProduct.value, res.total / pageSizeServiceAndProduct.value,
); );
if (!product.value) product.value = []; if (!product.value) product.value = [];
$q.screen.xs $q.screen.xs && !mobileFetch
? product.value.push( ? product.value.push(
...res.result.map((v) => { ...res.result.map((v) => {
return { return {
@ -691,13 +703,16 @@ async function fetchListOfProduct() {
} }
} }
async function fetchListOfService() { async function fetchListOfService(mobileFetch?: boolean) {
const serviceLength = service.value?.length || 0;
const res = await fetchListService({ const res = await fetchListService({
page: currentPageServiceAndProduct.value, page: mobileFetch ? 1 : currentPageServiceAndProduct.value,
query: !!inputSearchProductAndService.value query: !!inputSearchProductAndService.value
? inputSearchProductAndService.value ? inputSearchProductAndService.value
: undefined, : undefined,
pageSize: pageSizeServiceAndProduct.value, pageSize: mobileFetch
? serviceLength + (stat.value[1]?.count - serviceLength === 1 ? 1 : 0)
: pageSizeServiceAndProduct.value,
status: status:
currentStatus.value === 'INACTIVE' currentStatus.value === 'INACTIVE'
? 'INACTIVE' ? 'INACTIVE'
@ -708,14 +723,14 @@ async function fetchListOfService() {
}); });
if (res) { if (res) {
// currentPageServiceAndProduct.value = res.page;
totalService.value = res.total; totalService.value = res.total;
total.value = res.total; total.value = res.total;
currentPageServiceAndProduct.value = res.page;
maxPageServiceAndProduct.value = Math.ceil( maxPageServiceAndProduct.value = Math.ceil(
res.total / pageSizeServiceAndProduct.value, res.total / pageSizeServiceAndProduct.value,
); );
if (!service.value) service.value = []; if (!service.value) service.value = [];
$q.screen.xs $q.screen.xs && !mobileFetch
? service.value.push( ? service.value.push(
...res.result.map((v) => { ...res.result.map((v) => {
return { return {
@ -811,15 +826,18 @@ async function deleteServiceConfirm(serviceId?: string) {
action: async () => { action: async () => {
const res = await deleteService(serviceId ?? currentIdService.value); const res = await deleteService(serviceId ?? currentIdService.value);
if (productAndServiceTab.value === 'service') {
await fetchListOfService();
}
dialogServiceEdit.value = false; dialogServiceEdit.value = false;
if (res) { if (res) {
totalService.value = totalService.value - 1; totalService.value = totalService.value - 1;
allStat.value[1].count = allStat.value[1].count - 1;
stat.value[1].count = stat.value[1].count - 1;
if (productAndServiceTab.value === 'service') {
await fetchListOfService($q.screen.xs);
}
} }
flowStore.rotate(); flowStore.rotate();
calculateStats({ reFetch: true }); calculateStats({ reFetch: true });
}, },
@ -843,14 +861,16 @@ async function deleteProductConfirm(id?: string) {
return; return;
} }
if (productAndServiceTab.value === 'product') {
await fetchListOfProduct();
}
dialogProductEdit.value = false; dialogProductEdit.value = false;
if (res) { if (res) {
totalProduct.value = totalProduct.value - 1; totalProduct.value = totalProduct.value - 1;
allStat.value[2].count = allStat.value[2].count - 1;
stat.value[2].count = stat.value[2].count - 1;
if (productAndServiceTab.value === 'product') {
await fetchListOfProduct($q.screen.xs);
}
} }
flowStore.rotate(); flowStore.rotate();
calculateStats({ reFetch: true }); calculateStats({ reFetch: true });
@ -860,7 +880,7 @@ async function deleteProductConfirm(id?: string) {
} }
// type or group // type or group
async function deleteProductById(productId?: string) { async function deleteGroupById(productId?: string) {
dialog({ dialog({
color: 'negative', color: 'negative',
icon: 'mdi-alert', icon: 'mdi-alert',
@ -876,8 +896,10 @@ async function deleteProductById(productId?: string) {
productId ?? currentIdGroup.value, productId ?? currentIdGroup.value,
); );
if (res) { if (res) {
allStat.value[0].count = allStat.value[0].count - 1;
stat.value[0].count = stat.value[0].count - 1;
await fetchListGroups($q.screen.xs);
} }
await fetchListGroups();
} }
flowStore.rotate(); flowStore.rotate();
@ -891,8 +913,10 @@ async function deleteProductById(productId?: string) {
productId ?? currentIdGroup.value, productId ?? currentIdGroup.value,
); );
if (res) { if (res) {
allStat.value[0].count = allStat.value[0].count - 1;
stat.value[0].count = stat.value[0].count - 1;
await fetchListGroups();
} }
await fetchListGroups();
} }
flowStore.rotate(); flowStore.rotate();
@ -1259,7 +1283,7 @@ async function submitService(notClose = false) {
if (!notClose) clearFormService(); if (!notClose) clearFormService();
if (productAndServiceTab.value === 'service') { if (productAndServiceTab.value === 'service') {
await fetchListOfService(); await fetchListOfService($q.screen.xs);
} }
flowStore.rotate(); flowStore.rotate();
@ -1304,7 +1328,7 @@ async function submitProduct(notClose = false) {
if (!notClose) clearFormProduct(); if (!notClose) clearFormProduct();
if (productAndServiceTab.value === 'product') { if (productAndServiceTab.value === 'product') {
await fetchListOfProduct(); await fetchListOfProduct($q.screen.xs);
} }
flowStore.rotate(); flowStore.rotate();
} }
@ -1329,7 +1353,7 @@ async function submitGroup() {
currentIdGroupTree.value = ''; currentIdGroupTree.value = '';
drawerInfo.value = false; drawerInfo.value = false;
await fetchListGroups(); await fetchListGroups($q.screen.xs);
clearFormGroup(); clearFormGroup();
flowStore.rotate(); flowStore.rotate();
} }
@ -1470,17 +1494,22 @@ async function calculateStats(opt?: {
allStat.value.push({ mode: 'product', count: resStatsProduct ?? 0 }); allStat.value.push({ mode: 'product', count: resStatsProduct ?? 0 });
} }
stat.value[0].count = allStat.value[0].count; stat.value[0].count = allStat.value[0].count;
stat.value[1].count = allStat.value[1].count; if (productMode.value === 'group') {
stat.value[2].count = allStat.value[2].count; stat.value[1].count = allStat.value[1].count;
stat.value[2].count = allStat.value[2].count;
}
} }
async function fetchStatus() { async function fetchStatus() {
currentPageServiceAndProduct.value = 1;
if (productAndServiceTab.value === 'product') { if (productAndServiceTab.value === 'product') {
product.value = [];
await fetchListOfProduct(); await fetchListOfProduct();
flowStore.rotate(); flowStore.rotate();
} }
if (productAndServiceTab.value === 'service') { if (productAndServiceTab.value === 'service') {
service.value = [];
await fetchListOfService(); await fetchListOfService();
flowStore.rotate(); flowStore.rotate();
} }
@ -1577,10 +1606,14 @@ async function enterNext(type: 'service' | 'product') {
filterStat.value.push('service'); filterStat.value.push('service');
} }
if (productMode.value === 'service' && $q.screen.gt.xs) if (productMode.value === 'service') {
service.value = [];
await fetchListOfService(); await fetchListOfService();
if (productMode.value === 'product' && $q.screen.gt.xs) }
if (productMode.value === 'product') {
product.value = [];
await fetchListOfProduct(); await fetchListOfProduct();
}
flowStore.rotate(); flowStore.rotate();
} }
@ -1695,6 +1728,8 @@ watch(
watch(currentStatus, async () => { watch(currentStatus, async () => {
if (productMode.value === 'group') { if (productMode.value === 'group') {
productGroup.value = [];
currentPageGroup.value = 1;
await fetchListGroups(); await fetchListGroups();
} }
flowStore.rotate(); flowStore.rotate();
@ -1702,12 +1737,17 @@ watch(currentStatus, async () => {
watch(inputSearch, async () => { watch(inputSearch, async () => {
if (productMode.value === 'group') { if (productMode.value === 'group') {
productGroup.value = [];
currentPageGroup.value = 1;
await fetchListGroups(); await fetchListGroups();
flowStore.rotate(); flowStore.rotate();
} }
}); });
watch(inputSearchProductAndService, async () => { watch(inputSearchProductAndService, async () => {
product.value = [];
service.value = [];
currentPageServiceAndProduct.value = 1;
await alternativeFetch(); await alternativeFetch();
}); });
@ -1917,7 +1957,7 @@ watch(
<div class="col full-width scroll q-pa-md"> <div class="col full-width scroll q-pa-md">
<q-infinite-scroll <q-infinite-scroll
:offset="100" :offset="10"
@load=" @load="
async (_, done) => { async (_, done) => {
if ($q.screen.gt.sm) return; if ($q.screen.gt.sm) return;
@ -2018,7 +2058,7 @@ watch(
(v: (typeof treeProductTypeAndGroup)[number]) => { (v: (typeof treeProductTypeAndGroup)[number]) => {
editByTree = v.type as typeof editByTree; editByTree = v.type as typeof editByTree;
if (v.type === 'group') { if (v.type === 'group') {
deleteProductById(v.id); deleteGroupById(v.id);
} }
} }
" "
@ -2032,10 +2072,7 @@ watch(
@handle-hold="handleHold" @handle-hold="handleHold"
/> />
<template v-slot:loading> <template v-slot:loading>
<div <div v-if="$q.screen.lt.sm" class="row justify-center">
v-if="$q.screen.lt.sm && currentPageGroup !== maxPageGroup"
class="row justify-center"
>
<q-spinner-dots color="primary" size="40px" /> <q-spinner-dots color="primary" size="40px" />
</div> </div>
</template> </template>
@ -2262,9 +2299,11 @@ watch(
" "
> >
{{ {{
(currentPageGroup - 1) * pageSizeGroup + $q.screen.xs
props.rowIndex + ? props.rowIndex + 1
1 : (currentPageGroup - 1) * pageSizeGroup +
props.rowIndex +
1
}} }}
</q-td> </q-td>
<q-td <q-td
@ -2402,7 +2441,7 @@ watch(
@delete=" @delete="
() => { () => {
if (productMode === 'group') { if (productMode === 'group') {
deleteProductById(props.row.id); deleteGroupById(props.row.id);
} }
} }
" "
@ -2474,7 +2513,7 @@ watch(
@delete-card=" @delete-card="
() => { () => {
if (productMode === 'group') { if (productMode === 'group') {
deleteProductById(props.row.id); deleteGroupById(props.row.id);
} }
} }
" "
@ -2499,7 +2538,7 @@ watch(
<!-- footer group --> <!-- footer group -->
<footer <footer
v-if="productMode === 'group'" v-if="productMode === 'group' && $q.screen.gt.xs"
class="row items-center justify-between q-px-md q-py-sm full-width" class="row items-center justify-between q-px-md q-py-sm full-width"
> >
<div class="col-4"> <div class="col-4">
@ -2710,15 +2749,15 @@ watch(
class="flex scroll full-width q-pa-md surface-2 column col" class="flex scroll full-width q-pa-md surface-2 column col"
> >
<q-infinite-scroll <q-infinite-scroll
:offset="100" :offset="10"
@load=" @load="
(_, done) => { (_, done) => {
if ($q.screen.gt.xs) return; if ($q.screen.gt.xs) return;
currentPageServiceAndProduct =
currentPageServiceAndProduct + 1;
alternativeFetch().then(() => { alternativeFetch().then(() => {
currentPageServiceAndProduct =
currentPageServiceAndProduct + 1;
done( done(
currentPageServiceAndProduct > currentPageServiceAndProduct >=
maxPageServiceAndProduct, maxPageServiceAndProduct,
); );
}); });
@ -2794,10 +2833,12 @@ watch(
" "
> >
{{ {{
(currentPageServiceAndProduct - 1) * $q.screen.xs
pageSizeServiceAndProduct + ? props.rowIndex + 1
props.rowIndex + : (currentPageServiceAndProduct - 1) *
1 pageSizeServiceAndProduct +
props.rowIndex +
1
}} }}
</q-td> </q-td>
@ -3418,7 +3459,7 @@ watch(
} }
} }
" "
:delete-data="() => deleteProductById()" :delete-data="() => deleteGroupById()"
:close=" :close="
() => { () => {
(drawerInfo = false), (currentIdGroupType = ''); (drawerInfo = false), (currentIdGroupType = '');
@ -3515,7 +3556,7 @@ watch(
v-if="!isEdit" v-if="!isEdit"
id="btn-info-basic-delete" id="btn-info-basic-delete"
icon-only icon-only
@click="deleteProductById()" @click="deleteGroupById()"
type="button" type="button"
/> />
</div> </div>
@ -4941,10 +4982,10 @@ watch(
editByTree = currentNode.type as 'type' | 'group'; editByTree = currentNode.type as 'type' | 'group';
if (currentNode.type === 'type') { if (currentNode.type === 'type') {
deleteProductById(currentNode.id); deleteGroupById(currentNode.id);
} }
if (currentNode.type === 'group') { if (currentNode.type === 'group') {
deleteProductById(currentNode.id); deleteGroupById(currentNode.id);
} }
} }
" "