Skip to content

Commit b0d5e06

Browse files
authored
chore: refactor pagination (#4753)
* Extract PageButton * Fix import * Extract utils * Format * Separate pagination - wip * Spawn pagination machine - buggy filter * Make labels optional * Layout, fix send reset bug * Format * Fix refresh data bug * Remove debugging line * Fix url updates setSearchParams overwrites all search params, rather than merging * Update Audit Page * Simplify pagination widget * Fix workspaces story * Fix Audit story * Fix pagination story and pagebutton highlight * Fix pagination tests * Add to utils tests * Format * Add tests
1 parent a0bdb4f commit b0d5e06

16 files changed

+548
-461
lines changed
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import Button from "@material-ui/core/Button"
2+
import { makeStyles } from "@material-ui/core/styles"
3+
4+
interface PageButtonProps {
5+
activePage?: number
6+
page?: number
7+
placeholder?: string
8+
numPages?: number
9+
onPageClick?: (page: number) => void
10+
disabled?: boolean
11+
}
12+
13+
export const PageButton = ({
14+
activePage,
15+
page,
16+
placeholder = "...",
17+
numPages,
18+
onPageClick,
19+
disabled = false,
20+
}: PageButtonProps): JSX.Element => {
21+
const styles = useStyles()
22+
return (
23+
<Button
24+
className={
25+
activePage === page
26+
? `${styles.pageButton} ${styles.activePageButton}`
27+
: styles.pageButton
28+
}
29+
aria-label={`${page === activePage ? "Current Page" : ""} ${
30+
page === numPages ? "Last Page" : ""
31+
} Page${page}`}
32+
name={page === undefined ? undefined : "Page button"}
33+
onClick={() => onPageClick && page && onPageClick(page)}
34+
disabled={disabled}
35+
>
36+
<div>{page ?? placeholder}</div>
37+
</Button>
38+
)
39+
}
40+
41+
const useStyles = makeStyles((theme) => ({
42+
pageButton: {
43+
"&:not(:last-of-type)": {
44+
marginRight: theme.spacing(0.5),
45+
},
46+
},
47+
48+
activePageButton: {
49+
borderColor: `${theme.palette.info.main}`,
50+
backgroundColor: `${theme.palette.info.dark}`,
51+
},
52+
}))
Lines changed: 19 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,53 @@
1-
import { action } from "@storybook/addon-actions"
21
import { Story } from "@storybook/react"
32
import { PaginationWidget, PaginationWidgetProps } from "./PaginationWidget"
3+
import { createPaginationRef } from "./utils"
44

55
export default {
66
title: "components/PaginationWidget",
77
component: PaginationWidget,
8+
argTypes: {
9+
prevLabel: {
10+
defaultValue: "Previous",
11+
},
12+
nextLabel: {
13+
defaultValue: "Next",
14+
},
15+
paginationRef: {
16+
defaultValue: createPaginationRef({ page: 1, limit: 12 }),
17+
},
18+
numRecords: {
19+
defaultValue: 200,
20+
},
21+
},
822
}
923

1024
const Template: Story<PaginationWidgetProps> = (
1125
args: PaginationWidgetProps,
1226
) => <PaginationWidget {...args} />
1327

14-
const defaultProps = {
15-
prevLabel: "Previous",
16-
nextLabel: "Next",
17-
onPrevClick: action("previous"),
18-
onNextClick: action("next"),
19-
onPageClick: action("clicked"),
20-
}
21-
2228
export const UnknownPageNumbers = Template.bind({})
2329
UnknownPageNumbers.args = {
24-
...defaultProps,
30+
numRecords: undefined,
2531
}
2632

2733
export const LessThan8Pages = Template.bind({})
2834
LessThan8Pages.args = {
29-
...defaultProps,
3035
numRecords: 84,
31-
numRecordsPerPage: 12,
32-
activePage: 1,
3336
}
3437

3538
export const MoreThan8Pages = Template.bind({})
36-
MoreThan8Pages.args = {
37-
...defaultProps,
38-
numRecords: 200,
39-
numRecordsPerPage: 12,
40-
activePage: 1,
41-
}
4239

4340
export const MoreThan7PagesWithActivePageCloseToStart = Template.bind({})
4441
MoreThan7PagesWithActivePageCloseToStart.args = {
45-
...defaultProps,
46-
numRecords: 200,
47-
numRecordsPerPage: 12,
48-
activePage: 2,
42+
paginationRef: createPaginationRef({ page: 2, limit: 12 }),
4943
}
5044

5145
export const MoreThan7PagesWithActivePageFarFromBoundaries = Template.bind({})
5246
MoreThan7PagesWithActivePageFarFromBoundaries.args = {
53-
...defaultProps,
54-
numRecords: 200,
55-
numRecordsPerPage: 12,
56-
activePage: 4,
47+
paginationRef: createPaginationRef({ page: 4, limit: 12 }),
5748
}
5849

5950
export const MoreThan7PagesWithActivePageCloseToEnd = Template.bind({})
6051
MoreThan7PagesWithActivePageCloseToEnd.args = {
61-
...defaultProps,
62-
numRecords: 200,
63-
numRecordsPerPage: 12,
64-
activePage: 17,
52+
paginationRef: createPaginationRef({ page: 17, limit: 12 }),
6553
}
Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,30 @@
11
import { screen } from "@testing-library/react"
22
import { render } from "../../testHelpers/renderHelpers"
33
import { PaginationWidget } from "./PaginationWidget"
4+
import { createPaginationRef } from "./utils"
45

56
describe("PaginatedList", () => {
67
it("displays an accessible previous and next button", () => {
78
render(
89
<PaginationWidget
910
prevLabel="Previous"
1011
nextLabel="Next"
12+
paginationRef={createPaginationRef({ page: 2, limit: 12 })}
1113
numRecords={200}
12-
numRecordsPerPage={12}
13-
activePage={1}
14-
onPrevClick={() => jest.fn()}
15-
onNextClick={() => jest.fn()}
1614
/>,
1715
)
1816

19-
expect(
20-
screen.getByRole("button", { name: "Previous page" }),
21-
).toBeInTheDocument()
22-
expect(
23-
screen.getByRole("button", { name: "Next page" }),
24-
).toBeInTheDocument()
17+
expect(screen.getByRole("button", { name: "Previous page" })).toBeEnabled()
18+
expect(screen.getByRole("button", { name: "Next page" })).toBeEnabled()
2519
})
2620

2721
it("displays the expected number of pages with one ellipsis tile", () => {
2822
const { container } = render(
2923
<PaginationWidget
3024
prevLabel="Previous"
3125
nextLabel="Next"
32-
onPrevClick={() => jest.fn()}
33-
onNextClick={() => jest.fn()}
34-
onPageClick={(_) => jest.fn()}
3526
numRecords={200}
36-
numRecordsPerPage={12}
37-
activePage={1}
27+
paginationRef={createPaginationRef({ page: 1, limit: 12 })}
3828
/>,
3929
)
4030

@@ -49,12 +39,8 @@ describe("PaginatedList", () => {
4939
<PaginationWidget
5040
prevLabel="Previous"
5141
nextLabel="Next"
52-
onPrevClick={() => jest.fn()}
53-
onNextClick={() => jest.fn()}
54-
onPageClick={(_) => jest.fn()}
5542
numRecords={200}
56-
numRecordsPerPage={12}
57-
activePage={6}
43+
paginationRef={createPaginationRef({ page: 6, limit: 12 })}
5844
/>,
5945
)
6046

@@ -63,4 +49,26 @@ describe("PaginatedList", () => {
6349
container.querySelectorAll(`button[name="Page button"]`),
6450
).toHaveLength(5)
6551
})
52+
53+
it("disables the previous button on the first page", () => {
54+
render(
55+
<PaginationWidget
56+
numRecords={100}
57+
paginationRef={createPaginationRef({ page: 1, limit: 25 })}
58+
/>,
59+
)
60+
const prevButton = screen.getByLabelText("Previous page")
61+
expect(prevButton).toBeDisabled()
62+
})
63+
64+
it("disables the next button on the last page", () => {
65+
render(
66+
<PaginationWidget
67+
numRecords={100}
68+
paginationRef={createPaginationRef({ page: 4, limit: 25 })}
69+
/>,
70+
)
71+
const nextButton = screen.getByLabelText("Next page")
72+
expect(nextButton).toBeDisabled()
73+
})
6674
})

0 commit comments

Comments
 (0)