Skip to content

Commit

Permalink
10409: wip
Browse files Browse the repository at this point in the history
  • Loading branch information
JayFlexy committed Sep 19, 2024
1 parent ae79b24 commit a5a4547
Show file tree
Hide file tree
Showing 5 changed files with 258 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ export type SetTrialSessionsFilters = Partial<{
action: 'add' | 'remove';
trialLocation: string;
};
startDate?: string;
endDate?: string;
pageNumber: number;
startDate: string;
endDate: string;
}>;

export const setTrialSessionsFiltersAction = ({
Expand Down Expand Up @@ -85,6 +86,10 @@ export const setTrialSessionsFiltersAction = ({
);
}

if (props.pageNumber || props.pageNumber === 0) {
store.set(state.trialSessionsPage.filters.pageNumber, props.pageNumber);
}

if (props.startDate || props.startDate === '') {
store.set(state.trialSessionsPage.filters.startDate, props.startDate);
}
Expand Down
10 changes: 9 additions & 1 deletion web-client/src/presenter/computeds/trialSessionsHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,15 @@ export const trialSessionsHelper = (
searchableTrialLocationOptions: InputOption[];
trialCitiesByState: InputOption[];
trialSessionsCount: number;
totalPages: number;
} => {
const permissions = get(state.permissions)!;
const trialSessions = get(state.trialSessionsPage.trialSessions);
const filters = get(state.trialSessionsPage.filters);
const judge = get(state.judgeUser);

const pageSize = 5;

const showCurrentJudgesOnly =
filters.currentTab === 'new' ||
filters.sessionStatus === SESSION_STATUS_TYPES.open;
Expand Down Expand Up @@ -140,7 +143,11 @@ export const trialSessionsHelper = (
})
.sort((sessionA, sessionB) => {
return sessionA.startDate.localeCompare(sessionB.startDate);
});
})
.slice(
filters.pageNumber * pageSize,
filters.pageNumber * pageSize + pageSize,
);
const trialSessionRows = formatTrialSessions({
judgeAssociatedToUser: judge,
trialSessions: filteredTrialSessions,
Expand All @@ -165,6 +172,7 @@ export const trialSessionsHelper = (
showNoticeIssued: filters.currentTab === 'calendared',
showSessionStatus: filters.currentTab === 'calendared',
showUnassignedJudgeFilter: filters.currentTab === 'new',
totalPages: Math.ceil(filteredTrialSessions.length / pageSize),
trialCitiesByState: states,
trialSessionJudgeOptions,
trialSessionRows,
Expand Down
2 changes: 2 additions & 0 deletions web-client/src/presenter/state/trialSessionsPageState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const filters: TrialSessionsFilters = {
currentTab: 'calendared' as 'calendared' | 'new',
endDate: '',
judges: {},
pageNumber: 0,
proceedingType: 'All' as TrialSessionProceedingType,
sessionStatus: SESSION_STATUS_TYPES.open,
sessionTypes: {},
Expand All @@ -24,6 +25,7 @@ export const initialTrialSessionPageState = {
export type TrialSessionsFilters = {
currentTab: 'calendared' | 'new';
endDate: string;
pageNumber: number;
judges: Record<string, { name: string; userId: string }>;
proceedingType: TrialSessionProceedingType | 'All';
sessionStatus: string;
Expand Down
290 changes: 232 additions & 58 deletions web-client/src/ustc-ui/Pagination/Paginator.tsx
Original file line number Diff line number Diff line change
@@ -1,74 +1,248 @@
import { Button } from '@web-client/ustc-ui/Button/Button';
import React from 'react';
import classNames from 'classnames';

export const Paginator = ({
const numberOfPaginatorSlots = 7;
const PageButton = (props: {
pageNumber: number;
selected: boolean;
onClick: (selectedPage: number) => void;
}) => {
return (
<>
<li className="usa-pagination__item usa-pagination__page-no">
<button
aria-label="Page 1"
className={classNames(
'usa-pagination__button',
'background-none',
props.selected && 'usa-current',
)}
onClick={() => props.onClick(props.pageNumber)}
>
{props.pageNumber + 1}
</button>
</li>
</>
);
};

const PreviousPage = (props: { onPreviousClick: Function }) => {
return (
<>
<li className="usa-pagination__item usa-pagination__arrow">
<button
aria-label="Previous page"
className="usa-pagination__link usa-pagination__previous-page background-none border-none"
onClick={() => {
props.onPreviousClick();
}}
>
<svg aria-hidden="true" className="usa-icon" role="img">
<use xlinkHref="/assets/img/sprite.svg#navigate_before"></use>
</svg>
<span className="usa-pagination__link-text">Previous</span>
</button>
</li>
</>
);
};

const NextPage = (props: { onNextClick: Function }) => {
return (
<>
<li className="usa-pagination__item usa-pagination__arrow">
<button
aria-label="Next page"
className="usa-pagination__link usa-pagination__next-page background-none border-none"
onClick={() => {
props.onNextClick();
}}
>
<svg aria-hidden="true" className="usa-icon" role="img">
<use xlinkHref="/assets/img/sprite.svg#navigate_before"></use>
</svg>
<span className="usa-pagination__link-text">Next</span>
</button>
</li>
</>
);
};

const PageEllipsis = () => {
return (
<>
<li
className="usa-pagination__item usa-pagination__overflow"
role="presentation"
>
<span></span>
</li>
</>
);
};

function getSlotComponent({
currentPageIndex,
onPageChange,
slotNumber,
totalPages,
}: {
currentPageIndex: number;
onPageChange: (selectedPage: number) => any;
slotNumber: number;
totalPages: number;
}) {
const isHidingPreviousOptions =
currentPageIndex > 3 && totalPages > numberOfPaginatorSlots;
const isHidingFutureOptions =
totalPages - currentPageIndex > 4 && totalPages > numberOfPaginatorSlots;
if (slotNumber === 0) {
return (
<PageButton
pageNumber={0}
selected={currentPageIndex === 0}
onClick={selectedPage => {
onPageChange(selectedPage);
}}
/>
);
}
if (slotNumber === 1) {
if (isHidingPreviousOptions) {
return <PageEllipsis />;
} else {
return (
<PageButton
pageNumber={1}
selected={currentPageIndex === 1}
onClick={selectedPage => {
onPageChange(selectedPage);
}}
/>
);
}
}
if (slotNumber === 2 || slotNumber === 3 || slotNumber === 4) {
if (!isHidingPreviousOptions) {
return (
<PageButton
pageNumber={slotNumber}
selected={currentPageIndex === slotNumber}
onClick={selectedPage => {
onPageChange(selectedPage);
}}
/>
);
}
if (!isHidingFutureOptions) {
return (
<PageButton
pageNumber={totalPages - numberOfPaginatorSlots + slotNumber}
selected={
currentPageIndex ===
totalPages - numberOfPaginatorSlots + slotNumber
}
onClick={selectedPage => {
onPageChange(selectedPage);
}}
/>
);
}
return (
<PageButton
pageNumber={currentPageIndex + slotNumber - 3}
selected={currentPageIndex === currentPageIndex + slotNumber - 3}
onClick={selectedPage => {
onPageChange(selectedPage);
}}
/>
);
}
if (slotNumber === 5) {
if (isHidingFutureOptions) {
return <PageEllipsis />;
} else {
const subtractor = totalPages >= 7 ? 2 : 1;
return (
<PageButton
pageNumber={totalPages - subtractor}
selected={currentPageIndex === totalPages - subtractor}
onClick={selectedPage => {
onPageChange(selectedPage);
}}
/>
);
}
}
if (slotNumber === 6) {
return (
<PageButton
pageNumber={totalPages - 1}
selected={currentPageIndex === totalPages - 1}
onClick={selectedPage => {
onPageChange(selectedPage);
}}
/>
);
}
}

/*
This component is based off of USWDS implementation of a paginator: https://designsystem.digital.gov/components/pagination/
The totalPages and selected page work similarly to counting arrays. TotalPages is similar to array.length and selectedPage is 0 based indexing.
totalPages could be 20 but the maximum value selectedPage could be is 19 and the lowest pages is 0.
*/

export const Paginator = ({
currentPageIndex,
onPageChange,
totalPages,
}: {
currentPageIndex: number;
onPageChange: (currentPage: number) => void;
totalPages: number;
onPageChange: (selectedPage: number) => any;
}) => {
let currentPage = currentPageIndex + 1;
const sevenDisplayedSlots = [];
console.log('selected page number: ', currentPageIndex);
// 1. Should it render the slot at all?
// 2. Should it render a page button or an ellipse?
// 3. Should it render The slot number it is or should it add some extras?

const nextDisabled = currentPage >= totalPages;
const previousDisabled = currentPage <= 1;
for (let slotNumber = 0; slotNumber < numberOfPaginatorSlots; slotNumber++) {
if (slotNumber >= totalPages) {
continue;
}
const slotComponent = getSlotComponent({
currentPageIndex,
onPageChange,
slotNumber,
totalPages,
});
sevenDisplayedSlots.push(slotComponent);
}

return (
<nav
aria-label="Pagination"
className="usa-pagination margin-bottom-0 margin-top-0"
role="navigation"
>
<ul className="usa-pagination__list">
<li className="usa-pagination__item">
<Button
link
aria-disabled={previousDisabled}
aria-label="Previous"
className={classNames(
`${previousDisabled && 'hide'}`,
'usa-pagination__link usa-pagination__previous-page cursor-pointer',
)}
disabled={previousDisabled}
tabIndex={previousDisabled ? '-1' : '0'}
onClick={() => onPageChange(currentPage - 2)}
>
Previous
</Button>
</li>

<li
className={'usa-pagination__item usa-pagination__page-no'}
key={currentPage}
>
<button
aria-current="page"
aria-label={`Page ${currentPage} is your current page`}
className="usa-pagination__button cursor-pointer paginator-current"
>
{currentPage}
</button>
</li>
<li className="usa-pagination__item">
<Button
link
aria-label="Next"
className={classNames(
`${nextDisabled && 'hide'}`,
'usa-pagination__link usa-pagination__next-page cursor-pointer',
)}
disabled={nextDisabled}
tabIndex={nextDisabled ? '-1' : '0'}
onClick={() => onPageChange(currentPage)}
>
Next
</Button>
</li>
</ul>
</nav>
<>
<nav aria-label="Pagination" className="usa-pagination margin-bottom-0">
<ul className="usa-pagination__list">
{currentPageIndex !== 0 && (
<PreviousPage
onPreviousClick={() => {
onPageChange(currentPageIndex - 1);
}}
/>
)}
{sevenDisplayedSlots}
{currentPageIndex < totalPages - 1 && (
<NextPage
onNextClick={() => {
onPageChange(currentPageIndex + 1);
}}
/>
)}
</ul>
</nav>
</>
);
};

Expand Down
Loading

0 comments on commit a5a4547

Please sign in to comment.