-
Notifications
You must be signed in to change notification settings - Fork 229
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
Pagination Front End - Part 1 #9937
Conversation
background: #696969; | ||
`; | ||
const UnavailableBlock = styled(Block)` | ||
color: #bababa; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🐑
Er, I would leave it as it is for now and keep the same logic is Webcore? |
</EllipsisBlock> | ||
), | ||
}; | ||
/* eslint-enable react/prop-types */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like we have prop types. Can we remove this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an eslint-enable
- it corresponds with the eslint-disable
on line 97
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not quite finished reviewing this but just dropping what I've found so far, hope it helps!
activePage, | ||
pageCount, | ||
activePageOnEdge: activePage === 1 || activePage === pageCount, | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When I first looked at this file I was pretty unclear where state is initialised (here I eventually found). I'm unsure of the need for a global state variable in this case 🤔 Can we chain the functions so state is not mutated globally?
On this line for example we could reduce rather than map arrive at the final state value, see below for a sketch of what I might suggest
I feel it reads better and elimates the risk of errors being introduced later when working with global state.
if (pageCount <= 1) return null; | ||
state = { | ||
activePage, | ||
pageCount, | ||
activePageOnEdge: activePage === 1 || activePage === pageCount, | ||
}; | ||
state.result = Array(pageCount) | ||
.fill() | ||
.map((_, i) => createPage(i)); | ||
|
||
setRequiredVisibility(); | ||
setDynamicVisibility(); | ||
pruneInvisible(); | ||
insertEllipsis(); | ||
insertArrows(); | ||
addKeys(); | ||
|
||
return state.result; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (pageCount <= 1) return null; | |
state = { | |
activePage, | |
pageCount, | |
activePageOnEdge: activePage === 1 || activePage === pageCount, | |
}; | |
state.result = Array(pageCount) | |
.fill() | |
.map((_, i) => createPage(i)); | |
setRequiredVisibility(); | |
setDynamicVisibility(); | |
pruneInvisible(); | |
insertEllipsis(); | |
insertArrows(); | |
addKeys(); | |
return state.result; | |
if (pageCount <= 1) return null; | |
const intialState = { | |
activePage, | |
pageCount, | |
activePageOnEdge: activePage === 1 || activePage === pageCount, | |
}; | |
//state is no longer global | |
const state = Array(pageCount) | |
.fill() | |
.reduce((currentState, i) => createPage(i, currentState), intialState); | |
return pipe(setRequiredVisibility, setDynamicVisibility, pruneInvisible, insertEllipsis, insertArrows, addKeys)(state).result; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
btw, fully aware this code won't 'just work', just illustrating the general pattern
state.result.forEach((result, i) => { | ||
// eslint-disable-next-line no-param-reassign | ||
result.key = i; | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
state.result.forEach((result, i) => { | |
// eslint-disable-next-line no-param-reassign | |
result.key = i; | |
}); | |
state.result = state.result.map((result, i) => { | |
return { ...result, key: i }; | |
}); |
Think this will remove the need for the linting comment and make this more functional
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 this is a bigger problem since moving state
to being passed into each function
really don't think it's worth the added code complexity to try to make all of these helper functions pure
they're all private - the default export is pure
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Think I've finished my review of this, let me know if you need any help or clarification. Happy to debate the points as well, I know some of my suggestions result in significant changes.
|
||
const ActiveBlock = styled(Block)` | ||
color: ${C_WHITE}; | ||
background: #696969; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know it's annoying but I think these colours should be added to psammead styles or we should reference existing colours? As we make chameleon changes it'll be very difficult to make global changes without doing this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added this here RetiredBlob@50a2cde
|
||
const Pagination = ({ activePage, pageCount }) => { | ||
const { service } = useContext(ServiceContext); | ||
const clampedPageCount = clamp(1, 99, pageCount); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could consider maintaining the max page count in the BFF to keep this decision in one place in case we change it in the future?
Also there would be no need for the clamp logic as the BFF would only return up to 40 pages and 404 if any page higher (or lower) were requested
pageCount: 1, | ||
}; | ||
|
||
export default Pagination; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This component needs some tests to show it can take varying page ranges and return suitable visual components. It's not about retesting buildBlocks
as that has a lot of the complex view logic, but checking that the correct dom elements are rendered for different page ranges. It doesn't need to be as comprehensive as the buildBlocks
test.
Updated UX /a11y captured in this ticket: #9984 |
text-decoration: none; | ||
height: 100%; | ||
width: 100%; | ||
&:hover { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing focus?
if (!blocks) return null; | ||
|
||
return ( | ||
<OL role="list"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should 'OL' be in caps?
Co-authored-by: Jonathan Roebuck <[email protected]>
Part of #9943
The 240 breakpoint design will be done in a separate PR, since this PR is already quite big
cross-team
label to this PR if it requires visibility across World Service teamsTesting:
CYPRESS_APP_ENV=local CYPRESS_SMOKE=false yarn test:e2e:interactive
)