Skip to content

Commit 4d889f6

Browse files
authored
Merge pull request #345 from devforth/AdminForth/813
feat: add backend pagination for the afcl table
2 parents f2aec6a + 486b372 commit 4d889f6

File tree

2 files changed

+49
-10
lines changed

2 files changed

+49
-10
lines changed

adminforth/documentation/docs/tutorial/03-Customization/15-afcl.md

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -797,7 +797,7 @@ const isoFlagToEmoji = (iso) => iso.toUpperCase().replace(/./g, char => String.f
797797

798798

799799

800-
## Pagination
800+
### Pagination
801801

802802
Table provides front-end side pagination. You can set `pageSize` (default is 10) to set how many rows to show per page.
803803
If there is less then `pageSize` rows, pagination will not be shown.
@@ -829,6 +829,36 @@ If there is less then `pageSize` rows, pagination will not be shown.
829829
</div>
830830
</div>
831831

832+
### Server-side pagination
833+
834+
To load pages dynamically, simply pass async callback to data:
835+
836+
```ts
837+
async function loadPageData(offset, limit) {
838+
// in real app do await callAdminForthApi or await fetch to get date, use offset and limit value to slice data
839+
return {
840+
data: [
841+
{ name: 'John', age: offset, country: 'US' },
842+
{ name: 'Rick', age: offset+1, country: 'CA' },
843+
{ name: 'Alice', age: offset+2, country: 'BR' },
844+
],
845+
total: 3 // should return total amount of records in database
846+
}
847+
}
848+
849+
<Table
850+
:columns="[
851+
{ label: 'Name', fieldName: 'name' },
852+
{ label: 'Age', fieldName: 'age' },
853+
{ label: 'Country', fieldName: 'country' },
854+
]"
855+
//diff-remove
856+
:data="[...]
857+
//diff-add
858+
:data="loadPageData"
859+
860+
:pageSize="3"
861+
```
832862

833863
## ProgressBar
834864

adminforth/spa/src/afcl/Table.vue

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,9 @@
4444
<i18n-t
4545
keypath="Showing {from} to {to} of {total}" tag="span" class="afcl-table-pagination-text text-sm font-normal text-lightTablePaginationText dark:text-darkTablePaginationText mb-4 md:mb-0 block w-full md:inline md:w-auto"
4646
>
47-
<template #from><span class="font-semibold text-lightTablePaginationNumeration dark:text-darkTablePaginationNumeration">{{ Math.min((currentPage - 1) * props.pageSize + 1, props.data.length) }}</span></template>
48-
<template #to><span class="font-semibold text-lightTablePaginationNumeration dark:text-darkTablePaginationNumeration">{{ Math.min(currentPage * props.pageSize, props.data.length) }}</span></template>
49-
<template #total><span class="font-semibold text-lightTablePaginationNumeration dark:text-darkTablePaginationNumeration">{{ props.data.length }}</span></template>
47+
<template #from><span class="font-semibold text-lightTablePaginationNumeration dark:text-darkTablePaginationNumeration">{{ Math.min((currentPage - 1) * props.pageSize + 1, dataResult.total) }}</span></template>
48+
<template #to><span class="font-semibold text-lightTablePaginationNumeration dark:text-darkTablePaginationNumeration">{{ Math.min(currentPage * props.pageSize, dataResult.total) }}</span></template>
49+
<template #total><span class="font-semibold text-lightTablePaginationNumeration dark:text-darkTablePaginationNumeration">{{ dataResult.total }}</span></template>
5050
</i18n-t>
5151

5252
<ul class="afcl-table-pagination-list inline-flex -space-x-px rtl:space-x-reverse text-sm h-8">
@@ -74,6 +74,8 @@
7474

7575
<script setup lang="ts">
7676
import { ref, type Ref, computed } from 'vue';
77+
import { asyncComputed } from '@vueuse/core';
78+
import { IconArrowRightOutline, IconArrowLeftOutline } from '@iconify-prerendered/vue-flowbite';
7779
7880
const props = withDefaults(
7981
defineProps<{
@@ -83,7 +85,7 @@
8385
}[],
8486
data: {
8587
[key: string]: any,
86-
}[],
88+
}[] | ((offset: number, limit: number) => Promise<{data: {[key: string]: any}[], total: number}>),
8789
evenHighlights?: boolean,
8890
pageSize?: number,
8991
}>(), {
@@ -94,14 +96,21 @@
9496
9597
const currentPage = ref(1);
9698
99+
const dataResult = asyncComputed( async() => {
100+
if (typeof props.data === 'function') {
101+
return await props.data(currentPage.value, props.pageSize);
102+
}
103+
const start = (currentPage.value - 1) * props.pageSize;
104+
const end = start + props.pageSize;
105+
return { data: props.data.slice(start, end), total: props.data.length };
106+
});
107+
97108
const totalPages = computed(() => {
98-
return Math.ceil(props.data.length / props.pageSize);
109+
return dataResult.value?.total ? Math.ceil(dataResult.value.total / props.pageSize) : 1;
99110
});
100111
101-
const dataPage = computed(() => {
102-
const start = (currentPage.value - 1) * props.pageSize;
103-
const end = start + props.pageSize;
104-
return props.data.slice(start, end);
112+
const dataPage = asyncComputed( async() => {
113+
return dataResult.value.data;
105114
});
106115
107116
function switchPage(p: number) {

0 commit comments

Comments
 (0)