Refactor pagination for statistics and task history for improved usability and clarity
This commit is contained in:
@@ -898,30 +898,98 @@
|
||||
@json($statisticsExportRows)
|
||||
</template>
|
||||
<!-- Statistics History Pagination -->
|
||||
<div class="p-4 border-t border-neutral">
|
||||
<div class="flex flex-col sm:flex-row items-center justify-between gap-4">
|
||||
<!-- Per Page Selector -->
|
||||
<div class="flex items-center gap-2 text-sm">
|
||||
<span class="text-base/70">Show</span>
|
||||
<select wire:model.live="statisticsPerPage"
|
||||
class="bg-background border border-neutral rounded-md px-2 py-1 text-sm focus:outline-none focus:ring-2 focus:ring-primary/50">
|
||||
@if($this->statistics->total() > 0)
|
||||
<div class="p-4 border-t border-neutral flex flex-col sm:flex-row items-center justify-between gap-4">
|
||||
{{-- Records per page selector --}}
|
||||
<div class="flex items-center gap-3">
|
||||
<label class="text-sm text-base/70">Show:</label>
|
||||
<select wire:model.live="statisticsPerPage" class="px-3 py-1.5 border border-neutral rounded-lg bg-background text-sm">
|
||||
<option value="10">10</option>
|
||||
<option value="25">25</option>
|
||||
<option value="50">50</option>
|
||||
<option value="100">100</option>
|
||||
</select>
|
||||
<span class="text-base/70">entries</span>
|
||||
<span class="text-base/50 ml-2">({{ $this->statistics->total() }} total)</span>
|
||||
<span class="text-sm text-base/60">per page</span>
|
||||
</div>
|
||||
|
||||
<!-- Pagination Links -->
|
||||
@if($this->statistics->hasPages())
|
||||
<div class="flex items-center gap-1">
|
||||
{{ $this->statistics->links() }}
|
||||
</div>
|
||||
@endif
|
||||
{{-- Page info and navigation --}}
|
||||
<div class="flex items-center gap-4">
|
||||
<span class="text-sm text-base/60">
|
||||
Showing {{ (($this->statistics->currentPage() - 1) * $this->statistics->perPage()) + 1 }} - {{ min($this->statistics->currentPage() * $this->statistics->perPage(), $this->statistics->total()) }} of {{ $this->statistics->total() }} entries
|
||||
</span>
|
||||
|
||||
@if($this->statistics->hasPages())
|
||||
<div class="flex items-center gap-1">
|
||||
{{-- First page --}}
|
||||
<button type="button"
|
||||
wire:click="gotoPage(1)"
|
||||
@if($this->statistics->onFirstPage()) disabled @endif
|
||||
class="px-2 py-1 border border-neutral rounded hover:bg-background-secondary transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
title="First page">
|
||||
<x-ri-arrow-left-double-line class="size-4" />
|
||||
</button>
|
||||
|
||||
{{-- Previous page --}}
|
||||
<button type="button"
|
||||
wire:click="previousPage"
|
||||
@if($this->statistics->onFirstPage()) disabled @endif
|
||||
class="px-2 py-1 border border-neutral rounded hover:bg-background-secondary transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
title="Previous page">
|
||||
<x-ri-arrow-left-s-line class="size-4" />
|
||||
</button>
|
||||
|
||||
{{-- Page numbers --}}
|
||||
@php
|
||||
$statsTotalPages = $this->statistics->lastPage();
|
||||
$statsCurrentPage = $this->statistics->currentPage();
|
||||
$statsStartPage = max(1, $statsCurrentPage - 2);
|
||||
$statsEndPage = min($statsTotalPages, $statsCurrentPage + 2);
|
||||
@endphp
|
||||
|
||||
@if($statsStartPage > 1)
|
||||
<button type="button" wire:click="gotoPage(1)" class="px-3 py-1 border border-neutral rounded hover:bg-background-secondary transition-colors text-sm">1</button>
|
||||
@if($statsStartPage > 2)
|
||||
<span class="px-2 text-base/60">...</span>
|
||||
@endif
|
||||
@endif
|
||||
|
||||
@for($i = $statsStartPage; $i <= $statsEndPage; $i++)
|
||||
<button type="button"
|
||||
wire:click="gotoPage({{ $i }})"
|
||||
class="px-3 py-1 border rounded text-sm transition-colors {{ $statsCurrentPage === $i ? 'bg-primary text-white border-primary' : 'border-neutral hover:bg-background-secondary' }}">
|
||||
{{ $i }}
|
||||
</button>
|
||||
@endfor
|
||||
|
||||
@if($statsEndPage < $statsTotalPages)
|
||||
@if($statsEndPage < $statsTotalPages - 1)
|
||||
<span class="px-2 text-base/60">...</span>
|
||||
@endif
|
||||
<button type="button" wire:click="gotoPage({{ $statsTotalPages }})" class="px-3 py-1 border border-neutral rounded hover:bg-background-secondary transition-colors text-sm">{{ $statsTotalPages }}</button>
|
||||
@endif
|
||||
|
||||
{{-- Next page --}}
|
||||
<button type="button"
|
||||
wire:click="nextPage"
|
||||
@if($this->statistics->onLastPage()) disabled @endif
|
||||
class="px-2 py-1 border border-neutral rounded hover:bg-background-secondary transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
title="Next page">
|
||||
<x-ri-arrow-right-s-line class="size-4" />
|
||||
</button>
|
||||
|
||||
{{-- Last page --}}
|
||||
<button type="button"
|
||||
wire:click="gotoPage({{ $this->statistics->lastPage() }})"
|
||||
@if($this->statistics->onLastPage()) disabled @endif
|
||||
class="px-2 py-1 border border-neutral rounded hover:bg-background-secondary transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
title="Last page">
|
||||
<x-ri-arrow-right-double-line class="size-4" />
|
||||
</button>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<!-- Task History Section -->
|
||||
@@ -1322,91 +1390,101 @@
|
||||
@json($taskHistoryExportRows)
|
||||
</template>
|
||||
<!-- Task History Pagination -->
|
||||
<div class="p-4 border-t border-neutral">
|
||||
<div class="flex flex-col sm:flex-row items-center justify-between gap-4">
|
||||
<!-- Per Page Selector -->
|
||||
<div class="flex items-center gap-2 text-sm">
|
||||
<span class="text-base/70">Show</span>
|
||||
<select wire:model.live="taskHistoryPerPage"
|
||||
class="bg-background border border-neutral rounded-md px-2 py-1 text-sm focus:outline-none focus:ring-2 focus:ring-primary/50">
|
||||
@if(count($this->taskHistory) > 0)
|
||||
<div class="p-4 border-t border-neutral flex flex-col sm:flex-row items-center justify-between gap-4">
|
||||
{{-- Records per page selector --}}
|
||||
<div class="flex items-center gap-3">
|
||||
<label class="text-sm text-base/70">Show:</label>
|
||||
<select wire:model.live="taskHistoryPerPage" class="px-3 py-1.5 border border-neutral rounded-lg bg-background text-sm">
|
||||
<option value="10">10</option>
|
||||
<option value="25">25</option>
|
||||
<option value="50">50</option>
|
||||
<option value="100">100</option>
|
||||
</select>
|
||||
<span class="text-base/70">entries</span>
|
||||
<span class="text-base/50 ml-2">({{ count($this->taskHistory) }} total)</span>
|
||||
<span class="text-sm text-base/60">per page</span>
|
||||
</div>
|
||||
|
||||
<!-- Pagination Navigation -->
|
||||
{{-- Page info and navigation --}}
|
||||
@php
|
||||
$taskTotalPages = $this->taskHistoryTotalPages;
|
||||
$taskCurrentPage = $taskHistoryCurrentPage;
|
||||
$taskTotalCount = count($this->taskHistory);
|
||||
@endphp
|
||||
@if($taskTotalPages > 1)
|
||||
<div class="flex items-center gap-1">
|
||||
<!-- Previous Button -->
|
||||
<button wire:click="previousTaskHistoryPage"
|
||||
@if($taskCurrentPage <= 1) disabled @endif
|
||||
class="px-3 py-1.5 text-sm border border-neutral rounded-md hover:bg-background/80 disabled:opacity-50 disabled:cursor-not-allowed">
|
||||
<x-ri-arrow-left-s-line class="size-4" />
|
||||
</button>
|
||||
|
||||
<!-- Page Numbers -->
|
||||
@php
|
||||
$pages = [];
|
||||
<div class="flex items-center gap-4">
|
||||
<span class="text-sm text-base/60">
|
||||
Showing {{ (($taskCurrentPage - 1) * $taskHistoryPerPage) + 1 }} - {{ min($taskCurrentPage * $taskHistoryPerPage, $taskTotalCount) }} of {{ $taskTotalCount }} tasks
|
||||
</span>
|
||||
|
||||
@if($taskTotalPages > 1)
|
||||
<div class="flex items-center gap-1">
|
||||
{{-- First page --}}
|
||||
<button type="button"
|
||||
wire:click="goToTaskHistoryPage(1)"
|
||||
@if($taskCurrentPage === 1) disabled @endif
|
||||
class="px-2 py-1 border border-neutral rounded hover:bg-background-secondary transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
title="First page">
|
||||
<x-ri-arrow-left-double-line class="size-4" />
|
||||
</button>
|
||||
|
||||
// Always show first page
|
||||
$pages[] = 1;
|
||||
{{-- Previous page --}}
|
||||
<button type="button"
|
||||
wire:click="previousTaskHistoryPage"
|
||||
@if($taskCurrentPage === 1) disabled @endif
|
||||
class="px-2 py-1 border border-neutral rounded hover:bg-background-secondary transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
title="Previous page">
|
||||
<x-ri-arrow-left-s-line class="size-4" />
|
||||
</button>
|
||||
|
||||
// Calculate range around current page
|
||||
$start = max(2, $taskCurrentPage - 1);
|
||||
$end = min($taskTotalPages - 1, $taskCurrentPage + 1);
|
||||
{{-- Page numbers --}}
|
||||
@php
|
||||
$taskStartPage = max(1, $taskCurrentPage - 2);
|
||||
$taskEndPage = min($taskTotalPages, $taskCurrentPage + 2);
|
||||
@endphp
|
||||
|
||||
// Add ellipsis after first page if needed
|
||||
if ($start > 2) {
|
||||
$pages[] = '...';
|
||||
}
|
||||
|
||||
// Add pages around current
|
||||
for ($i = $start; $i <= $end; $i++) {
|
||||
$pages[] = $i;
|
||||
}
|
||||
|
||||
// Add ellipsis before last page if needed
|
||||
if ($end < $taskTotalPages - 1) {
|
||||
$pages[] = '...';
|
||||
}
|
||||
|
||||
// Always show last page if more than 1 page
|
||||
if ($taskTotalPages > 1) {
|
||||
$pages[] = $taskTotalPages;
|
||||
}
|
||||
@endphp
|
||||
|
||||
@foreach($pages as $page)
|
||||
@if($page === '...')
|
||||
<span class="px-2 py-1.5 text-sm text-base/50">...</span>
|
||||
@else
|
||||
<button wire:click="goToTaskHistoryPage({{ $page }})"
|
||||
class="px-3 py-1.5 text-sm border rounded-md {{ $taskCurrentPage == $page ? 'bg-primary text-white border-primary' : 'border-neutral hover:bg-background/80' }}">
|
||||
{{ $page }}
|
||||
</button>
|
||||
@if($taskStartPage > 1)
|
||||
<button type="button" wire:click="goToTaskHistoryPage(1)" class="px-3 py-1 border border-neutral rounded hover:bg-background-secondary transition-colors text-sm">1</button>
|
||||
@if($taskStartPage > 2)
|
||||
<span class="px-2 text-base/60">...</span>
|
||||
@endif
|
||||
@endif
|
||||
@endforeach
|
||||
|
||||
<!-- Next Button -->
|
||||
<button wire:click="nextTaskHistoryPage"
|
||||
@if($taskCurrentPage >= $taskTotalPages) disabled @endif
|
||||
class="px-3 py-1.5 text-sm border border-neutral rounded-md hover:bg-background/80 disabled:opacity-50 disabled:cursor-not-allowed">
|
||||
<x-ri-arrow-right-s-line class="size-4" />
|
||||
</button>
|
||||
</div>
|
||||
@else
|
||||
<div class="text-sm text-base/50">Page 1 of 1</div>
|
||||
@endif
|
||||
|
||||
@for($i = $taskStartPage; $i <= $taskEndPage; $i++)
|
||||
<button type="button"
|
||||
wire:click="goToTaskHistoryPage({{ $i }})"
|
||||
class="px-3 py-1 border rounded text-sm transition-colors {{ $taskCurrentPage === $i ? 'bg-primary text-white border-primary' : 'border-neutral hover:bg-background-secondary' }}">
|
||||
{{ $i }}
|
||||
</button>
|
||||
@endfor
|
||||
|
||||
@if($taskEndPage < $taskTotalPages)
|
||||
@if($taskEndPage < $taskTotalPages - 1)
|
||||
<span class="px-2 text-base/60">...</span>
|
||||
@endif
|
||||
<button type="button" wire:click="goToTaskHistoryPage({{ $taskTotalPages }})" class="px-3 py-1 border border-neutral rounded hover:bg-background-secondary transition-colors text-sm">{{ $taskTotalPages }}</button>
|
||||
@endif
|
||||
|
||||
{{-- Next page --}}
|
||||
<button type="button"
|
||||
wire:click="nextTaskHistoryPage"
|
||||
@if($taskCurrentPage === $taskTotalPages) disabled @endif
|
||||
class="px-2 py-1 border border-neutral rounded hover:bg-background-secondary transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
title="Next page">
|
||||
<x-ri-arrow-right-s-line class="size-4" />
|
||||
</button>
|
||||
|
||||
{{-- Last page --}}
|
||||
<button type="button"
|
||||
wire:click="goToTaskHistoryPage({{ $taskTotalPages }})"
|
||||
@if($taskCurrentPage === $taskTotalPages) disabled @endif
|
||||
class="px-2 py-1 border border-neutral rounded hover:bg-background-secondary transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
title="Last page">
|
||||
<x-ri-arrow-right-double-line class="size-4" />
|
||||
</button>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<!-- Recent Lifecycle Events Section -->
|
||||
|
||||
Reference in New Issue
Block a user