Skip to content

feat: paginating Users page #4792

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 34 commits into from
Oct 28, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
32263f5
Extract PageButton
presleyp Oct 21, 2022
5837c28
Fix import
presleyp Oct 21, 2022
a1303b0
Extract utils
presleyp Oct 21, 2022
ea12615
Format
presleyp Oct 21, 2022
74666ee
Separate pagination - wip
presleyp Oct 21, 2022
40f65ca
Spawn pagination machine - buggy filter
presleyp Oct 25, 2022
eef229e
Make labels optional
presleyp Oct 25, 2022
36ba04d
Layout, fix send reset bug
presleyp Oct 25, 2022
d99f149
Format
presleyp Oct 25, 2022
e4247fe
Fix refresh data bug
presleyp Oct 25, 2022
52b17f2
Remove debugging line
presleyp Oct 25, 2022
c4098f6
Fix url updates
presleyp Oct 25, 2022
b7edc7a
Update Audit Page
presleyp Oct 25, 2022
35b0cd3
Simplify pagination widget
presleyp Oct 25, 2022
ba3783b
Fix workspaces story
presleyp Oct 25, 2022
e92cbbf
Fix Audit story
presleyp Oct 25, 2022
23fdc3c
Fix pagination story and pagebutton highlight
presleyp Oct 25, 2022
1ebab32
Fix pagination tests
presleyp Oct 25, 2022
3f7e0aa
Add to utils tests
presleyp Oct 25, 2022
609af06
Format
presleyp Oct 25, 2022
86cda48
Merge branch 'main' into refactor-pagination/presleyp
presleyp Oct 25, 2022
e005aaf
Add tests
presleyp Oct 26, 2022
5715d38
Start adding pagination - type error
presleyp Oct 26, 2022
9a878fa
Merge branch 'main' into paginate-users/presleyp
presleyp Oct 26, 2022
4271fd1
Tweak machine
presleyp Oct 26, 2022
9a0ce5d
Refactor paginated api calls
presleyp Oct 27, 2022
20d5672
Show pagination when count is undefined
presleyp Oct 27, 2022
b68b46a
fix stories
presleyp Oct 27, 2022
50c5825
Fix api helper
presleyp Oct 27, 2022
2e249a0
Add test
presleyp Oct 27, 2022
953428b
Format
presleyp Oct 27, 2022
9056c44
Make widget show all the time to avoid blink
presleyp Oct 28, 2022
8f4691b
Merge branch 'main' into paginate-users/presleyp
presleyp Oct 28, 2022
b8ca97b
Merge branch 'main' into paginate-users/presleyp
presleyp Oct 28, 2022
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
Prev Previous commit
Next Next commit
Extract utils
  • Loading branch information
presleyp committed Oct 21, 2022
commit a1303b0ef37fa19e9bfea775fe7f81b77004348d
59 changes: 1 addition & 58 deletions site/src/components/PaginationWidget/PaginationWidget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { ChooseOne, Cond } from "components/Conditionals/ChooseOne"
import { Maybe } from "components/Conditionals/Maybe"
import { CSSProperties } from "react"
import { PageButton } from "./PageButton"
import { buildPagedList, DEFAULT_RECORDS_PER_PAGE } from "./utils"

export type PaginationWidgetProps = {
prevLabel: string
Expand All @@ -20,64 +21,6 @@ export type PaginationWidgetProps = {
containerStyle?: CSSProperties
}

/**
* Generates a ranged array with an option to step over values.
* Shamelessly stolen from:
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from#sequence_generator_range
*/
const range = (start: number, stop: number, step = 1) =>
Array.from({ length: (stop - start) / step + 1 }, (_, i) => start + i * step)

export const DEFAULT_RECORDS_PER_PAGE = 25
// Number of pages to the left or right of the current page selection.
const PAGE_NEIGHBORS = 1
// Number of pages displayed for cases where there are multiple ellipsis showing. This can be
// thought of as the minimum number of page numbers to display when multiple ellipsis are showing.
const PAGES_TO_DISPLAY = PAGE_NEIGHBORS * 2 + 3
// Total page blocks(page numbers or ellipsis) displayed, including the maximum number of ellipsis (2).
// This gives us maximum number of 7 page blocks to be displayed when the page neighbors value is 1.
const NUM_PAGE_BLOCKS = PAGES_TO_DISPLAY + 2

/**
* Builds a list of pages based on how many pages exist and where the user is in their navigation of those pages.
* List result is used to from the buttons that make up the Pagination Widget
*/
export const buildPagedList = (
numPages: number,
activePage: number,
): (string | number)[] => {
if (numPages > NUM_PAGE_BLOCKS) {
let pages = []
const leftBound = activePage - PAGE_NEIGHBORS
const rightBound = activePage + PAGE_NEIGHBORS
const beforeLastPage = numPages - 1
const startPage = leftBound > 2 ? leftBound : 2
const endPage = rightBound < beforeLastPage ? rightBound : beforeLastPage

pages = range(startPage, endPage)

const singleSpillOffset = PAGES_TO_DISPLAY - pages.length - 1
const hasLeftOverflow = startPage > 2
const hasRightOverflow = endPage < beforeLastPage
const leftOverflowPage = "left"
const rightOverflowPage = "right"

if (hasLeftOverflow && !hasRightOverflow) {
const extraPages = range(startPage - singleSpillOffset, startPage - 1)
pages = [leftOverflowPage, ...extraPages, ...pages]
} else if (!hasLeftOverflow && hasRightOverflow) {
const extraPages = range(endPage + 1, endPage + singleSpillOffset)
pages = [...pages, ...extraPages, rightOverflowPage]
} else if (hasLeftOverflow && hasRightOverflow) {
pages = [leftOverflowPage, ...pages, rightOverflowPage]
}

return [1, ...pages, numPages]
}

return range(1, numPages)
}

export const PaginationWidget = ({
prevLabel,
nextLabel,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { buildPagedList } from "./PaginationWidget"
import { buildPagedList } from "./utils"

describe("unit/PaginationWidget", () => {
describe("buildPagedList", () => {
Expand Down
58 changes: 58 additions & 0 deletions site/src/components/PaginationWidget/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@

/**
* Generates a ranged array with an option to step over values.
* Shamelessly stolen from:
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from#sequence_generator_range
*/
const range = (start: number, stop: number, step = 1) =>
Array.from({ length: (stop - start) / step + 1 }, (_, i) => start + i * step)

export const DEFAULT_RECORDS_PER_PAGE = 25
// Number of pages to the left or right of the current page selection.
const PAGE_NEIGHBORS = 1
// Number of pages displayed for cases where there are multiple ellipsis showing. This can be
// thought of as the minimum number of page numbers to display when multiple ellipsis are showing.
const PAGES_TO_DISPLAY = PAGE_NEIGHBORS * 2 + 3
// Total page blocks(page numbers or ellipsis) displayed, including the maximum number of ellipsis (2).
// This gives us maximum number of 7 page blocks to be displayed when the page neighbors value is 1.
const NUM_PAGE_BLOCKS = PAGES_TO_DISPLAY + 2

/**
* Builds a list of pages based on how many pages exist and where the user is in their navigation of those pages.
* List result is used to from the buttons that make up the Pagination Widget
*/
export const buildPagedList = (
numPages: number,
activePage: number,
): (string | number)[] => {
if (numPages > NUM_PAGE_BLOCKS) {
let pages = []
const leftBound = activePage - PAGE_NEIGHBORS
const rightBound = activePage + PAGE_NEIGHBORS
const beforeLastPage = numPages - 1
const startPage = leftBound > 2 ? leftBound : 2
const endPage = rightBound < beforeLastPage ? rightBound : beforeLastPage

pages = range(startPage, endPage)

const singleSpillOffset = PAGES_TO_DISPLAY - pages.length - 1
const hasLeftOverflow = startPage > 2
const hasRightOverflow = endPage < beforeLastPage
const leftOverflowPage = "left"
const rightOverflowPage = "right"

if (hasLeftOverflow && !hasRightOverflow) {
const extraPages = range(startPage - singleSpillOffset, startPage - 1)
pages = [leftOverflowPage, ...extraPages, ...pages]
} else if (!hasLeftOverflow && hasRightOverflow) {
const extraPages = range(endPage + 1, endPage + singleSpillOffset)
pages = [...pages, ...extraPages, rightOverflowPage]
} else if (hasLeftOverflow && hasRightOverflow) {
pages = [leftOverflowPage, ...pages, rightOverflowPage]
}

return [1, ...pages, numPages]
}

return range(1, numPages)
}