refactor: 04 => screen.xs fetch scroll

This commit is contained in:
puriphatt 2025-01-29 17:07:43 +07:00
parent a894bacb13
commit f559987e0c
2 changed files with 733 additions and 671 deletions

View file

@ -276,7 +276,10 @@ async function fetchWorkflowList() {
: 'INACTIVE',
});
if (res) {
workflowData.value = res.result;
$q.screen.xs
? workflowData.value.push(...res.result)
: (workflowData.value = res.result);
workflowPageMax.value = Math.ceil(res.total / workflowPageSize.value);
if (pageState.inputSearch || statusFilter.value !== 'all') return;
pageState.total = res.total;
@ -351,7 +354,7 @@ watch([() => pageState.inputSearch, workflowPageSize], fetchWorkflowList);
<!-- SEC: header content -->
<section class="col surface-1 rounded bordered overflow-hidden">
<div class="column full-height">
<div class="column full-height no-wrap">
<header
class="row surface-3 justify-between full-width items-center bordered-b"
style="z-index: 1"
@ -500,6 +503,18 @@ watch([() => pageState.inputSearch, workflowPageSize], fetchWorkflowList);
</article>
<article v-else class="col q-pa-md surface-2 scroll full-width">
<q-infinite-scroll
:offset="100"
@load="
(_, done) => {
if ($q.screen.gt.xs || workflowPage === workflowPageMax) return;
workflowPage = workflowPage + 1;
fetchWorkflowList().then(() =>
done(workflowPage >= workflowPageMax),
);
}
"
>
<q-table
flat
bordered
@ -588,7 +603,10 @@ watch([() => pageState.inputSearch, workflowPageSize], fetchWorkflowList);
{{ props.row.name }}
</section>
</q-td>
<q-td v-if="fieldSelected.includes('step')" class="text-right">
<q-td
v-if="fieldSelected.includes('step')"
class="text-right"
>
{{ props.row.step.length }}
</q-td>
<q-td style="width: 20%" class="text-right">
@ -659,9 +677,15 @@ watch([() => pageState.inputSearch, workflowPageSize], fetchWorkflowList);
{{ props.row.name }}
</q-tooltip>
</div>
<div v-if="fieldSelected.includes('step')" class="self-end">
<div
v-if="fieldSelected.includes('step')"
class="self-end"
>
<div class="bordered rounded q-px-sm">
<q-icon name="mdi-note-edit-outline" class="q-pr-sm" />
<q-icon
name="mdi-note-edit-outline"
class="q-pr-sm"
/>
{{ props.row.step.length }}
</div>
</div>
@ -703,12 +727,22 @@ watch([() => pageState.inputSearch, workflowPageSize], fetchWorkflowList);
</section>
</template>
</q-table>
<template v-slot:loading>
<div
v-if="$q.screen.lt.sm && workflowPage !== workflowPageMax"
class="row justify-center"
>
<q-spinner-dots color="primary" size="40px" />
</div>
</template>
</q-infinite-scroll>
</article>
<!-- SEC: footer content -->
<footer
class="row justify-between items-center q-px-md q-py-sm surface-2"
v-if="workflowPageMax > 0"
v-if="workflowPageMax > 0 && $q.screen.gt.xs"
>
<div class="col-4">
<div class="row items-center no-wrap">

View file

@ -35,6 +35,7 @@ import {
ToggleButton,
} from 'components/button';
import TableProduct from 'src/components/04_product-service/TableProduct.vue';
import PaginationPageSize from 'src/components/PaginationPageSize.vue';
import useFlowStore from 'stores/flow';
@ -612,7 +613,10 @@ async function fetchListGroups() {
currentPageGroup.value = res.page;
totalGroup.value = res.total;
maxPageGroup.value = Math.ceil(res.total / pageSizeGroup.value);
productGroup.value = res.result;
if (!productGroup.value) productGroup.value = [];
$q.screen.lt.md
? productGroup.value.push(...res.result)
: (productGroup.value = res.result);
}
}
@ -668,13 +672,22 @@ async function fetchListOfProduct() {
maxPageServiceAndProduct.value = Math.ceil(
res.total / pageSizeServiceAndProduct.value,
);
product.value = res.result.map((v) => {
if (!product.value) product.value = [];
$q.screen.xs
? product.value.push(
...res.result.map((v) => {
return {
...v,
type: 'product' as const,
};
}),
)
: (product.value = res.result.map((v) => {
return {
...v,
type: 'product',
};
});
}));
}
}
@ -701,12 +714,22 @@ async function fetchListOfService() {
maxPageServiceAndProduct.value = Math.ceil(
res.total / pageSizeServiceAndProduct.value,
);
service.value = res.result.map((v) => {
if (!service.value) service.value = [];
$q.screen.xs
? service.value.push(
...res.result.map((v) => {
return {
...v,
type: 'service' as const,
};
}),
)
: (service.value = res.result.map((v) => {
return {
...v,
type: 'service',
};
});
}));
}
}
@ -1541,8 +1564,11 @@ async function enterNext(type: 'service' | 'product') {
filterStat.value.push('group');
filterStat.value.push('service');
}
if (productMode.value === 'service') await fetchListOfService();
if (productMode.value === 'product') await fetchListOfProduct();
if (productMode.value === 'service' && $q.screen.gt.xs)
await fetchListOfService();
if (productMode.value === 'product' && $q.screen.gt.xs)
await fetchListOfProduct();
flowStore.rotate();
}
@ -1566,6 +1592,8 @@ async function fetchImageList(
}
onMounted(async () => {
$q.screen.gt.sm && (await fetchListGroups());
navigatorStore.current.title = 'productService.title';
navigatorStore.current.path = [
{
@ -1581,7 +1609,6 @@ onMounted(async () => {
modeView.value = $q.screen.lt.md ? true : false;
calculateStats();
await fetchListGroups();
flowStore.rotate();
});
@ -1876,8 +1903,20 @@ watch(
</q-input>
</div>
<div class="col full-width scroll">
<div class="q-pa-md">
<div class="col full-width scroll q-pa-md">
<q-infinite-scroll
:offset="100"
@load="
async (_, done) => {
if ($q.screen.gt.sm) return;
fetchListGroups().then(() => {
currentPageGroup = currentPageGroup + 1;
done(currentPageGroup > maxPageGroup);
});
}
"
>
<TreeComponent
v-model:nodes="treeProductTypeAndGroup"
v-model:expanded-tree="expandedTree"
@ -1980,7 +2019,15 @@ watch(
"
@handle-hold="handleHold"
/>
<template v-slot:loading>
<div
v-if="$q.screen.lt.sm && currentPageGroup !== maxPageGroup"
class="row justify-center"
>
<q-spinner-dots color="primary" size="40px" />
</div>
</template>
</q-infinite-scroll>
</div>
</div>
</template>
@ -2438,7 +2485,8 @@ watch(
</q-table>
</div>
<div
<!-- footer group -->
<footer
v-if="productMode === 'group'"
class="row items-center justify-between q-px-md q-py-sm full-width"
>
@ -2451,31 +2499,7 @@ watch(
{{ $t('general.recordPerPage') }}
</div>
<div>
<q-btn-dropdown
dense
unelevated
:label="pageSizeGroup"
class="bordered q-pl-md"
>
<q-list>
<q-item
v-for="v in [10, 30, 50, 100, 500, 1000]"
:key="v"
clickable
v-close-popup
@click="
async () => {
pageSizeGroup = v;
await fetchListGroups();
}
"
>
<q-item-section>
<q-item-label>{{ v }}</q-item-label>
</q-item-section>
</q-item>
</q-list>
</q-btn-dropdown>
<PaginationPageSize v-model="pageSizeGroup" />
</div>
</div>
</div>
@ -2506,7 +2530,7 @@ watch(
"
/>
</div>
</div>
</footer>
</template>
</div>
@ -2672,6 +2696,22 @@ watch(
<template v-else>
<div
class="flex scroll full-width q-pa-md surface-2 column col"
>
<q-infinite-scroll
:offset="100"
@load="
(_, done) => {
if ($q.screen.gt.xs) return;
alternativeFetch().then(() => {
currentPageServiceAndProduct =
currentPageServiceAndProduct + 1;
done(
currentPageServiceAndProduct >
maxPageServiceAndProduct,
);
});
}
"
>
<q-table
class="full-width"
@ -3094,7 +3134,11 @@ watch(
:price-display="priceDisplay"
@toggle-status="
() => {
triggerChangeStatus(row.id, row.status, row.type);
triggerChangeStatus(
row.id,
row.status,
row.type,
);
}
"
@menu-view-detail="
@ -3142,10 +3186,24 @@ watch(
</div>
</template>
</q-table>
<template v-slot:loading>
<div
v-if="
$q.screen.lt.sm &&
currentPageServiceAndProduct !==
maxPageServiceAndProduct
"
class="row justify-center"
>
<q-spinner-dots color="primary" size="40px" />
</div>
</template>
<!-- footer -->
<div
</q-infinite-scroll>
</div>
</template>
<!-- footer product service -->
<footer
v-if="$q.screen.gt.xs"
class="row items-center justify-between q-py-sm q-px-md surface-2"
>
<div class="col-4">
@ -3154,37 +3212,7 @@ watch(
{{ $t('general.recordPerPage') }}
</div>
<div>
<q-btn-dropdown
dense
unelevated
:label="pageSizeServiceAndProduct"
class="bordered q-pl-md"
>
<q-list>
<q-item
v-for="v in [10, 30, 50, 100, 500, 1000]"
:key="v"
clickable
v-close-popup
@click="
async () => {
pageSizeServiceAndProduct = v;
if (productAndServiceTab === 'product') {
await fetchListOfProduct();
}
if (productAndServiceTab === 'service') {
await fetchListOfService();
}
}
"
>
<q-item-section>
<q-item-label>{{ v }}</q-item-label>
</q-item-section>
</q-item>
</q-list>
</q-btn-dropdown>
<PaginationPageSize v-model="pageSizeServiceAndProduct" />
</div>
</div>
</div>
@ -3220,7 +3248,7 @@ watch(
"
/>
</div>
</div>
</footer>
</div>
</div>
</template>