11<script setup lang="ts">
2- import type { PageSize , PaginationMode } from ' #shared/types/preferences'
2+ import type { PageSize , PaginationMode , ViewMode } from ' #shared/types/preferences'
33import { PAGE_SIZE_OPTIONS } from ' #shared/types/preferences'
44
55const props = defineProps <{
66 mode: PaginationMode
77 pageSize: PageSize
88 currentPage: number
99 totalItems: number
10+ /** When in table view, force pagination mode (no infinite scroll for tables) */
11+ viewMode? : ViewMode
1012}>()
1113
14+ // Whether we should show pagination controls (table view always uses pagination)
15+ const shouldShowControls = computed (() => props .viewMode === ' table' || props .mode === ' paginated' )
16+
17+ // Table view forces pagination mode, otherwise use the provided mode
18+ const effectiveMode = computed <PaginationMode >(() =>
19+ shouldShowControls .value ? ' paginated' : ' infinite' ,
20+ )
21+
1222const emit = defineEmits <{
1323 ' update:mode' : [mode : PaginationMode ]
1424 ' update:pageSize' : [size : PageSize ]
1525 ' update:currentPage' : [page : number ]
1626}>()
1727
18- const totalPages = computed (() => Math .ceil (props .totalItems / props .pageSize ))
19-
20- const startItem = computed (() =>
21- props .totalItems === 0 ? 0 : (props .currentPage - 1 ) * props .pageSize + 1 ,
28+ // When 'all' is selected, there's only 1 page with everything
29+ const isShowingAll = computed (() => props .pageSize === ' all' )
30+ const effectivePageSize = computed (() => (isShowingAll .value ? props .totalItems : props .pageSize ))
31+ const totalPages = computed (() =>
32+ isShowingAll .value ? 1 : Math .ceil (props .totalItems / (props .pageSize as number )),
2233)
2334
24- const endItem = computed (() => Math .min (props .currentPage * props .pageSize , props .totalItems ))
35+ // Whether to show the mode toggle (hidden in table view since table always uses pagination)
36+ const showModeToggle = computed (() => props .viewMode !== ' table' )
37+
38+ const startItem = computed (() => {
39+ if (props .totalItems === 0 ) return 0
40+ if (isShowingAll .value ) return 1
41+ return (props .currentPage - 1 ) * (props .pageSize as number ) + 1
42+ })
43+
44+ const endItem = computed (() => {
45+ if (isShowingAll .value ) return props .totalItems
46+ return Math .min (props .currentPage * (props .pageSize as number ), props .totalItems )
47+ })
2548
2649const canGoPrev = computed (() => props .currentPage > 1 )
2750const canGoNext = computed (() => props .currentPage < totalPages .value )
@@ -86,19 +109,26 @@ const visiblePages = computed(() => {
86109
87110function handlePageSizeChange(event : Event ) {
88111 const target = event .target as HTMLSelectElement
89- const newSize = Number (target .value ) as PageSize
112+ const value = target .value
113+ // Handle 'all' as a special string value, otherwise parse as number
114+ const newSize = (value === ' all' ? ' all' : Number (value )) as PageSize
90115 emit (' update:pageSize' , newSize )
91116 // Reset to page 1 when changing page size
92117 emit (' update:currentPage' , 1 )
93118}
94119 </script >
95120
96121<template >
97- <div class =" flex flex-wrap items-center justify-between gap-4 py-4 border-t border-border mt-6" >
122+ <!-- Only show when in paginated mode (table view or explicit paginated mode) -->
123+ <div
124+ v-if =" shouldShowControls"
125+ class =" flex flex-wrap items-center justify-between gap-4 py-4 border-t border-border mt-6"
126+ >
98127 <!-- Left: Mode toggle and page size -->
99128 <div class =" flex items-center gap-4" >
100- <!-- Pagination mode toggle -->
129+ <!-- Pagination mode toggle (hidden in table view - tables always use pagination) -->
101130 <div
131+ v-if =" showModeToggle"
102132 class =" inline-flex rounded-md border border-border p-0.5 bg-bg-subtle"
103133 role =" group"
104134 :aria-label =" $t('filters.pagination.mode_label')"
@@ -123,8 +153,8 @@ function handlePageSizeChange(event: Event) {
123153 </button >
124154 </div >
125155
126- <!-- Page size (paginated mode only ) -->
127- <div v-if =" mode === 'paginated'" class =" relative shrink-0" >
156+ <!-- Page size (shown when paginated or table view ) -->
157+ <div v-if =" effectiveMode === 'paginated'" class =" relative shrink-0" >
128158 <label for =" page-size" class =" sr-only" >{{ $t('filters.pagination.items_per_page') }}</label >
129159 <select
130160 id =" page-size"
@@ -133,7 +163,11 @@ function handlePageSizeChange(event: Event) {
133163 @change =" handlePageSizeChange"
134164 >
135165 <option v-for =" size in PAGE_SIZE_OPTIONS" :key =" size" :value =" size" >
136- {{ size }}
166+ {{
167+ size === 'all'
168+ ? $t('filters.pagination.all_yolo')
169+ : $t('filters.pagination.per_page', { count: size })
170+ }}
137171 </option >
138172 </select >
139173 <div
@@ -146,7 +180,7 @@ function handlePageSizeChange(event: Event) {
146180 </div >
147181
148182 <!-- Right: Page info and navigation (paginated mode only) -->
149- <div v-if =" mode === 'paginated' && totalItems > 0 " class =" flex items-center gap-4" >
183+ <div v-if =" effectiveMode === 'paginated'" class =" flex items-center gap-4" >
150184 <!-- Showing X-Y of Z -->
151185 <span class =" text-sm font-mono text-fg-muted" >
152186 {{
0 commit comments