refactor: enhance pagination logic and UI for Proxmox Firewall view, improving user experience with better page range display and styling adjustments

This commit is contained in:
2025-12-03 04:21:04 -05:00
parent 93d215999c
commit ec5675e108

View File

@@ -394,23 +394,39 @@
get paginationRange() {
const total = this.totalPages;
const current = this.currentPage;
const delta = 2;
const delta = 2; // Show 2 pages on each side of current
if (total <= 0) return [];
if (total <= 7) {
// If 7 or fewer pages, show all pages
return Array.from({ length: total }, (_, i) => i + 1);
}
const range = [];
const left = Math.max(2, current - delta);
const right = Math.min(total - 1, current + delta);
for (let i = Math.max(2, current - delta); i <= Math.min(total - 1, current + delta); i++) {
range.push(i);
}
// Always include first page
range.push(1);
if (current - delta > 2) {
range.unshift('...');
}
if (current + delta < total - 1) {
// Add left ellipsis if there's a gap
if (left > 2) {
range.push('...');
}
if (total > 0) {
range.unshift(1);
// Add middle pages (avoiding duplicates with first/last)
for (let i = left; i <= right; i++) {
if (i !== 1 && i !== total) {
range.push(i);
}
}
// Add right ellipsis if there's a gap
if (right < total - 1) {
range.push('...');
}
// Always include last page (if different from first)
if (total > 1) {
range.push(total);
}
@@ -437,7 +453,7 @@
x-effect="if (currentPage > totalPages && totalPages > 0) currentPage = totalPages"
class="space-y-4"
>
<div class="flex flex-col md:flex-row md:items-center md:justify-between gap-3">
<div class="flex flex-col md:flex-row md:items-center md:justify-between gap-3 mb-4">
<div class="relative w-full md:w-72">
<x-ri-search-line class="size-4 absolute left-3 top-1/2 -translate-y-1/2 text-base/40" />
<input
@@ -448,12 +464,18 @@
class="firewall-log-search-input w-full pr-4 py-2 border border-neutral rounded-lg bg-background focus:outline-none focus:ring-2 focus:ring-primary/40"
/>
</div>
<div class="flex items-center gap-4">
<div class="text-xs text-base/50">
<span x-text="`${filteredLogs.length} / ${logs.length} results`"></span>
<div class="flex items-center gap-4 text-sm">
<div class="px-3 py-1.5 bg-background-secondary border border-neutral/30 rounded-lg">
<span class="text-base/70">Showing </span>
<span class="font-semibold text-primary" x-text="paginatedLogs.length"></span>
<span class="text-base/70"> of </span>
<span class="font-semibold" x-text="filteredLogs.length"></span>
</div>
<div class="text-xs text-base/50">
<span x-text="`Page ${currentPage} of ${totalPages || 1}`"></span>
<div class="px-3 py-1.5 bg-background-secondary border border-neutral/30 rounded-lg">
<span class="text-base/70">Page </span>
<span class="font-semibold text-primary" x-text="currentPage"></span>
<span class="text-base/70"> / </span>
<span class="font-semibold" x-text="totalPages || 1"></span>
</div>
</div>
</div>
@@ -534,34 +556,37 @@
</div>
<!-- Pagination Controls -->
<div x-show="totalPages > 1" class="flex items-center justify-center gap-2 mt-4">
<div x-show="totalPages > 1" class="flex items-center justify-center gap-2 mt-4 flex-wrap">
<button
type="button"
@click="prevPage()"
:disabled="currentPage === 1"
:class="currentPage === 1 ? 'opacity-50 cursor-not-allowed' : 'hover:bg-primary/10'"
class="px-3 py-2 border border-neutral rounded-lg transition-colors text-sm font-medium">
class="px-3 py-2 border border-neutral rounded-lg transition-all text-sm font-medium flex items-center justify-center"
:class="currentPage === 1 ? 'opacity-50 cursor-not-allowed bg-background-secondary' : 'hover:bg-primary/10 hover:border-primary/50'">
<x-ri-arrow-left-s-line class="size-4" />
</button>
<template x-for="page in paginationRange" :key="page">
<template x-for="(page, index) in paginationRange" :key="`page-${index}-${page}`">
<button
type="button"
@click="typeof page === 'number' ? goToPage(page) : null"
:class="{
'bg-primary text-white': page === currentPage,
'hover:bg-primary/10': typeof page === 'number' && page !== currentPage,
'cursor-default': typeof page !== 'number'
}"
:disabled="typeof page !== 'number'"
class="px-4 py-2 border border-neutral rounded-lg transition-colors text-sm font-medium min-w-[40px]"
class="px-4 py-2 border rounded-lg transition-all text-sm font-medium min-w-[44px] flex items-center justify-center"
:class="{
'bg-primary text-white border-primary hover:bg-primary/90': page === currentPage && typeof page === 'number',
'border-neutral hover:bg-primary/10 hover:border-primary/50': typeof page === 'number' && page !== currentPage,
'border-transparent cursor-default opacity-60': typeof page !== 'number'
}"
x-text="page">
</button>
</template>
<button
type="button"
@click="nextPage()"
:disabled="currentPage === totalPages"
:class="currentPage === totalPages ? 'opacity-50 cursor-not-allowed' : 'hover:bg-primary/10'"
class="px-3 py-2 border border-neutral rounded-lg transition-colors text-sm font-medium">
class="px-3 py-2 border border-neutral rounded-lg transition-all text-sm font-medium flex items-center justify-center"
:class="currentPage === totalPages ? 'opacity-50 cursor-not-allowed bg-background-secondary' : 'hover:bg-primary/10 hover:border-primary/50'">
<x-ri-arrow-right-s-line class="size-4" />
</button>
</div>