From a5a4547172389b9bfc0d35b3bb2c47f6b7cec43b Mon Sep 17 00:00:00 2001 From: Javis Sullivan Date: Thu, 19 Sep 2024 17:03:48 -0400 Subject: [PATCH] 10409: wip --- .../setTrialSessionsFiltersAction.ts | 9 +- .../computeds/trialSessionsHelper.ts | 10 +- .../presenter/state/trialSessionsPageState.ts | 2 + .../src/ustc-ui/Pagination/Paginator.tsx | 290 ++++++++++++++---- .../src/views/TrialSessions/TrialSessions.tsx | 8 + 5 files changed, 258 insertions(+), 61 deletions(-) diff --git a/web-client/src/presenter/actions/TrialSession/setTrialSessionsFiltersAction.ts b/web-client/src/presenter/actions/TrialSession/setTrialSessionsFiltersAction.ts index e4b50a26c2a..868c0bc9e10 100644 --- a/web-client/src/presenter/actions/TrialSession/setTrialSessionsFiltersAction.ts +++ b/web-client/src/presenter/actions/TrialSession/setTrialSessionsFiltersAction.ts @@ -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 = ({ @@ -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); } diff --git a/web-client/src/presenter/computeds/trialSessionsHelper.ts b/web-client/src/presenter/computeds/trialSessionsHelper.ts index c3e2285cb7f..aacd345fd45 100644 --- a/web-client/src/presenter/computeds/trialSessionsHelper.ts +++ b/web-client/src/presenter/computeds/trialSessionsHelper.ts @@ -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; @@ -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, @@ -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, diff --git a/web-client/src/presenter/state/trialSessionsPageState.ts b/web-client/src/presenter/state/trialSessionsPageState.ts index 40f856227c6..a198a815870 100644 --- a/web-client/src/presenter/state/trialSessionsPageState.ts +++ b/web-client/src/presenter/state/trialSessionsPageState.ts @@ -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: {}, @@ -24,6 +25,7 @@ export const initialTrialSessionPageState = { export type TrialSessionsFilters = { currentTab: 'calendared' | 'new'; endDate: string; + pageNumber: number; judges: Record; proceedingType: TrialSessionProceedingType | 'All'; sessionStatus: string; diff --git a/web-client/src/ustc-ui/Pagination/Paginator.tsx b/web-client/src/ustc-ui/Pagination/Paginator.tsx index 1beb6346bc7..7965e1f6317 100644 --- a/web-client/src/ustc-ui/Pagination/Paginator.tsx +++ b/web-client/src/ustc-ui/Pagination/Paginator.tsx @@ -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 ( + <> +
  • + +
  • + + ); +}; + +const PreviousPage = (props: { onPreviousClick: Function }) => { + return ( + <> +
  • + +
  • + + ); +}; + +const NextPage = (props: { onNextClick: Function }) => { + return ( + <> +
  • + +
  • + + ); +}; + +const PageEllipsis = () => { + return ( + <> +
  • + +
  • + + ); +}; + +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 ( + { + onPageChange(selectedPage); + }} + /> + ); + } + if (slotNumber === 1) { + if (isHidingPreviousOptions) { + return ; + } else { + return ( + { + onPageChange(selectedPage); + }} + /> + ); + } + } + if (slotNumber === 2 || slotNumber === 3 || slotNumber === 4) { + if (!isHidingPreviousOptions) { + return ( + { + onPageChange(selectedPage); + }} + /> + ); + } + if (!isHidingFutureOptions) { + return ( + { + onPageChange(selectedPage); + }} + /> + ); + } + return ( + { + onPageChange(selectedPage); + }} + /> + ); + } + if (slotNumber === 5) { + if (isHidingFutureOptions) { + return ; + } else { + const subtractor = totalPages >= 7 ? 2 : 1; + return ( + { + onPageChange(selectedPage); + }} + /> + ); + } + } + if (slotNumber === 6) { + return ( + { + 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 ( - + <> + + ); }; diff --git a/web-client/src/views/TrialSessions/TrialSessions.tsx b/web-client/src/views/TrialSessions/TrialSessions.tsx index a2d6bc6f7f7..a622d6c2c41 100644 --- a/web-client/src/views/TrialSessions/TrialSessions.tsx +++ b/web-client/src/views/TrialSessions/TrialSessions.tsx @@ -2,6 +2,7 @@ import { BigHeader } from '../BigHeader'; import { Button } from '../../ustc-ui/Button/Button'; import { DateRangePickerComponent } from '@web-client/ustc-ui/DateInput/DateRangePickerComponent'; import { ErrorNotification } from '../ErrorNotification'; +import { Paginator } from '@web-client/ustc-ui/Pagination/Paginator'; import { PillButton } from '@web-client/ustc-ui/Button/PillButton'; import { SESSION_STATUS_TYPES, @@ -411,6 +412,13 @@ const TrialSessionFilters = connect( > Reset Filters + { + setTrialSessionsFiltersSequence({ pageNumber: selectedPage }); + }} + /> ); },