Skip to content

Commit 32307d7

Browse files
authored
Merge pull request #2433 from kianamcc/PORTALS-3798
PORTALS-3798: Case where initial table pagination size is broken
2 parents b30a64d + 1cb5683 commit 32307d7

File tree

2 files changed

+62
-48
lines changed

2 files changed

+62
-48
lines changed

packages/synapse-react-client/src/components/SynapseTable/TablePagination.test.tsx

Lines changed: 33 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ function renderComponent(options: {
2222
pageSize: number
2323
currentPage: number
2424
queryCount: number
25-
maxRowsPerPage: number
25+
maxRowsPerPage?: number
2626
queryContextOverrides?: Partial<QueryContextType>
2727
}) {
2828
const user = userEvent.setup()
@@ -130,19 +130,47 @@ describe('TablePagination component', () => {
130130
).rejects.toThrow()
131131
})
132132

133+
it('hides pagination when maxRowsPerPage < 5', async () => {
134+
renderComponent({
135+
pageSize: 10,
136+
currentPage: 1,
137+
queryCount: 1,
138+
maxRowsPerPage: 4,
139+
})
140+
141+
await expect(
142+
screen.findByRole('navigation', undefined, { timeout: 100 }),
143+
).rejects.toThrow()
144+
})
145+
133146
it('small max rows per page with more than one page of results', async () => {
134147
const { user } = renderComponent({
135-
pageSize: 5,
148+
pageSize: 10,
136149
currentPage: 1,
137-
queryCount: 20,
138-
maxRowsPerPage: 5,
150+
queryCount: 13,
151+
maxRowsPerPage: 11,
139152
})
140153

141154
const comboBox = await screen.findByRole('combobox')
142155
await user.click(comboBox)
143156
const pageSizeOptions = await screen.findAllByRole('option')
144157
expect(pageSizeOptions).toHaveLength(1)
145-
expect(pageSizeOptions[0].textContent).toEqual('5 per page')
158+
expect(pageSizeOptions[0].textContent).toEqual('10 per page')
159+
})
160+
161+
it('no maxRowsPerPage value set', async () => {
162+
const { user } = renderComponent({
163+
pageSize: 3,
164+
currentPage: 1,
165+
queryCount: 3,
166+
maxRowsPerPage: undefined,
167+
})
168+
169+
const comboBox = await screen.findByRole('combobox')
170+
await user.click(comboBox)
171+
const pageSizeOptions = await screen.findAllByRole('option')
172+
expect(pageSizeOptions).toHaveLength(1)
173+
expect(pageSizeOptions[0].textContent).toEqual('10 per page')
146174
})
147175

148176
it('prefetches a page on hover', async () => {
@@ -168,30 +196,4 @@ describe('TablePagination component', () => {
168196
// Verify we did not go to a new page
169197
expect(mockGoToPage).not.toHaveBeenCalled()
170198
})
171-
172-
it('query.limit value that is not a default page size option is added to the page size options', async () => {
173-
const addLimitOption = 7
174-
const { user } = renderComponent({
175-
pageSize: 7,
176-
currentPage: 1,
177-
queryCount: 100,
178-
maxRowsPerPage: 100,
179-
queryContextOverrides: {
180-
currentQueryRequest: {
181-
...mockQueryBundleRequest,
182-
query: {
183-
...mockQueryBundleRequest.query,
184-
limit: addLimitOption,
185-
},
186-
},
187-
},
188-
})
189-
190-
// Verify that the current limit is displayed
191-
const pageSizeOptions = await screen.findByRole('combobox')
192-
await screen.findByText('7 per page')
193-
194-
await user.click(pageSizeOptions)
195-
await user.click(await screen.findByRole('option', { name: '7 per page' }))
196-
})
197199
})

packages/synapse-react-client/src/components/SynapseTable/TablePagination.tsx

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import { useSuspenseGetQueryMetadata } from '../QueryWrapper/useGetQueryMetadata
2020

2121
import { usePrefetchTableRows } from './usePrefetchTableData'
2222

23+
const PAGE_SIZE_OPTIONS = [10, 25, 100, 500]
24+
2325
export const TablePagination = (): React.ReactNode => {
2426
const { goToPage, pageSize, setPageSize, currentPage, currentQueryRequest } =
2527
useQueryContext()
@@ -31,29 +33,38 @@ export const TablePagination = (): React.ReactNode => {
3133
} = useSuspenseGetQueryMetadata()
3234

3335
const currentLimit = currentQueryRequest.query.limit
34-
const maxPageSize = maxRowsPerPage ?? pageSize
36+
const resolvedPageSize = currentLimit ?? pageSize
3537

36-
const pageSizeOptions = [10, 25, 100, 500]
37-
if (currentLimit && !pageSizeOptions.includes(currentLimit)) {
38-
pageSizeOptions.push(currentLimit)
39-
pageSizeOptions.sort((a, b) => a - b)
40-
}
41-
const pageSizeOptionsBasedOnData = pageSizeOptions.filter(
42-
value => value < maxPageSize,
43-
)
44-
if (pageSizeOptionsBasedOnData.length == 0) {
45-
pageSizeOptionsBasedOnData.push(maxPageSize)
46-
if (maxRowsPerPage && pageSize > maxRowsPerPage) {
47-
setPageSize(maxRowsPerPage)
38+
// Filter by backend limit maxRowsPerPage
39+
let pageSizeOptions = maxRowsPerPage
40+
? PAGE_SIZE_OPTIONS.filter(option => option < maxRowsPerPage)
41+
: [...PAGE_SIZE_OPTIONS]
42+
43+
if (queryCount) {
44+
// first option that is >= queryCount (show all rows)
45+
const firstSufficientOptionIndex = pageSizeOptions.findIndex(
46+
option => option >= queryCount,
47+
)
48+
// If found, slice to only include options up to and including that one
49+
if (firstSufficientOptionIndex !== -1) {
50+
pageSizeOptions = pageSizeOptions.slice(0, firstSufficientOptionIndex + 1)
4851
}
4952
}
53+
54+
// If resolvedPageSize isn't in the options, use the smallest available option
55+
const displayedPageSize = pageSizeOptions.includes(resolvedPageSize)
56+
? resolvedPageSize
57+
: pageSizeOptions[0]
58+
5059
const handlePage = (_event: ChangeEvent<unknown>, value: number) => {
5160
goToPage(value)
5261
}
5362

5463
const handlePageSize = (event: SelectChangeEvent<number>) => {
5564
const value = event.target.value
65+
5666
setPageSize(value)
67+
goToPage(1)
5768
}
5869

5970
// A custom `renderItem` implementation for the MUI Pagination component that prefetches a page's data when the page number button is hovered over
@@ -91,7 +102,8 @@ export const TablePagination = (): React.ReactNode => {
91102
// Also hide pagination if the query count is unavailable.
92103
if (
93104
(currentPage == 1 && queryCount == 1 && pageSize != 1) ||
94-
queryCount == undefined
105+
queryCount == undefined ||
106+
(maxRowsPerPage && maxRowsPerPage < 5)
95107
) {
96108
return null
97109
}
@@ -100,7 +112,7 @@ export const TablePagination = (): React.ReactNode => {
100112
<div>
101113
<Pagination
102114
page={currentPage}
103-
count={Math.ceil(queryCount / pageSize)}
115+
count={Math.ceil(queryCount / displayedPageSize)}
104116
color="secondary"
105117
onChange={handlePage}
106118
shape={'rounded'}
@@ -116,12 +128,12 @@ export const TablePagination = (): React.ReactNode => {
116128
</Typography>
117129
<Select
118130
name="page size"
119-
value={pageSize}
131+
value={displayedPageSize}
120132
size="small"
121133
onChange={handlePageSize}
122134
sx={{ ml: 0.5 }}
123135
>
124-
{pageSizeOptionsBasedOnData.map(pageSize => {
136+
{pageSizeOptions.map(pageSize => {
125137
return (
126138
<MenuItem key={pageSize} value={pageSize}>
127139
{pageSize} per page

0 commit comments

Comments
 (0)