Skip to content

Commit eabb02f

Browse files
committed
feat: add pagintion for the afcl table
1 parent 8982c3e commit eabb02f

File tree

1 file changed

+77
-20
lines changed

1 file changed

+77
-20
lines changed

adminforth/spa/src/afcl/Table.vue

Lines changed: 77 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -35,41 +35,74 @@
3535
{{ item[column.fieldName] }}
3636
</span>
3737
<div v-else>
38-
<div class="h-5 w-full">
38+
<div class=" w-full">
3939
<Skeleton class="h-4" />
4040
</div>
4141
</div>
4242
</td>
4343
</tr>
4444
</tbody>
4545
</table>
46-
<nav class="afcl-table-pagination-container bg-lightTableBackground dark:bg-darkTableBackground flex items-center flex-column flex-wrap md:flex-row justify-between p-4"
46+
<nav class="afcl-table-pagination-container bg-lightTableBackground dark:bg-darkTableBackground flex items-center flex-col flex-wrap justify-between px-4 pb-4"
4747
v-if="totalPages > 1"
4848
:aria-label="$t('Table navigation')">
49+
<div class="af-pagination-container flex flex-row items-center mt-4 xs:flex-row xs:justify-between xs:items-center gap-3">
50+
<div class="af-pagination-buttons-container inline-flex">
51+
<!-- Buttons -->
52+
<button
53+
class="af-pagination-prev-button flex items-center py-1 px-3 gap-1 text-sm font-medium text-lightListTablePaginationText focus:outline-none bg-lightListTablePaginationBackgoround border-r-0 rounded-s border border-lightListTablePaginationBorder hover:bg-lightListTablePaginationBackgoroundHover hover:text-lightListTablePaginationTextHover focus:z-10 focus:ring-4 focus:ring-lightListTablePaginationFocusRing dark:focus:ring-darkListTablePaginationFocusRing dark:bg-darkListTablePaginationBackgoround dark:text-darkListTablePaginationText dark:border-darkListTablePaginationBorder dark:hover:text-darkListTablePaginationTextHover dark:hover:bg-darkListTablePaginationBackgoroundHover disabled:opacity-50"
54+
@click="currentPage--; pageInput = currentPage.toString();" :disabled="currentPage <= 1">
55+
<svg class="w-3.5 h-3.5 rtl:rotate-180" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none"
56+
viewBox="0 0 14 10">
57+
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
58+
d="M13 5H1m0 0 4 4M1 5l4-4"/>
59+
</svg>
60+
<span class="hidden sm:inline">
61+
{{ $t('Prev') }}
62+
</span>
63+
</button>
64+
<button
65+
class="af-pagination-first-page-button flex items-center py-1 px-3 text-sm font-medium text-lightListTablePaginationText focus:outline-none bg-lightListTablePaginationBackgoround border-r-0 border border-lightListTablePaginationBorder hover:bg-lightListTablePaginationBackgoroundHover hover:text-lightListTablePaginationTextHover focus:z-10 focus:ring-4 focus:ring-lightListTablePaginationFocusRing dark:focus:ring-darkListTablePaginationFocusRing dark:bg-darkListTablePaginationBackgoround dark:text-darkListTablePaginationText dark:border-darkListTablePaginationBorder dark:hover:text-darkListTablePaginationTextHover dark:hover:bg-darkListTablePaginationBackgoroundHover disabled:opacity-50"
66+
@click="switchPage(1); pageInput = currentPage.toString();" :disabled="currentPage <= 1">
67+
<!-- <IconChevronDoubleLeftOutline class="w-4 h-4" /> -->
68+
1
69+
</button>
70+
<div
71+
contenteditable="true"
72+
class="af-pagination-input min-w-10 outline-none inline-block w-auto py-1.5 px-3 text-sm text-center text-lightListTablePaginationCurrentPageText border border-lightListTablePaginationBorder dark:border-darkListTablePaginationBorder dark:text-darkListTablePaginationCurrentPageText dark:bg-darkListTablePaginationBackgoround z-10"
73+
@keydown="onPageKeydown($event)"
74+
@input="onPageInput($event)"
75+
@blur="validatePageInput()"
76+
>
77+
{{ pageInput }}
78+
</div>
79+
80+
<button
81+
class="af-pagination-last-page-button flex items-center py-1 px-3 text-sm font-medium text-lightListTablePaginationText focus:outline-none bg-lightListTablePaginationBackgoround border-l-0 border border-lightListTablePaginationBorder hover:bg-lightListTablePaginationBackgoroundHover hover:text-lightListTablePaginationTextHover focus:z-10 focus:ring-4 focus:ring-lightListTablePaginationFocusRing dark:focus:ring-darkListTablePaginationFocusRing dark:bg-darkListTablePaginationBackgoround dark:text-darkListTablePaginationText dark:border-darkListTablePaginationBorder dark:hover:text-white dark:hover:bg-darkListTablePaginationBackgoroundHover disabled:opacity-50"
82+
@click="currentPage = totalPages; pageInput = currentPage.toString();" :disabled="currentPage >= totalPages">
83+
{{ totalPages }}
84+
85+
<!-- <IconChevronDoubleRightOutline class="w-4 h-4" /> -->
86+
</button>
87+
<button
88+
class="af-pagination-next-button flex items-center py-1 px-3 gap-1 text-sm font-medium text-lightListTablePaginationText focus:outline-none bg-lightListTablePaginationBackgoround border-l-0 rounded-e border border-lightListTablePaginationBorder hover:bg-lightListTablePaginationBackgoroundHover hover:text-lightListTablePaginationTextHover focus:z-10 focus:ring-4 focus:ring-lightListTablePaginationFocusRing dark:focus:ring-darkListTablePaginationFocusRing dark:bg-darkListTablePaginationBackgoround dark:text-darkListTablePaginationText dark:border-darkListTablePaginationBorder dark:hover:text-white dark:hover:bg-darkListTablePaginationBackgoroundHover disabled:opacity-50"
89+
@click="currentPage++; pageInput = currentPage.toString();" :disabled="currentPage >= totalPages">
90+
<span class="hidden sm:inline">{{ $t('Next') }}</span>
91+
<svg class="w-3.5 h-3.5 rtl:rotate-180" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none"
92+
viewBox="0 0 14 10">
93+
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
94+
d="M1 5h12m0 0L9 1m4 4L9 9"/>
95+
</svg>
96+
</button>
97+
</div>
98+
</div>
4999
<i18n-t
50-
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"
100+
keypath="Showing {from} to {to} of {total}" tag="span" class="afcl-table-pagination-text mt-2 text-sm font-normal text-lightTablePaginationText dark:text-darkTablePaginationText mb-4 md:mb-0 block w-full md:inline md:w-auto"
51101
>
52102
<template #from><span class="font-semibold text-lightTablePaginationNumeration dark:text-darkTablePaginationNumeration">{{ Math.min((currentPage - 1) * props.pageSize + 1, dataResult.total) }}</span></template>
53103
<template #to><span class="font-semibold text-lightTablePaginationNumeration dark:text-darkTablePaginationNumeration">{{ Math.min(currentPage * props.pageSize, dataResult.total) }}</span></template>
54104
<template #total><span class="font-semibold text-lightTablePaginationNumeration dark:text-darkTablePaginationNumeration">{{ dataResult.total }}</span></template>
55105
</i18n-t>
56-
57-
<ul class="afcl-table-pagination-list inline-flex -space-x-px rtl:space-x-reverse text-sm h-8">
58-
<li v-for="page in totalPages" :key="page">
59-
<a href="#"
60-
@click.prevent="switchPage(page)"
61-
:aria-current="page === page ? 'page' : undefined"
62-
:class='{
63-
"afcl-table-pagination-button text-blue-600 bg-lightActivePaginationButtonBackground text-lightActivePaginationButtonText dark:bg-darkActivePaginationButtonBackground dark:text-darkActivePaginationButtonText hover:opacity-90": page === currentPage,
64-
"text-lightUnactivePaginationButtonText border bg-lightUnactivePaginationButtonBackground border-lightUnactivePaginationButtonBorder hover:bg-lightUnactivePaginationButtonHoverBackground hover:text-lightUnactivePaginationButtonHoverText dark:bg-darkUnactivePaginationButtonBackground dark:border-darkUnactivePaginationButtonBorder dark:text-darkUnactivePaginationButtonText dark:hover:bg-darkUnactivePaginationButtonHoverBackground dark:hover:text-darkUnactivePaginationButtonHoverText": page !== currentPage,
65-
"rounded-s-lg ms-0": page === 1,
66-
"rounded-e-lg": page === totalPages,
67-
}'
68-
class="flex items-center justify-center px-3 h-8 leading-tight ">
69-
{{ page }}
70-
</a>
71-
</li>
72-
</ul>
73106
</nav>
74107
</div>
75108

@@ -101,6 +134,7 @@
101134
102135
const currentPage = ref(1);
103136
const isLoading = ref(false);
137+
const pageInput = ref('1');
104138
105139
const dataResult = asyncComputed( async() => {
106140
if (typeof props.data === 'function') {
@@ -130,5 +164,28 @@
130164
'update:activeTab',
131165
]);
132166
167+
function onPageInput(event: any) {
168+
pageInput.value = event.target.innerText;
169+
}
170+
171+
function validatePageInput() {
172+
const newPage = parseInt(pageInput.value) || 1;
173+
const validPage = Math.max(1, Math.min(newPage, totalPages.value));
174+
currentPage.value = validPage;
175+
pageInput.value = validPage.toString();
176+
}
177+
178+
async function onPageKeydown(event: any) {
179+
// page input should accept only numbers, arrow keys and backspace
180+
if (['Enter', 'Space'].includes(event.code) ||
181+
(!['Backspace', 'ArrowRight', 'ArrowLeft'].includes(event.code)
182+
&& isNaN(String.fromCharCode(event.keyCode)))) {
183+
event.preventDefault();
184+
if (event.code === 'Enter') {
185+
validatePageInput();
186+
event.target.blur();
187+
}
188+
}
189+
}
133190
134191
</script>

0 commit comments

Comments
 (0)