Skip to content

Commit 4ef041d

Browse files
committed
fix: pagination visibility based on totalCount
- Add totalCount prop to PaginationControlProps - Update PaginationControl to show/hide based on total items: - Hide when totalCount is 0 (empty state) - Hide when totalCount <= 5 (minimum page size) - Show when totalCount > 5 (user can adjust page size) - Show when totalCount undefined (fallback) - Pass totalCount from x-total-count header in all list components - Remove unused usePagination hook
1 parent 79de570 commit 4ef041d

File tree

14 files changed

+98
-261
lines changed

14 files changed

+98
-261
lines changed
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import { render, screen } from '@testing-library/react'
2+
import { describe, test, expect, vi } from 'vitest'
3+
import { PaginationControl } from './PaginationControl'
4+
import type { PaginationControlProps } from './PaginationControlTypes'
5+
import { ThemeProvider } from '@/contexts/ThemeProvider'
6+
import { ComponentsProvider } from '@/contexts/ComponentAdapter/ComponentsProvider'
7+
import { defaultComponents } from '@/contexts/ComponentAdapter/adapters/defaultComponentAdapter'
8+
9+
const basePaginationProps: PaginationControlProps = {
10+
currentPage: 1,
11+
totalPages: 3,
12+
itemsPerPage: 5,
13+
handleFirstPage: vi.fn(),
14+
handlePreviousPage: vi.fn(),
15+
handleNextPage: vi.fn(),
16+
handleLastPage: vi.fn(),
17+
handleItemsPerPageChange: vi.fn(),
18+
}
19+
20+
const renderPaginationControl = (props: Partial<PaginationControlProps> = {}) => {
21+
return render(
22+
<ThemeProvider>
23+
<ComponentsProvider value={defaultComponents}>
24+
<PaginationControl {...basePaginationProps} {...props} />
25+
</ComponentsProvider>
26+
</ThemeProvider>,
27+
)
28+
}
29+
30+
describe('PaginationControl Visibility', () => {
31+
describe('based on totalCount', () => {
32+
test('hides when totalCount is 0 (empty state)', () => {
33+
renderPaginationControl({ totalCount: 0 })
34+
expect(screen.queryByTestId('pagination-control')).not.toBeInTheDocument()
35+
})
36+
37+
test('hides when totalCount <= MINIMUM_PAGE_SIZE (5)', () => {
38+
renderPaginationControl({ totalCount: 5 })
39+
expect(screen.queryByTestId('pagination-control')).not.toBeInTheDocument()
40+
})
41+
42+
test('hides when totalCount is 3 (less than min page size)', () => {
43+
renderPaginationControl({ totalCount: 3 })
44+
expect(screen.queryByTestId('pagination-control')).not.toBeInTheDocument()
45+
})
46+
47+
test('shows when totalCount > MINIMUM_PAGE_SIZE', () => {
48+
renderPaginationControl({ totalCount: 6 })
49+
expect(screen.getByTestId('pagination-control')).toBeInTheDocument()
50+
})
51+
52+
test('shows when totalCount is undefined (server info unavailable)', () => {
53+
renderPaginationControl({ totalCount: undefined })
54+
expect(screen.getByTestId('pagination-control')).toBeInTheDocument()
55+
})
56+
57+
test('shows when totalCount is large', () => {
58+
renderPaginationControl({ totalCount: 100 })
59+
expect(screen.getByTestId('pagination-control')).toBeInTheDocument()
60+
})
61+
})
62+
63+
describe('edge cases', () => {
64+
test('shows pagination when totalCount > 5 even with totalPages = 1', () => {
65+
renderPaginationControl({ totalCount: 10, totalPages: 1, itemsPerPage: 50 })
66+
expect(screen.getByTestId('pagination-control')).toBeInTheDocument()
67+
})
68+
69+
test('hides when totalCount is exactly 5', () => {
70+
renderPaginationControl({ totalCount: 5, totalPages: 1 })
71+
expect(screen.queryByTestId('pagination-control')).not.toBeInTheDocument()
72+
})
73+
})
74+
})

src/components/Common/PaginationControl/PaginationControl.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,18 @@ import PaginationPrevIcon from '@/assets/icons/pagination_previous.svg?react'
99
import PaginationNextIcon from '@/assets/icons/pagination_next.svg?react'
1010
import PaginationLastIcon from '@/assets/icons/pagination_last.svg?react'
1111

12+
const MINIMUM_PAGE_SIZE = 5
13+
14+
const shouldShowPagination = (totalCount: number | undefined): boolean => {
15+
if (totalCount === undefined) return true
16+
if (totalCount === 0) return false
17+
return totalCount > MINIMUM_PAGE_SIZE
18+
}
19+
1220
const DefaultPaginationControl = ({
1321
currentPage,
1422
totalPages,
23+
totalCount,
1524
isFetching,
1625
handleFirstPage,
1726
handlePreviousPage,
@@ -23,7 +32,7 @@ const DefaultPaginationControl = ({
2332
const { t } = useTranslation('common')
2433
const Components = useComponentContext()
2534

26-
if (totalPages < 2) {
35+
if (!shouldShowPagination(totalCount)) {
2736
return null
2837
}
2938

src/components/Common/PaginationControl/PaginationControlTypes.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export type PaginationControlProps = {
88
handleItemsPerPageChange: (n: PaginationItemsPerPage) => void
99
currentPage: number
1010
totalPages: number
11+
totalCount?: number
1112
itemsPerPage?: PaginationItemsPerPage
1213
isFetching?: boolean
1314
}

src/components/Company/Locations/LocationsList/List.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export const List = () => {
1414
handleEditLocation,
1515
currentPage,
1616
totalPages,
17+
totalCount,
1718
handleFirstPage,
1819
handleItemsPerPageChange,
1920
handleLastPage,
@@ -89,6 +90,7 @@ export const List = () => {
8990
handleItemsPerPageChange,
9091
currentPage,
9192
totalPages,
93+
totalCount,
9294
itemsPerPage,
9395
},
9496
emptyState: () => (

src/components/Company/Locations/LocationsList/LocationsList.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ function Root({ companyId, className, children }: LocationsListProps) {
3535
} = useLocationsGetSuspense({ companyId, page: currentPage, per: itemsPerPage })
3636

3737
const totalPages = Number(httpMeta.response.headers.get('x-total-pages') ?? 1)
38+
const totalCount = Number(httpMeta.response.headers.get('x-total-count') ?? 0)
3839

3940
const handleItemsPerPageChange = (newCount: PaginationItemsPerPage) => {
4041
setItemsPerPage(newCount)
@@ -69,6 +70,7 @@ function Root({ companyId, className, children }: LocationsListProps) {
6970
locationList: locationList ?? [],
7071
currentPage,
7172
totalPages,
73+
totalCount,
7274
handleFirstPage,
7375
handlePreviousPage,
7476
handleNextPage,

src/components/Company/Locations/LocationsList/useLocationsList.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import type { PaginationItemsPerPage } from '@/components/Common/PaginationContr
55
type LocationsListContextType = {
66
locationList: Location[]
77
totalPages: number
8+
totalCount: number
89
currentPage: number
910
itemsPerPage: PaginationItemsPerPage
1011
handleItemsPerPageChange: (n: PaginationItemsPerPage) => void

src/components/Contractor/ContractorList/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ function Root({ companyId, className, dictionary, successMessage }: ContractorLi
139139
handleItemsPerPageChange,
140140
currentPage,
141141
totalPages,
142+
totalCount,
142143
itemsPerPage,
143144
},
144145
})

src/components/Employee/EmployeeList/EmployeeList.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ function Root({ companyId, className, children, dictionary }: EmployeeListProps)
6262
const employees = employeeList!
6363

6464
const totalPages = Number(httpMeta.response.headers.get('x-total-pages') ?? 1)
65+
const totalCount = Number(httpMeta.response.headers.get('x-total-count') ?? 0)
6566

6667
const handleItemsPerPageChange = (newCount: PaginationItemsPerPage) => {
6768
setItemsPerPage(newCount)
@@ -139,6 +140,7 @@ function Root({ companyId, className, children, dictionary }: EmployeeListProps)
139140
employees,
140141
currentPage,
141142
totalPages,
143+
totalCount,
142144
handleFirstPage,
143145
handlePreviousPage,
144146
handleNextPage,

src/components/Employee/EmployeeList/List.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export const List = () => {
2727
handleItemsPerPageChange,
2828
currentPage,
2929
totalPages,
30+
totalCount,
3031
itemsPerPage,
3132
handleSkip,
3233
isFetching,
@@ -139,6 +140,7 @@ export const List = () => {
139140
handleItemsPerPageChange,
140141
currentPage,
141142
totalPages,
143+
totalCount,
142144
itemsPerPage,
143145
},
144146
emptyState: () => (

src/components/Employee/EmployeeList/useEmployeeList.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ type EmployeeListContextType = {
1818
handleItemsPerPageChange: (newCount: PaginationItemsPerPage) => void
1919
currentPage: number
2020
totalPages: number
21+
totalCount: number
2122
employees: Employee[]
2223
itemsPerPage: PaginationItemsPerPage
2324
isFetching: boolean

0 commit comments

Comments
 (0)