refactor: 03 => screen.xs fetch scroll

This commit is contained in:
puriphatt 2025-01-30 10:10:15 +07:00
parent 508e6d3f5b
commit ef81a93690
2 changed files with 565 additions and 513 deletions

View file

@ -84,7 +84,6 @@ import { DialogContainer, DialogHeader } from 'components/dialog';
import KebabAction from 'src/components/shared/KebabAction.vue';
import { nextTick } from 'vue';
import FormEmployeeVisa from 'components/03_customer-management/FormEmployeeVisa.vue';
import { group } from 'node:console';
import PaginationPageSize from 'src/components/PaginationPageSize.vue';
import { AddButton } from 'components/button';
@ -224,10 +223,12 @@ watch(
if (tabName === 'employer') {
currentPageCustomer.value = 1;
currentBtnOpen.value = [];
listCustomer.value = [];
await fetchListCustomer(true);
}
if (tabName === 'employee') {
currentPageEmployee.value = 1;
listEmployee.value = [];
await fetchListEmployee({ fetchStats: true });
}
@ -383,8 +384,8 @@ async function fetchListCustomer(fetchStats = false) {
customerType: (
{
all: undefined,
customerLegalEntity: 'CORP',
customerNaturalPerson: 'PERS',
customerLegalEntity: CustomerType.Corporate,
customerNaturalPerson: CustomerType.Person,
} as const
)[customerTypeSelected.value.value],
});
@ -392,7 +393,9 @@ async function fetchListCustomer(fetchStats = false) {
if (resultList) {
currentPageCustomer.value = resultList.page;
maxPageCustomer.value = Math.ceil(resultList.total / pageSize.value);
listCustomer.value = resultList.result;
$q.screen.xs
? listCustomer.value.push(...resultList.result)
: (listCustomer.value = resultList.result);
}
if (fetchStats) {
@ -426,7 +429,9 @@ async function fetchListEmployee(opt?: {
maxPageEmployee.value = Math.ceil(
resultListEmployee.total / pageSize.value,
);
listEmployee.value = resultListEmployee.result;
$q.screen.xs
? listEmployee.value.push(...resultListEmployee.result)
: (listEmployee.value = resultListEmployee.result);
}
if (opt && opt.fetchStats)
@ -1098,7 +1103,7 @@ const emptyCreateDialog = ref(false);
class="q-px-md row q-gutter-x-sm items-center"
>
<nav
class="col rounded q-pa-sm text-center app-text-muted"
class="col rounded q-pa-sm text-center app-text-muted text-caption"
:class="{
'active-tab-sm': customerTypeSelected.value === v,
'bordered surface-1': customerTypeSelected.value !== v,
@ -1198,9 +1203,25 @@ const emptyCreateDialog = ref(false);
<NoData :not-found="!!inputSearch" />
</div>
<div
<article
v-if="listCustomer.length !== 0"
class="col q-pa-md scroll full-width"
>
<q-infinite-scroll
:offset="100"
@load="
(_, done) => {
if (
$q.screen.gt.xs ||
currentPageCustomer === maxPageCustomer
)
return;
currentPageCustomer = currentPageCustomer + 1;
fetchListCustomer().then(() =>
done(currentPageCustomer >= maxPageCustomer),
);
}
"
>
<q-table
flat
@ -1317,7 +1338,8 @@ const emptyCreateDialog = ref(false);
<div class="col app-text-muted">
{{
props.row.customerType === 'CORP'
? props.row.branch[0]?.registerNameEN || '-'
? props.row.branch[0]?.registerNameEN ||
'-'
: capitalizeFirstLetter(
props.row.branch[0].namePrefix,
) +
@ -1544,7 +1566,8 @@ const emptyCreateDialog = ref(false);
}
"
@edit="
(item: any) => editEmployeeFormPersonal(item.id)
(item: any) =>
editEmployeeFormPersonal(item.id)
"
@delete="
(item: any) => {
@ -1601,7 +1624,9 @@ const emptyCreateDialog = ref(false);
:inactive="props.row.status === 'INACTIVE'"
:field-selected="
fieldSelected.filter((v) => {
return columnsCustomer.some((c) => c.name === v);
return columnsCustomer.some(
(c) => c.name === v,
);
})
"
>
@ -1663,7 +1688,9 @@ const emptyCreateDialog = ref(false);
v !== 'titleName' &&
v !== 'address' &&
v !== 'contactName' &&
columnsCustomer.some((c) => c.name === v)
columnsCustomer.some(
(c) => c.name === v,
)
);
})
.sort((lhs, rhs) => {
@ -1672,7 +1699,9 @@ const emptyCreateDialog = ref(false);
...columnsCustomer,
];
return (
fields.findIndex((i) => i.name === lhs) -
fields.findIndex(
(i) => i.name === lhs,
) -
fields.findIndex((i) => i.name === rhs)
);
})"
@ -1692,7 +1721,8 @@ const emptyCreateDialog = ref(false);
props.row.branch[0].jobPosition,
)
: key === 'officeTel'
? props.row.branch[0].officeTel || '-'
? props.row.branch[0].officeTel ||
'-'
: ''
}}
</span>
@ -1729,10 +1759,22 @@ const emptyCreateDialog = ref(false);
</div>
</template>
</q-table>
</div>
<template v-slot:loading>
<div
v-if="listCustomer.length !== 0"
v-if="
$q.screen.lt.sm &&
currentPageCustomer !== maxPageCustomer
"
class="row justify-center"
>
<q-spinner-dots color="primary" size="40px" />
</div>
</template>
</q-infinite-scroll>
</article>
<footer
v-if="listCustomer.length !== 0 && $q.screen.gt.xs"
class="row justify-between items-center q-px-md q-py-sm"
>
<div class="row col-4 items-center">
@ -1775,7 +1817,7 @@ const emptyCreateDialog = ref(false);
"
/>
</div>
</div>
</footer>
</template>
<!-- employee -->
@ -1792,9 +1834,25 @@ const emptyCreateDialog = ref(false);
<NoData :not-found="!!inputSearch" />
</div>
<div
<article
v-if="listEmployee.length !== 0"
class="surface-2 q-pa-md scroll col full-width"
>
<q-infinite-scroll
:offset="100"
@load="
(_, done) => {
if (
$q.screen.gt.xs ||
currentPageEmployee === maxPageEmployee
)
return;
currentPageEmployee = currentPageEmployee + 1;
fetchListEmployee().then(() =>
done(currentPageEmployee >= maxPageEmployee),
);
}
"
>
<TableEmpoloyee
v-model:page-size="pageSize"
@ -1832,9 +1890,21 @@ const emptyCreateDialog = ref(false);
}
"
/>
</div>
<template v-slot:loading>
<div
v-if="listEmployee.length !== 0"
v-if="
$q.screen.lt.sm &&
currentPageEmployee !== maxPageEmployee
"
class="row justify-center"
>
<q-spinner-dots color="primary" size="40px" />
</div>
</template>
</q-infinite-scroll>
</article>
<footer
v-if="listEmployee.length !== 0 && $q.screen.gt.xs"
class="row justify-between items-center q-px-md q-py-sm"
>
<div class="row col-4 items-center">
@ -1875,7 +1945,7 @@ const emptyCreateDialog = ref(false);
"
/>
</div>
</div>
</footer>
</template>
<template

View file

@ -13,6 +13,7 @@ import { useInstitution } from 'src/stores/institution';
import { Institution, InstitutionPayload } from 'src/stores/institution/types';
import { formatAddress } from 'src/utils/address';
import PaginationPageSize from 'src/components/PaginationPageSize.vue';
import PaginationComponent from 'src/components/PaginationComponent.vue';
import KebabAction from 'src/components/shared/KebabAction.vue';
import StatCardComponent from 'src/components/StatCardComponent.vue';
@ -756,26 +757,7 @@ watch(
{{ $t('general.recordPerPage') }}
</div>
<div>
<q-btn-dropdown
dense
unelevated
:label="pageSize"
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="pageSize = v"
>
<q-item-section>
<q-item-label>{{ v }}</q-item-label>
</q-item-section>
</q-item>
</q-list>
</q-btn-dropdown>
<PaginationPageSize v-model="pageSize" />
</div>
</div>
</div>