Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 13 additions & 6 deletions src/features/pagination/__tests__/Pagination.test.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React from 'react'
import { render, waitFor, within } from '@testing-library/react'
import { PaginationExample } from '../stories/PaginationExample'
import { PaginationExample, PaginationExampleWithoutTotalPages } from '../stories/PaginationExample'
import userEvent from '@testing-library/user-event'
import '@testing-library/jest-dom'

describe('Pagination component', () => {
describe('Render pagination without rowsPerPage selector and with 100 as total elements', () => {
describe('Render pagination without rowsPerPage selector and with 120 as total elements', () => {
it('Should render correctly', () => {
const screen = render(<PaginationExample />)
expect(screen).toBeDefined()
Expand All @@ -17,7 +17,7 @@ describe('Pagination component', () => {
expect(selectElement).toBeNull()
})

it('If total elements are 100 and default limit is 10, total pages should be 10', () => {
it('If total elements are 120 and default limit is 12, total pages should be 10', () => {
const screen = render(<PaginationExample />)
const paginationElement = screen.getByRole('navigation')

Expand All @@ -43,13 +43,13 @@ describe('Pagination component', () => {
})
})

describe('Render pagination with rowsPerPage selector enabled and with 100 as total elements', () => {
describe('Render pagination with rowsPerPage selector enabled and with 120 as total elements', () => {
it('Should render correctly', () => {
const screen = render(<PaginationExample withRowsPerPage />)
expect(screen).toBeDefined()
})

it('Should be available [10,24,36] as rows per page as default options', async () => {
it('Should be available [12,24,36] as rows per page as default options', async () => {
const screen = render(<PaginationExample withRowsPerPage />)
const selectElement = screen.getByTestId('rows-per-page-select')
const selectButton = within(selectElement).getByRole('button')
Expand All @@ -61,10 +61,17 @@ describe('Pagination component', () => {
const getOptions = screen.getAllByRole('option')
expect(getOptions).toHaveLength(3)

expect(getOptions[0]).toHaveTextContent('10')
expect(getOptions[0]).toHaveTextContent('12')
expect(getOptions[1]).toHaveTextContent('24')
expect(getOptions[2]).toHaveTextContent('36')
})
})
})

it('Should not render rows per page selector if total pages are 0', () => {
const screen = render(<PaginationExampleWithoutTotalPages />)
const selectElement = screen.queryByTestId('rows-per-page-select')

expect(selectElement).toBeNull()
})
Comment thread
martinaCampoli marked this conversation as resolved.
})
4 changes: 2 additions & 2 deletions src/features/pagination/components/Pagination.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
} from '@mui/material'
import type { InteropTheme } from '@/theme'

const defaultOptions = [10, 24, 36]
const defaultOptions = [12, 24, 36]
Comment thread
martinaCampoli marked this conversation as resolved.
export interface PaginationProps extends StackProps {
totalPages: number
pageNum: number
Expand Down Expand Up @@ -56,7 +56,7 @@ export const Pagination: React.FC<PaginationProps> = ({
alignItems="center"
{...stackProps}
>
{rowPerPageOptions && (
{rowPerPageOptions && totalPages > 0 && (

Copilot AI Feb 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The condition added here (totalPages > 0) successfully hides the rows-per-page selector when the table is empty. However, there's a layout consideration: the parent Stack's justifyContent is set to 'space-between' when rowPerPageOptions is provided (line 55, which is outside the diff), but now the selector won't render when totalPages is 0. If both the selector (totalPages = 0) and the pagination controls (totalPages <= 1) don't render, you'll have an empty Stack with 'space-between' justification. While this doesn't break functionality, it may be worth ensuring the justifyContent logic aligns with the actual rendering conditions.

Copilot uses AI. Check for mistakes.
Comment thread
martinaCampoli marked this conversation as resolved.
<Select
size="small"
labelId="rows-per-page-select"
Expand Down
4 changes: 2 additions & 2 deletions src/features/pagination/hooks/usePagination.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import { useSearchParams } from 'react-router-dom'
import { z } from 'zod'

const paramsSchema = z.coerce.number().int().positive()
const limitSchema = paramsSchema.max(50).catch(10)
const limitSchema = paramsSchema.max(50).catch(12)
const offsetSchema = paramsSchema.catch(0)
const defaultOptions = [10, 24, 36]
const defaultOptions = [12, 24, 36]
/**
* @description
* This hook is used to manage the pagination state keeping it in sync with the url params.
Expand Down
62 changes: 61 additions & 1 deletion src/features/pagination/stories/PaginationExample.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export const _PaginationExample: React.FC<{ withRowsPerPage?: boolean }> = ({
const { paginationParams, paginationProps, getTotalPageCount } = usePagination()
const [debug, setDebug] = React.useState(false)
const location = useLocation()
const totalPages = getTotalPageCount(100)
const totalPages = getTotalPageCount(120)

const { onLimitChange, ...restPaginationProps } = paginationProps

Expand Down Expand Up @@ -60,12 +60,72 @@ export const _PaginationExample: React.FC<{ withRowsPerPage?: boolean }> = ({
)
}

export const _PaginationExampleWithoutTotalPages: React.FC = () => {
const { paginationParams, paginationProps, getTotalPageCount } = usePagination()
const [debug, setDebug] = React.useState(false)
const location = useLocation()
const totalPages = getTotalPageCount(0)

const { onLimitChange, ...restPaginationProps } = paginationProps

const rowsPerPageProps = {
onLimitChange: onLimitChange,
limit: paginationParams.limit,
}

const urlSearchParams = new URLSearchParams(location.search)
// Remove all params except offset
urlSearchParams.delete('id')
for (const key of urlSearchParams.keys()) {
if (key !== 'offset') {
urlSearchParams.delete(key)
}
}

return (
<>
<Container sx={{ mt: 4, p: 2 }}>
<Pagination
totalPages={totalPages}
{...restPaginationProps}
rowPerPageOptions={rowsPerPageProps}
/>
</Container>
<Container sx={{ bgcolor: debug ? 'white' : 'initial', mt: 4, py: 4 }}>
<Button variant="naked" onClick={() => setDebug(!debug)}>
{debug ? 'Hide' : 'Show'} debug values
</Button>
{debug && (
<Stack mt={2} spacing={2}>
<Box>
<Typography variant="subtitle1">URL search param</Typography>
<CodeBlock code={'?' + urlSearchParams.toString()} />
</Box>
<Box>
<Typography variant="subtitle1">paginationParams</Typography>
<CodeBlock code={paginationParams} />
</Box>
</Stack>
)}
</Container>
</>
)
}
Comment thread
martinaCampoli marked this conversation as resolved.

const router = createBrowserRouter([{ path: '*', element: <_PaginationExample /> }])

const routerPaginationWithoutRowsPerPage = createBrowserRouter([
{ path: '*', element: <_PaginationExample withRowsPerPage /> },
])

const routerPaginationWithoutTotalPages = createBrowserRouter([
{ path: '*', element: <_PaginationExampleWithoutTotalPages /> },
])

export const PaginationExample: React.FC<{ withRowsPerPage?: boolean }> = ({ withRowsPerPage }) => {
return <RouterProvider router={withRowsPerPage ? routerPaginationWithoutRowsPerPage : router} />
}

export const PaginationExampleWithoutTotalPages: React.FC = () => {
return <RouterProvider router={routerPaginationWithoutTotalPages} />
}
Loading