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:
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user