From e3e26183ae5b5bd569d3ff239cff17cc16c518a7 Mon Sep 17 00:00:00 2001 From: Zachary Rogers Date: Fri, 30 Aug 2024 10:57:41 -0700 Subject: [PATCH 01/59] 10409: Add new styling for trial sessions. Extract filters to its own component separate from the table --- .../src/views/TrialSessions/TrialSessions.tsx | 194 +++++++++++++++--- .../TrialSessions/TrialSessionsTable.tsx | 82 +------- 2 files changed, 162 insertions(+), 114 deletions(-) diff --git a/web-client/src/views/TrialSessions/TrialSessions.tsx b/web-client/src/views/TrialSessions/TrialSessions.tsx index fc7f48debd4..2f32c8e590b 100644 --- a/web-client/src/views/TrialSessions/TrialSessions.tsx +++ b/web-client/src/views/TrialSessions/TrialSessions.tsx @@ -1,8 +1,14 @@ import { BigHeader } from '../BigHeader'; +import { BindedSelect } from '@web-client/ustc-ui/BindedSelect/BindedSelect'; import { Button } from '../../ustc-ui/Button/Button'; import { ErrorNotification } from '../ErrorNotification'; +import { + SESSION_TYPES, + TRIAL_SESSION_PROCEEDING_TYPES, +} from '@shared/business/entities/EntityConstants'; import { SuccessNotification } from '../SuccessNotification'; import { Tab, Tabs } from '../../ustc-ui/Tabs/Tabs'; +import { TrialCityOptions } from '@web-client/views/TrialCityOptions'; import { TrialSessionsTable } from './TrialSessionsTable'; import { connect } from '@web-client/presenter/shared.cerebral'; import { sequences } from '@web-client/presenter/app.cerebral'; @@ -14,12 +20,12 @@ export const TrialSessions = connect( defaultTab: state.screenMetadata.trialSessionFilters.status, openTrialSessionPlanningModalSequence: sequences.openTrialSessionPlanningModalSequence, - showNewTrialSession: state.trialSessionsHelper.showNewTrialSession, + trialSessionHelper: state.trialSessionsHelper, }, function TrialSessions({ defaultTab, openTrialSessionPlanningModalSequence, - showNewTrialSession, + trialSessionHelper, }) { return ( <> @@ -30,7 +36,7 @@ export const TrialSessions = connect( @@ -44,48 +50,24 @@ export const TrialSessions = connect( Trial Session Planning Report - {showNewTrialSession && ( - - )} - {showNewTrialSession && ( + {trialSessionHelper.showNewTrialSession && ( + )} - - - - - - + @@ -95,4 +77,148 @@ export const TrialSessions = connect( }, ); +const TrialSessionFilters = connect( + { trialSessionsHelper: state.trialSessionsHelper }, + function TrialSessionFilters({ trialSessionsHelper }) { + return ( + <> +
+
+ Session Status + {}} + /> + + {}} + /> + + {}} + /> + +
+
+
+
+ + + + + + + + {Object.values(TRIAL_SESSION_PROCEEDING_TYPES).map( + proceedingType => ( + + ), + )} + + + + {Object.values(SESSION_TYPES).map(sessionType => ( + + ))} + + + + {trialSessionsHelper.trialSessionJudges.map(judge => ( + + ))} + + {trialSessionsHelper.showUnassignedJudgeFilter && ( + + )} + +
+ {trialSessionsHelper.showNewTrialSession && ( + + )} +
+ + ); + }, +); +// }); + TrialSessions.displayName = 'TrialSessions'; diff --git a/web-client/src/views/TrialSessions/TrialSessionsTable.tsx b/web-client/src/views/TrialSessions/TrialSessionsTable.tsx index 8e2875d6591..b46dd42c07f 100644 --- a/web-client/src/views/TrialSessions/TrialSessionsTable.tsx +++ b/web-client/src/views/TrialSessions/TrialSessionsTable.tsx @@ -1,10 +1,4 @@ -import { BindedSelect } from '../../ustc-ui/BindedSelect/BindedSelect'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { - SESSION_TYPES, - TRIAL_SESSION_PROCEEDING_TYPES, -} from '../../../../shared/src/business/entities/EntityConstants'; -import { TrialCityOptions } from '../TrialCityOptions'; import { connect } from '@web-client/presenter/shared.cerebral'; import { props } from 'cerebral'; import { state } from '@web-client/presenter/app.cerebral'; @@ -30,79 +24,7 @@ export const TrialSessionsTable = connect( }; }) { return ( - -
- - - - - - - - {Object.values(TRIAL_SESSION_PROCEEDING_TYPES).map( - proceedingType => ( - - ), - )} - - - - {Object.values(SESSION_TYPES).map(sessionType => ( - - ))} - - - - {trialSessionsHelper.trialSessionJudges.map(judge => ( - - ))} - - {trialSessionsHelper.showUnassignedJudgeFilter && ( - - )} - -
+ <> There are no trial sessions.

)} - + ); }, ); From 482d62f9e0f27d54ac14159865d3a8e5061ca449 Mon Sep 17 00:00:00 2001 From: Zachary Rogers Date: Fri, 30 Aug 2024 15:44:32 -0700 Subject: [PATCH 02/59] 10409: Split out state for trialsessionPage into its own page container. --- .../trialSessions/getTrialSessionsProxy.ts | 5 ++- .../setTrialSessionsPageAction.ts | 5 +++ .../sequences/gotoTrialSessionsSequence.ts | 4 +- web-client/src/presenter/state.ts | 2 + .../presenter/state/trialSessionsPageState.ts | 14 ++++++ .../src/views/TrialSessions/TrialSessions.tsx | 43 +++++++++---------- 6 files changed, 47 insertions(+), 26 deletions(-) create mode 100644 web-client/src/presenter/actions/TrialSession/setTrialSessionsPageAction.ts create mode 100644 web-client/src/presenter/state/trialSessionsPageState.ts diff --git a/shared/src/proxies/trialSessions/getTrialSessionsProxy.ts b/shared/src/proxies/trialSessions/getTrialSessionsProxy.ts index b561ff5be22..56456ad8c74 100644 --- a/shared/src/proxies/trialSessions/getTrialSessionsProxy.ts +++ b/shared/src/proxies/trialSessions/getTrialSessionsProxy.ts @@ -1,3 +1,4 @@ +import { TrialSessionInfoDTO } from '@shared/business/dto/trialSessions/TrialSessionInfoDTO'; import { get } from '../requests'; /** @@ -6,7 +7,9 @@ import { get } from '../requests'; * @param {object} applicationContext the application context * @returns {Promise<*>} the promise of the api call */ -export const getTrialSessionsInteractor = applicationContext => { +export const getTrialSessionsInteractor = ( + applicationContext, +): Promise => { return get({ applicationContext, endpoint: '/trial-sessions', diff --git a/web-client/src/presenter/actions/TrialSession/setTrialSessionsPageAction.ts b/web-client/src/presenter/actions/TrialSession/setTrialSessionsPageAction.ts new file mode 100644 index 00000000000..72f2ee896e1 --- /dev/null +++ b/web-client/src/presenter/actions/TrialSession/setTrialSessionsPageAction.ts @@ -0,0 +1,5 @@ +import { state } from '@web-client/presenter/app.cerebral'; + +export const setTrialSessionsPageAction = ({ props, store }: ActionProps) => { + store.set(state.trialSessionsPage.trialSessions, props.trialSessions); +}; diff --git a/web-client/src/presenter/sequences/gotoTrialSessionsSequence.ts b/web-client/src/presenter/sequences/gotoTrialSessionsSequence.ts index 5dd87fa401d..bf83e17b438 100644 --- a/web-client/src/presenter/sequences/gotoTrialSessionsSequence.ts +++ b/web-client/src/presenter/sequences/gotoTrialSessionsSequence.ts @@ -9,8 +9,8 @@ import { parallel } from 'cerebral/factories'; import { setAllAndCurrentJudgesAction } from '../actions/setAllAndCurrentJudgesAction'; import { setJudgeUserAction } from '../actions/setJudgeUserAction'; import { setNotificationsAction } from '../actions/setNotificationsAction'; -import { setTrialSessionsAction } from '../actions/TrialSession/setTrialSessionsAction'; import { setTrialSessionsFiltersAction } from '../actions/TrialSession/setTrialSessionsFiltersAction'; +import { setTrialSessionsPageAction } from '@web-client/presenter/actions/TrialSession/setTrialSessionsPageAction'; import { setupCurrentPageAction } from '../actions/setupCurrentPageAction'; import { startWebSocketConnectionSequenceDecorator } from '../utilities/startWebSocketConnectionSequenceDecorator'; @@ -23,7 +23,7 @@ export const gotoTrialSessionsSequence = parallel([ [getJudgeForCurrentUserAction, setJudgeUserAction], [getNotificationsAction, setNotificationsAction], - [getTrialSessionsAction, setTrialSessionsAction], + [getTrialSessionsAction, setTrialSessionsPageAction], [ getUsersInSectionAction({ section: 'judge' }), setAllAndCurrentJudgesAction, diff --git a/web-client/src/presenter/state.ts b/web-client/src/presenter/state.ts index 643ef2b6fee..a1923173901 100644 --- a/web-client/src/presenter/state.ts +++ b/web-client/src/presenter/state.ts @@ -94,6 +94,7 @@ import { headerHelper } from './computeds/headerHelper'; import { initialBlockedCaseReportFilter } from '@web-client/presenter/state/blockedCasesReportState'; import { initialCustomCaseReportState } from './customCaseReportState'; import { initialPendingReportsState } from '@web-client/presenter/state/pendingReportState'; +import { initialTrialSessionPageState } from '@web-client/presenter/state/trialSessionsPageState'; import { initialTrialSessionState } from '@web-client/presenter/state/trialSessionState'; import { initialTrialSessionWorkingCopyState } from '@web-client/presenter/state/trialSessionWorkingCopyState'; import { internalPetitionPartiesHelper } from './computeds/internalPetitionPartiesHelper'; @@ -850,6 +851,7 @@ export const baseState = { name: '', }, trialSessionWorkingCopy: cloneDeep(initialTrialSessionWorkingCopyState), + trialSessionsPage: cloneDeep(initialTrialSessionPageState), user: cloneDeep(emptyUserState), userContactEditProgress: {} as { inProgress?: boolean }, users: [] as RawUser[], diff --git a/web-client/src/presenter/state/trialSessionsPageState.ts b/web-client/src/presenter/state/trialSessionsPageState.ts new file mode 100644 index 00000000000..7c90373ab1c --- /dev/null +++ b/web-client/src/presenter/state/trialSessionsPageState.ts @@ -0,0 +1,14 @@ +import { TrialSessionInfoDTO } from '@shared/business/dto/trialSessions/TrialSessionInfoDTO'; +import { TrialSessionProceedingType } from '@shared/business/entities/EntityConstants'; + +export const initialTrialSessionPageState = { + filters: { + isCalendared: true, // This filter is relly just if the user is on the "Calendared" or "New" tab + judgeId: 'All', + proceedingType: 'All' as TrialSessionProceedingType, + sessionStatus: 'All', + sessionType: 'All', + trialLocation: 'All', + }, + trialSessions: [] as TrialSessionInfoDTO[], +}; diff --git a/web-client/src/views/TrialSessions/TrialSessions.tsx b/web-client/src/views/TrialSessions/TrialSessions.tsx index 2f32c8e590b..0d37a937290 100644 --- a/web-client/src/views/TrialSessions/TrialSessions.tsx +++ b/web-client/src/views/TrialSessions/TrialSessions.tsx @@ -1,5 +1,4 @@ import { BigHeader } from '../BigHeader'; -import { BindedSelect } from '@web-client/ustc-ui/BindedSelect/BindedSelect'; import { Button } from '../../ustc-ui/Button/Button'; import { ErrorNotification } from '../ErrorNotification'; import { @@ -141,24 +140,22 @@ const TrialSessionFilters = connect( > Filter by - {}} > - + - - + {}} > {Object.values(SESSION_TYPES).map(sessionType => ( @@ -180,17 +177,17 @@ const TrialSessionFilters = connect( {sessionType} ))} - - + {trialSessionsHelper.showNewTrialSession && (
@@ -44,38 +34,42 @@ export const TrialSessionsTable = connect( {trialSessionsHelper.showSessionStatus && } - {formattedTrialSessions.map(trialDate => ( - - - - - - - {trialDate.sessions.map(item => ( - + {trialSessionsHelper.trialSessionRows.map(row => ( + <> + {isTrialSessionWeek(row) && ( + + + + + + )} + {isTrialSessionRow(row) && ( + - + - - - + + + {trialSessionsHelper.showNoticeIssued && ( - + )} {trialSessionsHelper.showSessionStatus && ( - + )} - ))} - + )} + ))}
Session Status
-

- {'Week of '} - {trialDate.dateFormatted} -

-
+

+ {'Week of '} + {row.dateFormatted} +

+
- {item.showAlertForNOTTReminder && ( + {row.showAlertForNOTTReminder && ( )} - {item.formattedStartDate} + {row.formattedStartDate} {item.formattedEstimatedEndDate}{row.formattedEstimatedEndDate} - {item.swingSession && ( + {row.swingSession && ( - {item.trialLocation} + {row.trialLocation} {item.proceedingType}{item.sessionType}{item.judge && item.judge.name}{row.proceedingType}{row.sessionType}{row.judge && row.judge.name}{item.formattedNoticeIssuedDate}{row.formattedNoticeIssuedDate}{item.sessionStatus}{row.sessionStatus}
- {formattedTrialSessions.length === 0 && ( + {trialSessionsHelper.trialSessionRows.length === 0 && (

There are no trial sessions.

)} From 7e6ee33dbd3b871357a92f82a722cfd0b4c6dec1 Mon Sep 17 00:00:00 2001 From: Zachary Rogers Date: Tue, 3 Sep 2024 10:42:17 -0700 Subject: [PATCH 06/59] 10409: Add sorting --- web-api/storage/fixtures/seed/efcms-local.json | 2 +- .../src/presenter/computeds/trialSessionsHelper.ts | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/web-api/storage/fixtures/seed/efcms-local.json b/web-api/storage/fixtures/seed/efcms-local.json index f5b8ec14898..4175e7a6c73 100644 --- a/web-api/storage/fixtures/seed/efcms-local.json +++ b/web-api/storage/fixtures/seed/efcms-local.json @@ -50345,7 +50345,7 @@ { "caseOrder": [], "gsi1pk": "trial-session-catalog", - "sessionStatus": "New", + "sessionStatus": "Open", "trialLocation": "Denver, Colorado", "proceedingType": "In Person", "createdAt": "2019-11-02T05:00:00.000Z", diff --git a/web-client/src/presenter/computeds/trialSessionsHelper.ts b/web-client/src/presenter/computeds/trialSessionsHelper.ts index a9ef10e83be..e8731b94bd5 100644 --- a/web-client/src/presenter/computeds/trialSessionsHelper.ts +++ b/web-client/src/presenter/computeds/trialSessionsHelper.ts @@ -66,7 +66,16 @@ export const trialSessionsHelper = ( .filter(trialSession => { if (filters.trialLocation === 'All') return true; return filters.trialLocation === trialSession.trialLocation; + }) + .sort((sessionA, sessionB) => { + if (sessionA.startDate === sessionB.startDate) { + const sessionATrialLocation = sessionA.trialLocation || ''; + const sessionBTrialLocation = sessionA.trialLocation || ''; + return sessionATrialLocation.localeCompare(sessionBTrialLocation); + } + return sessionA.startDate.localeCompare(sessionB.startDate); }); + const trialSessionRows = formatTrialSessions({ judgeAssociatedToUser: judge, trialSessions: filteredTrialSessions, From 3a7709f77b52c47e62113ea50ab1d1ceb404e620 Mon Sep 17 00:00:00 2001 From: Zachary Rogers Date: Tue, 3 Sep 2024 11:51:11 -0700 Subject: [PATCH 07/59] 10409: Add blue rows to display session weeks --- .../computeds/trialSessionsHelper.ts | 47 ++++++++++++++----- .../TrialSessions/TrialSessionsTable.tsx | 6 +-- 2 files changed, 37 insertions(+), 16 deletions(-) diff --git a/web-client/src/presenter/computeds/trialSessionsHelper.ts b/web-client/src/presenter/computeds/trialSessionsHelper.ts index e8731b94bd5..755166e874b 100644 --- a/web-client/src/presenter/computeds/trialSessionsHelper.ts +++ b/web-client/src/presenter/computeds/trialSessionsHelper.ts @@ -1,5 +1,6 @@ import { FORMATS, + createDateAtStartOfWeekEST, formatDateString, } from '@shared/business/utilities/DateHandler'; import { Get } from 'cerebral'; @@ -10,7 +11,6 @@ import { state } from '@web-client/presenter/app.cerebral'; export const trialSessionsHelper = ( get: Get, ): { - additionalColumnsShown: number; showNewTrialSession: boolean; showNoticeIssued: boolean; showSessionStatus: boolean; @@ -27,11 +27,6 @@ export const trialSessionsHelper = ( const isNewTab = tab === 'new'; const isCalendared = tab === 'calendared'; - let additionalColumnsShown = 0; - if (isCalendared) { - additionalColumnsShown = 1; - } - const showCurrentJudgesOnly = isNewTab; let trialSessionJudges; @@ -82,7 +77,6 @@ export const trialSessionsHelper = ( }); return { - additionalColumnsShown, showNewTrialSession: permissions.CREATE_TRIAL_SESSION, showNoticeIssued: isCalendared, showSessionStatus: isCalendared, @@ -96,12 +90,13 @@ type TrialSessionRow = { trialSessionId: string; showAlertForNOTTReminder: boolean; alertMessageForNOTT: string; - formattedStartDate: string; + formattedStartDate: string; //MM/DD/YYYY formattedEstimatedEndDate: string; swingSession: boolean; userIsAssignedToSession: boolean; trialLocation: string; proceedingType: string; + startDate: string; // ISO format sessionType: string; judge?: { name: string; userId: string }; formattedNoticeIssuedDate: string; @@ -109,8 +104,8 @@ type TrialSessionRow = { }; type TrialSessionWeek = { - startOfWeekSortable: string; - dateFormatted: string; + sessionWeekStartDate: string; + formattedSessionWeekStartDate: string; }; export function isTrialSessionRow(item: any): item is TrialSessionRow { @@ -118,7 +113,7 @@ export function isTrialSessionRow(item: any): item is TrialSessionRow { } export function isTrialSessionWeek(item: any): item is TrialSessionWeek { - return !!item?.startOfWeekSortable; + return !!item?.sessionWeekStartDate; } const formatTrialSessions = ({ @@ -168,6 +163,7 @@ const formatTrialSessions = ({ sessionStatus: trialSession.sessionStatus, sessionType: trialSession.sessionType, showAlertForNOTTReminder, + startDate: trialSession.startDate, swingSession: !!trialSession.swingSession, trialLocation: trialSession.trialLocation || '', trialSessionId: trialSession.trialSessionId || '', @@ -176,5 +172,32 @@ const formatTrialSessions = ({ }, ); - return trialSessionRows; + const trialSessionWithStartWeeks: (TrialSessionRow | TrialSessionWeek)[] = []; + + let lastSessionWeek: TrialSessionWeek = { + formattedSessionWeekStartDate: '', + sessionWeekStartDate: '', + }; + trialSessionRows.forEach(trialSession => { + const trialSessionStartOfWeek = createDateAtStartOfWeekEST( + trialSession.startDate, + FORMATS.ISO, + ); + if (lastSessionWeek.sessionWeekStartDate < trialSessionStartOfWeek) { + const formattedSessionWeekStartDate = createDateAtStartOfWeekEST( + trialSession.startDate, + FORMATS.MONTH_DAY_YEAR, + ); + + lastSessionWeek = { + formattedSessionWeekStartDate, + sessionWeekStartDate: trialSessionStartOfWeek, + }; + + trialSessionWithStartWeeks.push(lastSessionWeek); + } + trialSessionWithStartWeeks.push(trialSession); + }); + + return trialSessionWithStartWeeks; }; diff --git a/web-client/src/views/TrialSessions/TrialSessionsTable.tsx b/web-client/src/views/TrialSessions/TrialSessionsTable.tsx index 1ce8175d36c..396b24fd192 100644 --- a/web-client/src/views/TrialSessions/TrialSessionsTable.tsx +++ b/web-client/src/views/TrialSessions/TrialSessionsTable.tsx @@ -39,12 +39,10 @@ export const TrialSessionsTable = connect( {isTrialSessionWeek(row) && ( - +

{'Week of '} - {row.dateFormatted} + {row.formattedSessionWeekStartDate}

From aa34374d650de8da6d0b93032f85ada354fbdda0 Mon Sep 17 00:00:00 2001 From: Zachary Rogers Date: Tue, 3 Sep 2024 11:52:24 -0700 Subject: [PATCH 08/59] 10409: organize functions --- .../computeds/trialSessionsHelper.ts | 58 +++++++++---------- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/web-client/src/presenter/computeds/trialSessionsHelper.ts b/web-client/src/presenter/computeds/trialSessionsHelper.ts index 755166e874b..ebdc1e85347 100644 --- a/web-client/src/presenter/computeds/trialSessionsHelper.ts +++ b/web-client/src/presenter/computeds/trialSessionsHelper.ts @@ -86,36 +86,6 @@ export const trialSessionsHelper = ( }; }; -type TrialSessionRow = { - trialSessionId: string; - showAlertForNOTTReminder: boolean; - alertMessageForNOTT: string; - formattedStartDate: string; //MM/DD/YYYY - formattedEstimatedEndDate: string; - swingSession: boolean; - userIsAssignedToSession: boolean; - trialLocation: string; - proceedingType: string; - startDate: string; // ISO format - sessionType: string; - judge?: { name: string; userId: string }; - formattedNoticeIssuedDate: string; - sessionStatus: string; -}; - -type TrialSessionWeek = { - sessionWeekStartDate: string; - formattedSessionWeekStartDate: string; -}; - -export function isTrialSessionRow(item: any): item is TrialSessionRow { - return !!item?.trialSessionId; -} - -export function isTrialSessionWeek(item: any): item is TrialSessionWeek { - return !!item?.sessionWeekStartDate; -} - const formatTrialSessions = ({ judgeAssociatedToUser, trialSessions, @@ -201,3 +171,31 @@ const formatTrialSessions = ({ return trialSessionWithStartWeeks; }; + +type TrialSessionRow = { + trialSessionId: string; + showAlertForNOTTReminder: boolean; + alertMessageForNOTT: string; + formattedStartDate: string; //MM/DD/YYYY + formattedEstimatedEndDate: string; + swingSession: boolean; + userIsAssignedToSession: boolean; + trialLocation: string; + proceedingType: string; + startDate: string; // ISO format + sessionType: string; + judge?: { name: string; userId: string }; + formattedNoticeIssuedDate: string; + sessionStatus: string; +}; +export function isTrialSessionRow(item: any): item is TrialSessionRow { + return !!item?.trialSessionId; +} + +type TrialSessionWeek = { + sessionWeekStartDate: string; + formattedSessionWeekStartDate: string; +}; +export function isTrialSessionWeek(item: any): item is TrialSessionWeek { + return !!item?.sessionWeekStartDate; +} From c77edccab121ed8e69fe1555f07938655cc2da60 Mon Sep 17 00:00:00 2001 From: Zachary Rogers Date: Tue, 3 Sep 2024 13:06:26 -0700 Subject: [PATCH 09/59] 10409: Update Default state of filters --- web-client/src/presenter/state/trialSessionsPageState.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web-client/src/presenter/state/trialSessionsPageState.ts b/web-client/src/presenter/state/trialSessionsPageState.ts index 1643371d0bc..f0c77f51ae2 100644 --- a/web-client/src/presenter/state/trialSessionsPageState.ts +++ b/web-client/src/presenter/state/trialSessionsPageState.ts @@ -5,7 +5,7 @@ const filters: TrialSessionsFilters = { currentTab: 'calendared' as 'calendared' | 'new', judgeId: 'All', proceedingType: 'All' as TrialSessionProceedingType, - sessionStatus: 'All', + sessionStatus: 'Open', sessionType: 'All', trialLocation: 'All', }; From 3b49cd6d38b99bd7ed3e8521330c374a0555673e Mon Sep 17 00:00:00 2001 From: Zachary Rogers Date: Tue, 3 Sep 2024 15:35:41 -0700 Subject: [PATCH 10/59] 10409 fix radio buttons --- .../src/views/TrialSessions/TrialSessions.tsx | 130 +++++++++--------- 1 file changed, 67 insertions(+), 63 deletions(-) diff --git a/web-client/src/views/TrialSessions/TrialSessions.tsx b/web-client/src/views/TrialSessions/TrialSessions.tsx index 880c87f4816..8ab91648e5e 100644 --- a/web-client/src/views/TrialSessions/TrialSessions.tsx +++ b/web-client/src/views/TrialSessions/TrialSessions.tsx @@ -97,69 +97,73 @@ const TrialSessionFilters = connect( <>
{trialSessionsHelper.showSessionStatus && ( -
- Session Status - { - setTrialSessionsFiltersSequence({ - sessionStatus: e.target.value, - }); - }} - /> - - { - setTrialSessionsFiltersSequence({ - sessionStatus: e.target.value, - }); - }} - /> - - { - setTrialSessionsFiltersSequence({ - sessionStatus: e.target.value, - }); - }} - /> - -
+
+
+ + Session Status + + { + setTrialSessionsFiltersSequence({ + sessionStatus: e.target.value, + }); + }} + /> + + { + setTrialSessionsFiltersSequence({ + sessionStatus: e.target.value, + }); + }} + /> + + { + setTrialSessionsFiltersSequence({ + sessionStatus: e.target.value, + }); + }} + /> + +
+
)}
From 16580d6b0398b51c5aee0cab26fb90f7a4000070 Mon Sep 17 00:00:00 2001 From: Javis Sullivan Date: Wed, 4 Sep 2024 11:10:31 -0400 Subject: [PATCH 11/59] 10409 fix setTrialSessionsFiltersActions test --- .../setTrialSessionsFiltersAction.test.ts | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/web-client/src/presenter/actions/TrialSession/setTrialSessionsFiltersAction.test.ts b/web-client/src/presenter/actions/TrialSession/setTrialSessionsFiltersAction.test.ts index dc70b6861ae..130c782be17 100644 --- a/web-client/src/presenter/actions/TrialSession/setTrialSessionsFiltersAction.test.ts +++ b/web-client/src/presenter/actions/TrialSession/setTrialSessionsFiltersAction.test.ts @@ -1,23 +1,16 @@ -import { presenter } from '../../presenter-mock'; import { runAction } from '@web-client/presenter/test.cerebral'; import { setTrialSessionsFiltersAction } from './setTrialSessionsFiltersAction'; describe('setTrialSessionsFiltersAction', () => { it('call the use case to get the eligible cases', async () => { const result = await runAction(setTrialSessionsFiltersAction, { - modules: { - presenter, - }, props: { - query: { - trialLocation: 'Baton Rouge, Louisiana', - trialSessionId: '123', - }, + trialLocation: 'Baton Rouge, Louisiana', }, - state: { screenMetadata: {} }, - }); - expect(result.state.screenMetadata.trialSessionFilters).toEqual({ - trialLocation: 'Baton Rouge, Louisiana', }); + + expect(result.state.trialSessionsPage.filters.trialLocation).toEqual( + 'Baton Rouge, Louisiana', + ); }); }); From a52ecfd69ea18313a7a861e2e2a691201a386537 Mon Sep 17 00:00:00 2001 From: Javis Sullivan Date: Thu, 5 Sep 2024 11:13:39 -0400 Subject: [PATCH 12/59] 10409: fix some tests, wip still figuring out purpose of other legacy tests --- .../computeds/trialSessionsHelper.test.ts | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/web-client/src/presenter/computeds/trialSessionsHelper.test.ts b/web-client/src/presenter/computeds/trialSessionsHelper.test.ts index 025c74c8e6c..c67d57abf51 100644 --- a/web-client/src/presenter/computeds/trialSessionsHelper.test.ts +++ b/web-client/src/presenter/computeds/trialSessionsHelper.test.ts @@ -262,11 +262,6 @@ describe('trialSessionsHelper', () => { it('returns only non-legacy judges when state.currentViewMetadata.trialSessions.tab is Open', () => { const result = runCompute(trialSessionsHelper, { state: { - currentViewMetadata: { - trialSessions: { - tab: 'open', - }, - }, judges: [ { name: 'I am not a legacy judge part 2', role: ROLES.judge }, ], @@ -275,6 +270,7 @@ describe('trialSessionsHelper', () => { { name: 'I am a legacy judge', role: ROLES.legacyJudge }, ], permissions: getUserPermissions(docketClerk1User), + trialSessionsPage: { trialSessions: [] }, }, }); @@ -412,12 +408,8 @@ describe('trialSessionsHelper', () => { it('should return showNewTrialSession as true when current user has CREATE_TRIAL_SESSION permission', () => { const result = runCompute(trialSessionsHelper, { state: { - currentViewMetadata: { - trialSessions: { - tab: 'open', - }, - }, permissions: getUserPermissions(docketClerk1User), + trialSessionsPage: { trialSessions: [] }, }, }); @@ -427,12 +419,8 @@ describe('trialSessionsHelper', () => { it('should return showNewTrialSession as false when current user does not have CREATE_TRIAL_SESSION permission', () => { const result = runCompute(trialSessionsHelper, { state: { - currentViewMetadata: { - trialSessions: { - tab: 'open', - }, - }, permissions: getUserPermissions(judgeUser), + trialSessionsPage: { trialSessions: [] }, }, }); From df63eddd82acd2140875b7498090aaf321c62bf5 Mon Sep 17 00:00:00 2001 From: Javis Sullivan Date: Thu, 5 Sep 2024 13:00:35 -0400 Subject: [PATCH 13/59] 10409 fix trialSessionsHelper.test.ts tests --- .../computeds/trialSessionsHelper.test.ts | 347 +++--------------- 1 file changed, 44 insertions(+), 303 deletions(-) diff --git a/web-client/src/presenter/computeds/trialSessionsHelper.test.ts b/web-client/src/presenter/computeds/trialSessionsHelper.test.ts index c67d57abf51..3c1d0178b50 100644 --- a/web-client/src/presenter/computeds/trialSessionsHelper.test.ts +++ b/web-client/src/presenter/computeds/trialSessionsHelper.test.ts @@ -1,6 +1,8 @@ import { ROLES } from '../../../../shared/src/business/entities/EntityConstants'; +import { cloneDeep } from 'lodash'; import { docketClerk1User, judgeUser } from '@shared/test/mockUsers'; import { getUserPermissions } from '@shared/authorization/getUserPermissions'; +import { initialTrialSessionPageState } from '../state/trialSessionsPageState'; import { runCompute } from '@web-client/presenter/test.cerebral'; import { trialSessionsHelper as trialSessionsHelperComputed } from './trialSessionsHelper'; import { withAppContextDecorator } from '../../withAppContext'; @@ -10,61 +12,31 @@ const trialSessionsHelper = withAppContextDecorator( ); describe('trialSessionsHelper', () => { - describe('showNoticeIssued', () => { - it('should show the Notice Issued column for `open` sessions', () => { - const result = runCompute(trialSessionsHelper, { - state: { - currentViewMetadata: { - trialSessions: { - tab: 'open', - }, - }, - permissions: getUserPermissions(docketClerk1User), - }, - }); - - expect(result.showNoticeIssued).toEqual(true); - }); - - it('should NOT show the Notice Issued column for `new` sessions', () => { - const result = runCompute(trialSessionsHelper, { - state: { - currentViewMetadata: { - trialSessions: { - tab: 'new', - }, - }, - permissions: getUserPermissions(docketClerk1User), - }, - }); + let trialSessionsPageState: typeof initialTrialSessionPageState; + beforeEach(() => { + trialSessionsPageState = cloneDeep(initialTrialSessionPageState); + }); - expect(result.showNoticeIssued).toEqual(false); - }); + describe('showNoticeIssued', () => { + it('should show the Notice Issued column when on the calendared tab', () => { + trialSessionsPageState.filters.currentTab = 'calendared'; - it('should NOT show the Notice Issued column for `closed` sessions', () => { const result = runCompute(trialSessionsHelper, { state: { - currentViewMetadata: { - trialSessions: { - tab: 'closed', - }, - }, permissions: getUserPermissions(docketClerk1User), + trialSessionsPage: trialSessionsPageState, }, }); - expect(result.showNoticeIssued).toEqual(false); + expect(result.showNoticeIssued).toEqual(true); }); - it('should NOT show the Notice Issued column for `all` sessions', () => { + it('should NOT show the Notice Issued column when on the new tab', () => { + trialSessionsPageState.filters.currentTab = 'new'; const result = runCompute(trialSessionsHelper, { state: { - currentViewMetadata: { - trialSessions: { - tab: 'all', - }, - }, permissions: getUserPermissions(docketClerk1User), + trialSessionsPage: trialSessionsPageState, }, }); @@ -73,60 +45,26 @@ describe('trialSessionsHelper', () => { }); describe('showSessionStatus', () => { - it('should show the Session Status column for `all` sessions', () => { - const result = runCompute(trialSessionsHelper, { - state: { - currentViewMetadata: { - trialSessions: { - tab: 'all', - }, - }, - permissions: getUserPermissions(docketClerk1User), - }, - }); + it('should show the Session Status column when on the `calendared` tab', () => { + trialSessionsPageState.filters.currentTab = 'calendared'; - expect(result.showSessionStatus).toEqual(true); - }); - - it('should NOT show the Session Status column for `new` sessions', () => { const result = runCompute(trialSessionsHelper, { state: { - currentViewMetadata: { - trialSessions: { - tab: 'new', - }, - }, permissions: getUserPermissions(docketClerk1User), + trialSessionsPage: trialSessionsPageState, }, }); - expect(result.showSessionStatus).toEqual(false); + expect(result.showSessionStatus).toEqual(true); }); - it('should NOT show the Session Status column for `open` sessions', () => { - const result = runCompute(trialSessionsHelper, { - state: { - currentViewMetadata: { - trialSessions: { - tab: 'open', - }, - }, - permissions: getUserPermissions(docketClerk1User), - }, - }); + it('should NOT show the Session Status column when on the `new` tab', () => { + trialSessionsPageState.filters.currentTab = 'new'; - expect(result.showSessionStatus).toEqual(false); - }); - - it('should NOT show the Session Status column for `closed` sessions', () => { const result = runCompute(trialSessionsHelper, { state: { - currentViewMetadata: { - trialSessions: { - tab: 'closed', - }, - }, permissions: getUserPermissions(docketClerk1User), + trialSessionsPage: trialSessionsPageState, }, }); @@ -134,209 +72,39 @@ describe('trialSessionsHelper', () => { }); }); - describe('additionalColumnsShown', () => { - it('should show 0 additional table columns for `new` sessions', () => { - const result = runCompute(trialSessionsHelper, { - state: { - currentViewMetadata: { - trialSessions: { - tab: 'new', - }, - }, - permissions: getUserPermissions(docketClerk1User), - }, - }); - - expect(result.additionalColumnsShown).toEqual(0); - }); - - it('should show 0 additional table columns for `closed` sessions', () => { - const result = runCompute(trialSessionsHelper, { - state: { - currentViewMetadata: { - trialSessions: { - tab: 'closed', - }, - }, - permissions: getUserPermissions(docketClerk1User), - }, - }); - - expect(result.additionalColumnsShown).toEqual(0); - }); - - it('should show 1 additional table column for `open` sessions', () => { - const result = runCompute(trialSessionsHelper, { - state: { - currentViewMetadata: { - trialSessions: { - tab: 'open', - }, - }, - permissions: getUserPermissions(docketClerk1User), - }, - }); - - expect(result.additionalColumnsShown).toEqual(1); - }); - - it('should show 1 additional table column for `all` sessions', () => { - const result = runCompute(trialSessionsHelper, { - state: { - currentViewMetadata: { - trialSessions: { - tab: 'all', - }, - }, - permissions: getUserPermissions(docketClerk1User), - }, - }); - - expect(result.additionalColumnsShown).toEqual(1); - }); - }); - describe('showUnassignedJudgeFilter', () => { - it('should show the `unassigned` judge filter for `new` sessions', () => { - const result = runCompute(trialSessionsHelper, { - state: { - currentViewMetadata: { - trialSessions: { - tab: 'new', - }, - }, - permissions: getUserPermissions(docketClerk1User), - }, - }); - - expect(result.showUnassignedJudgeFilter).toBeTruthy(); - }); + it('should show the `unassigned` judge filter when on the new tab', () => { + trialSessionsPageState.filters.currentTab = 'new'; - it('should NOT show the `unassigned` judge filter for `open` sessions', () => { const result = runCompute(trialSessionsHelper, { state: { - currentViewMetadata: { - trialSessions: { - tab: 'open', - }, - }, permissions: getUserPermissions(docketClerk1User), + trialSessionsPage: trialSessionsPageState, }, }); - expect(result.showUnassignedJudgeFilter).toBeFalsy(); + expect(result.showUnassignedJudgeFilter).toBeTruthy(); }); - it('should NOT show the `unassigned` judge filter for `closed` sessions', () => { - const result = runCompute(trialSessionsHelper, { - state: { - currentViewMetadata: { - trialSessions: { - tab: 'close', - }, - }, - permissions: getUserPermissions(docketClerk1User), - }, - }); + it('should show the `unassigned` judge filter when on the calendared tab', () => { + trialSessionsPageState.filters.currentTab = 'calendared'; - expect(result.showUnassignedJudgeFilter).toBeFalsy(); - }); - - it('should NOT show the `unassigned` judge filter for `all` sessions', () => { const result = runCompute(trialSessionsHelper, { state: { - currentViewMetadata: { - trialSessions: { - tab: 'all', - }, - }, permissions: getUserPermissions(docketClerk1User), + trialSessionsPage: trialSessionsPageState, }, }); - expect(result.showUnassignedJudgeFilter).toBeFalsy(); + expect(result.showUnassignedJudgeFilter).toEqual(false); }); }); describe('trialSessionJudges', () => { - it('returns only non-legacy judges when state.currentViewMetadata.trialSessions.tab is Open', () => { - const result = runCompute(trialSessionsHelper, { - state: { - judges: [ - { name: 'I am not a legacy judge part 2', role: ROLES.judge }, - ], - legacyAndCurrentJudges: [ - { name: 'I am not a legacy judge', role: ROLES.judge }, - { name: 'I am a legacy judge', role: ROLES.legacyJudge }, - ], - permissions: getUserPermissions(docketClerk1User), - trialSessionsPage: { trialSessions: [] }, - }, - }); - - expect(result.trialSessionJudges).toMatchObject( - expect.arrayContaining([ - expect.objectContaining({ - name: 'I am not a legacy judge part 2', - role: ROLES.judge, - }), - ]), - ); - expect(result.trialSessionJudges).not.toMatchObject( - expect.arrayContaining([ - expect.objectContaining({ - name: 'I am a legacy judge', - role: ROLES.legacyJudge, - }), - ]), - ); - }); - - it('returns only non-legacy judges when state.currentViewMetadata.trialSessions.tab is New', () => { - const result = runCompute(trialSessionsHelper, { - state: { - currentViewMetadata: { - trialSessions: { - tab: 'new', - }, - }, - judges: [ - { name: 'I am not a legacy judge part 2', role: ROLES.judge }, - ], - legacyAndCurrentJudges: [ - { name: 'I am not a legacy judge', role: ROLES.judge }, - { name: 'I am a legacy judge', role: ROLES.legacyJudge }, - ], - permissions: getUserPermissions(docketClerk1User), - }, - }); - - expect(result.trialSessionJudges).toMatchObject( - expect.arrayContaining([ - expect.objectContaining({ - name: 'I am not a legacy judge part 2', - role: ROLES.judge, - }), - ]), - ); - expect(result.trialSessionJudges).not.toMatchObject( - expect.arrayContaining([ - expect.objectContaining({ - name: 'I am a legacy judge', - role: ROLES.legacyJudge, - }), - ]), - ); - }); - - it('returns all current and legacy judges when state.currentViewMetadata.trialSessions.tab is Closed', () => { + it('returns all current and legacy judges when the current tab is calendared', () => { + trialSessionsPageState.filters.currentTab = 'calendared'; const result = runCompute(trialSessionsHelper, { state: { - currentViewMetadata: { - trialSessions: { - tab: 'closed', - }, - }, judges: [ { name: 'I am not a legacy judge part 2', role: ROLES.judge }, ], @@ -345,35 +113,20 @@ describe('trialSessionsHelper', () => { { name: 'I am a legacy judge', role: ROLES.legacyJudge }, ], permissions: getUserPermissions(docketClerk1User), + trialSessionsPage: trialSessionsPageState, }, }); - expect(result.trialSessionJudges).toMatchObject( - expect.arrayContaining([ - expect.objectContaining({ - name: 'I am not a legacy judge', - role: ROLES.judge, - }), - ]), - ); - expect(result.trialSessionJudges).toMatchObject( - expect.arrayContaining([ - expect.objectContaining({ - name: 'I am a legacy judge', - role: ROLES.legacyJudge, - }), - ]), - ); + expect(result.trialSessionJudges).toEqual([ + { name: 'I am not a legacy judge', role: ROLES.judge }, + { name: 'I am a legacy judge', role: ROLES.legacyJudge }, + ]); }); - it('returns all current and legacy judges when state.currentViewMetadata.trialSessions.tab is All', () => { + it('returns only non-legacy judges when the current tab is new', () => { + trialSessionsPageState.filters.currentTab = 'new'; const result = runCompute(trialSessionsHelper, { state: { - currentViewMetadata: { - trialSessions: { - tab: 'all', - }, - }, judges: [ { name: 'I am not a legacy judge part 2', role: ROLES.judge }, ], @@ -382,25 +135,13 @@ describe('trialSessionsHelper', () => { { name: 'I am a legacy judge', role: ROLES.legacyJudge }, ], permissions: getUserPermissions(docketClerk1User), + trialSessionsPage: trialSessionsPageState, }, }); - expect(result.trialSessionJudges).toMatchObject( - expect.arrayContaining([ - expect.objectContaining({ - name: 'I am not a legacy judge', - role: ROLES.judge, - }), - ]), - ); - expect(result.trialSessionJudges).toMatchObject( - expect.arrayContaining([ - expect.objectContaining({ - name: 'I am a legacy judge', - role: ROLES.legacyJudge, - }), - ]), - ); + expect(result.trialSessionJudges).toEqual([ + { name: 'I am not a legacy judge part 2', role: ROLES.judge }, + ]); }); }); @@ -409,7 +150,7 @@ describe('trialSessionsHelper', () => { const result = runCompute(trialSessionsHelper, { state: { permissions: getUserPermissions(docketClerk1User), - trialSessionsPage: { trialSessions: [] }, + trialSessionsPage: trialSessionsPageState, }, }); @@ -420,7 +161,7 @@ describe('trialSessionsHelper', () => { const result = runCompute(trialSessionsHelper, { state: { permissions: getUserPermissions(judgeUser), - trialSessionsPage: { trialSessions: [] }, + trialSessionsPage: trialSessionsPageState, }, }); From de7c984b8950d1f33d44d6213a82efa363cea3c1 Mon Sep 17 00:00:00 2001 From: Javis Sullivan Date: Thu, 5 Sep 2024 14:04:02 -0400 Subject: [PATCH 14/59] 10409 add some tests for new table functionality --- .../computeds/trialSessionsHelper.test.ts | 121 +++++++++++++++++- 1 file changed, 119 insertions(+), 2 deletions(-) diff --git a/web-client/src/presenter/computeds/trialSessionsHelper.test.ts b/web-client/src/presenter/computeds/trialSessionsHelper.test.ts index 3c1d0178b50..a5567f3574c 100644 --- a/web-client/src/presenter/computeds/trialSessionsHelper.test.ts +++ b/web-client/src/presenter/computeds/trialSessionsHelper.test.ts @@ -1,10 +1,17 @@ -import { ROLES } from '../../../../shared/src/business/entities/EntityConstants'; +import { + ROLES, + TRIAL_SESSION_SCOPE_TYPES, +} from '../../../../shared/src/business/entities/EntityConstants'; +import { TrialSessionInfoDTO } from '@shared/business/dto/trialSessions/TrialSessionInfoDTO'; import { cloneDeep } from 'lodash'; import { docketClerk1User, judgeUser } from '@shared/test/mockUsers'; import { getUserPermissions } from '@shared/authorization/getUserPermissions'; import { initialTrialSessionPageState } from '../state/trialSessionsPageState'; +import { + isTrialSessionRow, + trialSessionsHelper as trialSessionsHelperComputed, +} from './trialSessionsHelper'; import { runCompute } from '@web-client/presenter/test.cerebral'; -import { trialSessionsHelper as trialSessionsHelperComputed } from './trialSessionsHelper'; import { withAppContextDecorator } from '../../withAppContext'; const trialSessionsHelper = withAppContextDecorator( @@ -13,8 +20,36 @@ const trialSessionsHelper = withAppContextDecorator( describe('trialSessionsHelper', () => { let trialSessionsPageState: typeof initialTrialSessionPageState; + let trialSession1: TrialSessionInfoDTO; + let trialSession2: TrialSessionInfoDTO; beforeEach(() => { trialSessionsPageState = cloneDeep(initialTrialSessionPageState); + trialSession1 = { + isCalendared: true, + judge: { name: 'howdy', userId: '1' }, + proceedingType: 'Remote', + sessionScope: TRIAL_SESSION_SCOPE_TYPES.locationBased, + sessionStatus: 'Open', + sessionType: 'Regular', + startDate: '2022-03-01T21:00:00.000Z', + term: 'Winter', + termYear: '2022', + trialLocation: 'Boise', + trialSessionId: '294038', + }; + trialSession2 = { + isCalendared: true, + judge: { name: 'howdy', userId: '2' }, + proceedingType: 'Remote', + sessionScope: TRIAL_SESSION_SCOPE_TYPES.locationBased, + sessionStatus: 'Open', + sessionType: 'Regular', + startDate: '2022-03-01T21:00:00.000Z', + term: 'Winter', + termYear: '2022', + trialLocation: 'Boise', + trialSessionId: '392810', + }; }); describe('showNoticeIssued', () => { @@ -168,4 +203,86 @@ describe('trialSessionsHelper', () => { expect(result.showNewTrialSession).toEqual(false); }); }); + + describe('trialSessionRows', () => { + describe('filters', () => { + it('should filter trial sessions by judge', () => { + trialSession1.judge!.userId = '1'; + trialSession2.judge!.userId = '2'; + trialSessionsPageState.trialSessions = [trialSession1, trialSession2]; + trialSessionsPageState.filters.judgeId = '1'; + + const result = runCompute(trialSessionsHelper, { + state: { + permissions: getUserPermissions(docketClerk1User), + trialSessionsPage: trialSessionsPageState, + }, + }); + + const trialSessionsOnly = + result.trialSessionRows.filter(isTrialSessionRow); + expect(trialSessionsOnly.length).toEqual(1); + }); + + it('should not filter trial sessions by judge when judge filter is All', () => { + trialSessionsPageState.trialSessions = [trialSession1, trialSession2]; + trialSessionsPageState.filters.judgeId = 'All'; + + const result = runCompute(trialSessionsHelper, { + state: { + permissions: getUserPermissions(docketClerk1User), + trialSessionsPage: trialSessionsPageState, + }, + }); + + const trialSessionsOnly = + result.trialSessionRows.filter(isTrialSessionRow); + expect(trialSessionsOnly.length).toEqual(2); + }); + }); + describe('formatting', () => { + it('sets userIsAssignedToSession false for all sessions if there is no associated judgeUser', () => { + trialSessionsPageState.trialSessions = [trialSession1, trialSession2]; + + const result = runCompute(trialSessionsHelper, { + state: { + judgeUser: {}, + permissions: getUserPermissions(docketClerk1User), + trialSessionsPage: trialSessionsPageState, + }, + }); + + const trialSessionsOnly = + result.trialSessionRows.filter(isTrialSessionRow); + trialSessionsOnly.forEach(t => { + expect(t.userIsAssignedToSession).toEqual(false); + }); + }); + it('sets userIsAssignedToSession true for all sessions the judge user is assigned to', () => { + trialSession1.judge!.userId = '1'; + trialSession2.judge!.userId = '2'; + trialSessionsPageState.trialSessions = [trialSession1, trialSession2]; + + const result = runCompute(trialSessionsHelper, { + state: { + judgeUser: { + userId: '1', + }, + permissions: getUserPermissions(docketClerk1User), + trialSessionsPage: trialSessionsPageState, + }, + }); + + const trialSessionsOnly = + result.trialSessionRows.filter(isTrialSessionRow); + trialSessionsOnly.forEach(t => { + if (t.trialSessionId === trialSession1.trialSessionId) { + expect(t.userIsAssignedToSession).toEqual(true); + } else { + expect(t.userIsAssignedToSession).toEqual(false); + } + }); + }); + }); + }); }); From a6218f85ec8a86602c11aebdc9d72b24fb566c85 Mon Sep 17 00:00:00 2001 From: Zachary Rogers Date: Thu, 5 Sep 2024 12:34:12 -0700 Subject: [PATCH 15/59] 10409: Remove unused --- .../src/presenter/computeds/formattedTrialSessions.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/web-client/src/presenter/computeds/formattedTrialSessions.ts b/web-client/src/presenter/computeds/formattedTrialSessions.ts index e33ec8d5669..b36acdb161f 100644 --- a/web-client/src/presenter/computeds/formattedTrialSessions.ts +++ b/web-client/src/presenter/computeds/formattedTrialSessions.ts @@ -181,7 +181,11 @@ const sortSessionsByTerm = ({ export const formattedTrialSessions = ( get: Get, applicationContext: ClientApplicationContext, -): any => { +): { + sessionsByTerm: any[]; + showSwingSessionList: boolean; + showSwingSessionOption: boolean; +} => { const judgeId = get(state.judgeUser.userId); const currentTrialSessionId = get(state.trialSession.trialSessionId); const currentUser = get(state.user); @@ -249,8 +253,6 @@ export const formattedTrialSessions = ( } return { - filteredTrialSessions: filterFormattedSessionsByStatus(formattedSessions), - formattedSessions, sessionsByTerm, showSwingSessionList: get(state.form.swingSession), showSwingSessionOption: sessionsByTerm.length > 0, From fba167287cf95db8e6b248bc779e58a482d63e56 Mon Sep 17 00:00:00 2001 From: Zachary Rogers Date: Thu, 5 Sep 2024 13:53:25 -0700 Subject: [PATCH 16/59] 10409: Add tests for filtering trial sessions --- .../computeds/trialSessionsHelper.test.ts | 159 ++++++++++++++++++ .../computeds/trialSessionsHelper.ts | 5 - 2 files changed, 159 insertions(+), 5 deletions(-) diff --git a/web-client/src/presenter/computeds/trialSessionsHelper.test.ts b/web-client/src/presenter/computeds/trialSessionsHelper.test.ts index a5567f3574c..3caa8da55aa 100644 --- a/web-client/src/presenter/computeds/trialSessionsHelper.test.ts +++ b/web-client/src/presenter/computeds/trialSessionsHelper.test.ts @@ -1,5 +1,8 @@ import { ROLES, + SESSION_STATUS_TYPES, + SESSION_TYPES, + TRIAL_SESSION_PROCEEDING_TYPES, TRIAL_SESSION_SCOPE_TYPES, } from '../../../../shared/src/business/entities/EntityConstants'; import { TrialSessionInfoDTO } from '@shared/business/dto/trialSessions/TrialSessionInfoDTO'; @@ -239,6 +242,162 @@ describe('trialSessionsHelper', () => { result.trialSessionRows.filter(isTrialSessionRow); expect(trialSessionsOnly.length).toEqual(2); }); + + it('should show open and closed trial sessions when the current tab is calendared', () => { + trialSession1.isCalendared = false; + trialSession2.isCalendared = true; + trialSession2.sessionStatus = SESSION_STATUS_TYPES.open; + trialSessionsPageState.trialSessions = [trialSession1, trialSession2]; + + const result = runCompute(trialSessionsHelper, { + state: { + permissions: getUserPermissions(docketClerk1User), + trialSessionsPage: trialSessionsPageState, + }, + }); + + const trialSessionsOnly = + result.trialSessionRows.filter(isTrialSessionRow); + + expect(trialSessionsOnly[0].trialSessionId).toEqual( + trialSession2.trialSessionId, + ); + }); + + it('should show remote proceeding types when proceeding type is remote', () => { + trialSession1.proceedingType = TRIAL_SESSION_PROCEEDING_TYPES.remote; + trialSession2.proceedingType = TRIAL_SESSION_PROCEEDING_TYPES.inPerson; + trialSessionsPageState.trialSessions = [trialSession1, trialSession2]; + + const result = runCompute(trialSessionsHelper, { + state: { + permissions: getUserPermissions(docketClerk1User), + trialSessionsPage: trialSessionsPageState, + }, + }); + + const trialSessionsOnly = + result.trialSessionRows.filter(isTrialSessionRow); + + expect(trialSessionsOnly[0].trialSessionId).toEqual( + trialSession1.trialSessionId, + ); + }); + + it('should show open trial sessions when session status filter is open', () => { + trialSession1.sessionStatus = SESSION_STATUS_TYPES.open; + trialSession1.isCalendared = true; + trialSession2.sessionStatus = SESSION_STATUS_TYPES.closed; + trialSession2.isCalendared = true; + trialSessionsPageState.filters.sessionStatus = + SESSION_STATUS_TYPES.open; + trialSessionsPageState.trialSessions = [trialSession1, trialSession2]; + + const result = runCompute(trialSessionsHelper, { + state: { + permissions: getUserPermissions(docketClerk1User), + trialSessionsPage: trialSessionsPageState, + }, + }); + + const trialSessionsOnly = + result.trialSessionRows.filter(isTrialSessionRow); + expect(trialSessionsOnly.length).toEqual(1); + expect(trialSessionsOnly[0].trialSessionId).toEqual( + trialSession1.trialSessionId, + ); + }); + + it('should show closed trial sessions when session status filter is closed', () => { + trialSession1.sessionStatus = SESSION_STATUS_TYPES.closed; + trialSession1.isCalendared = true; + trialSession2.sessionStatus = SESSION_STATUS_TYPES.open; + trialSession2.isCalendared = true; + trialSessionsPageState.filters.sessionStatus = + SESSION_STATUS_TYPES.closed; + trialSessionsPageState.trialSessions = [trialSession1, trialSession2]; + + const result = runCompute(trialSessionsHelper, { + state: { + permissions: getUserPermissions(docketClerk1User), + trialSessionsPage: trialSessionsPageState, + }, + }); + + const trialSessionsOnly = + result.trialSessionRows.filter(isTrialSessionRow); + expect(trialSessionsOnly.length).toEqual(1); + expect(trialSessionsOnly[0].trialSessionId).toEqual( + trialSession1.trialSessionId, + ); + }); + + it('should ignore session status filter when the current tab is new', () => { + trialSession1.sessionStatus = SESSION_STATUS_TYPES.closed; + trialSession1.isCalendared = true; + trialSession2.sessionStatus = SESSION_STATUS_TYPES.new; + trialSession2.isCalendared = false; + trialSessionsPageState.filters.sessionStatus = + SESSION_STATUS_TYPES.closed; + trialSessionsPageState.filters.currentTab = 'new'; + trialSessionsPageState.trialSessions = [trialSession1, trialSession2]; + + const result = runCompute(trialSessionsHelper, { + state: { + permissions: getUserPermissions(docketClerk1User), + trialSessionsPage: trialSessionsPageState, + }, + }); + + const trialSessionsOnly = + result.trialSessionRows.filter(isTrialSessionRow); + expect(trialSessionsOnly.length).toEqual(1); + expect(trialSessionsOnly[0].trialSessionId).toEqual( + trialSession2.trialSessionId, + ); + }); + + it('should show regular trial sessions when session type filter is regular', () => { + trialSession1.sessionType = SESSION_TYPES.regular; + trialSession2.sessionType = SESSION_TYPES.hybridSmall; + trialSessionsPageState.filters.sessionType = SESSION_TYPES.regular; + trialSessionsPageState.trialSessions = [trialSession1, trialSession2]; + + const result = runCompute(trialSessionsHelper, { + state: { + permissions: getUserPermissions(docketClerk1User), + trialSessionsPage: trialSessionsPageState, + }, + }); + + const trialSessionsOnly = + result.trialSessionRows.filter(isTrialSessionRow); + expect(trialSessionsOnly.length).toEqual(1); + expect(trialSessionsOnly[0].trialSessionId).toEqual( + trialSession1.trialSessionId, + ); + }); + + it('should show trial sessions in honolulu when trial sessions when trial location filter is honolulu', () => { + trialSession1.trialLocation = 'Honolulu, Hawaii'; + trialSession2.trialLocation = 'Jacksonville, Florida'; + trialSessionsPageState.filters.trialLocation = 'Honolulu, Hawaii'; + trialSessionsPageState.trialSessions = [trialSession1, trialSession2]; + + const result = runCompute(trialSessionsHelper, { + state: { + permissions: getUserPermissions(docketClerk1User), + trialSessionsPage: trialSessionsPageState, + }, + }); + + const trialSessionsOnly = + result.trialSessionRows.filter(isTrialSessionRow); + expect(trialSessionsOnly.length).toEqual(1); + expect(trialSessionsOnly[0].trialSessionId).toEqual( + trialSession1.trialSessionId, + ); + }); }); describe('formatting', () => { it('sets userIsAssignedToSession false for all sessions if there is no associated judgeUser', () => { diff --git a/web-client/src/presenter/computeds/trialSessionsHelper.ts b/web-client/src/presenter/computeds/trialSessionsHelper.ts index ebdc1e85347..c68fb57960c 100644 --- a/web-client/src/presenter/computeds/trialSessionsHelper.ts +++ b/web-client/src/presenter/computeds/trialSessionsHelper.ts @@ -63,11 +63,6 @@ export const trialSessionsHelper = ( return filters.trialLocation === trialSession.trialLocation; }) .sort((sessionA, sessionB) => { - if (sessionA.startDate === sessionB.startDate) { - const sessionATrialLocation = sessionA.trialLocation || ''; - const sessionBTrialLocation = sessionA.trialLocation || ''; - return sessionATrialLocation.localeCompare(sessionBTrialLocation); - } return sessionA.startDate.localeCompare(sessionB.startDate); }); From 1d781c6bf2f3e1912efebd592699f3894313ca09 Mon Sep 17 00:00:00 2001 From: Zachary Rogers Date: Thu, 5 Sep 2024 15:41:21 -0700 Subject: [PATCH 17/59] 10409: Move trial sessions filtering tests over to trialSessionsHelper --- ...ns.filterFormattedSessionsByStatus.test.ts | 81 ----- ...rmattedTrialSessions.formatSession.test.ts | 101 ------ .../computeds/formattedTrialSessions.test.ts | 326 +----------------- .../computeds/trialSessionsHelper.test.ts | 125 ++++++- 4 files changed, 126 insertions(+), 507 deletions(-) delete mode 100644 web-client/src/presenter/computeds/formattedTrialSessions.filterFormattedSessionsByStatus.test.ts delete mode 100644 web-client/src/presenter/computeds/formattedTrialSessions.formatSession.test.ts diff --git a/web-client/src/presenter/computeds/formattedTrialSessions.filterFormattedSessionsByStatus.test.ts b/web-client/src/presenter/computeds/formattedTrialSessions.filterFormattedSessionsByStatus.test.ts deleted file mode 100644 index 192a278a4e7..00000000000 --- a/web-client/src/presenter/computeds/formattedTrialSessions.filterFormattedSessionsByStatus.test.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { filterFormattedSessionsByStatus } from './formattedTrialSessions'; - -describe('formattedTrialSessions filterFormattedSessionsByStatus', () => { - let TRIAL_SESSIONS_LIST: any[] = []; - let trialTerms; - - beforeEach(() => { - TRIAL_SESSIONS_LIST = [ - { - caseOrder: [], - judge: { name: '1', userId: '1' }, - sessionStatus: 'Open', - startDate: '2019-11-25T15:00:00.000Z', - swingSession: true, - trialLocation: 'Hartford, Connecticut', - }, - { - caseOrder: [], - judge: { name: '2', userId: '2' }, - sessionStatus: 'New', - startDate: '2019-11-25T15:00:00.000Z', - swingSession: true, - trialClerk: { name: '10', userId: '10' }, - trialLocation: 'Knoxville, TN', - }, - { - caseOrder: [], - judge: { name: '3', userId: '3' }, - noticeIssuedDate: '2019-07-25T15:00:00.000Z', - sessionStatus: 'Closed', - startDate: '2019-11-27T15:00:00.000Z', - swingSession: true, - trialLocation: 'Jacksonville, FL', - }, - ]; - - trialTerms = [ - { - dateFormatted: 'October 1, 2022', - sessions: [TRIAL_SESSIONS_LIST[0]], - }, - { - dateFormatted: 'November 1, 2022', - sessions: [TRIAL_SESSIONS_LIST[1]], - }, - { - dateFormatted: 'December 1, 2022', - sessions: [TRIAL_SESSIONS_LIST[2]], - }, - ]; - }); - - it('filters closed cases when all trial session cases are inactive', () => { - const results = filterFormattedSessionsByStatus(trialTerms); - expect(results.Closed.length).toEqual(1); - }); - - it('filters open trial sessions', () => { - const results = filterFormattedSessionsByStatus(trialTerms); - expect(results.Open.length).toEqual(1); - }); - - it('filters new trial sessions', () => { - const results = filterFormattedSessionsByStatus(trialTerms); - expect(results.New.length).toEqual(1); - }); - - it('filters all trial sessions (returns everything) with the sessionStatus on the session', () => { - const results = filterFormattedSessionsByStatus(trialTerms); - - const getSessionCount = trialTermsList => { - let count = 0; - trialTermsList.forEach(term => (count += term.sessions.length)); - return count; - }; - - expect(results.All.length).toEqual(trialTerms.length); - expect(getSessionCount(results.All)).toEqual(getSessionCount(trialTerms)); - expect(results.All[0].sessions[0]).toHaveProperty('sessionStatus'); - }); -}); diff --git a/web-client/src/presenter/computeds/formattedTrialSessions.formatSession.test.ts b/web-client/src/presenter/computeds/formattedTrialSessions.formatSession.test.ts deleted file mode 100644 index b028396fd82..00000000000 --- a/web-client/src/presenter/computeds/formattedTrialSessions.formatSession.test.ts +++ /dev/null @@ -1,101 +0,0 @@ -import { - SESSION_TYPES, - TRIAL_SESSION_PROCEEDING_TYPES, -} from '../../../../shared/src/business/entities/EntityConstants'; -import { applicationContext } from '../../applicationContext'; -import { formatSession } from './formattedTrialSessions'; - -describe('formattedTrialSessions formatSession', () => { - const mockTrialSessions = [ - { - caseOrder: [], - isCalendared: true, - judge: { name: '3', userId: '3' }, - noticeIssuedDate: '2019-07-25T15:00:00.000Z', - proceedingType: TRIAL_SESSION_PROCEEDING_TYPES.inPerson, - sessionType: SESSION_TYPES.regular, - startDate: '2019-11-27T15:00:00.000Z', - swingSession: true, - term: 'Winter', - trialLocation: 'Jacksonville, FL', - }, - { - caseOrder: [], - estimatedEndDate: '2045-02-17T15:00:00.000Z', - judge: { name: '6', userId: '6' }, - proceedingType: TRIAL_SESSION_PROCEEDING_TYPES.inPerson, - sessionType: SESSION_TYPES.regular, - startDate: '2044-02-17T15:00:00.000Z', - swingSession: false, - term: 'Spring', - trialLocation: 'Jacksonville, FL', - }, - ]; - - it('formats trial sessions correctly selecting startOfWeek and formatting start date, startOfWeekSortable, and formattedNoticeIssued', () => { - const result = formatSession(mockTrialSessions[0], applicationContext); - expect(result).toMatchObject({ - formattedNoticeIssuedDate: '07/25/2019', - formattedStartDate: '11/27/19', - judge: { name: '3', userId: '3' }, - startDate: '2019-11-27T15:00:00.000Z', - startOfWeek: 'November 25, 2019', - startOfWeekSortable: '20191125', - }); - }); - - it('should format start date and estimated end date as "MM/DD/YYYY"', () => { - const result = formatSession(mockTrialSessions[1], applicationContext); - expect(result).toMatchObject({ - formattedEstimatedEndDate: '02/17/45', - formattedStartDate: '02/17/44', - }); - }); - - describe('NOTT reminder', () => { - it('should set showAlertForNOTTReminder to true when the alert has not been previously dismissed and isStartDateWithinNOTTReminderRange is true', () => { - const session = formatSession( - { - ...mockTrialSessions[0], - dismissedAlertForNOTT: false, - isStartDateWithinNOTTReminderRange: true, - thirtyDaysBeforeTrialFormatted: '2/2/2022', - }, - applicationContext, - ); - - expect(session.showAlertForNOTTReminder).toBe(true); - expect(session.alertMessageForNOTT).toEqual( - 'The 30-day notice is due by 2/2/2022', - ); - }); - - it('should set showAlertForNOTTReminder to false when the alert has been previously dismissed', () => { - const session = formatSession( - { - ...mockTrialSessions[0], - dismissedAlertForNOTT: true, - isStartDateWithinNOTTReminderRange: true, - }, - applicationContext, - ); - - expect(session.showAlertForNOTTReminder).toBe(false); - expect(session.alertMessageForNOTT).toBeUndefined(); - }); - - it('should set showAlertForNOTTReminder to false when isStartDateWithinNOTTReminderRange is false', () => { - const session = formatSession( - { - ...mockTrialSessions[0], - dismissedAlertForNOTT: true, - isStartDateWithinNOTTReminderRange: false, - }, - applicationContext, - ); - - expect(session.showAlertForNOTTReminder).toBe(false); - expect(session.alertMessageForNOTT).toBeUndefined(); - }); - }); -}); diff --git a/web-client/src/presenter/computeds/formattedTrialSessions.test.ts b/web-client/src/presenter/computeds/formattedTrialSessions.test.ts index c30830cd766..b205166b314 100644 --- a/web-client/src/presenter/computeds/formattedTrialSessions.test.ts +++ b/web-client/src/presenter/computeds/formattedTrialSessions.test.ts @@ -1,12 +1,11 @@ import { FORMATS, formatNow, - prepareDateFromString, } from '../../../../shared/src/business/utilities/DateHandler'; import { applicationContextForClient as applicationContext } from '@web-client/test/createClientTestApplicationContext'; import { formatTrialSessionDisplayOptions } from './addToTrialSessionModalHelper'; import { formattedTrialSessions as formattedTrialSessionsComputed } from './formattedTrialSessions'; -import { judgeUser, petitionsClerkUser } from '@shared/test/mockUsers'; +import { judgeUser } from '@shared/test/mockUsers'; import { runCompute } from '@web-client/presenter/test.cerebral'; import { withAppContextDecorator } from '../../withAppContext'; jest.mock('./addToTrialSessionModalHelper.ts'); @@ -24,17 +23,8 @@ const formattedTrialSessions = withAppContextDecorator( }, ); -const getStartOfWeek = date => { - return prepareDateFromString(date).startOf('week').toFormat('DDD'); -}; - let nextYear; -const testTrialClerkUser = { - role: ROLES.trialClerk, - userId: '10', -}; - const baseState = { constants: { USER_ROLES: ROLES }, judgeUser, @@ -160,110 +150,11 @@ describe('formattedTrialSessions', () => { }, ]; - formatTrialSessionDisplayOptions.mockImplementation(session => session); - }); - - it('does not error if user is undefined', () => { - let error; - try { - runCompute(formattedTrialSessions, { - state: { - ...baseState, - trialSessions: TRIAL_SESSIONS_LIST, - user: judgeUser, - }, - }); - } catch (err) { - error = err; - } - expect(error).toBeUndefined(); - }); - - it('groups trial sessions into arrays according to session weeks', () => { - const result = runCompute(formattedTrialSessions, { - state: { - ...baseState, - trialSessions: TRIAL_SESSIONS_LIST, - user: judgeUser, - }, - }); - - expect(result.filteredTrialSessions).toBeDefined(); - expect(result.formattedSessions.length).toBe(4); - expect(result.formattedSessions[0].dateFormatted).toEqual( - 'November 25, 2019', - ); - expect(result.formattedSessions[1].dateFormatted).toEqual( - getStartOfWeek(result.formattedSessions[1].sessions[0].startDate), + (formatTrialSessionDisplayOptions as jest.Mock).mockImplementation( + session => session, ); }); - it('should filter trial sessions by judge', () => { - const result = runCompute(formattedTrialSessions, { - state: { - ...baseState, - screenMetadata: { - trialSessionFilters: { judge: { userId: judgeUser.userId } }, - }, - trialSessions: TRIAL_SESSIONS_LIST, - user: judgeUser, - }, - }); - expect(result.formattedSessions.length).toBe(1); - }); - - it('should double filter trial sessions', () => { - const result = runCompute(formattedTrialSessions, { - state: { - ...baseState, - screenMetadata: { - trialSessionFilters: { - proceedingType: TRIAL_SESSION_PROCEEDING_TYPES.inPerson, - sessionType: SESSION_TYPES.regular, - }, - }, - trialSessions: TRIAL_SESSIONS_LIST, - user: judgeUser, - }, - }); - const flattenedSessions = result.formattedSessions.flatMap( - week => week.sessions, - ); - expect(flattenedSessions.length).toBe(5); - }); - - it('returns all trial sessions if judge userId trial session filter is an empty string', () => { - const result = runCompute(formattedTrialSessions, { - state: { - ...baseState, - screenMetadata: { trialSessionFilters: { judge: { userId: '' } } }, - trialSessions: TRIAL_SESSIONS_LIST, - user: judgeUser, - }, - }); - expect(result.formattedSessions.length).toBe(4); - }); - - it('does NOT return the unassigned judge filter on trial sessions tabs other than "new"', () => { - let result = runCompute(formattedTrialSessions, { - state: { - ...baseState, - currentViewMetadata: { - trialSessions: { - tab: 'open', - }, - }, - screenMetadata: { - trialSessionFilters: { judge: { userId: 'unassigned' } }, - }, - trialSessions: TRIAL_SESSIONS_LIST, - user: judgeUser, - }, - }); - - expect(result.formattedSessions.length).toBe(4); - }); - it('shows swing session option only if matching term and term year is found', () => { let form = { term: 'Winter', @@ -440,215 +331,4 @@ describe('formattedTrialSessions', () => { ), ).toBeUndefined(); }); - - it('sets userIsAssignedToSession false for all sessions if there is no associated judgeUser', () => { - const result = runCompute(formattedTrialSessions, { - state: { - ...baseState, - judgeUser: undefined, - trialSessions: TRIAL_SESSIONS_LIST, - user: petitionsClerkUser, - }, - }); - - expect(result.formattedSessions[0]).toMatchObject({ - dateFormatted: 'November 25, 2019', - sessions: [ - { - judge: { name: '5', userId: '5' }, - userIsAssignedToSession: false, - }, - { - judge: { name: judgeUser.name, userId: judgeUser.userId }, - userIsAssignedToSession: false, - }, - { - judge: { name: '2', userId: '2' }, - userIsAssignedToSession: false, - }, - { - judge: { name: '3', userId: '3' }, - userIsAssignedToSession: false, - }, - { - judge: { name: '4', userId: '4' }, - userIsAssignedToSession: false, - }, - ], - }); - - expect(result.formattedSessions[1]).toMatchObject({ - dateFormatted: getStartOfWeek( - result.formattedSessions[1].sessions[0].startDate, - ), - sessions: [ - { - judge: { name: '55', userId: '55' }, - userIsAssignedToSession: false, - }, - ], - }); - }); - - it('sets userIsAssignedToSession true for sessions the judge user is assigned to', () => { - const result = runCompute(formattedTrialSessions, { - state: { - ...baseState, - trialSessions: TRIAL_SESSIONS_LIST, - user: judgeUser, - }, - }); - expect(result.formattedSessions).toMatchObject([ - { - dateFormatted: 'November 25, 2019', - sessions: [ - { - judge: { name: '5', userId: '5' }, - userIsAssignedToSession: false, - }, - { - judge: { name: judgeUser.name, userId: judgeUser.userId }, - userIsAssignedToSession: true, - }, - { - judge: { name: '2', userId: '2' }, - userIsAssignedToSession: false, - }, - { - judge: { name: '3', userId: '3' }, - userIsAssignedToSession: false, - }, - { - judge: { name: '4', userId: '4' }, - userIsAssignedToSession: false, - }, - ], - }, - { - dateFormatted: getStartOfWeek( - result.formattedSessions[1].sessions[0].startDate, - ), - sessions: [ - { - judge: { name: '55', userId: '55' }, - userIsAssignedToSession: false, - }, - ], - }, - { - dateFormatted: 'November 23, 2020', - sessions: [ - { - judge: { name: '88', userId: '88' }, - userIsAssignedToSession: false, - }, - ], - }, - { - dateFormatted: 'February 17, 2025', - sessions: [ - { - caseOrder: [], - estimatedEndDate: '2045-02-17T15:00:00.000Z', - formattedEstimatedEndDate: '02/17/45', - formattedNoticeIssuedDate: '', - formattedStartDate: '02/17/25', - isCalendared: true, - judge: { name: '6', userId: '6' }, - proceedingType: 'In Person', - sessionStatus: 'Open', - sessionType: SESSION_TYPES.regular, - showAlertForNOTTReminder: undefined, - startDate: '2025-02-17T15:00:00.000Z', - startOfWeek: 'February 17, 2025', - startOfWeekSortable: '20250217', - swingSession: false, - term: 'Spring', - trialLocation: 'Jacksonville, FL', - userIsAssignedToSession: false, - }, - ], - }, - ]); - }); - - it('sets userIsAssignedToSession true for sessions the current trial clerk user is assigned to', () => { - const result = runCompute(formattedTrialSessions, { - state: { - ...baseState, - judgeUser: undefined, - trialSessions: TRIAL_SESSIONS_LIST, - user: testTrialClerkUser, - }, - }); - - expect(result.formattedSessions[0]).toMatchObject({ - dateFormatted: 'November 25, 2019', - sessions: [ - { - judge: { name: '5', userId: '5' }, - userIsAssignedToSession: false, - }, - { - judge: { name: judgeUser.name, userId: judgeUser.userId }, - userIsAssignedToSession: false, - }, - { - trialClerk: { name: '10', userId: '10' }, - userIsAssignedToSession: true, - }, - { - judge: { name: '3', userId: '3' }, - userIsAssignedToSession: false, - }, - { - judge: { name: '4', userId: '4' }, - userIsAssignedToSession: false, - }, - ], - }); - - expect(result.formattedSessions[1]).toMatchObject({ - dateFormatted: getStartOfWeek( - result.formattedSessions[1].sessions[0].startDate, - ), - sessions: [ - { - judge: { name: '55', userId: '55' }, - userIsAssignedToSession: false, - }, - ], - }); - }); - - it('sets userIsAssignedToSession false if the current user and session have no associated judge', () => { - const startDate = `${nextYear}-02-17T15:00:00.000Z`; - const result = runCompute(formattedTrialSessions, { - state: { - ...baseState, - judgeUser: undefined, - trialSessions: [ - { - caseOrder: [], - judge: undefined, - sessionStatus: 'Open', - startDate, - swingSession: false, - trialLocation: 'Jacksonville, FL', - }, - ], - user: petitionsClerkUser, - }, - }); - expect(result.formattedSessions).toMatchObject([ - { - dateFormatted: getStartOfWeek(startDate), - sessions: [ - { - userIsAssignedToSession: false, - }, - ], - }, - ]); - }); }); diff --git a/web-client/src/presenter/computeds/trialSessionsHelper.test.ts b/web-client/src/presenter/computeds/trialSessionsHelper.test.ts index 3caa8da55aa..50f0d892615 100644 --- a/web-client/src/presenter/computeds/trialSessionsHelper.test.ts +++ b/web-client/src/presenter/computeds/trialSessionsHelper.test.ts @@ -12,6 +12,7 @@ import { getUserPermissions } from '@shared/authorization/getUserPermissions'; import { initialTrialSessionPageState } from '../state/trialSessionsPageState'; import { isTrialSessionRow, + isTrialSessionWeek, trialSessionsHelper as trialSessionsHelperComputed, } from './trialSessionsHelper'; import { runCompute } from '@web-client/presenter/test.cerebral'; @@ -399,8 +400,31 @@ describe('trialSessionsHelper', () => { ); }); }); + describe('formatting', () => { - it('sets userIsAssignedToSession false for all sessions if there is no associated judgeUser', () => { + it('should format trialSessions startDate, endDate, noticeIssuedDate', () => { + trialSession1.noticeIssuedDate = '2020-05-03T21:00:00.000Z'; + trialSession1.startDate = '2020-05-03T21:00:00.000Z'; + trialSession1.estimatedEndDate = '2020-05-03T21:00:00.000Z'; + trialSessionsPageState.trialSessions = [trialSession1]; + + const result = runCompute(trialSessionsHelper, { + state: { + permissions: getUserPermissions(docketClerk1User), + trialSessionsPage: trialSessionsPageState, + }, + }); + + const trialSessionsOnly = + result.trialSessionRows.filter(isTrialSessionRow); + expect(trialSessionsOnly[0]).toMatchObject({ + formattedEstimatedEndDate: '05/03/20', + formattedNoticeIssuedDate: '05/03/2020', + formattedStartDate: '05/03/20', + }); + }); + + it('should set userIsAssignedToSession false for all sessions if there is no associated judgeUser', () => { trialSessionsPageState.trialSessions = [trialSession1, trialSession2]; const result = runCompute(trialSessionsHelper, { @@ -417,7 +441,8 @@ describe('trialSessionsHelper', () => { expect(t.userIsAssignedToSession).toEqual(false); }); }); - it('sets userIsAssignedToSession true for all sessions the judge user is assigned to', () => { + + it('should set userIsAssignedToSession true for all sessions the judge user is assigned to', () => { trialSession1.judge!.userId = '1'; trialSession2.judge!.userId = '2'; trialSessionsPageState.trialSessions = [trialSession1, trialSession2]; @@ -442,6 +467,102 @@ describe('trialSessionsHelper', () => { } }); }); + + it('should show an alertMessage for NOTT reminders when the user has not dismissed the alert and the start day is within the reminder range', () => { + trialSession1.dismissedAlertForNOTT = false; + trialSession1.isStartDateWithinNOTTReminderRange = true; + trialSession1.thirtyDaysBeforeTrialFormatted = '06/03/13'; + trialSessionsPageState.trialSessions = [trialSession1]; + + const result = runCompute(trialSessionsHelper, { + state: { + permissions: getUserPermissions(docketClerk1User), + trialSessionsPage: trialSessionsPageState, + }, + }); + + const trialSessionsOnly = + result.trialSessionRows.filter(isTrialSessionRow); + expect(trialSessionsOnly[0].alertMessageForNOTT).toEqual( + `The 30-day notice is due by ${trialSession1.thirtyDaysBeforeTrialFormatted}`, + ); + expect(trialSessionsOnly[0].showAlertForNOTTReminder).toEqual(true); + }); + }); + + describe('sorting', () => { + it('should order trial sessions by start date from oldest to newest', () => { + trialSession1.startDate = '2022-03-01T21:00:00.000Z'; + trialSession2.startDate = '2020-03-01T21:00:00.000Z'; + trialSessionsPageState.trialSessions = [trialSession1, trialSession2]; + + const result = runCompute(trialSessionsHelper, { + state: { + permissions: getUserPermissions(docketClerk1User), + trialSessionsPage: trialSessionsPageState, + }, + }); + + const trialSessionsOnly = + result.trialSessionRows.filter(isTrialSessionRow); + expect(trialSessionsOnly.length).toEqual(2); + expect(trialSessionsOnly[0].trialSessionId).toEqual( + trialSession2.trialSessionId, + ); + expect(trialSessionsOnly[1].trialSessionId).toEqual( + trialSession1.trialSessionId, + ); + }); + }); + + describe('trial session weeks', () => { + it('should insert one trialSessionWeek row when two trial sessions are within the same week(week starts on Monday EST)', () => { + trialSession1.startDate = '2024-09-03T21:00:00.000Z'; // A Tuesday + trialSession2.startDate = '2024-09-05T21:00:00.000Z'; // A Thursday + trialSessionsPageState.trialSessions = [trialSession1, trialSession2]; + + const result = runCompute(trialSessionsHelper, { + state: { + permissions: getUserPermissions(docketClerk1User), + trialSessionsPage: trialSessionsPageState, + }, + }); + + const trialSessionWeeks = + result.trialSessionRows.filter(isTrialSessionWeek); + expect(trialSessionWeeks).toEqual([ + { + formattedSessionWeekStartDate: 'September 2, 2024', + sessionWeekStartDate: '2024-09-02T04:00:00.000+00:00', + }, + ]); + }); + + it('should insert two trialSessionWeek rows when two trial sessions are not within the same week(week starts on Monday EST)', () => { + trialSession1.startDate = '2024-09-03T21:00:00.000Z'; // A Tuesday + trialSession2.startDate = '2024-09-12T21:00:00.000Z'; // A Thursday next week + trialSessionsPageState.trialSessions = [trialSession1, trialSession2]; + + const result = runCompute(trialSessionsHelper, { + state: { + permissions: getUserPermissions(docketClerk1User), + trialSessionsPage: trialSessionsPageState, + }, + }); + + const trialSessionWeeks = + result.trialSessionRows.filter(isTrialSessionWeek); + expect(trialSessionWeeks).toEqual([ + { + formattedSessionWeekStartDate: 'September 2, 2024', + sessionWeekStartDate: '2024-09-02T04:00:00.000+00:00', + }, + { + formattedSessionWeekStartDate: 'September 9, 2024', + sessionWeekStartDate: '2024-09-09T04:00:00.000+00:00', + }, + ]); + }); }); }); }); From 30579c3a79cbacb140f3571012376ecb89a29c6a Mon Sep 17 00:00:00 2001 From: Zachary Rogers Date: Thu, 5 Sep 2024 16:10:38 -0700 Subject: [PATCH 18/59] 10409: Add filtering for unassigned judges --- .../computeds/trialSessionsHelper.test.ts | 21 +++++++++++++++++++ .../computeds/trialSessionsHelper.ts | 1 + .../src/views/TrialSessions/TrialSessions.tsx | 9 ++++---- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/web-client/src/presenter/computeds/trialSessionsHelper.test.ts b/web-client/src/presenter/computeds/trialSessionsHelper.test.ts index 50f0d892615..b8f07bcc8b0 100644 --- a/web-client/src/presenter/computeds/trialSessionsHelper.test.ts +++ b/web-client/src/presenter/computeds/trialSessionsHelper.test.ts @@ -228,6 +228,27 @@ describe('trialSessionsHelper', () => { expect(trialSessionsOnly.length).toEqual(1); }); + it('should only show trial sessions who do not have a judge when the judge filter is "unassigned"', () => { + trialSession1.judge = undefined; + trialSession2.judge!.userId = '2'; + trialSessionsPageState.trialSessions = [trialSession1, trialSession2]; + trialSessionsPageState.filters.judgeId = 'unassigned'; + + const result = runCompute(trialSessionsHelper, { + state: { + permissions: getUserPermissions(docketClerk1User), + trialSessionsPage: trialSessionsPageState, + }, + }); + + const trialSessionsOnly = + result.trialSessionRows.filter(isTrialSessionRow); + expect(trialSessionsOnly.length).toEqual(1); + expect(trialSessionsOnly[0].trialSessionId).toEqual( + trialSession1.trialSessionId, + ); + }); + it('should not filter trial sessions by judge when judge filter is All', () => { trialSessionsPageState.trialSessions = [trialSession1, trialSession2]; trialSessionsPageState.filters.judgeId = 'All'; diff --git a/web-client/src/presenter/computeds/trialSessionsHelper.ts b/web-client/src/presenter/computeds/trialSessionsHelper.ts index c68fb57960c..aa7cd6a73f9 100644 --- a/web-client/src/presenter/computeds/trialSessionsHelper.ts +++ b/web-client/src/presenter/computeds/trialSessionsHelper.ts @@ -43,6 +43,7 @@ export const trialSessionsHelper = ( }) .filter(trialSession => { if (filters.judgeId === 'All') return true; + if (filters.judgeId === 'unassigned') return !trialSession.judge?.userId; return trialSession.judge?.userId === filters.judgeId; }) .filter(trialSession => { diff --git a/web-client/src/views/TrialSessions/TrialSessions.tsx b/web-client/src/views/TrialSessions/TrialSessions.tsx index 8ab91648e5e..34cb2ba0df8 100644 --- a/web-client/src/views/TrialSessions/TrialSessions.tsx +++ b/web-client/src/views/TrialSessions/TrialSessions.tsx @@ -178,6 +178,7 @@ const TrialSessionFilters = connect( From adc8b4f06ff2ce73f560c51e6ef7510d5f31b925 Mon Sep 17 00:00:00 2001 From: Zachary Rogers Date: Mon, 9 Sep 2024 13:32:44 -0700 Subject: [PATCH 22/59] 10409: Update swing session helper. fix sorting --- .../computeds/formattedTrialSessions.ts | 231 +----------------- 1 file changed, 1 insertion(+), 230 deletions(-) diff --git a/web-client/src/presenter/computeds/formattedTrialSessions.ts b/web-client/src/presenter/computeds/formattedTrialSessions.ts index 62f1a63c3e2..c862965248c 100644 --- a/web-client/src/presenter/computeds/formattedTrialSessions.ts +++ b/web-client/src/presenter/computeds/formattedTrialSessions.ts @@ -4,169 +4,6 @@ import { TrialSessionInfoDTO } from '@shared/business/dto/trialSessions/TrialSes import { state } from '@web-client/presenter/app.cerebral'; import { trialSessionOptionText } from './addToTrialSessionModalHelper'; -// export const formatSession = (session, applicationContext) => { -// const { DATE_FORMATS } = applicationContext.getConstants(); - -// session.startOfWeek = createDateAtStartOfWeekEST( -// session.startDate, -// DATE_FORMATS.MONTH_DAY_YEAR, -// ); - -// session.startOfWeekSortable = createDateAtStartOfWeekEST( -// session.startDate, -// DATE_FORMATS.YYYYMMDD_NUMERIC, -// ); - -// session.formattedStartDate = applicationContext -// .getUtilities() -// .formatDateString(session.startDate, DATE_FORMATS.MMDDYY); - -// session.formattedEstimatedEndDate = applicationContext -// .getUtilities() -// .formatDateString(session.estimatedEndDate, DATE_FORMATS.MMDDYY); - -// session.formattedNoticeIssuedDate = applicationContext -// .getUtilities() -// .formatDateString(session.noticeIssuedDate, DATE_FORMATS.MMDDYYYY); - -// session.showAlertForNOTTReminder = -// !session.dismissedAlertForNOTT && -// session.isStartDateWithinNOTTReminderRange; - -// if (session.showAlertForNOTTReminder) { -// session.alertMessageForNOTT = `The 30-day notice is due by ${session.thirtyDaysBeforeTrialFormatted}`; -// } - -// return session; -// }; - -// export const sessionSorter = (sessionList, dateSort = 'asc') => { -// return orderBy( -// sessionList, -// ['startDate', 'trialLocation'], -// [dateSort, 'asc'], -// ); -// }; - -// export const filterFormattedSessionsByStatus = trialTerms => { -// const sessionSort = { -// All: 'desc', -// Closed: 'desc', -// New: 'asc', -// Open: 'asc', -// }; - -// const filteredbyStatusType = { -// All: [], -// Closed: [], -// New: [], -// Open: [], -// }; - -// const initTermIndex = (trialTerm, filtered) => { -// let termIndex = filtered.findIndex( -// term => term.dateFormatted === trialTerm.dateFormatted, -// ); - -// if (termIndex === -1) { -// filtered.push({ -// dateFormatted: trialTerm.dateFormatted, -// sessions: [], -// startOfWeekSortable: trialTerm.startOfWeekSortable, -// }); -// termIndex = filtered.length - 1; -// } - -// return termIndex; -// }; - -// trialTerms.forEach(trialTerm => { -// trialTerm.sessions.forEach(session => { -// const termIndex = initTermIndex( -// trialTerm, -// filteredbyStatusType[session.sessionStatus], -// ); - -// if (!session.judge) { -// session.judge = { -// name: 'Unassigned', -// userId: 'unassigned', -// }; -// } -// // Add session status to filtered session -// filteredbyStatusType[session.sessionStatus][termIndex].sessions.push( -// session, -// ); - -// // Push to all -// const allTermIndex = initTermIndex(trialTerm, filteredbyStatusType.All); -// filteredbyStatusType.All[allTermIndex].sessions.push(session); -// }); -// }); - -// for (let [status, entryTrialTerms] of Object.entries(filteredbyStatusType)) { -// filteredbyStatusType[status] = orderBy( -// entryTrialTerms, -// ['startOfWeekSortable'], -// [sessionSort[status]], -// ); -// entryTrialTerms.forEach(trialTerm => { -// trialTerm.sessions = sessionSorter(trialTerm.sessions, [ -// sessionSort[status], -// ]); -// }); -// } - -// return filteredbyStatusType; -// }; - -// const sortSessionsByTerm = ({ -// applicationContext, -// currentTrialSessionId, -// selectedTerm, -// selectedTermYear, -// sessions, -// }: { -// applicationContext: ClientApplicationContext; -// selectedTermYear: string; -// selectedTerm: string; -// sessions: RawTrialSession[]; -// currentTrialSessionId?: string; -// }) => { -// const sessionsByTermOrderedByTrialLocation = orderBy( -// sessions.filter( -// session => -// session.term === selectedTerm && session.termYear == selectedTermYear, -// ), -// 'trialLocation', -// ); - -// const sessionsGroupedByTrialLocation = groupBy( -// sessionsByTermOrderedByTrialLocation, -// 'trialLocation', -// ); - -// const sessionsOrderedChronologically = flatMap( -// sessionsGroupedByTrialLocation, -// group => { -// return orderBy(group, 'startDate', 'asc'); -// }, -// ); - -// const sessionsByTermFormatted = formatTrialSessionDisplayOptions( -// sessionsOrderedChronologically, -// applicationContext, -// ); - -// if (currentTrialSessionId) { -// return sessionsByTermFormatted.filter( -// session => session.trialSessionId !== currentTrialSessionId, -// ); -// } - -// return sessionsByTermFormatted; -// }; - export const formattedTrialSessions = ( get: Get, ): { @@ -194,7 +31,7 @@ export const formattedTrialSessions = ( ) .sort((sessionA, sessionB) => { const aTrialLocation = sessionA.trialLocation || ''; - const bTrialLocation = sessionA.trialLocation || ''; + const bTrialLocation = sessionB.trialLocation || ''; if (aTrialLocation === bTrialLocation) { return sessionA.startDate.localeCompare(sessionB.startDate); } @@ -208,72 +45,6 @@ export const formattedTrialSessions = ( }; }); - // const judgeId = get(state.judgeUser.userId); - // const currentTrialSessionId = get(state.trialSession.trialSessionId); - // const currentUser = get(state.user); - - // const trialSessionFilters = pickBy( - // omit(get(state.screenMetadata.trialSessionFilters), 'status'), - // identity, - // ); - // const judgeFilter = get( - // state.screenMetadata.trialSessionFilters.judge.userId, - // ); - - // const tab = get(state.currentViewMetadata.trialSessions.tab); - - // if (!judgeFilter || (tab !== 'new' && judgeFilter === 'unassigned')) { - // delete trialSessionFilters.judge; - // } - - // const sessions = filter(get(state.trialSessions), trialSessionFilters); - - // const formattedSessions = []; - // sessions.forEach(session => { - // const isJudgeUserAssigned = !!( - // session.judge?.userId === judgeId && judgeId - // ); - // const isTrialClerkUserAssigned = - // session.trialClerk?.userId === currentUser.userId; - - // session.userIsAssignedToSession = - // isJudgeUserAssigned || isTrialClerkUserAssigned; - - // const formattedSession = formatSession(session, applicationContext); - - // let sessionWeek = find(formattedSessions, { - // startOfWeekSortable: formattedSession.startOfWeekSortable, - // }); - - // if (!sessionWeek) { - // sessionWeek = { - // dateFormatted: formattedSession.startOfWeek, - // sessions: [], - // startOfWeekSortable: formattedSession.startOfWeekSortable, - // }; - // formattedSessions.push(sessionWeek); - // } - // sessionWeek.sessions.push(session); - // }); - - // formattedSessions.forEach( - // week => (week.sessions = sessionSorter(week.sessions)), - // ); - - // const selectedTerm = get(state.form.term); - // let sessionsByTerm: any[] = []; - - // if (selectedTerm) { - // const selectedTermYear = get(state.form.termYear); - // sessionsByTerm = sortSessionsByTerm({ - // applicationContext, - // currentTrialSessionId, - // selectedTerm, - // selectedTermYear, - // sessions, - // }); - // } - return { showSwingSessionList: get(state.form.swingSession), showSwingSessionOption: validSwingSessions.length > 0, From 1d7655020d8d59512f79f1cac4f93322c76d2f7e Mon Sep 17 00:00:00 2001 From: Zachary Rogers Date: Mon, 9 Sep 2024 14:21:48 -0700 Subject: [PATCH 23/59] 10409: Remove formattedTrialSessions and split into trialSessionsPage and add/edit trial sessions --- .../addTrialSessionInformationHelper.test.ts | 231 ++++++++++++++++++ .../addTrialSessionInformationHelper.ts | 43 +++- .../computeds/formattedTrialSessions.ts | 53 ---- web-client/src/presenter/state.ts | 4 - .../TrialSessions/SessionInformationForm.tsx | 24 +- 5 files changed, 285 insertions(+), 70 deletions(-) delete mode 100644 web-client/src/presenter/computeds/formattedTrialSessions.ts diff --git a/web-client/src/presenter/computeds/TrialSession/addTrialSessionInformationHelper.test.ts b/web-client/src/presenter/computeds/TrialSession/addTrialSessionInformationHelper.test.ts index dbc6603e246..c863f19b0d2 100644 --- a/web-client/src/presenter/computeds/TrialSession/addTrialSessionInformationHelper.test.ts +++ b/web-client/src/presenter/computeds/TrialSession/addTrialSessionInformationHelper.test.ts @@ -1,13 +1,46 @@ import { + SESSION_STATUS_TYPES, TRIAL_SESSION_PROCEEDING_TYPES, TRIAL_SESSION_SCOPE_TYPES, } from '../../../../../shared/src/business/entities/EntityConstants'; +import { TrialSessionInfoDTO } from '@shared/business/dto/trialSessions/TrialSessionInfoDTO'; import { addTrialSessionInformationHelper as addTrialSessionInformationHelperComputed } from './addTrialSessionInformationHelper'; import { applicationContextForClient as applicationContext } from '@web-client/test/createClientTestApplicationContext'; +import { docketClerk1User } from '@shared/test/mockUsers'; import { runCompute } from '@web-client/presenter/test.cerebral'; import { withAppContextDecorator } from '../../../withAppContext'; describe('addTrialSessionInformationHelper', () => { + let trialSession1: TrialSessionInfoDTO; + let trialSession2: TrialSessionInfoDTO; + beforeEach(() => { + trialSession1 = { + isCalendared: true, + judge: { name: 'howdy', userId: '1' }, + proceedingType: 'Remote', + sessionScope: TRIAL_SESSION_SCOPE_TYPES.locationBased, + sessionStatus: 'Open', + sessionType: 'Regular', + startDate: '2022-03-01T21:00:00.000Z', + term: 'Winter', + termYear: '2022', + trialLocation: 'Boise', + trialSessionId: '43bc50b8-8b0b-47db-817b-a666af7a703e', + }; + trialSession2 = { + isCalendared: true, + judge: { name: 'howdy', userId: '2' }, + proceedingType: 'Remote', + sessionScope: TRIAL_SESSION_SCOPE_TYPES.locationBased, + sessionStatus: 'Open', + sessionType: 'Regular', + startDate: '2022-03-01T21:00:00.000Z', + term: 'Winter', + termYear: '2022', + trialLocation: 'Boise', + trialSessionId: '933ac8d9-68f0-4bfa-b7be-99c465c6799e', + }; + }); const addTrialSessionInformationHelper = withAppContextDecorator( addTrialSessionInformationHelperComputed, { @@ -171,4 +204,202 @@ describe('addTrialSessionInformationHelper', () => { expect(result.sessionTypes).toEqual(['Special', 'Motion/Hearing']); }); }); + + describe('showSwingSessionList', () => { + it('should show the swing session options list when the user has selected that their trial session is part of a swing session', () => { + const result = runCompute(addTrialSessionInformationHelper, { + state: { + form: { swingSession: true }, + user: docketClerk1User, + }, + }); + + expect(result.showSwingSessionList).toEqual(true); + }); + + it('should not show the swing session options list when the user has not selected that their trial session is part of a swing session', () => { + const result = runCompute(addTrialSessionInformationHelper, { + state: { + form: { swingSession: false }, + user: docketClerk1User, + }, + }); + + expect(result.showSwingSessionList).toEqual(false); + }); + }); + + describe('showSwingSessionOption', () => { + it('should show the option to associate the current trial session with another swing session when there are valid swing session options', () => { + const term = 'Fall'; + const termYear = '2020'; + trialSession1.term = term; + trialSession1.termYear = termYear; + trialSession1.sessionStatus = SESSION_STATUS_TYPES.open; + + const result = runCompute(addTrialSessionInformationHelper, { + state: { + form: { swingSession: true, term, termYear }, + trialSession: { + trialSessionId: '74f24014-2cf1-4e97-b80a-40f970d5376d', + }, + trialSessions: [trialSession1], + user: docketClerk1User, + }, + }); + + expect(result.showSwingSessionOption).toEqual(true); + }); + + it('should not show the option to associate the current trial session with another swing session when there are no valid swing session options', () => { + const term = 'Fall'; + const termYear = '2020'; + + const result = runCompute(addTrialSessionInformationHelper, { + state: { + form: { swingSession: true, term, termYear }, + trialSession: { + trialSessionId: '74f24014-2cf1-4e97-b80a-40f970d5376d', + }, + trialSessions: [], + user: docketClerk1User, + }, + }); + + expect(result.showSwingSessionOption).toEqual(false); + }); + }); + + describe('swingSessions', () => { + describe('valid swing sessions', () => { + it('should show only trial sessions in the same term year as the current trial session', () => { + const term = 'Fall'; + const termYear = '2020'; + trialSession1.term = term; + trialSession1.termYear = termYear; + trialSession1.sessionStatus = SESSION_STATUS_TYPES.open; + trialSession2.term = term; + trialSession2.termYear = '2021'; + trialSession2.sessionStatus = SESSION_STATUS_TYPES.open; + + const result = runCompute(addTrialSessionInformationHelper, { + state: { + form: { swingSession: true, term, termYear }, + trialSession: { + trialSessionId: '74f24014-2cf1-4e97-b80a-40f970d5376d', + }, + trialSessions: [trialSession1, trialSession2], + user: docketClerk1User, + }, + }); + + expect(result.swingSessions[0].trialSessionId).toEqual( + trialSession1.trialSessionId, + ); + expect(result.swingSessions.length).toEqual(1); + }); + + it('should show only trial sessions in the same term as the current trial session', () => { + const term = 'Fall'; + const termYear = '2020'; + trialSession1.term = term; + trialSession1.termYear = termYear; + trialSession1.sessionStatus = SESSION_STATUS_TYPES.open; + trialSession2.term = 'Summer'; + trialSession2.termYear = termYear; + trialSession2.sessionStatus = SESSION_STATUS_TYPES.open; + + const result = runCompute(addTrialSessionInformationHelper, { + state: { + form: { swingSession: true, term, termYear }, + trialSession: { + trialSessionId: '74f24014-2cf1-4e97-b80a-40f970d5376d', + }, + trialSessions: [trialSession1, trialSession2], + user: docketClerk1User, + }, + }); + + expect(result.swingSessions[0].trialSessionId).toEqual( + trialSession1.trialSessionId, + ); + expect(result.swingSessions.length).toEqual(1); + }); + + it('should not show closed trial sessions as valid swing sessions', () => { + const term = 'Fall'; + const termYear = '2020'; + trialSession1.term = term; + trialSession1.termYear = termYear; + trialSession1.sessionStatus = SESSION_STATUS_TYPES.closed; + + const result = runCompute(addTrialSessionInformationHelper, { + state: { + form: { swingSession: true, term, termYear }, + trialSession: { + trialSessionId: '74f24014-2cf1-4e97-b80a-40f970d5376d', + }, + trialSessions: [trialSession1], + user: docketClerk1User, + }, + }); + + expect(result.swingSessions.length).toEqual(0); + }); + + it('should not show the current trial session as a valid trialSession option to create a swing session with', () => { + const term = 'Fall'; + const termYear = '2020'; + trialSession1.term = term; + trialSession1.termYear = termYear; + trialSession1.sessionStatus = SESSION_STATUS_TYPES.open; + + const result = runCompute(addTrialSessionInformationHelper, { + state: { + form: { swingSession: true, term, termYear }, + trialSession: { + trialSessionId: trialSession1.trialSessionId, + }, + trialSessions: [trialSession1, trialSession2], + user: docketClerk1User, + }, + }); + + expect(result.swingSessions.length).toEqual(0); + }); + }); + + describe('sorting', () => { + it('should sort swing session options by trial location', () => { + const term = 'Fall'; + const termYear = '2020'; + trialSession1.term = term; + trialSession1.termYear = termYear; + trialSession1.sessionStatus = SESSION_STATUS_TYPES.open; + trialSession1.trialLocation = 'San Diego, California'; + trialSession2.term = term; + trialSession2.termYear = termYear; + trialSession2.sessionStatus = SESSION_STATUS_TYPES.open; + trialSession2.trialLocation = 'Birmingham, Alabama'; + + const result = runCompute(addTrialSessionInformationHelper, { + state: { + form: { swingSession: true, term, termYear }, + trialSession: { + trialSessionId: '74f24014-2cf1-4e97-b80a-40f970d5376d', + }, + trialSessions: [trialSession1, trialSession2], + user: docketClerk1User, + }, + }); + + expect(result.swingSessions[0].trialSessionId).toEqual( + trialSession2.trialSessionId, + ); + expect(result.swingSessions[1].trialSessionId).toEqual( + trialSession1.trialSessionId, + ); + }); + }); + }); }); diff --git a/web-client/src/presenter/computeds/TrialSession/addTrialSessionInformationHelper.ts b/web-client/src/presenter/computeds/TrialSession/addTrialSessionInformationHelper.ts index 053875fd7db..60c91ea3f86 100644 --- a/web-client/src/presenter/computeds/TrialSession/addTrialSessionInformationHelper.ts +++ b/web-client/src/presenter/computeds/TrialSession/addTrialSessionInformationHelper.ts @@ -2,8 +2,11 @@ import { AuthUser } from '@shared/business/entities/authUser/AuthUser'; import { ClientApplicationContext } from '@web-client/applicationContext'; import { FORMATS } from '../../../../../shared/src/business/utilities/DateHandler'; import { Get } from 'cerebral'; +import { SESSION_STATUS_TYPES } from '@shared/business/entities/EntityConstants'; import { TrialSession } from '../../../../../shared/src/business/entities/trialSessions/TrialSession'; +import { TrialSessionInfoDTO } from '@shared/business/dto/trialSessions/TrialSessionInfoDTO'; import { state } from '@web-client/presenter/app.cerebral'; +import { trialSessionOptionText } from '@web-client/presenter/computeds/addToTrialSessionModalHelper'; export const addTrialSessionInformationHelper = ( get: Get, @@ -14,11 +17,17 @@ export const addTrialSessionInformationHelper = ( sessionTypes: string[]; title: string; today: string; + swingSessions: { trialSessionId: string; swingSessionText: string }[]; + showSwingSessionList: boolean; + showSwingSessionOption: boolean; } => { const { SESSION_TYPES, TRIAL_SESSION_PROCEEDING_TYPES } = applicationContext.getConstants(); - const { proceedingType, sessionScope } = get(state.form); + const trialSessions: TrialSessionInfoDTO[] = get(state.trialSessions) || []; + const selectedTerm = get(state.form.term); + const selectedTermYear = get(state.form.termYear); + const currentTrialSessionId = get(state.trialSession.trialSessionId); const isStandaloneSession = TrialSession.isStandaloneRemote(sessionScope); @@ -49,10 +58,42 @@ export const addTrialSessionInformationHelper = ( }; const today = applicationContext.getUtilities().formatNow(FORMATS.YYYYMMDD); + const validSwingSessions: { + trialSessionId: string; + swingSessionText: string; + }[] = trialSessions + .filter(trialSession => trialSession.termYear === selectedTermYear) + .filter(trialSession => trialSession.term === selectedTerm) + .filter( + trialSession => + trialSession.sessionStatus !== SESSION_STATUS_TYPES.closed, + ) + .filter( + trialSession => trialSession.trialSessionId !== currentTrialSessionId, + ) + .sort((sessionA, sessionB) => { + const aTrialLocation = sessionA.trialLocation || ''; + const bTrialLocation = sessionB.trialLocation || ''; + if (aTrialLocation === bTrialLocation) { + return sessionA.startDate.localeCompare(sessionB.startDate); + } + return aTrialLocation.localeCompare(bTrialLocation); + }) + .map(trialSession => { + const swingSessionText = trialSessionOptionText(trialSession); + return { + swingSessionText, + trialSessionId: trialSession.trialSessionId || '', + }; + }); + return { displayRemoteProceedingForm, isStandaloneSession, sessionTypes: getSessionTypes(get(state.user)), + showSwingSessionList: get(state.form.swingSession), + showSwingSessionOption: validSwingSessions.length > 0, + swingSessions: validSwingSessions, title, today, }; diff --git a/web-client/src/presenter/computeds/formattedTrialSessions.ts b/web-client/src/presenter/computeds/formattedTrialSessions.ts deleted file mode 100644 index c862965248c..00000000000 --- a/web-client/src/presenter/computeds/formattedTrialSessions.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { Get } from 'cerebral'; -import { SESSION_STATUS_TYPES } from '@shared/business/entities/EntityConstants'; -import { TrialSessionInfoDTO } from '@shared/business/dto/trialSessions/TrialSessionInfoDTO'; -import { state } from '@web-client/presenter/app.cerebral'; -import { trialSessionOptionText } from './addToTrialSessionModalHelper'; - -export const formattedTrialSessions = ( - get: Get, -): { - swingSessions: { trialSessionId: string; swingSessionText: string }[]; - showSwingSessionList: boolean; - showSwingSessionOption: boolean; -} => { - const trialSessions: TrialSessionInfoDTO[] = get(state.trialSessions) || []; - const selectedTerm = get(state.form.term); - const selectedTermYear = get(state.form.termYear); - const currentTrialSessionId = get(state.trialSession.trialSessionId); - - const validSwingSessions: { - trialSessionId: string; - swingSessionText: string; - }[] = trialSessions - .filter(trialSession => trialSession.termYear === selectedTermYear) - .filter(trialSession => trialSession.term === selectedTerm) - .filter( - trialSession => - trialSession.sessionStatus !== SESSION_STATUS_TYPES.closed, - ) - .filter( - trialSession => trialSession.trialSessionId !== currentTrialSessionId, - ) - .sort((sessionA, sessionB) => { - const aTrialLocation = sessionA.trialLocation || ''; - const bTrialLocation = sessionB.trialLocation || ''; - if (aTrialLocation === bTrialLocation) { - return sessionA.startDate.localeCompare(sessionB.startDate); - } - return aTrialLocation.localeCompare(bTrialLocation); - }) - .map(trialSession => { - const swingSessionText = trialSessionOptionText(trialSession); - return { - swingSessionText, - trialSessionId: trialSession.trialSessionId || '', - }; - }); - - return { - showSwingSessionList: get(state.form.swingSession), - showSwingSessionOption: validSwingSessions.length > 0, - swingSessions: validSwingSessions, - }; -}; diff --git a/web-client/src/presenter/state.ts b/web-client/src/presenter/state.ts index a1923173901..ef2f8cf4155 100644 --- a/web-client/src/presenter/state.ts +++ b/web-client/src/presenter/state.ts @@ -85,7 +85,6 @@ import { formattedMessageDetail } from './computeds/formattedMessageDetail'; import { formattedMessages } from './computeds/formattedMessages'; import { formattedPendingItemsHelper } from './computeds/formattedPendingItems'; import { formattedTrialSessionDetails } from './computeds/formattedTrialSessionDetails'; -import { formattedTrialSessions } from './computeds/formattedTrialSessions'; import { formattedWorkQueue } from './computeds/formattedWorkQueue'; import { getAllIrsPractitionersForSelectHelper } from '@web-client/presenter/computeds/TrialSession/getAllIrsPractitionersForSelectHelper'; import { getConstants } from '../getConstants'; @@ -381,9 +380,6 @@ export const computeds = { formattedTrialSessionDetails as unknown as ReturnType< typeof formattedTrialSessionDetails >, - formattedTrialSessions: formattedTrialSessions as unknown as ReturnType< - typeof formattedTrialSessions - >, formattedWorkQueue: formattedWorkQueue as unknown as ReturnType< typeof formattedWorkQueue >, diff --git a/web-client/src/views/TrialSessions/SessionInformationForm.tsx b/web-client/src/views/TrialSessions/SessionInformationForm.tsx index 880b82fb0bd..e556aa7eeb3 100644 --- a/web-client/src/views/TrialSessions/SessionInformationForm.tsx +++ b/web-client/src/views/TrialSessions/SessionInformationForm.tsx @@ -15,7 +15,6 @@ const sessionInformationDeps = { form: state.form, formatAndUpdateDateFromDatePickerSequence: sequences.formatAndUpdateDateFromDatePickerSequence, - formattedTrialSessions: state.formattedTrialSessions, updateTrialSessionFormDataSequence: sequences.updateTrialSessionFormDataSequence, user: state.user, @@ -34,7 +33,6 @@ export const SessionInformationForm = connect< DATE_FORMATS, form, formatAndUpdateDateFromDatePickerSequence, - formattedTrialSessions, TRIAL_SESSION_SCOPE_TYPES, updateTrialSessionFormDataSequence, validateTrialSessionSequence, @@ -223,7 +221,7 @@ export const SessionInformationForm = connect<
- {formattedTrialSessions.showSwingSessionOption && + {addTrialSessionInformationHelper.showSwingSessionOption && !addTrialSessionInformationHelper.isStandaloneSession && ( <>
@@ -249,7 +247,7 @@ export const SessionInformationForm = connect<
- {formattedTrialSessions.showSwingSessionList && ( + {addTrialSessionInformationHelper.showSwingSessionList && ( )} From 225f53fda42b2f9a4ae4b34b0d70c11bb4b1aa0f Mon Sep 17 00:00:00 2001 From: Zachary Rogers Date: Mon, 9 Sep 2024 15:29:31 -0700 Subject: [PATCH 24/59] 10409: Update integration tests to reflect new trial sessions page state --- .../dismissNOTTReminder.test.ts | 50 ++++++------------- .../docketClerkViewsTrialSessionList.ts | 16 ++---- .../docketClerkViewsTrialSessionsTab.ts | 50 ++++++------------- .../src/views/TrialSessions/TrialSessions.tsx | 4 +- 4 files changed, 36 insertions(+), 84 deletions(-) diff --git a/web-client/integration-tests/dismissNOTTReminder.test.ts b/web-client/integration-tests/dismissNOTTReminder.test.ts index 8314bc5e827..e113eafa988 100644 --- a/web-client/integration-tests/dismissNOTTReminder.test.ts +++ b/web-client/integration-tests/dismissNOTTReminder.test.ts @@ -2,7 +2,10 @@ import { SESSION_TYPES } from '../../shared/src/business/entities/EntityConstant import { docketClerkCreatesATrialSession } from './journey/docketClerkCreatesATrialSession'; import { docketClerkViewsTrialSessionsTab } from './journey/docketClerkViewsTrialSessionsTab'; import { formattedTrialSessionDetails } from '../src/presenter/computeds/formattedTrialSessionDetails'; -import { formattedTrialSessions } from '../src/presenter/computeds/formattedTrialSessions'; +import { + isTrialSessionRow, + trialSessionsHelper as trialSessionsHelperComputed, +} from '@web-client/presenter/computeds/trialSessionsHelper'; import { loginAs, setupTest } from './helpers'; import { petitionsClerkSetsATrialSessionsSchedule } from './journey/petitionsClerkSetsATrialSessionsSchedule'; import { petitionsClerkViewsNewTrialSession } from './journey/petitionsClerkViewsNewTrialSession'; @@ -58,35 +61,21 @@ describe('Dismiss NOTT reminder on calendared trial session within 30-35 day ran expect(cerebralTest.getState('currentPage')).toEqual('TrialSessions'); - const trialSessionFormatted: any = runCompute( - withAppContextDecorator(formattedTrialSessions), - { - state: cerebralTest.getState(), - }, + const trialSessionsHelper = withAppContextDecorator( + trialSessionsHelperComputed, ); - - const filteredSessions: any[] = - trialSessionFormatted.filteredTrialSessions['Open']; - - let foundSession; - filteredSessions.some(trialSession => { - trialSession.sessions.some(session => { - if ( - session.trialSessionId === cerebralTest.lastCreatedTrialSessionId - ) { - foundSession = session; - return true; - } - }); - if (foundSession) { - return true; - } + const helper = runCompute(trialSessionsHelper, { + state: cerebralTest.getState(), }); + const foundSession = helper.trialSessionRows + .filter(isTrialSessionRow) + .find(t => t.trialSessionId === cerebralTest.lastCreatedTrialSessionId); + expect(foundSession).toBeDefined(); - expect(foundSession.showAlertForNOTTReminder).toEqual(true); - expect(foundSession.alertMessageForNOTT).toEqual( - `The 30-day notice is due by ${foundSession.thirtyDaysBeforeTrialFormatted}`, + expect(foundSession?.showAlertForNOTTReminder).toEqual(true); + expect(foundSession?.alertMessageForNOTT).toContain( + 'The 30-day notice is due by', ); }); @@ -124,16 +113,9 @@ describe('Dismiss NOTT reminder on calendared trial session within 30-35 day ran describe('Petitions clerk views calendared trial session in trial session list', () => { loginAs(cerebralTest, 'petitionsclerk@example.com'); it('should go to the created trial session', async () => { - await cerebralTest.runSequence('gotoTrialSessionsSequence', { - query: { - status: 'Open', - }, - }); + await cerebralTest.runSequence('gotoTrialSessionsSequence'); expect(cerebralTest.getState('currentPage')).toEqual('TrialSessions'); - expect( - cerebralTest.getState('screenMetadata.trialSessionFilters.status'), - ).toEqual('Open'); }); it('should see the alert banner in the latest trial session and can clear it', async () => { diff --git a/web-client/integration-tests/journey/docketClerkViewsTrialSessionList.ts b/web-client/integration-tests/journey/docketClerkViewsTrialSessionList.ts index 26cbd3f5e55..a72b777ca71 100644 --- a/web-client/integration-tests/journey/docketClerkViewsTrialSessionList.ts +++ b/web-client/integration-tests/journey/docketClerkViewsTrialSessionList.ts @@ -1,11 +1,4 @@ import { find } from 'lodash'; -import { formattedTrialSessions as formattedTrialSessionsComputed } from '../../src/presenter/computeds/formattedTrialSessions'; -import { runCompute } from '@web-client/presenter/test.cerebral'; -import { withAppContextDecorator } from '../../src/withAppContext'; - -const formattedTrialSessions = withAppContextDecorator( - formattedTrialSessionsComputed, -); export const docketClerkViewsTrialSessionList = ( cerebralTest, @@ -15,12 +8,11 @@ export const docketClerkViewsTrialSessionList = ( await cerebralTest.runSequence('gotoTrialSessionsSequence'); expect(cerebralTest.getState('currentPage')).toEqual('TrialSessions'); - const formatted = runCompute(formattedTrialSessions, { - state: cerebralTest.getState(), - }); - expect(formatted.sessionsByTerm.length).toBeGreaterThan(0); + const { trialSessions } = cerebralTest.getState().trialSessionsPage; + + expect(trialSessions.length).toBeGreaterThan(0); - const trialSession = find(formatted.sessionsByTerm, { + const trialSession = find(trialSessions, { trialSessionId: cerebralTest.lastCreatedTrialSessionId, }); diff --git a/web-client/integration-tests/journey/docketClerkViewsTrialSessionsTab.ts b/web-client/integration-tests/journey/docketClerkViewsTrialSessionsTab.ts index 1325e2c6629..c319aa023fe 100644 --- a/web-client/integration-tests/journey/docketClerkViewsTrialSessionsTab.ts +++ b/web-client/integration-tests/journey/docketClerkViewsTrialSessionsTab.ts @@ -1,35 +1,26 @@ -import { formattedTrialSessions as formattedTrialSessionsComputed } from '../../src/presenter/computeds/formattedTrialSessions'; +import { + isTrialSessionRow, + trialSessionsHelper as trialSessionsHelperComputed, +} from '@web-client/presenter/computeds/trialSessionsHelper'; import { runCompute } from '@web-client/presenter/test.cerebral'; -import { trialSessionsHelper as trialSessionsHelperComputed } from '../../src/presenter/computeds/trialSessionsHelper'; import { withAppContextDecorator } from '../../src/withAppContext'; -const formattedTrialSessions = withAppContextDecorator( - formattedTrialSessionsComputed, -); - export const docketClerkViewsTrialSessionsTab = ( cerebralTest: any, - overrides: { tab?: string } = { tab: undefined }, + overrides: { tab?: 'calendared' | 'new' } = { tab: 'calendared' }, ) => { - const status = overrides.tab || 'Open'; - return it(`Docket clerk views ${status} Trial Sessions tab`, async () => { - // resetting view metadata to counteract the fact that state is not being reset on login as it would be outside of a test - cerebralTest.setState('currentViewMetadata.trialSessions.tab', undefined); - + const { tab } = overrides; + return it(`Docket clerk views ${tab} Trial Sessions tab`, async () => { await cerebralTest.runSequence('gotoTrialSessionsSequence', { query: { - status, + status: tab, }, }); + await cerebralTest.runSequence('setTrialSessionsFiltersSequence', { + currentTab: tab, + }); expect(cerebralTest.getState('currentPage')).toEqual('TrialSessions'); - expect( - cerebralTest.getState('screenMetadata.trialSessionFilters.status'), - ).toEqual(status); - - const formatted = runCompute(formattedTrialSessions, { - state: cerebralTest.getState(), - }); const trialSessionsHelper = withAppContextDecorator( trialSessionsHelperComputed, @@ -43,26 +34,15 @@ export const docketClerkViewsTrialSessionsTab = ( judge => judge.role === 'legacyJudge', ); - if (status === 'Closed' || status === 'All') { + if (tab === 'calendared') { expect(legacyJudge).toBeTruthy(); } else { expect(legacyJudge).toBeFalsy(); } - const filteredSessions = formatted.sessionsByTerm[status]; - - let foundSession; - filteredSessions.some(trialSession => { - trialSession.sessions.some(session => { - if (session.trialSessionId === cerebralTest.trialSessionId) { - foundSession = session; - return true; - } - }); - if (foundSession) { - return true; - } - }); + const foundSession = helper.trialSessionRows + .filter(isTrialSessionRow) + .find(t => t.trialSessionId === cerebralTest.trialSessionId); expect(foundSession).toBeTruthy(); }); diff --git a/web-client/src/views/TrialSessions/TrialSessions.tsx b/web-client/src/views/TrialSessions/TrialSessions.tsx index 34cb2ba0df8..31b4657ae44 100644 --- a/web-client/src/views/TrialSessions/TrialSessions.tsx +++ b/web-client/src/views/TrialSessions/TrialSessions.tsx @@ -18,14 +18,12 @@ import React from 'react'; export const TrialSessions = connect( { - defaultTab: state.screenMetadata.trialSessionFilters.status, openTrialSessionPlanningModalSequence: sequences.openTrialSessionPlanningModalSequence, setTrialSessionsFiltersSequence: sequences.setTrialSessionsFiltersSequence, trialSessionHelper: state.trialSessionsHelper, }, function TrialSessions({ - defaultTab, openTrialSessionPlanningModalSequence, setTrialSessionsFiltersSequence, trialSessionHelper, @@ -38,7 +36,7 @@ export const TrialSessions = connect( { From ff9b48a770802dbfe76581f21a1c2f04edf2b760 Mon Sep 17 00:00:00 2001 From: Zachary Rogers Date: Mon, 9 Sep 2024 15:41:58 -0700 Subject: [PATCH 25/59] 10409: Update integration tests to reflect new trial sessions page state --- .../docketClerkViewsTrialSessionTabs.test.ts | 8 +- ...ClerkClosesStandaloneRemoteTrialSession.ts | 34 +- .../docketClerkVerifiesSessionIsNotClosed.ts | 44 +-- .../computeds/formattedTrialSessions.test.ts | 334 ------------------ 4 files changed, 18 insertions(+), 402 deletions(-) delete mode 100644 web-client/src/presenter/computeds/formattedTrialSessions.test.ts diff --git a/web-client/integration-tests/docketClerkViewsTrialSessionTabs.test.ts b/web-client/integration-tests/docketClerkViewsTrialSessionTabs.test.ts index bc4a582c250..55c3b749588 100644 --- a/web-client/integration-tests/docketClerkViewsTrialSessionTabs.test.ts +++ b/web-client/integration-tests/docketClerkViewsTrialSessionTabs.test.ts @@ -47,7 +47,7 @@ describe('Docket Clerk Views Trial Session Tabs', () => { docketClerkCreatesATrialSession(cerebralTest, overrides); docketClerkViewsTrialSessionList(cerebralTest); // Trial Session should exist in New tab - docketClerkViewsTrialSessionsTab(cerebralTest, { tab: 'New' }); + docketClerkViewsTrialSessionsTab(cerebralTest, { tab: 'new' }); for (let i = 0; i < caseCount; i++) { const id = i + 1; @@ -66,14 +66,14 @@ describe('Docket Clerk Views Trial Session Tabs', () => { loginAs(cerebralTest, 'docketclerk@example.com'); // Trial Session should exist in Open tab - docketClerkViewsTrialSessionsTab(cerebralTest, { tab: 'Open' }); + docketClerkViewsTrialSessionsTab(cerebralTest, { tab: 'calendared' }); loginAs(cerebralTest, 'petitionsclerk@example.com'); petitionsClerkManuallyRemovesCaseFromTrial(cerebralTest); loginAs(cerebralTest, 'docketclerk@example.com'); // Trial Session should exist in Closed tab - docketClerkViewsTrialSessionsTab(cerebralTest, { tab: 'Closed' }); + docketClerkViewsTrialSessionsTab(cerebralTest, { tab: 'calendared' }); // Trial Session should exist in All tab - docketClerkViewsTrialSessionsTab(cerebralTest, { tab: 'All' }); + docketClerkViewsTrialSessionsTab(cerebralTest, { tab: 'calendared' }); }); diff --git a/web-client/integration-tests/journey/docketClerkClosesStandaloneRemoteTrialSession.ts b/web-client/integration-tests/journey/docketClerkClosesStandaloneRemoteTrialSession.ts index a7e116b2b66..2bedb3e3b6f 100644 --- a/web-client/integration-tests/journey/docketClerkClosesStandaloneRemoteTrialSession.ts +++ b/web-client/integration-tests/journey/docketClerkClosesStandaloneRemoteTrialSession.ts @@ -1,12 +1,4 @@ -import { formattedTrialSessions as formattedTrialSessionsComputed } from '../../src/presenter/computeds/formattedTrialSessions'; -import { runCompute } from '@web-client/presenter/test.cerebral'; -import { withAppContextDecorator } from '../../src/withAppContext'; - -const formattedTrialSessions = withAppContextDecorator( - formattedTrialSessionsComputed, -); - -const status = 'Closed'; +import { SESSION_STATUS_TYPES } from '@shared/business/entities/EntityConstants'; export const docketClerkClosesStandaloneRemoteTrialSession = cerebralTest => { return it('Docket Clerk closes the trial session', async () => { @@ -17,25 +9,13 @@ export const docketClerkClosesStandaloneRemoteTrialSession = cerebralTest => { await cerebralTest.runSequence('closeTrialSessionSequence'); - const formatted = runCompute(formattedTrialSessions, { - state: cerebralTest.getState(), - }); - - const filteredSessions = formatted.sessionsByTerm[status]; - - let foundSession; - filteredSessions.some(trialSession => { - trialSession.sessions.some(session => { - if (session.trialSessionId === cerebralTest.lastCreatedTrialSessionId) { - foundSession = session; - return true; - } - }); - if (foundSession) { - return true; - } - }); + const { trialSessions } = cerebralTest.getState().trialSessionsPage; + expect(trialSessions.length).toBeGreaterThan(0); + const foundSession = trialSessions.find( + t => t.trialSessionId === cerebralTest.lastCreatedTrialSessionId, + ); expect(foundSession).toBeTruthy(); + expect(foundSession.sessionStatus).toEqual(SESSION_STATUS_TYPES.closed); }); }; diff --git a/web-client/integration-tests/journey/docketClerkVerifiesSessionIsNotClosed.ts b/web-client/integration-tests/journey/docketClerkVerifiesSessionIsNotClosed.ts index da83ab802d8..9bbd194db78 100644 --- a/web-client/integration-tests/journey/docketClerkVerifiesSessionIsNotClosed.ts +++ b/web-client/integration-tests/journey/docketClerkVerifiesSessionIsNotClosed.ts @@ -1,45 +1,15 @@ -import { formattedTrialSessions as formattedTrialSessionsComputed } from '../../src/presenter/computeds/formattedTrialSessions'; -import { runCompute } from '@web-client/presenter/test.cerebral'; -import { withAppContextDecorator } from '../../src/withAppContext'; - -const formattedTrialSessions = withAppContextDecorator( - formattedTrialSessionsComputed, -); - -const status = 'Closed'; +import { SESSION_STATUS_TYPES } from '@shared/business/entities/EntityConstants'; export const docketClerkVerifiesSessionIsNotClosed = cerebralTest => { return it('Docket Clerk verifies session is not closed', async () => { - await cerebralTest.runSequence('gotoTrialSessionsSequence', { - query: { - status, - }, - }); + await cerebralTest.runSequence('gotoTrialSessionsSequence'); expect(cerebralTest.getState('currentPage')).toEqual('TrialSessions'); - expect( - cerebralTest.getState('screenMetadata.trialSessionFilters.status'), - ).toEqual(status); - - const formatted = runCompute(formattedTrialSessions, { - state: cerebralTest.getState(), - }); - - const filteredSessions = formatted.sessionsByTerm[status]; - - let foundSession; - filteredSessions.some(trialSession => { - trialSession.sessions.some(session => { - if (session.trialSessionId === cerebralTest.lastCreatedTrialSessionId) { - foundSession = session; - return true; - } - }); - if (foundSession) { - return true; - } - }); - expect(foundSession).toBeFalsy(); + const { trialSessions } = cerebralTest.getState().trialSessionsPage; + const foundSession = trialSessions.find( + t => t.trialSessionId === cerebralTest.lastCreatedTrialSessionId, + ); + expect(foundSession.sessionStatus).not.toEqual(SESSION_STATUS_TYPES.closed); }); }; diff --git a/web-client/src/presenter/computeds/formattedTrialSessions.test.ts b/web-client/src/presenter/computeds/formattedTrialSessions.test.ts deleted file mode 100644 index b205166b314..00000000000 --- a/web-client/src/presenter/computeds/formattedTrialSessions.test.ts +++ /dev/null @@ -1,334 +0,0 @@ -import { - FORMATS, - formatNow, -} from '../../../../shared/src/business/utilities/DateHandler'; -import { applicationContextForClient as applicationContext } from '@web-client/test/createClientTestApplicationContext'; -import { formatTrialSessionDisplayOptions } from './addToTrialSessionModalHelper'; -import { formattedTrialSessions as formattedTrialSessionsComputed } from './formattedTrialSessions'; -import { judgeUser } from '@shared/test/mockUsers'; -import { runCompute } from '@web-client/presenter/test.cerebral'; -import { withAppContextDecorator } from '../../withAppContext'; -jest.mock('./addToTrialSessionModalHelper.ts'); - -const { - SESSION_TYPES, - TRIAL_SESSION_PROCEEDING_TYPES, - USER_ROLES: ROLES, -} = applicationContext.getConstants(); - -const formattedTrialSessions = withAppContextDecorator( - formattedTrialSessionsComputed, - { - ...applicationContext, - }, -); - -let nextYear; - -const baseState = { - constants: { USER_ROLES: ROLES }, - judgeUser, -}; - -let TRIAL_SESSIONS_LIST: any[] = []; - -describe('formattedTrialSessions', () => { - beforeAll(() => { - nextYear = (parseInt(formatNow(FORMATS.YEAR)) + 1).toString(); - }); - - beforeEach(() => { - TRIAL_SESSIONS_LIST = [ - { - caseOrder: [], - isCalendared: true, - judge: { name: judgeUser.name, userId: judgeUser.userId }, - proceedingType: TRIAL_SESSION_PROCEEDING_TYPES.inPerson, - sessionStatus: 'Open', - sessionType: SESSION_TYPES.regular, - startDate: '2019-11-25T15:00:00.000Z', - swingSession: true, - term: 'Fall', - termYear: '2019', - trialLocation: 'Hartford, Connecticut', - trialSessionId: '1', - }, - { - caseOrder: [], - isCalendared: false, - judge: { name: '2', userId: '2' }, - proceedingType: TRIAL_SESSION_PROCEEDING_TYPES.remote, - sessionStatus: 'New', - sessionType: SESSION_TYPES.small, - startDate: '2019-11-25T15:00:00.000Z', - swingSession: true, - term: 'Winter', - trialClerk: { name: '10', userId: '10' }, - trialLocation: 'Knoxville, TN', - trialSessionId: '2', - }, - { - caseOrder: [], - isCalendared: false, - judge: { name: '3', userId: '3' }, - noticeIssuedDate: '2019-07-25T15:00:00.000Z', - proceedingType: TRIAL_SESSION_PROCEEDING_TYPES.inPerson, - sessionStatus: 'New', - sessionType: SESSION_TYPES.regular, - startDate: '2019-11-27T15:00:00.000Z', - swingSession: true, - term: 'Winter', - trialLocation: 'Jacksonville, FL', - trialSessionId: '3', - }, - { - caseOrder: [], - isCalendared: false, - judge: { name: '55', userId: '55' }, - noticeIssuedDate: '2019-07-25T15:00:00.000Z', - proceedingType: TRIAL_SESSION_PROCEEDING_TYPES.inPerson, - sessionStatus: 'New', - sessionType: SESSION_TYPES.regular, - startDate: '2019-10-27T15:00:00.000Z', - swingSession: true, - term: 'Winter', - trialLocation: 'Jacksonville, FL', - trialSessionId: '5', - }, - { - caseOrder: [], - isCalendared: false, - judge: { name: '88', userId: '88' }, - noticeIssuedDate: '2020-07-26T15:00:00.000Z', - proceedingType: TRIAL_SESSION_PROCEEDING_TYPES.inPerson, - sessionStatus: 'New', - sessionType: SESSION_TYPES.regular, - startDate: '2020-11-26T15:00:00.000Z', - swingSession: true, - term: 'Winter', - trialLocation: 'Jacksonville, FL', - trialSessionId: '8', - }, - { - caseOrder: [], - isCalendared: true, - judge: { name: '4', userId: '4' }, - proceedingType: TRIAL_SESSION_PROCEEDING_TYPES.inPerson, - sessionStatus: 'Open', - sessionType: SESSION_TYPES.hybrid, - startDate: '2019-11-27T15:00:00.000Z', - swingSession: true, - term: 'Summer', - trialLocation: 'Memphis, TN', - trialSessionId: '4', - }, - { - caseOrder: [], - isCalendared: true, - judge: { name: '5', userId: '5' }, - proceedingType: TRIAL_SESSION_PROCEEDING_TYPES.remote, - sessionStatus: 'Open', - sessionType: SESSION_TYPES.hybrid, - startDate: '2019-11-25T15:00:00.000Z', - swingSession: false, - term: 'Spring', - termYear: '2019', - trialLocation: 'Anchorage, AK', - }, - { - caseOrder: [], - estimatedEndDate: '2045-02-17T15:00:00.000Z', - isCalendared: true, - judge: { name: '6', userId: '6' }, - proceedingType: TRIAL_SESSION_PROCEEDING_TYPES.inPerson, - sessionStatus: 'Open', - sessionType: SESSION_TYPES.regular, - startDate: `${nextYear}-02-17T15:00:00.000Z`, - swingSession: false, - term: 'Spring', - trialLocation: 'Jacksonville, FL', - }, - ]; - - (formatTrialSessionDisplayOptions as jest.Mock).mockImplementation( - session => session, - ); - }); - - it('shows swing session option only if matching term and term year is found', () => { - let form = { - term: 'Winter', - termYear: '2019', - }; - let result = runCompute(formattedTrialSessions, { - state: { - ...baseState, - form, - trialSessions: TRIAL_SESSIONS_LIST, - user: judgeUser, - }, - }); - expect(result.sessionsByTerm.length).toEqual(0); - expect(result.showSwingSessionOption).toBeFalsy(); - - form.term = 'Spring'; - result = runCompute(formattedTrialSessions, { - state: { - ...baseState, - form, - trialSessions: TRIAL_SESSIONS_LIST, - user: judgeUser, - }, - }); - expect(result.sessionsByTerm.length).toEqual(1); - expect(result.showSwingSessionOption).toBeTruthy(); - - form.termYear = '2011'; // similar term but not a matching year - result = runCompute(formattedTrialSessions, { - state: { - ...baseState, - form, - trialSessions: TRIAL_SESSIONS_LIST, - user: judgeUser, - }, - }); - expect(result.sessionsByTerm.length).toEqual(0); - expect(result.showSwingSessionOption).toBeFalsy(); - }); - - it('returns sessionsByTerm with only sessions in that term sorted chronologically if form.term is set', () => { - const result = runCompute(formattedTrialSessions, { - state: { - ...baseState, - form: { - term: 'Winter', - }, - trialSessions: TRIAL_SESSIONS_LIST, - user: judgeUser, - }, - }); - - expect(result.sessionsByTerm).toEqual([ - { - caseOrder: [], - formattedEstimatedEndDate: '', - formattedNoticeIssuedDate: '07/25/2019', - formattedStartDate: '10/27/19', - isCalendared: false, - judge: { name: '55', userId: '55' }, - noticeIssuedDate: '2019-07-25T15:00:00.000Z', - proceedingType: 'In Person', - sessionStatus: 'New', - sessionType: SESSION_TYPES.regular, - showAlertForNOTTReminder: undefined, - startDate: '2019-10-27T15:00:00.000Z', - startOfWeek: 'October 21, 2019', - startOfWeekSortable: '20191021', - swingSession: true, - term: 'Winter', - trialLocation: 'Jacksonville, FL', - trialSessionId: '5', - userIsAssignedToSession: false, - }, - { - caseOrder: [], - formattedEstimatedEndDate: '', - formattedNoticeIssuedDate: '07/25/2019', - formattedStartDate: '11/27/19', - isCalendared: false, - judge: { name: '3', userId: '3' }, - noticeIssuedDate: '2019-07-25T15:00:00.000Z', - proceedingType: 'In Person', - sessionStatus: 'New', - sessionType: SESSION_TYPES.regular, - showAlertForNOTTReminder: undefined, - startDate: '2019-11-27T15:00:00.000Z', - startOfWeek: 'November 25, 2019', - startOfWeekSortable: '20191125', - swingSession: true, - term: 'Winter', - trialLocation: 'Jacksonville, FL', - trialSessionId: '3', - userIsAssignedToSession: false, - }, - { - caseOrder: [], - formattedEstimatedEndDate: '', - formattedNoticeIssuedDate: '07/26/2020', - formattedStartDate: '11/26/20', - isCalendared: false, - judge: { name: '88', userId: '88' }, - noticeIssuedDate: '2020-07-26T15:00:00.000Z', - proceedingType: 'In Person', - sessionStatus: 'New', - sessionType: SESSION_TYPES.regular, - showAlertForNOTTReminder: undefined, - startDate: '2020-11-26T15:00:00.000Z', - startOfWeek: 'November 23, 2020', - startOfWeekSortable: '20201123', - swingSession: true, - term: 'Winter', - trialLocation: 'Jacksonville, FL', - trialSessionId: '8', - userIsAssignedToSession: false, - }, - { - caseOrder: [], - formattedEstimatedEndDate: '', - formattedNoticeIssuedDate: '', - formattedStartDate: '11/25/19', - isCalendared: false, - judge: { name: '2', userId: '2' }, - proceedingType: 'Remote', - sessionStatus: 'New', - sessionType: SESSION_TYPES.small, - showAlertForNOTTReminder: undefined, - startDate: '2019-11-25T15:00:00.000Z', - startOfWeek: 'November 25, 2019', - startOfWeekSortable: '20191125', - swingSession: true, - term: 'Winter', - trialClerk: { name: '10', userId: '10' }, - trialLocation: 'Knoxville, TN', - trialSessionId: '2', - userIsAssignedToSession: false, - }, - ]); - }); - - it('makes a call to format display text on sessionsByTerm', () => { - runCompute(formattedTrialSessions, { - state: { - ...baseState, - form: { - term: 'Winter', - }, - trialSessions: TRIAL_SESSIONS_LIST, - user: judgeUser, - }, - }); - - expect(formatTrialSessionDisplayOptions).toHaveBeenCalled(); - }); - - it('removes the current trial session from the sessionsByTerm when state.trialSession.trialSessionId is defined', () => { - const { sessionsByTerm } = runCompute(formattedTrialSessions, { - state: { - ...baseState, - form: { - term: 'Winter', - }, - trialSession: { trialSessionId: TRIAL_SESSIONS_LIST[1].trialSessionId }, - trialSessions: TRIAL_SESSIONS_LIST, - user: judgeUser, - }, - }); - - expect( - sessionsByTerm.find( - session => - session.trialSessionId === TRIAL_SESSIONS_LIST[1].trialSessionId, - ), - ).toBeUndefined(); - }); -}); From 42828f4822cd9bdf6d9e7e75b138ad4da74d28cd Mon Sep 17 00:00:00 2001 From: Zachary Rogers Date: Mon, 9 Sep 2024 17:59:27 -0700 Subject: [PATCH 26/59] 10409: Update integration tests to reflect new trial sessions page state --- .../docketClerkViewsTrialSessionTabs.test.ts | 26 ++++++++++++++----- .../docketClerkViewsTrialSessionsTab.ts | 17 +++++++----- web-client/src/presenter/presenter.ts | 5 ++-- .../sequences/gotoTrialSessionsSequence.ts | 2 +- 4 files changed, 34 insertions(+), 16 deletions(-) diff --git a/web-client/integration-tests/docketClerkViewsTrialSessionTabs.test.ts b/web-client/integration-tests/docketClerkViewsTrialSessionTabs.test.ts index 55c3b749588..92e0e24de72 100644 --- a/web-client/integration-tests/docketClerkViewsTrialSessionTabs.test.ts +++ b/web-client/integration-tests/docketClerkViewsTrialSessionTabs.test.ts @@ -47,7 +47,10 @@ describe('Docket Clerk Views Trial Session Tabs', () => { docketClerkCreatesATrialSession(cerebralTest, overrides); docketClerkViewsTrialSessionList(cerebralTest); // Trial Session should exist in New tab - docketClerkViewsTrialSessionsTab(cerebralTest, { tab: 'new' }); + docketClerkViewsTrialSessionsTab(cerebralTest, { + sessionStatus: 'All', + tab: 'new', + }); for (let i = 0; i < caseCount; i++) { const id = i + 1; @@ -65,15 +68,24 @@ describe('Docket Clerk Views Trial Session Tabs', () => { petitionsClerkSetsATrialSessionsSchedule(cerebralTest); loginAs(cerebralTest, 'docketclerk@example.com'); - // Trial Session should exist in Open tab - docketClerkViewsTrialSessionsTab(cerebralTest, { tab: 'calendared' }); + // Trial Session should exist in Open + docketClerkViewsTrialSessionsTab(cerebralTest, { + sessionStatus: 'Open', + tab: 'calendared', + }); loginAs(cerebralTest, 'petitionsclerk@example.com'); petitionsClerkManuallyRemovesCaseFromTrial(cerebralTest); loginAs(cerebralTest, 'docketclerk@example.com'); - // Trial Session should exist in Closed tab - docketClerkViewsTrialSessionsTab(cerebralTest, { tab: 'calendared' }); - // Trial Session should exist in All tab - docketClerkViewsTrialSessionsTab(cerebralTest, { tab: 'calendared' }); + // Trial Session should exist in Closed + docketClerkViewsTrialSessionsTab(cerebralTest, { + sessionStatus: 'Closed', + tab: 'calendared', + }); + // Trial Session should exist in All + docketClerkViewsTrialSessionsTab(cerebralTest, { + sessionStatus: 'All', + tab: 'calendared', + }); }); diff --git a/web-client/integration-tests/journey/docketClerkViewsTrialSessionsTab.ts b/web-client/integration-tests/journey/docketClerkViewsTrialSessionsTab.ts index c319aa023fe..1f164955c95 100644 --- a/web-client/integration-tests/journey/docketClerkViewsTrialSessionsTab.ts +++ b/web-client/integration-tests/journey/docketClerkViewsTrialSessionsTab.ts @@ -7,18 +7,23 @@ import { withAppContextDecorator } from '../../src/withAppContext'; export const docketClerkViewsTrialSessionsTab = ( cerebralTest: any, - overrides: { tab?: 'calendared' | 'new' } = { tab: 'calendared' }, + overrides: { + tab?: 'calendared' | 'new'; + sessionStatus?: 'Closed' | 'Open' | 'All'; + } = { + sessionStatus: 'Open', + tab: 'calendared', + }, ) => { const { tab } = overrides; return it(`Docket clerk views ${tab} Trial Sessions tab`, async () => { - await cerebralTest.runSequence('gotoTrialSessionsSequence', { - query: { - status: tab, - }, - }); + await cerebralTest.runSequence('gotoTrialSessionsSequence'); await cerebralTest.runSequence('setTrialSessionsFiltersSequence', { currentTab: tab, }); + await cerebralTest.runSequence('setTrialSessionsFiltersSequence', { + sessionStatus: overrides.sessionStatus, + }); expect(cerebralTest.getState('currentPage')).toEqual('TrialSessions'); diff --git a/web-client/src/presenter/presenter.ts b/web-client/src/presenter/presenter.ts index 9a5dece9267..7fc7a7ef8c5 100644 --- a/web-client/src/presenter/presenter.ts +++ b/web-client/src/presenter/presenter.ts @@ -952,8 +952,9 @@ export const presenterSequences = { gotoTrialSessionPlanningReportSequence as unknown as Function, gotoTrialSessionWorkingCopySequence: gotoTrialSessionWorkingCopySequence as unknown as Function, - gotoTrialSessionsSequence: gotoTrialSessionsSequence as unknown as Function, - gotoUpdatedPetitionFlowSequence, + gotoTrialSessionsSequence, + gotoUpdatedPetitionFlowSequence: + gotoUpdatedPetitionFlowSequence as unknown as Function, gotoUploadCorrespondenceDocumentSequence: gotoUploadCorrespondenceDocumentSequence as unknown as Function, gotoUploadCourtIssuedDocumentSequence: diff --git a/web-client/src/presenter/sequences/gotoTrialSessionsSequence.ts b/web-client/src/presenter/sequences/gotoTrialSessionsSequence.ts index 4d798aadf6b..c8cb98091a7 100644 --- a/web-client/src/presenter/sequences/gotoTrialSessionsSequence.ts +++ b/web-client/src/presenter/sequences/gotoTrialSessionsSequence.ts @@ -29,4 +29,4 @@ export const gotoTrialSessionsSequence = ], ]), setupCurrentPageAction('TrialSessions'), - ]); + ]) as unknown as () => void; From 2d14442aa7144de1edef0e0c7fd54a472415d4f1 Mon Sep 17 00:00:00 2001 From: Zachary Rogers Date: Tue, 10 Sep 2024 07:11:39 -0700 Subject: [PATCH 27/59] 10409: Update integration tests to reflect new trial sessions page state --- web-client/src/presenter/state.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/web-client/src/presenter/state.ts b/web-client/src/presenter/state.ts index ef2f8cf4155..d4e2e6187ac 100644 --- a/web-client/src/presenter/state.ts +++ b/web-client/src/presenter/state.ts @@ -847,6 +847,7 @@ export const baseState = { name: '', }, trialSessionWorkingCopy: cloneDeep(initialTrialSessionWorkingCopyState), + trialSessions: [] as any[], // Sometimes trialSessions, sometimes TrialSessionInfoDTO, sometimes ad-hoc trial sessions trialSessionsPage: cloneDeep(initialTrialSessionPageState), user: cloneDeep(emptyUserState), userContactEditProgress: {} as { inProgress?: boolean }, From 75858d862f3c23b643389259907cca7e9dcfaf50 Mon Sep 17 00:00:00 2001 From: Zachary Rogers Date: Tue, 10 Sep 2024 09:54:17 -0700 Subject: [PATCH 28/59] 10409: Remove validation before returning trial sessions. --- .../getTrialSessionsInteractor.test.ts | 15 +-------------- .../trialSessions/getTrialSessionsInteractor.ts | 5 +---- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/web-api/src/business/useCases/trialSessions/getTrialSessionsInteractor.test.ts b/web-api/src/business/useCases/trialSessions/getTrialSessionsInteractor.test.ts index 60e283bdd13..a6784a3fc35 100644 --- a/web-api/src/business/useCases/trialSessions/getTrialSessionsInteractor.test.ts +++ b/web-api/src/business/useCases/trialSessions/getTrialSessionsInteractor.test.ts @@ -10,7 +10,6 @@ import { mockPetitionerUser, mockPetitionsClerkUser, } from '@shared/test/mockAuthUsers'; -import { omit } from 'lodash'; describe('getTrialSessionsInteractor', () => { it('should throw an unauthorized error when the user does not have permission to view trial sessions', async () => { @@ -19,19 +18,7 @@ describe('getTrialSessionsInteractor', () => { ).rejects.toThrow(new UnauthorizedError('Unauthorized')); }); - it('should throw an error when the entity returned from persistence is invalid', async () => { - applicationContext - .getPersistenceGateway() - .getTrialSessions.mockResolvedValue([ - omit(MOCK_TRIAL_INPERSON, 'maxCases'), - ]); - - await expect( - getTrialSessionsInteractor(applicationContext, mockPetitionsClerkUser), - ).rejects.toThrow('The TrialSession entity was invalid.'); - }); - - it('should return a list of validated trial sessions', async () => { + it('should return a list of trial sessions', async () => { applicationContext .getPersistenceGateway() .getTrialSessions.mockResolvedValue([ diff --git a/web-api/src/business/useCases/trialSessions/getTrialSessionsInteractor.ts b/web-api/src/business/useCases/trialSessions/getTrialSessionsInteractor.ts index 854d6a181f6..fc5d1288edd 100644 --- a/web-api/src/business/useCases/trialSessions/getTrialSessionsInteractor.ts +++ b/web-api/src/business/useCases/trialSessions/getTrialSessionsInteractor.ts @@ -3,7 +3,6 @@ import { isAuthorized, } from '../../../../../shared/src/authorization/authorizationClientService'; import { ServerApplicationContext } from '@web-api/applicationContext'; -import { TrialSession } from '../../../../../shared/src/business/entities/trialSessions/TrialSession'; import { TrialSessionInfoDTO } from '../../../../../shared/src/business/dto/trialSessions/TrialSessionInfoDTO'; import { UnauthorizedError } from '@web-api/errors/errors'; import { UnknownAuthUser } from '@shared/business/entities/authUser/AuthUser'; @@ -22,9 +21,7 @@ export const getTrialSessionsInteractor = async ( applicationContext, }); - const validatedSessions = TrialSession.validateRawCollection(trialSessions); - - return validatedSessions.map( + return trialSessions.map( trialSession => new TrialSessionInfoDTO(trialSession), ); }; From 3536f6de351368516604fae4f6d6fa437a08fc84 Mon Sep 17 00:00:00 2001 From: Zachary Rogers Date: Tue, 10 Sep 2024 13:19:19 -0700 Subject: [PATCH 29/59] 10409: Make a new trialSession before turning into DTO so the NOTT can be recalculated --- .../useCases/trialSessions/getTrialSessionsInteractor.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/web-api/src/business/useCases/trialSessions/getTrialSessionsInteractor.ts b/web-api/src/business/useCases/trialSessions/getTrialSessionsInteractor.ts index fc5d1288edd..54491f7e430 100644 --- a/web-api/src/business/useCases/trialSessions/getTrialSessionsInteractor.ts +++ b/web-api/src/business/useCases/trialSessions/getTrialSessionsInteractor.ts @@ -3,6 +3,7 @@ import { isAuthorized, } from '../../../../../shared/src/authorization/authorizationClientService'; import { ServerApplicationContext } from '@web-api/applicationContext'; +import { TrialSession } from '@shared/business/entities/trialSessions/TrialSession'; import { TrialSessionInfoDTO } from '../../../../../shared/src/business/dto/trialSessions/TrialSessionInfoDTO'; import { UnauthorizedError } from '@web-api/errors/errors'; import { UnknownAuthUser } from '@shared/business/entities/authUser/AuthUser'; @@ -21,7 +22,7 @@ export const getTrialSessionsInteractor = async ( applicationContext, }); - return trialSessions.map( - trialSession => new TrialSessionInfoDTO(trialSession), - ); + return trialSessions + .map(t => new TrialSession(t).toRawObject()) + .map(trialSession => new TrialSessionInfoDTO(trialSession)); }; From eda57a0bb1cd65ae27d3856e8c02981373aed7f8 Mon Sep 17 00:00:00 2001 From: Zachary Rogers Date: Tue, 10 Sep 2024 14:49:37 -0700 Subject: [PATCH 30/59] 10409 calculate isStartDateWithinNOTTReminderRange --- .../dto/trialSessions/TrialSessionInfoDTO.ts | 3 -- ...TrialSession.noticeOfTrialReminder.test.ts | 20 ++++++--- .../entities/trialSessions/TrialSession.ts | 41 +++++++++++++------ .../formattedTrialSessionDetails.test.ts | 14 ++++--- .../computeds/formattedTrialSessionDetails.ts | 6 ++- .../computeds/trialSessionsHelper.test.ts | 7 +++- .../computeds/trialSessionsHelper.ts | 6 ++- 7 files changed, 67 insertions(+), 30 deletions(-) diff --git a/shared/src/business/dto/trialSessions/TrialSessionInfoDTO.ts b/shared/src/business/dto/trialSessions/TrialSessionInfoDTO.ts index f3291519721..87ae68e9b11 100644 --- a/shared/src/business/dto/trialSessions/TrialSessionInfoDTO.ts +++ b/shared/src/business/dto/trialSessions/TrialSessionInfoDTO.ts @@ -21,15 +21,12 @@ export class TrialSessionInfoDTO { public sessionStatus: string; public swingSession?: boolean; public dismissedAlertForNOTT?: boolean; - public isStartDateWithinNOTTReminderRange?: boolean; public thirtyDaysBeforeTrialFormatted?: string; constructor(rawTrialSession: RawTrialSession) { this.estimatedEndDate = rawTrialSession.estimatedEndDate; this.isCalendared = rawTrialSession.isCalendared; this.judge = rawTrialSession.judge; - this.isStartDateWithinNOTTReminderRange = - rawTrialSession.isStartDateWithinNOTTReminderRange; this.thirtyDaysBeforeTrialFormatted = rawTrialSession.thirtyDaysBeforeTrialFormatted; this.proceedingType = rawTrialSession.proceedingType; diff --git a/shared/src/business/entities/trialSessions/TrialSession.noticeOfTrialReminder.test.ts b/shared/src/business/entities/trialSessions/TrialSession.noticeOfTrialReminder.test.ts index 3e0ff04614b..da856eb91c8 100644 --- a/shared/src/business/entities/trialSessions/TrialSession.noticeOfTrialReminder.test.ts +++ b/shared/src/business/entities/trialSessions/TrialSession.noticeOfTrialReminder.test.ts @@ -20,17 +20,22 @@ describe('TrialSession entity', () => { { daysFromToday: 34, expectedOutput: true }, { daysFromToday: 35, expectedOutput: false }, ]; - it('should set isStartDateWithinNOTTReminderRange to false when the trial session is not calendared', () => { + it('should return false when the trial session is not calendared', () => { const trialSession = new TrialSession({ ...MOCK_TRIAL_REGULAR, isCalendared: false, }); - expect(trialSession.isStartDateWithinNOTTReminderRange).toBe(false); + expect( + TrialSession.isStartDateWithinNOTTReminderRange({ + isCalendared: trialSession.isCalendared, + startDate: trialSession.startDate, + }), + ).toBe(false); }); tests.forEach(({ daysFromToday, expectedOutput }) => { - it(`should set isStartDateWithinNOTTReminderRange to ${expectedOutput} when the trial session is calendared and the start date is ${daysFromToday} days from today`, () => { + it(`should return ${expectedOutput} when the trial session is calendared and the start date is ${daysFromToday} days from today`, () => { const thirtyDaysFromToday = today.plus({ ['days']: daysFromToday }); const trialSession = new TrialSession({ @@ -39,9 +44,12 @@ describe('TrialSession entity', () => { startDate: thirtyDaysFromToday, }); - expect(trialSession.isStartDateWithinNOTTReminderRange).toBe( - expectedOutput, - ); + expect( + TrialSession.isStartDateWithinNOTTReminderRange({ + isCalendared: trialSession.isCalendared, + startDate: trialSession.startDate, + }), + ).toBe(expectedOutput); }); }); }); diff --git a/shared/src/business/entities/trialSessions/TrialSession.ts b/shared/src/business/entities/trialSessions/TrialSession.ts index 570050287da..d46335e5b8c 100644 --- a/shared/src/business/entities/trialSessions/TrialSession.ts +++ b/shared/src/business/entities/trialSessions/TrialSession.ts @@ -87,7 +87,6 @@ export class TrialSession extends JoiValidationEntity { public irsCalendarAdministratorInfo?: RawIrsCalendarAdministratorInfo; public isCalendared: boolean; public isClosed?: boolean; - public isStartDateWithinNOTTReminderRange?: boolean; public joinPhoneNumber?: string; public judge?: TJudge; public maxCases?: number; @@ -200,8 +199,6 @@ export class TrialSession extends JoiValidationEntity { if (rawSession.isCalendared && rawSession.startDate) { this.setNoticeOfTrialReminderAlert(); - } else { - this.isStartDateWithinNOTTReminderRange = false; } if (rawSession.trialClerk && rawSession.trialClerk.name) { @@ -216,6 +213,33 @@ export class TrialSession extends JoiValidationEntity { return sessionScope === TRIAL_SESSION_SCOPE_TYPES.standaloneRemote; } + static isStartDateWithinNOTTReminderRange({ + isCalendared, + startDate, + }: { + isCalendared?: boolean; + startDate?: string; + }): boolean { + if (!isCalendared || !startDate) { + return false; + } + + const formattedStartDate = formatDateString(startDate, FORMATS.MMDDYY); + const trialStartDateString = prepareDateFromString( + formattedStartDate, + FORMATS.MMDDYY, + ); + + return isTodayWithinGivenInterval({ + intervalEndDate: trialStartDateString.minus({ + ['days']: 24, // luxon's interval end date is not inclusive + }), + intervalStartDate: trialStartDateString.minus({ + ['days']: 34, + }), + }); + } + static validationRules = { COMMON: { address1: JoiValidationConstants.STRING.max(100).allow('').optional(), @@ -408,20 +432,11 @@ export class TrialSession extends JoiValidationEntity { setNoticeOfTrialReminderAlert() { const formattedStartDate = formatDateString(this.startDate, FORMATS.MMDDYY); - const trialStartDateString: any = prepareDateFromString( + const trialStartDateString = prepareDateFromString( formattedStartDate, FORMATS.MMDDYY, ); - this.isStartDateWithinNOTTReminderRange = isTodayWithinGivenInterval({ - intervalEndDate: trialStartDateString.minus({ - ['days']: 24, // luxon's interval end date is not inclusive - }), - intervalStartDate: trialStartDateString.minus({ - ['days']: 34, - }), - }); - const thirtyDaysBeforeTrialInclusive: any = trialStartDateString.minus({ ['days']: 29, }); diff --git a/web-client/src/presenter/computeds/formattedTrialSessionDetails.test.ts b/web-client/src/presenter/computeds/formattedTrialSessionDetails.test.ts index 5f7ac902ce3..b6d1ca36b6d 100644 --- a/web-client/src/presenter/computeds/formattedTrialSessionDetails.test.ts +++ b/web-client/src/presenter/computeds/formattedTrialSessionDetails.test.ts @@ -6,6 +6,7 @@ import { TRIAL_SESSION_SCOPE_TYPES, } from '../../../../shared/src/business/entities/EntityConstants'; import { applicationContextForClient as applicationContext } from '@web-client/test/createClientTestApplicationContext'; +import { calculateISODate } from '@shared/business/utilities/DateHandler'; import { colvinsChambersUser, docketClerkUser, @@ -522,11 +523,12 @@ describe('formattedTrialSessionDetails', () => { }); describe('NOTT reminder', () => { - it('should set showAlertForNOTTReminder to true when the alert has not been previously dismissed and isStartDateWithinNOTTReminderRange is true', () => { + it('should set showAlertForNOTTReminder to true when the alert has not been previously dismissed and start date is within NOTT reminder range', () => { mockTrialSession = { ...TRIAL_SESSION, dismissedAlertForNOTT: false, - isStartDateWithinNOTTReminderRange: true, + isCalendared: true, + startDate: calculateISODate({ howMuch: 30, units: 'days' }), thirtyDaysBeforeTrialFormatted: '2/2/2022', }; @@ -549,7 +551,8 @@ describe('formattedTrialSessionDetails', () => { mockTrialSession = { ...TRIAL_SESSION, dismissedAlertForNOTT: true, - isStartDateWithinNOTTReminderRange: true, + isCalendared: true, + startDate: calculateISODate({ howMuch: 30, units: 'days' }), }; const result: any = runCompute(formattedTrialSessionDetails, { @@ -565,11 +568,12 @@ describe('formattedTrialSessionDetails', () => { expect(result.alertMessageForNOTT).toBeUndefined(); }); - it('should set showAlertForNOTTReminder to false when isStartDateWithinNOTTReminderRange is false', () => { + it('should set showAlertForNOTTReminder to false when start date is within NOTT reminder range', () => { mockTrialSession = { ...TRIAL_SESSION, dismissedAlertForNOTT: true, - isStartDateWithinNOTTReminderRange: false, + isCalendared: true, + startDate: calculateISODate({ howMuch: 60, units: 'days' }), }; const result: any = runCompute(formattedTrialSessionDetails, { diff --git a/web-client/src/presenter/computeds/formattedTrialSessionDetails.ts b/web-client/src/presenter/computeds/formattedTrialSessionDetails.ts index f4f17cbfb68..90a7e6b3037 100644 --- a/web-client/src/presenter/computeds/formattedTrialSessionDetails.ts +++ b/web-client/src/presenter/computeds/formattedTrialSessionDetails.ts @@ -1,6 +1,7 @@ import { ClientApplicationContext } from '@web-client/applicationContext'; import { FormattedTrialSessionDetailsType } from '@shared/business/utilities/getFormattedTrialSessionDetails'; import { Get } from 'cerebral'; +import { TrialSession } from '@shared/business/entities/trialSessions/TrialSession'; import { isEmpty, isEqual } from 'lodash'; import { state } from '@web-client/presenter/app.cerebral'; @@ -58,7 +59,10 @@ export const formattedTrialSessionDetails = ( showAlertForNOTTReminder = !formattedTrialSession.dismissedAlertForNOTT && - !!formattedTrialSession.isStartDateWithinNOTTReminderRange && + TrialSession.isStartDateWithinNOTTReminderRange({ + isCalendared: formattedTrialSession.isCalendared, + startDate: formattedTrialSession.startDate, + }) && formattedTrialSession.sessionStatus !== SESSION_STATUS_TYPES.closed; if (showAlertForNOTTReminder) { diff --git a/web-client/src/presenter/computeds/trialSessionsHelper.test.ts b/web-client/src/presenter/computeds/trialSessionsHelper.test.ts index c4acd6171e4..69fa7724e74 100644 --- a/web-client/src/presenter/computeds/trialSessionsHelper.test.ts +++ b/web-client/src/presenter/computeds/trialSessionsHelper.test.ts @@ -6,6 +6,7 @@ import { TRIAL_SESSION_SCOPE_TYPES, } from '../../../../shared/src/business/entities/EntityConstants'; import { TrialSessionInfoDTO } from '@shared/business/dto/trialSessions/TrialSessionInfoDTO'; +import { calculateISODate } from '@shared/business/utilities/DateHandler'; import { cloneDeep } from 'lodash'; import { docketClerk1User, judgeUser } from '@shared/test/mockUsers'; import { getUserPermissions } from '@shared/authorization/getUserPermissions'; @@ -513,7 +514,11 @@ describe('trialSessionsHelper', () => { it('should show an alertMessage for NOTT reminders when the user has not dismissed the alert and the start day is within the reminder range', () => { trialSession1.dismissedAlertForNOTT = false; - trialSession1.isStartDateWithinNOTTReminderRange = true; + trialSession1.isCalendared = true; + trialSession1.startDate = calculateISODate({ + howMuch: 30, + units: 'days', + }); trialSession1.thirtyDaysBeforeTrialFormatted = '06/03/13'; trialSessionsPageState.trialSessions = [trialSession1]; diff --git a/web-client/src/presenter/computeds/trialSessionsHelper.ts b/web-client/src/presenter/computeds/trialSessionsHelper.ts index aa7cd6a73f9..56ade66e792 100644 --- a/web-client/src/presenter/computeds/trialSessionsHelper.ts +++ b/web-client/src/presenter/computeds/trialSessionsHelper.ts @@ -5,6 +5,7 @@ import { } from '@shared/business/utilities/DateHandler'; import { Get } from 'cerebral'; import { RawUser } from '@shared/business/entities/User'; +import { TrialSession } from '@shared/business/entities/trialSessions/TrialSession'; import { TrialSessionInfoDTO } from '@shared/business/dto/trialSessions/TrialSessionInfoDTO'; import { state } from '@web-client/presenter/app.cerebral'; @@ -93,7 +94,10 @@ const formatTrialSessions = ({ trialSession => { const showAlertForNOTTReminder = !trialSession.dismissedAlertForNOTT && - !!trialSession.isStartDateWithinNOTTReminderRange; + TrialSession.isStartDateWithinNOTTReminderRange({ + isCalendared: trialSession.isCalendared, + startDate: trialSession.startDate, + }); const alertMessageForNOTT = showAlertForNOTTReminder ? `The 30-day notice is due by ${trialSession.thirtyDaysBeforeTrialFormatted}` From 147596178a84c5ccb78bf78a9113363ea68c92c1 Mon Sep 17 00:00:00 2001 From: Zachary Rogers Date: Tue, 10 Sep 2024 15:39:03 -0700 Subject: [PATCH 31/59] 10409 calculate thirtyDaysBeforeTrialFormatted instead of storing on entity. Move to presenter layer --- .../dto/trialSessions/TrialSessionInfoDTO.ts | 3 --- ...ion.thirtyDaysBeforeTrialFormatted.test.ts | 18 --------------- .../entities/trialSessions/TrialSession.ts | 22 ------------------- .../dismissNOTTReminder.test.ts | 14 ++++++++---- .../serveNOTTsFromReminder.test.ts | 9 +++++--- .../formattedTrialSessionDetails.test.ts | 11 ++++++---- .../computeds/formattedTrialSessionDetails.ts | 3 ++- .../computeds/trialSessionsHelper.test.ts | 11 ++++++---- .../computeds/trialSessionsHelper.ts | 10 ++++++++- 9 files changed, 41 insertions(+), 60 deletions(-) delete mode 100644 shared/src/business/entities/trialSessions/TrialSession.thirtyDaysBeforeTrialFormatted.test.ts diff --git a/shared/src/business/dto/trialSessions/TrialSessionInfoDTO.ts b/shared/src/business/dto/trialSessions/TrialSessionInfoDTO.ts index 87ae68e9b11..fca87992417 100644 --- a/shared/src/business/dto/trialSessions/TrialSessionInfoDTO.ts +++ b/shared/src/business/dto/trialSessions/TrialSessionInfoDTO.ts @@ -21,14 +21,11 @@ export class TrialSessionInfoDTO { public sessionStatus: string; public swingSession?: boolean; public dismissedAlertForNOTT?: boolean; - public thirtyDaysBeforeTrialFormatted?: string; constructor(rawTrialSession: RawTrialSession) { this.estimatedEndDate = rawTrialSession.estimatedEndDate; this.isCalendared = rawTrialSession.isCalendared; this.judge = rawTrialSession.judge; - this.thirtyDaysBeforeTrialFormatted = - rawTrialSession.thirtyDaysBeforeTrialFormatted; this.proceedingType = rawTrialSession.proceedingType; this.sessionType = rawTrialSession.sessionType; this.startDate = rawTrialSession.startDate; diff --git a/shared/src/business/entities/trialSessions/TrialSession.thirtyDaysBeforeTrialFormatted.test.ts b/shared/src/business/entities/trialSessions/TrialSession.thirtyDaysBeforeTrialFormatted.test.ts deleted file mode 100644 index 4e4c6d00d6e..00000000000 --- a/shared/src/business/entities/trialSessions/TrialSession.thirtyDaysBeforeTrialFormatted.test.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { MOCK_TRIAL_REGULAR } from '../../../test/mockTrial'; -import { TrialSession } from './TrialSession'; - -describe('TrialSession entity', () => { - describe('thirtyDaysBeforeTrialFormatted', () => { - // this is how the court was calculating the duration days between dates - // https://www.timeanddate.com/date/durationresult.html?m1=5&d1=17&y1=2023&m2=6&d2=15&y2=2023&ti=on - it("should set thirtyDaysBeforeTrialFormatted to 30 days prior to the trial's startDate, inclusive of the startDate, when the trial session is calendared", () => { - const trialSession = new TrialSession({ - ...MOCK_TRIAL_REGULAR, - isCalendared: true, - startDate: '2023-06-15', - }); - - expect(trialSession.thirtyDaysBeforeTrialFormatted).toBe('05/17/23'); - }); - }); -}); diff --git a/shared/src/business/entities/trialSessions/TrialSession.ts b/shared/src/business/entities/trialSessions/TrialSession.ts index d46335e5b8c..bba85f21107 100644 --- a/shared/src/business/entities/trialSessions/TrialSession.ts +++ b/shared/src/business/entities/trialSessions/TrialSession.ts @@ -106,7 +106,6 @@ export class TrialSession extends JoiValidationEntity { public swingSessionId?: string; public term: string; public termYear: string; - public thirtyDaysBeforeTrialFormatted?: string; public trialClerk?: TTrialClerk; public trialLocation?: string; public trialSessionId?: string; @@ -197,10 +196,6 @@ export class TrialSession extends JoiValidationEntity { }; } - if (rawSession.isCalendared && rawSession.startDate) { - this.setNoticeOfTrialReminderAlert(); - } - if (rawSession.trialClerk && rawSession.trialClerk.name) { this.trialClerk = { name: rawSession.trialClerk.name, @@ -430,23 +425,6 @@ export class TrialSession extends JoiValidationEntity { return skPrefix; } - setNoticeOfTrialReminderAlert() { - const formattedStartDate = formatDateString(this.startDate, FORMATS.MMDDYY); - const trialStartDateString = prepareDateFromString( - formattedStartDate, - FORMATS.MMDDYY, - ); - - const thirtyDaysBeforeTrialInclusive: any = trialStartDateString.minus({ - ['days']: 29, - }); - - this.thirtyDaysBeforeTrialFormatted = formatDateString( - thirtyDaysBeforeTrialInclusive, - FORMATS.MMDDYY, - ); - } - setAsCalendared() { this.isCalendared = true; this.sessionStatus = SESSION_STATUS_TYPES.open; diff --git a/web-client/integration-tests/dismissNOTTReminder.test.ts b/web-client/integration-tests/dismissNOTTReminder.test.ts index e113eafa988..10d50993a69 100644 --- a/web-client/integration-tests/dismissNOTTReminder.test.ts +++ b/web-client/integration-tests/dismissNOTTReminder.test.ts @@ -93,8 +93,11 @@ describe('Dismiss NOTT reminder on calendared trial session within 30-35 day ran }, ); - expect(trialSessionDetailsFormatted.alertMessageForNOTT).toEqual( - `30-day trial notices are due by ${trialSessionDetailsFormatted.thirtyDaysBeforeTrialFormatted}. Have notices been served?`, + expect(trialSessionDetailsFormatted.alertMessageForNOTT).toContain( + '30-day trial notices are due by', + ); + expect(trialSessionDetailsFormatted.alertMessageForNOTT).toContain( + 'Have notices been served?', ); let trialSessionDetailsHelperComputed: any = runCompute( @@ -130,8 +133,11 @@ describe('Dismiss NOTT reminder on calendared trial session within 30-35 day ran }, ); - expect(trialSessionDetailsFormatted.alertMessageForNOTT).toEqual( - `30-day trial notices are due by ${trialSessionDetailsFormatted.thirtyDaysBeforeTrialFormatted}. Have notices been served?`, + expect(trialSessionDetailsFormatted.alertMessageForNOTT).toContain( + '30-day trial notices are due by', + ); + expect(trialSessionDetailsFormatted.alertMessageForNOTT).toContain( + 'Have notices been served?', ); let trialSessionDetailsHelperComputed: any = runCompute( diff --git a/web-client/integration-tests/serveNOTTsFromReminder.test.ts b/web-client/integration-tests/serveNOTTsFromReminder.test.ts index 3f380a9b8c8..298b9496e83 100644 --- a/web-client/integration-tests/serveNOTTsFromReminder.test.ts +++ b/web-client/integration-tests/serveNOTTsFromReminder.test.ts @@ -107,15 +107,18 @@ describe('Serve NOTTs from reminder on calendared trial session detail page', () trialSessionId: cerebralTest.trialSessionId, }); - const trialSessionDetailsFormatted: any = runCompute( + const trialSessionDetailsFormatted = runCompute( withAppContextDecorator(formattedTrialSessionDetails), { state: cerebralTest.getState(), }, ); - expect(trialSessionDetailsFormatted.alertMessageForNOTT).toEqual( - `30-day trial notices are due by ${trialSessionDetailsFormatted.thirtyDaysBeforeTrialFormatted}. Have notices been served?`, + expect(trialSessionDetailsFormatted.alertMessageForNOTT).toContain( + '30-day trial notices are due by', + ); + expect(trialSessionDetailsFormatted.alertMessageForNOTT).toContain( + 'Have notices been served?', ); }); diff --git a/web-client/src/presenter/computeds/formattedTrialSessionDetails.test.ts b/web-client/src/presenter/computeds/formattedTrialSessionDetails.test.ts index b6d1ca36b6d..cd255d525bb 100644 --- a/web-client/src/presenter/computeds/formattedTrialSessionDetails.test.ts +++ b/web-client/src/presenter/computeds/formattedTrialSessionDetails.test.ts @@ -1,3 +1,8 @@ +import { + FORMATS, + calculateISODate, + formatNow, +} from '@shared/business/utilities/DateHandler'; import { HYBRID_SESSION_TYPES, SESSION_STATUS_GROUPS, @@ -6,7 +11,6 @@ import { TRIAL_SESSION_SCOPE_TYPES, } from '../../../../shared/src/business/entities/EntityConstants'; import { applicationContextForClient as applicationContext } from '@web-client/test/createClientTestApplicationContext'; -import { calculateISODate } from '@shared/business/utilities/DateHandler'; import { colvinsChambersUser, docketClerkUser, @@ -528,8 +532,7 @@ describe('formattedTrialSessionDetails', () => { ...TRIAL_SESSION, dismissedAlertForNOTT: false, isCalendared: true, - startDate: calculateISODate({ howMuch: 30, units: 'days' }), - thirtyDaysBeforeTrialFormatted: '2/2/2022', + startDate: calculateISODate({ howMuch: 29, units: 'days' }), }; const result: any = runCompute(formattedTrialSessionDetails, { @@ -543,7 +546,7 @@ describe('formattedTrialSessionDetails', () => { expect(result.showAlertForNOTTReminder).toBe(true); expect(result.alertMessageForNOTT).toEqual( - '30-day trial notices are due by 2/2/2022. Have notices been served?', + `30-day trial notices are due by ${formatNow(FORMATS.MMDDYY)}. Have notices been served?`, ); }); diff --git a/web-client/src/presenter/computeds/formattedTrialSessionDetails.ts b/web-client/src/presenter/computeds/formattedTrialSessionDetails.ts index 90a7e6b3037..ff5d83d8434 100644 --- a/web-client/src/presenter/computeds/formattedTrialSessionDetails.ts +++ b/web-client/src/presenter/computeds/formattedTrialSessionDetails.ts @@ -4,6 +4,7 @@ import { Get } from 'cerebral'; import { TrialSession } from '@shared/business/entities/trialSessions/TrialSession'; import { isEmpty, isEqual } from 'lodash'; import { state } from '@web-client/presenter/app.cerebral'; +import { thirtyDaysBeforeTrial } from '@web-client/presenter/computeds/trialSessionsHelper'; type FormatTrialSessionHelperType = FormattedTrialSessionDetailsType & { alertMessageForNOTT?: string; @@ -66,7 +67,7 @@ export const formattedTrialSessionDetails = ( formattedTrialSession.sessionStatus !== SESSION_STATUS_TYPES.closed; if (showAlertForNOTTReminder) { - alertMessageForNOTT = `30-day trial notices are due by ${formattedTrialSession.thirtyDaysBeforeTrialFormatted}. Have notices been served?`; + alertMessageForNOTT = `30-day trial notices are due by ${thirtyDaysBeforeTrial(formattedTrialSession.startDate)}. Have notices been served?`; } if (formattedTrialSession.chambersPhoneNumber) { diff --git a/web-client/src/presenter/computeds/trialSessionsHelper.test.ts b/web-client/src/presenter/computeds/trialSessionsHelper.test.ts index 69fa7724e74..d2b814c8e81 100644 --- a/web-client/src/presenter/computeds/trialSessionsHelper.test.ts +++ b/web-client/src/presenter/computeds/trialSessionsHelper.test.ts @@ -1,3 +1,8 @@ +import { + FORMATS, + calculateISODate, + formatNow, +} from '@shared/business/utilities/DateHandler'; import { ROLES, SESSION_STATUS_TYPES, @@ -6,7 +11,6 @@ import { TRIAL_SESSION_SCOPE_TYPES, } from '../../../../shared/src/business/entities/EntityConstants'; import { TrialSessionInfoDTO } from '@shared/business/dto/trialSessions/TrialSessionInfoDTO'; -import { calculateISODate } from '@shared/business/utilities/DateHandler'; import { cloneDeep } from 'lodash'; import { docketClerk1User, judgeUser } from '@shared/test/mockUsers'; import { getUserPermissions } from '@shared/authorization/getUserPermissions'; @@ -516,10 +520,9 @@ describe('trialSessionsHelper', () => { trialSession1.dismissedAlertForNOTT = false; trialSession1.isCalendared = true; trialSession1.startDate = calculateISODate({ - howMuch: 30, + howMuch: 29, units: 'days', }); - trialSession1.thirtyDaysBeforeTrialFormatted = '06/03/13'; trialSessionsPageState.trialSessions = [trialSession1]; const result = runCompute(trialSessionsHelper, { @@ -532,7 +535,7 @@ describe('trialSessionsHelper', () => { const trialSessionsOnly = result.trialSessionRows.filter(isTrialSessionRow); expect(trialSessionsOnly[0].alertMessageForNOTT).toEqual( - `The 30-day notice is due by ${trialSession1.thirtyDaysBeforeTrialFormatted}`, + `The 30-day notice is due by ${formatNow(FORMATS.MMDDYY)}`, ); expect(trialSessionsOnly[0].showAlertForNOTTReminder).toEqual(true); }); diff --git a/web-client/src/presenter/computeds/trialSessionsHelper.ts b/web-client/src/presenter/computeds/trialSessionsHelper.ts index 56ade66e792..3ce8a569ee8 100644 --- a/web-client/src/presenter/computeds/trialSessionsHelper.ts +++ b/web-client/src/presenter/computeds/trialSessionsHelper.ts @@ -2,6 +2,7 @@ import { FORMATS, createDateAtStartOfWeekEST, formatDateString, + subtractISODates, } from '@shared/business/utilities/DateHandler'; import { Get } from 'cerebral'; import { RawUser } from '@shared/business/entities/User'; @@ -100,7 +101,7 @@ const formatTrialSessions = ({ }); const alertMessageForNOTT = showAlertForNOTTReminder - ? `The 30-day notice is due by ${trialSession.thirtyDaysBeforeTrialFormatted}` + ? `The 30-day notice is due by ${thirtyDaysBeforeTrial(trialSession.startDate)}` : ''; const formattedEstimatedEndDate = formatDateString( trialSession.estimatedEndDate, @@ -172,6 +173,13 @@ const formatTrialSessions = ({ return trialSessionWithStartWeeks; }; +export const thirtyDaysBeforeTrial = (startDate?: string): string => { + if (!startDate) return ''; + const thirtyDaysBeforeTrialIso = subtractISODates(startDate, { day: 29 }); + + return formatDateString(thirtyDaysBeforeTrialIso, FORMATS.MMDDYY); +}; + type TrialSessionRow = { trialSessionId: string; showAlertForNOTTReminder: boolean; From 6fd73e3ac064afc8a03f93848b283f2a5f64eaef Mon Sep 17 00:00:00 2001 From: Zachary Rogers Date: Wed, 11 Sep 2024 10:29:26 -0700 Subject: [PATCH 32/59] 10409 always route the user to the new tab once they have created a trial session --- .../setActiveTrialSessionsTabAction.test.ts | 19 ++----------------- .../setActiveTrialSessionsTabAction.ts | 13 ++----------- 2 files changed, 4 insertions(+), 28 deletions(-) diff --git a/web-client/src/presenter/actions/TrialSession/setActiveTrialSessionsTabAction.test.ts b/web-client/src/presenter/actions/TrialSession/setActiveTrialSessionsTabAction.test.ts index b1358480693..c1a64879083 100644 --- a/web-client/src/presenter/actions/TrialSession/setActiveTrialSessionsTabAction.test.ts +++ b/web-client/src/presenter/actions/TrialSession/setActiveTrialSessionsTabAction.test.ts @@ -1,27 +1,12 @@ -import { TRIAL_SESSION_SCOPE_TYPES } from '@shared/business/entities/EntityConstants'; import { runAction } from '@web-client/presenter/test.cerebral'; import { setActiveTrialSessionsTabAction } from '@web-client/presenter/actions/TrialSession/setActiveTrialSessionsTabAction'; describe('setActiveTrialSessionsTabAction', () => { - it('sets state.currentViewMetadata.tab to new when props.sessionScope location-based', async () => { + it('sets the trial sessions page tab to new after creating a trial session so the user can see their newly created trial sesison', async () => { const result = await runAction(setActiveTrialSessionsTabAction, { - props: { - sessionScope: TRIAL_SESSION_SCOPE_TYPES.locationBased, - }, state: {}, }); - expect(result.state.currentViewMetadata.trialSessions.tab).toEqual('new'); - }); - - it('sets state.currentViewMetadata.tab to open when props.sessionScope is not location-based', async () => { - const result = await runAction(setActiveTrialSessionsTabAction, { - props: { - sessionScope: TRIAL_SESSION_SCOPE_TYPES.standaloneRemote, - }, - state: {}, - }); - - expect(result.state.currentViewMetadata.trialSessions.tab).toEqual('open'); + expect(result.state.trialSessionsPage.filters.currentTab).toEqual('new'); }); }); diff --git a/web-client/src/presenter/actions/TrialSession/setActiveTrialSessionsTabAction.ts b/web-client/src/presenter/actions/TrialSession/setActiveTrialSessionsTabAction.ts index 6c1da46e62a..0d66660a724 100644 --- a/web-client/src/presenter/actions/TrialSession/setActiveTrialSessionsTabAction.ts +++ b/web-client/src/presenter/actions/TrialSession/setActiveTrialSessionsTabAction.ts @@ -1,17 +1,8 @@ -import { - TRIAL_SESSION_SCOPE_TYPES, - TrialSessionScope, -} from '@shared/business/entities/EntityConstants'; +import { TrialSessionScope } from '@shared/business/entities/EntityConstants'; import { state } from '@web-client/presenter/app.cerebral'; export const setActiveTrialSessionsTabAction = ({ - props, store, }: ActionProps<{ sessionScope: TrialSessionScope }>) => { - const activeTab = - props.sessionScope === TRIAL_SESSION_SCOPE_TYPES.locationBased - ? 'new' - : 'open'; - - store.set(state.currentViewMetadata.trialSessions.tab, activeTab); + store.set(state.trialSessionsPage.filters.currentTab, 'new'); }; From 4f289cd29b1fefab77ddbb5b86a3e878f97093c8 Mon Sep 17 00:00:00 2001 From: Zachary Rogers Date: Wed, 11 Sep 2024 10:57:01 -0700 Subject: [PATCH 33/59] 10409 add query params back when navigating to trial sessions --- .../src/presenter/sequences/gotoTrialSessionsSequence.ts | 5 ++++- web-client/src/router.ts | 3 ++- web-client/src/views/TrialSessions/TrialSessionsSummary.tsx | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/web-client/src/presenter/sequences/gotoTrialSessionsSequence.ts b/web-client/src/presenter/sequences/gotoTrialSessionsSequence.ts index c8cb98091a7..3a11c70f1eb 100644 --- a/web-client/src/presenter/sequences/gotoTrialSessionsSequence.ts +++ b/web-client/src/presenter/sequences/gotoTrialSessionsSequence.ts @@ -1,3 +1,4 @@ +import { TrialSessionsFilters } from '@web-client/presenter/state/trialSessionsPageState'; import { clearErrorAlertsAction } from '../actions/clearErrorAlertsAction'; import { clearScreenMetadataAction } from '../actions/clearScreenMetadataAction'; import { closeMobileMenuAction } from '../actions/closeMobileMenuAction'; @@ -9,6 +10,7 @@ import { parallel } from 'cerebral/factories'; import { setAllAndCurrentJudgesAction } from '../actions/setAllAndCurrentJudgesAction'; import { setJudgeUserAction } from '../actions/setJudgeUserAction'; import { setNotificationsAction } from '../actions/setNotificationsAction'; +import { setTrialSessionsFiltersAction } from '@web-client/presenter/actions/TrialSession/setTrialSessionsFiltersAction'; import { setTrialSessionsPageAction } from '@web-client/presenter/actions/TrialSession/setTrialSessionsPageAction'; import { setupCurrentPageAction } from '../actions/setupCurrentPageAction'; import { startWebSocketConnectionSequenceDecorator } from '../utilities/startWebSocketConnectionSequenceDecorator'; @@ -19,6 +21,7 @@ export const gotoTrialSessionsSequence = clearScreenMetadataAction, closeMobileMenuAction, clearErrorAlertsAction, + setTrialSessionsFiltersAction, parallel([ [getJudgeForCurrentUserAction, setJudgeUserAction], [getNotificationsAction, setNotificationsAction], @@ -29,4 +32,4 @@ export const gotoTrialSessionsSequence = ], ]), setupCurrentPageAction('TrialSessions'), - ]) as unknown as () => void; + ]) as unknown as (props: ActionProps>) => void; diff --git a/web-client/src/router.ts b/web-client/src/router.ts index 0418fe1c75f..4b6788787bf 100644 --- a/web-client/src/router.ts +++ b/web-client/src/router.ts @@ -1147,8 +1147,9 @@ const router = { ifHasAccess( { app, permissionToCheck: ROLE_PERMISSIONS.TRIAL_SESSIONS }, () => { + const queryParams = route.query(); setPageTitle('Trial sessions'); - return app.getSequence('gotoTrialSessionsSequence')(); + return app.getSequence('gotoTrialSessionsSequence')(queryParams); }, ), ); diff --git a/web-client/src/views/TrialSessions/TrialSessionsSummary.tsx b/web-client/src/views/TrialSessions/TrialSessionsSummary.tsx index e587f21740c..14fdf373f5d 100644 --- a/web-client/src/views/TrialSessions/TrialSessionsSummary.tsx +++ b/web-client/src/views/TrialSessions/TrialSessionsSummary.tsx @@ -24,7 +24,7 @@ export const TrialSessionsSummary = connect( link className="margin-left-205" data-testid="view-all-trial-sessions-button" - href={`/trial-sessions?judge[userId]=${trialSessionsSummaryHelper.judgeUserId}`} + href={`/trial-sessions?judgeId=${trialSessionsSummaryHelper.judgeUserId}`} > View All From 79c56e90fc4977797f5115a6a15388159b2f357f Mon Sep 17 00:00:00 2001 From: Zachary Rogers Date: Wed, 11 Sep 2024 11:52:54 -0700 Subject: [PATCH 34/59] 10409 look at calendared trial sessions after making one --- web-client/integration-tests/dismissNOTTReminder.test.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/web-client/integration-tests/dismissNOTTReminder.test.ts b/web-client/integration-tests/dismissNOTTReminder.test.ts index 10d50993a69..33c6ed0dcf2 100644 --- a/web-client/integration-tests/dismissNOTTReminder.test.ts +++ b/web-client/integration-tests/dismissNOTTReminder.test.ts @@ -58,6 +58,9 @@ describe('Dismiss NOTT reminder on calendared trial session within 30-35 day ran loginAs(cerebralTest, 'docketclerk@example.com'); it('should see the NOTT reminder icon on the trial session list', async () => { await cerebralTest.runSequence('gotoTrialSessionsSequence'); + await cerebralTest.runSequence('setTrialSessionsFiltersSequence', { + currentTab: 'calendared', + }); expect(cerebralTest.getState('currentPage')).toEqual('TrialSessions'); From 1f863f380cf01078c7fddfb411577a0605e25c83 Mon Sep 17 00:00:00 2001 From: Zachary Rogers Date: Thu, 12 Sep 2024 14:55:41 -0700 Subject: [PATCH 35/59] 10409: Reset state when a user signs out. Only show inactive judges on All/Closed trial sessions. --- .../Login/resetToBaseStateAction.test.ts | 28 +++++++++++++++++++ .../actions/Login/resetToBaseStateAction.ts | 18 ++++++++++++ .../resetTrialSessionsFiltersAction.test.ts | 15 ++++++++++ .../resetTrialSessionsFiltersAction.ts | 7 +++++ .../actions/clearLoginFormAction.test.ts | 19 ------------- .../presenter/actions/clearLoginFormAction.ts | 13 --------- .../computeds/trialSessionsHelper.test.ts | 27 ++++++++++++++++-- .../computeds/trialSessionsHelper.ts | 15 +++++----- web-client/src/presenter/presenter.ts | 3 +- .../sequences/gotoTrialSessionsSequence.ts | 4 +-- .../presenter/sequences/signOutSequence.ts | 4 +-- 11 files changed, 106 insertions(+), 47 deletions(-) create mode 100644 web-client/src/presenter/actions/Login/resetToBaseStateAction.test.ts create mode 100644 web-client/src/presenter/actions/Login/resetToBaseStateAction.ts create mode 100644 web-client/src/presenter/actions/TrialSession/resetTrialSessionsFiltersAction.test.ts create mode 100644 web-client/src/presenter/actions/TrialSession/resetTrialSessionsFiltersAction.ts delete mode 100644 web-client/src/presenter/actions/clearLoginFormAction.test.ts delete mode 100644 web-client/src/presenter/actions/clearLoginFormAction.ts diff --git a/web-client/src/presenter/actions/Login/resetToBaseStateAction.test.ts b/web-client/src/presenter/actions/Login/resetToBaseStateAction.test.ts new file mode 100644 index 00000000000..0c175f35fee --- /dev/null +++ b/web-client/src/presenter/actions/Login/resetToBaseStateAction.test.ts @@ -0,0 +1,28 @@ +import { baseState } from '@web-client/presenter/state'; +import { resetToBaseStateAction } from '@web-client/presenter/actions/Login/resetToBaseStateAction'; +import { runAction } from '@web-client/presenter/test.cerebral'; + +describe('resetToBaseStateAction', () => { + it('should reset state to baseState except for a few state slices', async () => { + const stateThatShouldNotBeReset = { + featureFlags: {}, + header: {}, + idleLogoutState: {}, + idleStatus: {}, + lastIdleAction: {}, + maintenanceMode: {}, + }; + + const result = await runAction(resetToBaseStateAction, { + state: { + ...stateThatShouldNotBeReset, + trialSessionsPage: { stuff: 'this should be reset' }, + }, + }); + + expect(result.state).toEqual({ + ...baseState, + ...stateThatShouldNotBeReset, + }); + }); +}); diff --git a/web-client/src/presenter/actions/Login/resetToBaseStateAction.ts b/web-client/src/presenter/actions/Login/resetToBaseStateAction.ts new file mode 100644 index 00000000000..061feac1fe6 --- /dev/null +++ b/web-client/src/presenter/actions/Login/resetToBaseStateAction.ts @@ -0,0 +1,18 @@ +import { baseState } from '@web-client/presenter/state'; +import { cloneDeep } from 'lodash'; +import { state } from '@web-client/presenter/app.cerebral'; + +export const resetToBaseStateAction = ({ store }: ActionProps) => { + Object.entries(cloneDeep(baseState)).forEach(([key, value]) => { + const stateSlicesToPersist = [ + 'maintenanceMode', + 'featureFlags', + 'idleLogoutState', + 'idleStatus', + 'lastIdleAction', + 'header', + ]; + if (stateSlicesToPersist.includes(key)) return; + store.set(state[key], value); + }); +}; diff --git a/web-client/src/presenter/actions/TrialSession/resetTrialSessionsFiltersAction.test.ts b/web-client/src/presenter/actions/TrialSession/resetTrialSessionsFiltersAction.test.ts new file mode 100644 index 00000000000..487f0db01e4 --- /dev/null +++ b/web-client/src/presenter/actions/TrialSession/resetTrialSessionsFiltersAction.test.ts @@ -0,0 +1,15 @@ +import { initialTrialSessionPageState } from '@web-client/presenter/state/trialSessionsPageState'; +import { resetTrialSessionsFiltersAction } from '@web-client/presenter/actions/TrialSession/resetTrialSessionsFiltersAction'; +import { runAction } from '@web-client/presenter/test.cerebral'; + +describe('resetTrialSessionsFiltersAction', () => { + it('should reset the trialSessions filters', async () => { + const result = await runAction(resetTrialSessionsFiltersAction, { + state: {}, + }); + + expect(result.state.trialSessionsPage).toEqual( + initialTrialSessionPageState, + ); + }); +}); diff --git a/web-client/src/presenter/actions/TrialSession/resetTrialSessionsFiltersAction.ts b/web-client/src/presenter/actions/TrialSession/resetTrialSessionsFiltersAction.ts new file mode 100644 index 00000000000..57f6678c48e --- /dev/null +++ b/web-client/src/presenter/actions/TrialSession/resetTrialSessionsFiltersAction.ts @@ -0,0 +1,7 @@ +import { cloneDeep } from 'lodash'; +import { initialTrialSessionPageState } from '@web-client/presenter/state/trialSessionsPageState'; +import { state } from '@web-client/presenter/app.cerebral'; + +export const resetTrialSessionsFiltersAction = ({ store }: ActionProps) => { + store.set(state.trialSessionsPage, cloneDeep(initialTrialSessionPageState)); +}; diff --git a/web-client/src/presenter/actions/clearLoginFormAction.test.ts b/web-client/src/presenter/actions/clearLoginFormAction.test.ts deleted file mode 100644 index 4a84513be8d..00000000000 --- a/web-client/src/presenter/actions/clearLoginFormAction.test.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { clearLoginFormAction } from './clearLoginFormAction'; -import { runAction } from '@web-client/presenter/test.cerebral'; - -describe('clearLoginFormAction', () => { - it('should reset the form state', async () => { - const result = await runAction(clearLoginFormAction, { - state: { - form: { - name: 'Joe', - nature: 'Exotic', - }, - }, - }); - - expect(result.state.form).toMatchObject({ - email: '', - }); - }); -}); diff --git a/web-client/src/presenter/actions/clearLoginFormAction.ts b/web-client/src/presenter/actions/clearLoginFormAction.ts deleted file mode 100644 index 676d1fe3370..00000000000 --- a/web-client/src/presenter/actions/clearLoginFormAction.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { state } from '@web-client/presenter/app.cerebral'; - -/** - * resets the form. - * state.form is used throughout the app for storing html form values - * @param {object} providers the providers object - * @param {object} providers.store the cerebral store object used for setting the form - */ -export const clearLoginFormAction = ({ store }: ActionProps) => { - store.set(state.form, { - email: '', - }); -}; diff --git a/web-client/src/presenter/computeds/trialSessionsHelper.test.ts b/web-client/src/presenter/computeds/trialSessionsHelper.test.ts index d2b814c8e81..249900ed39a 100644 --- a/web-client/src/presenter/computeds/trialSessionsHelper.test.ts +++ b/web-client/src/presenter/computeds/trialSessionsHelper.test.ts @@ -145,8 +145,10 @@ describe('trialSessionsHelper', () => { }); describe('trialSessionJudges', () => { - it('returns all current and legacy judges when the current tab is calendared', () => { + it('returns all current and legacy judges when the session status is closed', () => { trialSessionsPageState.filters.currentTab = 'calendared'; + trialSessionsPageState.filters.sessionStatus = + SESSION_STATUS_TYPES.closed; const result = runCompute(trialSessionsHelper, { state: { judges: [ @@ -167,7 +169,7 @@ describe('trialSessionsHelper', () => { ]); }); - it('returns only non-legacy judges when the current tab is new', () => { + it('returns only current judges when the current tab is new', () => { trialSessionsPageState.filters.currentTab = 'new'; const result = runCompute(trialSessionsHelper, { state: { @@ -187,6 +189,27 @@ describe('trialSessionsHelper', () => { { name: 'I am not a legacy judge part 2', role: ROLES.judge }, ]); }); + + it('returns only current judges when the session status is open', () => { + trialSessionsPageState.filters.sessionStatus = SESSION_STATUS_TYPES.open; + const result = runCompute(trialSessionsHelper, { + state: { + judges: [ + { name: 'I am not a legacy judge part 2', role: ROLES.judge }, + ], + legacyAndCurrentJudges: [ + { name: 'I am not a legacy judge', role: ROLES.judge }, + { name: 'I am a legacy judge', role: ROLES.legacyJudge }, + ], + permissions: getUserPermissions(docketClerk1User), + trialSessionsPage: trialSessionsPageState, + }, + }); + + expect(result.trialSessionJudges).toEqual([ + { name: 'I am not a legacy judge part 2', role: ROLES.judge }, + ]); + }); }); describe('showNewTrialSession', () => { diff --git a/web-client/src/presenter/computeds/trialSessionsHelper.ts b/web-client/src/presenter/computeds/trialSessionsHelper.ts index 3ce8a569ee8..5ab8fe8ce8a 100644 --- a/web-client/src/presenter/computeds/trialSessionsHelper.ts +++ b/web-client/src/presenter/computeds/trialSessionsHelper.ts @@ -6,6 +6,7 @@ import { } from '@shared/business/utilities/DateHandler'; import { Get } from 'cerebral'; import { RawUser } from '@shared/business/entities/User'; +import { SESSION_STATUS_TYPES } from '@shared/business/entities/EntityConstants'; import { TrialSession } from '@shared/business/entities/trialSessions/TrialSession'; import { TrialSessionInfoDTO } from '@shared/business/dto/trialSessions/TrialSessionInfoDTO'; import { state } from '@web-client/presenter/app.cerebral'; @@ -21,15 +22,13 @@ export const trialSessionsHelper = ( trialSessionRows: (TrialSessionRow | TrialSessionWeek)[]; } => { const permissions = get(state.permissions)!; - const tab = get(state.trialSessionsPage.filters.currentTab); const trialSessions = get(state.trialSessionsPage.trialSessions); const filters = get(state.trialSessionsPage.filters); const judge = get(state.judgeUser); - const isNewTab = tab === 'new'; - const isCalendared = tab === 'calendared'; - - const showCurrentJudgesOnly = isNewTab; + const showCurrentJudgesOnly = + filters.currentTab === 'new' || + filters.sessionStatus === SESSION_STATUS_TYPES.open; let trialSessionJudges; if (showCurrentJudgesOnly) { @@ -76,9 +75,9 @@ export const trialSessionsHelper = ( return { showNewTrialSession: permissions.CREATE_TRIAL_SESSION, - showNoticeIssued: isCalendared, - showSessionStatus: isCalendared, - showUnassignedJudgeFilter: isNewTab, + showNoticeIssued: filters.currentTab === 'calendared', + showSessionStatus: filters.currentTab === 'calendared', + showUnassignedJudgeFilter: filters.currentTab === 'new', trialSessionJudges, trialSessionRows, }; diff --git a/web-client/src/presenter/presenter.ts b/web-client/src/presenter/presenter.ts index 7fc7a7ef8c5..2d0f96387bf 100644 --- a/web-client/src/presenter/presenter.ts +++ b/web-client/src/presenter/presenter.ts @@ -67,6 +67,7 @@ import { clearPreferredTrialCitySequence } from './sequences/clearPreferredTrial import { clearSelectedWorkItemsSequence } from './sequences/clearSelectedWorkItemsSequence'; import { clearStatusReportOrderFormSequence } from './sequences/StatusReportOrder/clearStatusReportOrderFormSequence'; import { clearViewerDocumentToDisplaySequence } from './sequences/clearViewerDocumentToDisplaySequence'; +import { cloneDeep } from 'lodash'; import { closeModalAndNavigateBackSequence } from './sequences/closeModalAndNavigateBackSequence'; import { closeModalAndNavigateSequence } from './sequences/closeModalAndNavigateSequence'; import { closeModalAndNavigateToMaintenanceSequence } from './sequences/closeModalAndNavigateToMaintenanceSequence'; @@ -1650,7 +1651,7 @@ export const presenter = { ], providers: {} as { applicationContext: ClientApplicationContext; router: {} }, sequences: presenterSequences, - state: initialState, + state: cloneDeep(initialState), }; export type Sequences = typeof presenterSequences; diff --git a/web-client/src/presenter/sequences/gotoTrialSessionsSequence.ts b/web-client/src/presenter/sequences/gotoTrialSessionsSequence.ts index 3a11c70f1eb..1e1fd2e0a17 100644 --- a/web-client/src/presenter/sequences/gotoTrialSessionsSequence.ts +++ b/web-client/src/presenter/sequences/gotoTrialSessionsSequence.ts @@ -1,12 +1,12 @@ import { TrialSessionsFilters } from '@web-client/presenter/state/trialSessionsPageState'; import { clearErrorAlertsAction } from '../actions/clearErrorAlertsAction'; -import { clearScreenMetadataAction } from '../actions/clearScreenMetadataAction'; import { closeMobileMenuAction } from '../actions/closeMobileMenuAction'; import { getJudgeForCurrentUserAction } from '../actions/getJudgeForCurrentUserAction'; import { getNotificationsAction } from '../actions/getNotificationsAction'; import { getTrialSessionsAction } from '../actions/TrialSession/getTrialSessionsAction'; import { getUsersInSectionAction } from '../actions/getUsersInSectionAction'; import { parallel } from 'cerebral/factories'; +import { resetTrialSessionsFiltersAction } from '@web-client/presenter/actions/TrialSession/resetTrialSessionsFiltersAction'; import { setAllAndCurrentJudgesAction } from '../actions/setAllAndCurrentJudgesAction'; import { setJudgeUserAction } from '../actions/setJudgeUserAction'; import { setNotificationsAction } from '../actions/setNotificationsAction'; @@ -18,7 +18,7 @@ import { startWebSocketConnectionSequenceDecorator } from '../utilities/startWeb export const gotoTrialSessionsSequence = startWebSocketConnectionSequenceDecorator([ setupCurrentPageAction('Interstitial'), - clearScreenMetadataAction, + resetTrialSessionsFiltersAction, closeMobileMenuAction, clearErrorAlertsAction, setTrialSessionsFiltersAction, diff --git a/web-client/src/presenter/sequences/signOutSequence.ts b/web-client/src/presenter/sequences/signOutSequence.ts index 709b012240b..d9afcf9c0e4 100644 --- a/web-client/src/presenter/sequences/signOutSequence.ts +++ b/web-client/src/presenter/sequences/signOutSequence.ts @@ -1,11 +1,11 @@ import { broadcastLogoutAction } from '../actions/broadcastLogoutAction'; import { clearAlertsAction } from '../actions/clearAlertsAction'; -import { clearLoginFormAction } from '../actions/clearLoginFormAction'; import { clearLogoutTypeAction } from '@web-client/presenter/actions/clearLogoutTypeAction'; import { clearMaintenanceModeAction } from '../actions/clearMaintenanceModeAction'; import { clearUserAction } from '../actions/clearUserAction'; import { deleteAuthCookieAction } from '../actions/deleteAuthCookieAction'; import { resetIdleTimerAction } from '@web-client/presenter/actions/resetIdleTimerAction'; +import { resetToBaseStateAction } from '@web-client/presenter/actions/Login/resetToBaseStateAction'; import { setupCurrentPageAction } from '../actions/setupCurrentPageAction'; import { stopWebSocketConnectionAction } from '../actions/WebSocketConnection/stopWebSocketConnectionAction'; @@ -17,7 +17,7 @@ export const signOutSequence = [ clearAlertsAction, clearUserAction, clearMaintenanceModeAction, - clearLoginFormAction, clearLogoutTypeAction, resetIdleTimerAction, + resetToBaseStateAction, ]; From 80c2791bcdc8f28a22942a6d128894e6bbc8fd1b Mon Sep 17 00:00:00 2001 From: Zachary Rogers Date: Thu, 12 Sep 2024 14:56:30 -0700 Subject: [PATCH 36/59] 10409: Update text --- web-client/src/views/TrialSessions/TrialSessionsTable.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web-client/src/views/TrialSessions/TrialSessionsTable.tsx b/web-client/src/views/TrialSessions/TrialSessionsTable.tsx index 396b24fd192..f97331bc764 100644 --- a/web-client/src/views/TrialSessions/TrialSessionsTable.tsx +++ b/web-client/src/views/TrialSessions/TrialSessionsTable.tsx @@ -105,7 +105,7 @@ export const TrialSessionsTable = connect( ))} {trialSessionsHelper.trialSessionRows.length === 0 && ( -

There are no trial sessions.

+

There are no trial sessions for the selected filters.

)} ); From 79b89f71f90e07e4a2b8e5ebca219da5afa2ae0c Mon Sep 17 00:00:00 2001 From: Zachary Rogers Date: Thu, 12 Sep 2024 15:23:00 -0700 Subject: [PATCH 37/59] 10409: Remove reset to base state --- web-client/src/presenter/sequences/signOutSequence.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/web-client/src/presenter/sequences/signOutSequence.ts b/web-client/src/presenter/sequences/signOutSequence.ts index d9afcf9c0e4..c6fa7d2f221 100644 --- a/web-client/src/presenter/sequences/signOutSequence.ts +++ b/web-client/src/presenter/sequences/signOutSequence.ts @@ -5,7 +5,6 @@ import { clearMaintenanceModeAction } from '../actions/clearMaintenanceModeActio import { clearUserAction } from '../actions/clearUserAction'; import { deleteAuthCookieAction } from '../actions/deleteAuthCookieAction'; import { resetIdleTimerAction } from '@web-client/presenter/actions/resetIdleTimerAction'; -import { resetToBaseStateAction } from '@web-client/presenter/actions/Login/resetToBaseStateAction'; import { setupCurrentPageAction } from '../actions/setupCurrentPageAction'; import { stopWebSocketConnectionAction } from '../actions/WebSocketConnection/stopWebSocketConnectionAction'; @@ -19,5 +18,4 @@ export const signOutSequence = [ clearMaintenanceModeAction, clearLogoutTypeAction, resetIdleTimerAction, - resetToBaseStateAction, ]; From 452ba072ede91b31330109576a6c9b7e4bcac2da Mon Sep 17 00:00:00 2001 From: Zachary Rogers Date: Fri, 13 Sep 2024 08:19:46 -0700 Subject: [PATCH 38/59] 10409: Update tests for legacy judges only showing on closed and all --- .../journey/docketClerkViewsTrialSessionsTab.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/web-client/integration-tests/journey/docketClerkViewsTrialSessionsTab.ts b/web-client/integration-tests/journey/docketClerkViewsTrialSessionsTab.ts index 1f164955c95..7b71a99491f 100644 --- a/web-client/integration-tests/journey/docketClerkViewsTrialSessionsTab.ts +++ b/web-client/integration-tests/journey/docketClerkViewsTrialSessionsTab.ts @@ -1,3 +1,4 @@ +import { SESSION_STATUS_TYPES } from '@shared/business/entities/EntityConstants'; import { isTrialSessionRow, trialSessionsHelper as trialSessionsHelperComputed, @@ -39,10 +40,13 @@ export const docketClerkViewsTrialSessionsTab = ( judge => judge.role === 'legacyJudge', ); - if (tab === 'calendared') { - expect(legacyJudge).toBeTruthy(); - } else { + if ( + tab === 'new' || + overrides.sessionStatus === SESSION_STATUS_TYPES.open + ) { expect(legacyJudge).toBeFalsy(); + } else { + expect(legacyJudge).toBeTruthy(); } const foundSession = helper.trialSessionRows From 6795a5ba5bc11976801459575da994ff04e51688 Mon Sep 17 00:00:00 2001 From: Zachary Rogers Date: Fri, 13 Sep 2024 16:07:46 -0700 Subject: [PATCH 39/59] 10409: temp docs --- 10409_validation_delete_me.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 10409_validation_delete_me.md diff --git a/10409_validation_delete_me.md b/10409_validation_delete_me.md new file mode 100644 index 00000000000..44ba212c975 --- /dev/null +++ b/10409_validation_delete_me.md @@ -0,0 +1,26 @@ +Problem statement: How can we detect when making a validation changes to entities, we do not create invalid data in the database? + +- Pull all validation rules into a single file, if they change in any way, a validation sweep must be run on the database +- Continue validating before we return inside all of our interactors but instead of exploding just silently log which entities are now invalid. +- On each deployment validate all data in the database. + + +Assumptions +- Not all business rules can or should live inside of the persistence layer. + - For example when a trialSession is calendared it should have a sessionType +- What is and what is not a valid entity can only be expressed inside of functions. + - Is it possible to tell if a function has been modified between different git commits? + - If it is a pure function that does not modify any external state + + +shared/src/business/entities/contacts/Contact.ts getValidationRules depends on instance.countryType + + +Thoughts +- If validation rules are expressed inside of functions it is impossible to tell if a function has changed its behavior from one release to another. If it is impossible to tell if validation rules have changed then maybe defensively checking if they have changed, and running a validation sweep on the DB is not the correct approach +- Another option is better warnings to devs about making validation changes. +- Another option is continue validating, but only log invalid values instead of throwing errors to reduce application impact. + + +Resources +- Validate at input time. Validate again before you put it in the database. And have database constraints to prevent bad input. And you can bet in spite of all that, bad data will still get into your database, so validate it again when you use it. \ No newline at end of file From c92d7d0e58bee481b87dca5a83f0b1db6c0878cd Mon Sep 17 00:00:00 2001 From: Zachary Rogers Date: Tue, 17 Sep 2024 15:55:05 -0700 Subject: [PATCH 40/59] 10409: WIP adding inputs for new select dropdowns on trial sessions --- web-client/src/styles/_index.scss | 1 + web-client/src/styles/utility-classes.scss | 14 ++ .../src/views/TrialSessions/TrialSessions.tsx | 238 ++++++++++-------- 3 files changed, 152 insertions(+), 101 deletions(-) create mode 100644 web-client/src/styles/utility-classes.scss diff --git a/web-client/src/styles/_index.scss b/web-client/src/styles/_index.scss index 0c6c375a3af..ca82403b7a6 100644 --- a/web-client/src/styles/_index.scss +++ b/web-client/src/styles/_index.scss @@ -13,3 +13,4 @@ @forward './tables'; @forward './tabs'; @forward './typography'; +@forward './utility-classes'; diff --git a/web-client/src/styles/utility-classes.scss b/web-client/src/styles/utility-classes.scss new file mode 100644 index 00000000000..4b19f6728d6 --- /dev/null +++ b/web-client/src/styles/utility-classes.scss @@ -0,0 +1,14 @@ +@use '../uswds' as *; +@use '../variables' as *; + +.gap-1 { + gap: 8px; +} + +.gap-2 { + gap: 16px; +} + +.gap-3 { + gap: 24px; +} \ No newline at end of file diff --git a/web-client/src/views/TrialSessions/TrialSessions.tsx b/web-client/src/views/TrialSessions/TrialSessions.tsx index 31b4657ae44..d252d363f99 100644 --- a/web-client/src/views/TrialSessions/TrialSessions.tsx +++ b/web-client/src/views/TrialSessions/TrialSessions.tsx @@ -1,15 +1,15 @@ 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 { SESSION_STATUS_TYPES, - SESSION_TYPES, TRIAL_SESSION_PROCEEDING_TYPES, TrialSessionProceedingType, } from '@shared/business/entities/EntityConstants'; +import { SelectSearch } from '@web-client/ustc-ui/Select/SelectSearch'; import { SuccessNotification } from '../SuccessNotification'; import { Tab, Tabs } from '../../ustc-ui/Tabs/Tabs'; -import { TrialCityOptions } from '@web-client/views/TrialCityOptions'; import { TrialSessionsTable } from './TrialSessionsTable'; import { connect } from '@web-client/presenter/shared.cerebral'; import { sequences } from '@web-client/presenter/app.cerebral'; @@ -21,12 +21,12 @@ export const TrialSessions = connect( openTrialSessionPlanningModalSequence: sequences.openTrialSessionPlanningModalSequence, setTrialSessionsFiltersSequence: sequences.setTrialSessionsFiltersSequence, - trialSessionHelper: state.trialSessionsHelper, + trialSessionsHelper: state.trialSessionsHelper, }, function TrialSessions({ openTrialSessionPlanningModalSequence, setTrialSessionsFiltersSequence, - trialSessionHelper, + trialSessionsHelper, }) { return ( <> @@ -52,8 +52,17 @@ export const TrialSessions = connect( > Trial Session Planning Report + {trialSessionsHelper.showNewTrialSession && ( + + )} - {trialSessionHelper.showNewTrialSession && ( + {trialSessionsHelper.showNewTrialSession && ( -
+
{trialSessionsHelper.showSessionStatus && (
+ Session Status
- - Session Status -
)} +
+ Proceeding Type +
+ { + setTrialSessionsFiltersSequence({ + proceedingType: e.target.value as 'All', + }); + }} + /> + + { + setTrialSessionsFiltersSequence({ + proceedingType: e.target + .value as TrialSessionProceedingType, + }); + }} + /> + + { + setTrialSessionsFiltersSequence({ + proceedingType: e.target + .value as TrialSessionProceedingType, + }); + }} + /> + +
+
+ { + console.log('onChangeEnd', e.target.value); + }} + onChangeStart={e => { + console.log('onChangeStart', e.target.value); + }} + />
-
-
- {showDateHint && MM/DD/YYYY}
@@ -172,6 +174,8 @@ export const DateRangePickerComponent = ({
+ {/* {to && to} */} +
- {endLabel || 'End date'}{' '} + {endLabel}{' '} {showDateHint && MM/DD/YYYY}
diff --git a/web-client/src/views/TrialSessions/TrialSessions.tsx b/web-client/src/views/TrialSessions/TrialSessions.tsx index d252d363f99..44672ede328 100644 --- a/web-client/src/views/TrialSessions/TrialSessions.tsx +++ b/web-client/src/views/TrialSessions/TrialSessions.tsx @@ -243,11 +243,18 @@ const TrialSessionFilters = connect( endValue="" formGroupCls="margin-bottom-0" maxDate={''} - rangePickerCls={'grid-row '} + rangePickerCls={'display-flex flex-align-end'} startDateErrorText={''} + startLabel={ + + Trial Start Date range{' '} + (optional) + + } startName="trialSessionEndDate" startPickerCls="padding-right-2" startValue="" + to={true} onChangeEnd={e => { console.log('onChangeEnd', e.target.value); }} From 5356374da734db5867e6582f9983eec61871b1e2 Mon Sep 17 00:00:00 2001 From: Zachary Rogers Date: Wed, 18 Sep 2024 11:43:33 -0700 Subject: [PATCH 42/59] 10409: Remove temp styling --- .../src/ustc-ui/DateInput/DateRangePickerComponent.tsx | 5 ----- web-client/src/views/TrialSessions/TrialSessions.tsx | 1 - 2 files changed, 6 deletions(-) diff --git a/web-client/src/ustc-ui/DateInput/DateRangePickerComponent.tsx b/web-client/src/ustc-ui/DateInput/DateRangePickerComponent.tsx index cd52c69f1ea..184ccfc756c 100644 --- a/web-client/src/ustc-ui/DateInput/DateRangePickerComponent.tsx +++ b/web-client/src/ustc-ui/DateInput/DateRangePickerComponent.tsx @@ -22,7 +22,6 @@ export const DateRangePickerComponent = ({ startName, startPickerCls, startValue, - to = false, }: { showDateHint?: boolean; endDateErrorText?: string; @@ -37,7 +36,6 @@ export const DateRangePickerComponent = ({ startDateErrorText?: string; startPickerCls?: string; startLabel?: string | React.ReactNode; - to?: boolean; omitFormGroupClass?: boolean; startName: string; startValue: string; @@ -173,9 +171,6 @@ export const DateRangePickerComponent = ({
- - {/* {to && to} */} -
{ console.log('onChangeEnd', e.target.value); }} From 77cbf3dd971da2f79cccc69121b6e234edbe2f9e Mon Sep 17 00:00:00 2001 From: Zachary Rogers Date: Wed, 18 Sep 2024 11:59:06 -0700 Subject: [PATCH 43/59] 10409: WIP start adding options to trial sessions --- .../computeds/trialSessionsHelper.ts | 43 ++++++++++++++++++- .../src/views/TrialSessions/TrialSessions.tsx | 8 +++- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/web-client/src/presenter/computeds/trialSessionsHelper.ts b/web-client/src/presenter/computeds/trialSessionsHelper.ts index 5ab8fe8ce8a..eeb9a85ad19 100644 --- a/web-client/src/presenter/computeds/trialSessionsHelper.ts +++ b/web-client/src/presenter/computeds/trialSessionsHelper.ts @@ -5,10 +5,16 @@ import { subtractISODates, } from '@shared/business/utilities/DateHandler'; import { Get } from 'cerebral'; +import { InputOption } from '@web-client/ustc-ui/Utils/types'; import { RawUser } from '@shared/business/entities/User'; -import { SESSION_STATUS_TYPES } from '@shared/business/entities/EntityConstants'; +import { + SESSION_STATUS_TYPES, + SESSION_TYPES, + TRIAL_CITIES, +} from '@shared/business/entities/EntityConstants'; import { TrialSession } from '@shared/business/entities/trialSessions/TrialSession'; import { TrialSessionInfoDTO } from '@shared/business/dto/trialSessions/TrialSessionInfoDTO'; +import { sortBy } from 'lodash'; import { state } from '@web-client/presenter/app.cerebral'; export const trialSessionsHelper = ( @@ -20,6 +26,8 @@ export const trialSessionsHelper = ( showUnassignedJudgeFilter: boolean; trialSessionJudges: RawUser[]; trialSessionRows: (TrialSessionRow | TrialSessionWeek)[]; + sessionTypeOptions: InputOption[]; + trialLocationOptions: InputOption[]; } => { const permissions = get(state.permissions)!; const trialSessions = get(state.trialSessionsPage.trialSessions); @@ -37,6 +45,38 @@ export const trialSessionsHelper = ( trialSessionJudges = get(state.legacyAndCurrentJudges); } + const sessionTypeOptions = Object.values(SESSION_TYPES).map(sessionType => ({ + label: sessionType, + value: sessionType, + })); + + const trialCities = sortBy(TRIAL_CITIES.ALL, ['state', 'city']); + const trialLocationOptions: InputOption[] = []; + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const states: InputOption[] = trialCities.reduce( + (listOfStates: InputOption[], cityStatePair) => { + const existingState = listOfStates.find( + trialState => trialState.label === cityStatePair.state, + ); + const cityOption: InputOption = { + label: `${cityStatePair.city}, ${cityStatePair.state}`, + value: `${cityStatePair.city}, ${cityStatePair.state}`, + }; + if (existingState) { + existingState.options?.push(cityOption); + } else { + listOfStates.push({ + label: cityStatePair.state, + options: [cityOption], + }); + } + trialLocationOptions.push(cityOption); + return listOfStates; + }, + [], + ); + const filteredTrialSessions = trialSessions .filter(trialSession => { const isCalendaredFilter = filters.currentTab === 'calendared'; @@ -74,6 +114,7 @@ export const trialSessionsHelper = ( }); return { + sessionTypeOptions, showNewTrialSession: permissions.CREATE_TRIAL_SESSION, showNoticeIssued: filters.currentTab === 'calendared', showSessionStatus: filters.currentTab === 'calendared', diff --git a/web-client/src/views/TrialSessions/TrialSessions.tsx b/web-client/src/views/TrialSessions/TrialSessions.tsx index 7acc2ea41a6..684766dcad9 100644 --- a/web-client/src/views/TrialSessions/TrialSessions.tsx +++ b/web-client/src/views/TrialSessions/TrialSessions.tsx @@ -271,7 +271,9 @@ const TrialSessionFilters = connect( { console.log('session type', inputValue); }} @@ -285,6 +287,8 @@ const TrialSessionFilters = connect( id="location-filter" name="location" options={[]} + placeholder="- Select one or more -" + value="Select one or more" onChange={inputValue => { console.log('location', inputValue); }} @@ -298,6 +302,8 @@ const TrialSessionFilters = connect( id="judge-filter" name="judgeId" options={[]} + placeholder="- Select one or more -" + value="Select one or more" onChange={inputValue => { console.log('judgeId', inputValue); }} From 417f79e7cdc01ce7d53318ecd798f920ed5d368a Mon Sep 17 00:00:00 2001 From: Nechama Krigsman Date: Wed, 18 Sep 2024 16:10:32 -0400 Subject: [PATCH 44/59] 10409: add options to filter dropdowns; --- .../setTrialSessionsFiltersAction.ts | 28 ++++++++++++++----- .../computeds/trialSessionsHelper.ts | 17 +++++++++-- .../setTrialSessionsFiltersSequence.ts | 8 ++++-- .../presenter/state/trialSessionsPageState.ts | 4 +-- .../src/views/TrialSessions/TrialSessions.tsx | 20 +++++++++---- 5 files changed, 58 insertions(+), 19 deletions(-) diff --git a/web-client/src/presenter/actions/TrialSession/setTrialSessionsFiltersAction.ts b/web-client/src/presenter/actions/TrialSession/setTrialSessionsFiltersAction.ts index 1fe75fa28db..dffce64f177 100644 --- a/web-client/src/presenter/actions/TrialSession/setTrialSessionsFiltersAction.ts +++ b/web-client/src/presenter/actions/TrialSession/setTrialSessionsFiltersAction.ts @@ -1,16 +1,30 @@ -import { TrialSessionsFilters } from '@web-client/presenter/state/trialSessionsPageState'; import { state } from '@web-client/presenter/app.cerebral'; export const setTrialSessionsFiltersAction = ({ + get, props, store, -}: ActionProps>) => { +}: ActionProps) => { + const currentFilters = get(state.trialSessionsPage.filters); + if (props.currentTab) { store.set(state.trialSessionsPage.filters.currentTab, props.currentTab); } - - if (props.judgeId) { - store.set(state.trialSessionsPage.filters.judgeId, props.judgeId); + // Update for Trial Sessions Page + if (props.judges) { + if ( + props.judges.action === 'add' && + !currentFilters.judges.includes(props.judges.judge) + ) { + currentFilters.judges.push(props.judges.judge); + store.merge(state.trialSessionsPage.filters, currentFilters); + } else if (props.judges.action === 'remove') { + const foundIndex = currentFilters.judges.findIndex( + caseType => caseType === props.judges!.judge, + ); + currentFilters.judges.splice(foundIndex, 1); + store.merge(state.trialSessionsPage.filters, currentFilters); + } } if (props.proceedingType) { @@ -26,11 +40,11 @@ export const setTrialSessionsFiltersAction = ({ props.sessionStatus, ); } - + // Update for Trial Sessions Page if (props.sessionType) { store.set(state.trialSessionsPage.filters.sessionType, props.sessionType); } - + // Update for Trial Sessions Page if (props.trialLocation) { store.set( state.trialSessionsPage.filters.trialLocation, diff --git a/web-client/src/presenter/computeds/trialSessionsHelper.ts b/web-client/src/presenter/computeds/trialSessionsHelper.ts index eeb9a85ad19..4c3a41aaed6 100644 --- a/web-client/src/presenter/computeds/trialSessionsHelper.ts +++ b/web-client/src/presenter/computeds/trialSessionsHelper.ts @@ -25,9 +25,11 @@ export const trialSessionsHelper = ( showSessionStatus: boolean; showUnassignedJudgeFilter: boolean; trialSessionJudges: RawUser[]; + trialSessionJudgeOptions: InputOption[]; trialSessionRows: (TrialSessionRow | TrialSessionWeek)[]; sessionTypeOptions: InputOption[]; - trialLocationOptions: InputOption[]; + searchableTrialLocationOptions: InputOption[]; + trialCitiesByState: InputOption[]; } => { const permissions = get(state.permissions)!; const trialSessions = get(state.trialSessionsPage.trialSessions); @@ -50,8 +52,14 @@ export const trialSessionsHelper = ( value: sessionType, })); + const trialSessionJudgeOptions = trialSessionJudges.map( + trialSessionJudge => ({ + label: trialSessionJudge.name, + value: trialSessionJudge.name, + }), + ); const trialCities = sortBy(TRIAL_CITIES.ALL, ['state', 'city']); - const trialLocationOptions: InputOption[] = []; + const searchableTrialLocationOptions: InputOption[] = []; // eslint-disable-next-line @typescript-eslint/no-unused-vars const states: InputOption[] = trialCities.reduce( @@ -71,7 +79,7 @@ export const trialSessionsHelper = ( options: [cityOption], }); } - trialLocationOptions.push(cityOption); + searchableTrialLocationOptions.push(cityOption); return listOfStates; }, [], @@ -114,11 +122,14 @@ export const trialSessionsHelper = ( }); return { + searchableTrialLocationOptions, sessionTypeOptions, showNewTrialSession: permissions.CREATE_TRIAL_SESSION, showNoticeIssued: filters.currentTab === 'calendared', showSessionStatus: filters.currentTab === 'calendared', showUnassignedJudgeFilter: filters.currentTab === 'new', + trialCitiesByState: states, + trialSessionJudgeOptions, trialSessionJudges, trialSessionRows, }; diff --git a/web-client/src/presenter/sequences/setTrialSessionsFiltersSequence.ts b/web-client/src/presenter/sequences/setTrialSessionsFiltersSequence.ts index 294f2fe20ed..b357d594f2d 100644 --- a/web-client/src/presenter/sequences/setTrialSessionsFiltersSequence.ts +++ b/web-client/src/presenter/sequences/setTrialSessionsFiltersSequence.ts @@ -1,6 +1,10 @@ -import { TrialSessionsFilters } from '@web-client/presenter/state/trialSessionsPageState'; import { setTrialSessionsFiltersAction } from '@web-client/presenter/actions/TrialSession/setTrialSessionsFiltersAction'; export const setTrialSessionsFiltersSequence = [ setTrialSessionsFiltersAction, -] as unknown as (props: Partial) => void; +] as unknown as (props: { + currentTab?: string; + proceedingType?: string; + sessionStatus?: string; + judges?: { action: 'add' | 'remove'; judge: string }; +}) => void; diff --git a/web-client/src/presenter/state/trialSessionsPageState.ts b/web-client/src/presenter/state/trialSessionsPageState.ts index f0c77f51ae2..956ddeb09a8 100644 --- a/web-client/src/presenter/state/trialSessionsPageState.ts +++ b/web-client/src/presenter/state/trialSessionsPageState.ts @@ -3,7 +3,7 @@ import { TrialSessionProceedingType } from '@shared/business/entities/EntityCons const filters: TrialSessionsFilters = { currentTab: 'calendared' as 'calendared' | 'new', - judgeId: 'All', + judges: [], proceedingType: 'All' as TrialSessionProceedingType, sessionStatus: 'Open', sessionType: 'All', @@ -17,7 +17,7 @@ export const initialTrialSessionPageState = { export type TrialSessionsFilters = { currentTab: 'calendared' | 'new'; - judgeId: string; + judges: string[]; proceedingType: TrialSessionProceedingType | 'All'; sessionStatus: string; sessionType: string; diff --git a/web-client/src/views/TrialSessions/TrialSessions.tsx b/web-client/src/views/TrialSessions/TrialSessions.tsx index 684766dcad9..f62b8d0999c 100644 --- a/web-client/src/views/TrialSessions/TrialSessions.tsx +++ b/web-client/src/views/TrialSessions/TrialSessions.tsx @@ -286,8 +286,11 @@ const TrialSessionFilters = connect( { console.log('location', inputValue); @@ -299,13 +302,20 @@ const TrialSessionFilters = connect( Judge (optional) { - console.log('judgeId', inputValue); + if (inputValue) { + setTrialSessionsFiltersSequence({ + judges: { + action: 'add', + judge: inputValue.value, + }, + }); + } }} />
From 6d6cb5a1057f5ef34d851daa750680217ab2764c Mon Sep 17 00:00:00 2001 From: Zachary Rogers Date: Wed, 18 Sep 2024 14:22:59 -0700 Subject: [PATCH 45/59] 10409: WIP Converting judgeIds into a multi select --- .../setTrialSessionsFiltersAction.ts | 36 ++++++++++--------- .../computeds/trialSessionsHelper.ts | 18 ++++++---- .../setTrialSessionsFiltersSequence.ts | 12 +++---- .../presenter/state/trialSessionsPageState.ts | 4 +-- .../src/views/TrialSessions/TrialSessions.tsx | 5 +-- 5 files changed, 42 insertions(+), 33 deletions(-) diff --git a/web-client/src/presenter/actions/TrialSession/setTrialSessionsFiltersAction.ts b/web-client/src/presenter/actions/TrialSession/setTrialSessionsFiltersAction.ts index dffce64f177..765b2531883 100644 --- a/web-client/src/presenter/actions/TrialSession/setTrialSessionsFiltersAction.ts +++ b/web-client/src/presenter/actions/TrialSession/setTrialSessionsFiltersAction.ts @@ -1,30 +1,34 @@ +import { TrialSessionProceedingType } from '@shared/business/entities/EntityConstants'; import { state } from '@web-client/presenter/app.cerebral'; +export type SetTrialSessionsFilters = Partial<{ + currentTab: 'calendared' | 'new'; + judgeIds: { action: 'add' | 'remove'; judgeId: string }; + proceedingType: TrialSessionProceedingType | 'All'; + sessionStatus: string; + sessionType: string; + trialLocation: string; +}>; + export const setTrialSessionsFiltersAction = ({ get, props, store, -}: ActionProps) => { +}: ActionProps) => { const currentFilters = get(state.trialSessionsPage.filters); if (props.currentTab) { store.set(state.trialSessionsPage.filters.currentTab, props.currentTab); } - // Update for Trial Sessions Page - if (props.judges) { - if ( - props.judges.action === 'add' && - !currentFilters.judges.includes(props.judges.judge) - ) { - currentFilters.judges.push(props.judges.judge); - store.merge(state.trialSessionsPage.filters, currentFilters); - } else if (props.judges.action === 'remove') { - const foundIndex = currentFilters.judges.findIndex( - caseType => caseType === props.judges!.judge, - ); - currentFilters.judges.splice(foundIndex, 1); - store.merge(state.trialSessionsPage.filters, currentFilters); - } + + if (props.judgeIds) { + const newJudgeIds = + props.judgeIds.action === 'add' + ? currentFilters.judgeIds.concat([props.judgeIds.judgeId]) + : currentFilters.judgeIds.filter( + (id: string) => id !== props.judgeIds!.judgeId, + ); + store.set(state.trialSessionsPage.filters.judgeIds, newJudgeIds); } if (props.proceedingType) { diff --git a/web-client/src/presenter/computeds/trialSessionsHelper.ts b/web-client/src/presenter/computeds/trialSessionsHelper.ts index 4c3a41aaed6..0f659e633e4 100644 --- a/web-client/src/presenter/computeds/trialSessionsHelper.ts +++ b/web-client/src/presenter/computeds/trialSessionsHelper.ts @@ -40,11 +40,13 @@ export const trialSessionsHelper = ( filters.currentTab === 'new' || filters.sessionStatus === SESSION_STATUS_TYPES.open; - let trialSessionJudges; + let trialSessionJudges; // 10409 TODO BUG. The judge options is not updating correctly. Showing legacy when it should not. if (showCurrentJudgesOnly) { trialSessionJudges = get(state.judges); + console.log('current length: ', trialSessionJudges.length); } else { trialSessionJudges = get(state.legacyAndCurrentJudges); + console.log('legecy length: ', trialSessionJudges.length); } const sessionTypeOptions = Object.values(SESSION_TYPES).map(sessionType => ({ @@ -52,10 +54,10 @@ export const trialSessionsHelper = ( value: sessionType, })); - const trialSessionJudgeOptions = trialSessionJudges.map( + const trialSessionJudgeOptions: InputOption[] = trialSessionJudges.map( trialSessionJudge => ({ label: trialSessionJudge.name, - value: trialSessionJudge.name, + value: trialSessionJudge.userId, }), ); const trialCities = sortBy(TRIAL_CITIES.ALL, ['state', 'city']); @@ -91,9 +93,13 @@ export const trialSessionsHelper = ( return trialSession.isCalendared === isCalendaredFilter; }) .filter(trialSession => { - if (filters.judgeId === 'All') return true; - if (filters.judgeId === 'unassigned') return !trialSession.judge?.userId; - return trialSession.judge?.userId === filters.judgeId; + if (filters.judgeIds.length === 0) return true; + const trialSessionHasJudge = filters.judgeIds.some(judgeIdFilter => { + if (judgeIdFilter === 'unassigned') return !trialSession.judge?.userId; + return judgeIdFilter === trialSession.judge?.userId; + }); + + return trialSessionHasJudge; }) .filter(trialSession => { if (filters.proceedingType === 'All') return true; diff --git a/web-client/src/presenter/sequences/setTrialSessionsFiltersSequence.ts b/web-client/src/presenter/sequences/setTrialSessionsFiltersSequence.ts index b357d594f2d..9016d6c9974 100644 --- a/web-client/src/presenter/sequences/setTrialSessionsFiltersSequence.ts +++ b/web-client/src/presenter/sequences/setTrialSessionsFiltersSequence.ts @@ -1,10 +1,8 @@ -import { setTrialSessionsFiltersAction } from '@web-client/presenter/actions/TrialSession/setTrialSessionsFiltersAction'; +import { + SetTrialSessionsFilters, + setTrialSessionsFiltersAction, +} from '@web-client/presenter/actions/TrialSession/setTrialSessionsFiltersAction'; export const setTrialSessionsFiltersSequence = [ setTrialSessionsFiltersAction, -] as unknown as (props: { - currentTab?: string; - proceedingType?: string; - sessionStatus?: string; - judges?: { action: 'add' | 'remove'; judge: string }; -}) => void; +] as unknown as (props: SetTrialSessionsFilters) => void; diff --git a/web-client/src/presenter/state/trialSessionsPageState.ts b/web-client/src/presenter/state/trialSessionsPageState.ts index 956ddeb09a8..c7e96b4dd66 100644 --- a/web-client/src/presenter/state/trialSessionsPageState.ts +++ b/web-client/src/presenter/state/trialSessionsPageState.ts @@ -3,7 +3,7 @@ import { TrialSessionProceedingType } from '@shared/business/entities/EntityCons const filters: TrialSessionsFilters = { currentTab: 'calendared' as 'calendared' | 'new', - judges: [], + judgeIds: [], proceedingType: 'All' as TrialSessionProceedingType, sessionStatus: 'Open', sessionType: 'All', @@ -17,7 +17,7 @@ export const initialTrialSessionPageState = { export type TrialSessionsFilters = { currentTab: 'calendared' | 'new'; - judges: string[]; + judgeIds: string[]; proceedingType: TrialSessionProceedingType | 'All'; sessionStatus: string; sessionType: string; diff --git a/web-client/src/views/TrialSessions/TrialSessions.tsx b/web-client/src/views/TrialSessions/TrialSessions.tsx index f62b8d0999c..0083b6aeff2 100644 --- a/web-client/src/views/TrialSessions/TrialSessions.tsx +++ b/web-client/src/views/TrialSessions/TrialSessions.tsx @@ -100,6 +100,7 @@ const TrialSessionFilters = connect( trialSessionsHelper, trialSessionsPage, }) { + console.log(trialSessionsPage.filters); return ( <>
@@ -310,9 +311,9 @@ const TrialSessionFilters = connect( onChange={inputValue => { if (inputValue) { setTrialSessionsFiltersSequence({ - judges: { + judgeIds: { action: 'add', - judge: inputValue.value, + judgeId: inputValue.value, }, }); } From 6c717b3f1e33c5186b134eb959c980b61cef0499 Mon Sep 17 00:00:00 2001 From: Zachary Rogers Date: Wed, 18 Sep 2024 15:30:25 -0700 Subject: [PATCH 46/59] 10409: WIP Converting TrialLocations into a multi select --- .../setTrialSessionsFiltersAction.test.ts | 2 +- .../setTrialSessionsFiltersAction.ts | 39 ++++--- .../computeds/trialSessionsHelper.test.ts | 2 +- .../computeds/trialSessionsHelper.ts | 25 +++-- .../presenter/state/trialSessionsPageState.ts | 8 +- web-client/src/ustc-ui/Utils/types.ts | 4 +- .../src/views/TrialSessions/TrialSessions.tsx | 106 ++++++++++++------ 7 files changed, 121 insertions(+), 65 deletions(-) diff --git a/web-client/src/presenter/actions/TrialSession/setTrialSessionsFiltersAction.test.ts b/web-client/src/presenter/actions/TrialSession/setTrialSessionsFiltersAction.test.ts index 130c782be17..ff73e9884f1 100644 --- a/web-client/src/presenter/actions/TrialSession/setTrialSessionsFiltersAction.test.ts +++ b/web-client/src/presenter/actions/TrialSession/setTrialSessionsFiltersAction.test.ts @@ -9,7 +9,7 @@ describe('setTrialSessionsFiltersAction', () => { }, }); - expect(result.state.trialSessionsPage.filters.trialLocation).toEqual( + expect(result.state.trialSessionsPage.filters.trialLocations).toEqual( 'Baton Rouge, Louisiana', ); }); diff --git a/web-client/src/presenter/actions/TrialSession/setTrialSessionsFiltersAction.ts b/web-client/src/presenter/actions/TrialSession/setTrialSessionsFiltersAction.ts index 765b2531883..4cc186ab76b 100644 --- a/web-client/src/presenter/actions/TrialSession/setTrialSessionsFiltersAction.ts +++ b/web-client/src/presenter/actions/TrialSession/setTrialSessionsFiltersAction.ts @@ -3,11 +3,17 @@ import { state } from '@web-client/presenter/app.cerebral'; export type SetTrialSessionsFilters = Partial<{ currentTab: 'calendared' | 'new'; - judgeIds: { action: 'add' | 'remove'; judgeId: string }; + judges: { + action: 'add' | 'remove'; + judge: { name: string; userId: string }; + }; proceedingType: TrialSessionProceedingType | 'All'; sessionStatus: string; sessionType: string; - trialLocation: string; + trialLocations: { + action: 'add' | 'remove'; + trialLocation: string; + }; }>; export const setTrialSessionsFiltersAction = ({ @@ -21,14 +27,14 @@ export const setTrialSessionsFiltersAction = ({ store.set(state.trialSessionsPage.filters.currentTab, props.currentTab); } - if (props.judgeIds) { - const newJudgeIds = - props.judgeIds.action === 'add' - ? currentFilters.judgeIds.concat([props.judgeIds.judgeId]) - : currentFilters.judgeIds.filter( - (id: string) => id !== props.judgeIds!.judgeId, - ); - store.set(state.trialSessionsPage.filters.judgeIds, newJudgeIds); + if (props.judges) { + if (props.judges.action === 'add') { + currentFilters.judges[props.judges.judge.userId] = props.judges.judge; + } else { + delete currentFilters.judges[props.judges.judge.userId]; + } + + store.set(state.trialSessionsPage.filters.judges, currentFilters.judges); } if (props.proceedingType) { @@ -49,10 +55,17 @@ export const setTrialSessionsFiltersAction = ({ store.set(state.trialSessionsPage.filters.sessionType, props.sessionType); } // Update for Trial Sessions Page - if (props.trialLocation) { + if (props.trialLocations) { + const { action, trialLocation } = props.trialLocations; + if (action === 'add') { + currentFilters.trialLocations[trialLocation] = trialLocation; + } else { + delete currentFilters.trialLocations[trialLocation]; + } + store.set( - state.trialSessionsPage.filters.trialLocation, - props.trialLocation, + state.trialSessionsPage.filters.trialLocations, + currentFilters.trialLocations, ); } }; diff --git a/web-client/src/presenter/computeds/trialSessionsHelper.test.ts b/web-client/src/presenter/computeds/trialSessionsHelper.test.ts index 249900ed39a..952177f5f08 100644 --- a/web-client/src/presenter/computeds/trialSessionsHelper.test.ts +++ b/web-client/src/presenter/computeds/trialSessionsHelper.test.ts @@ -453,7 +453,7 @@ describe('trialSessionsHelper', () => { it('should show trial sessions in honolulu when trial sessions when trial location filter is honolulu', () => { trialSession1.trialLocation = 'Honolulu, Hawaii'; trialSession2.trialLocation = 'Jacksonville, Florida'; - trialSessionsPageState.filters.trialLocation = 'Honolulu, Hawaii'; + trialSessionsPageState.filters.trialLocations = 'Honolulu, Hawaii'; trialSessionsPageState.trialSessions = [trialSession1, trialSession2]; const result = runCompute(trialSessionsHelper, { diff --git a/web-client/src/presenter/computeds/trialSessionsHelper.ts b/web-client/src/presenter/computeds/trialSessionsHelper.ts index 0f659e633e4..2489afc1536 100644 --- a/web-client/src/presenter/computeds/trialSessionsHelper.ts +++ b/web-client/src/presenter/computeds/trialSessionsHelper.ts @@ -24,8 +24,7 @@ export const trialSessionsHelper = ( showNoticeIssued: boolean; showSessionStatus: boolean; showUnassignedJudgeFilter: boolean; - trialSessionJudges: RawUser[]; - trialSessionJudgeOptions: InputOption[]; + trialSessionJudgeOptions: InputOption<{ name: string; userId: string }>[]; trialSessionRows: (TrialSessionRow | TrialSessionWeek)[]; sessionTypeOptions: InputOption[]; searchableTrialLocationOptions: InputOption[]; @@ -40,7 +39,7 @@ export const trialSessionsHelper = ( filters.currentTab === 'new' || filters.sessionStatus === SESSION_STATUS_TYPES.open; - let trialSessionJudges; // 10409 TODO BUG. The judge options is not updating correctly. Showing legacy when it should not. + let trialSessionJudges: { name: string; userId: string }[]; // 10409 TODO BUG. The judge options is not updating correctly. Showing legacy when it should not. if (showCurrentJudgesOnly) { trialSessionJudges = get(state.judges); console.log('current length: ', trialSessionJudges.length); @@ -54,10 +53,10 @@ export const trialSessionsHelper = ( value: sessionType, })); - const trialSessionJudgeOptions: InputOption[] = trialSessionJudges.map( + const trialSessionJudgeOptions = trialSessionJudges.map( trialSessionJudge => ({ label: trialSessionJudge.name, - value: trialSessionJudge.userId, + value: { name: trialSessionJudge.name, userId: trialSessionJudge.userId }, }), ); const trialCities = sortBy(TRIAL_CITIES.ALL, ['state', 'city']); @@ -93,10 +92,13 @@ export const trialSessionsHelper = ( return trialSession.isCalendared === isCalendaredFilter; }) .filter(trialSession => { - if (filters.judgeIds.length === 0) return true; - const trialSessionHasJudge = filters.judgeIds.some(judgeIdFilter => { - if (judgeIdFilter === 'unassigned') return !trialSession.judge?.userId; - return judgeIdFilter === trialSession.judge?.userId; + const selectedJudges = Object.values(filters.judges); + if (selectedJudges.length === 0) return true; + const trialSessionHasJudge = selectedJudges.some(judgeFilter => { + if (judgeFilter.userId === 'unassigned') { + return !trialSession.judge?.userId; + } + return judgeFilter.userId === trialSession.judge?.userId; }); return trialSessionHasJudge; @@ -115,8 +117,8 @@ export const trialSessionsHelper = ( return filters.sessionType === trialSession.sessionType; }) .filter(trialSession => { - if (filters.trialLocation === 'All') return true; - return filters.trialLocation === trialSession.trialLocation; + if (Object.values(filters.trialLocations).length === 0) return true; + return !!filters.trialLocations[trialSession.trialLocation || '']; }) .sort((sessionA, sessionB) => { return sessionA.startDate.localeCompare(sessionB.startDate); @@ -136,7 +138,6 @@ export const trialSessionsHelper = ( showUnassignedJudgeFilter: filters.currentTab === 'new', trialCitiesByState: states, trialSessionJudgeOptions, - trialSessionJudges, trialSessionRows, }; }; diff --git a/web-client/src/presenter/state/trialSessionsPageState.ts b/web-client/src/presenter/state/trialSessionsPageState.ts index c7e96b4dd66..95d69df4891 100644 --- a/web-client/src/presenter/state/trialSessionsPageState.ts +++ b/web-client/src/presenter/state/trialSessionsPageState.ts @@ -3,11 +3,11 @@ import { TrialSessionProceedingType } from '@shared/business/entities/EntityCons const filters: TrialSessionsFilters = { currentTab: 'calendared' as 'calendared' | 'new', - judgeIds: [], + judges: {}, proceedingType: 'All' as TrialSessionProceedingType, sessionStatus: 'Open', sessionType: 'All', - trialLocation: 'All', + trialLocations: {}, }; export const initialTrialSessionPageState = { @@ -17,9 +17,9 @@ export const initialTrialSessionPageState = { export type TrialSessionsFilters = { currentTab: 'calendared' | 'new'; - judgeIds: string[]; + judges: Record; proceedingType: TrialSessionProceedingType | 'All'; sessionStatus: string; sessionType: string; - trialLocation: string; + trialLocations: Record; }; diff --git a/web-client/src/ustc-ui/Utils/types.ts b/web-client/src/ustc-ui/Utils/types.ts index 300cea8b962..d9c0cd43583 100644 --- a/web-client/src/ustc-ui/Utils/types.ts +++ b/web-client/src/ustc-ui/Utils/types.ts @@ -4,9 +4,9 @@ import { GetCasesByStatusAndByJudgeResponse } from '@web-api/business/useCases/j import { JudgeActivityReportFilters } from '@web-api/business/useCases/judgeActivityReport/getCountOfCaseDocumentsFiledByJudgesInteractor'; import { TrialSessionReturnType } from '@web-api/business/useCases/judgeActivityReport/getTrialSessionsForJudgeActivityReportInteractor'; -export type InputOption = { +export type InputOption = { label: string; - value?: string; + value?: T; options?: InputOption[]; }; diff --git a/web-client/src/views/TrialSessions/TrialSessions.tsx b/web-client/src/views/TrialSessions/TrialSessions.tsx index 0083b6aeff2..ff31e2b076f 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 { PillButton } from '@web-client/ustc-ui/Button/PillButton'; import { SESSION_STATUS_TYPES, TRIAL_SESSION_PROCEEDING_TYPES, @@ -281,44 +282,85 @@ const TrialSessionFilters = connect( />
- - { - console.log('location', inputValue); - }} - /> +
+ + { + setTrialSessionsFiltersSequence({ + trialLocations: { + action: 'add', + trialLocation: location.value, + }, + }); + }} + /> +
+
+ {Object.values(trialSessionsPage.filters.trialLocations).map( + location => ( + { + setTrialSessionsFiltersSequence({ + trialLocations: { + action: 'remove', + trialLocation: location, + }, + }); + }} + /> + ), + )} +
- - { - if (inputValue) { +
+ + { setTrialSessionsFiltersSequence({ - judgeIds: { + judges: { action: 'add', - judgeId: inputValue.value, + judge: inputValue.value, }, }); - } - }} - /> + }} + /> +
+
+ {Object.values(trialSessionsPage.filters.judges).map(judge => ( + { + setTrialSessionsFiltersSequence({ + judges: { + action: 'remove', + judge, + }, + }); + }} + /> + ))} +
From 77e2631fb8e77997a1b8a8e6ac444ab1c9de99d7 Mon Sep 17 00:00:00 2001 From: Zachary Rogers Date: Wed, 18 Sep 2024 16:06:04 -0700 Subject: [PATCH 47/59] 10409: WIP Converting session types to multi select filter --- .../setTrialSessionsFiltersAction.ts | 32 ++++++++--- .../computeds/trialSessionsHelper.test.ts | 2 +- .../computeds/trialSessionsHelper.ts | 4 +- .../presenter/state/trialSessionsPageState.ts | 9 ++- .../src/views/TrialSessions/TrialSessions.tsx | 57 +++++++++++++------ 5 files changed, 73 insertions(+), 31 deletions(-) diff --git a/web-client/src/presenter/actions/TrialSession/setTrialSessionsFiltersAction.ts b/web-client/src/presenter/actions/TrialSession/setTrialSessionsFiltersAction.ts index 4cc186ab76b..744b609691d 100644 --- a/web-client/src/presenter/actions/TrialSession/setTrialSessionsFiltersAction.ts +++ b/web-client/src/presenter/actions/TrialSession/setTrialSessionsFiltersAction.ts @@ -1,4 +1,7 @@ -import { TrialSessionProceedingType } from '@shared/business/entities/EntityConstants'; +import { + TrialSessionProceedingType, + TrialSessionTypes, +} from '@shared/business/entities/EntityConstants'; import { state } from '@web-client/presenter/app.cerebral'; export type SetTrialSessionsFilters = Partial<{ @@ -9,7 +12,7 @@ export type SetTrialSessionsFilters = Partial<{ }; proceedingType: TrialSessionProceedingType | 'All'; sessionStatus: string; - sessionType: string; + sessionTypes: { action: 'add' | 'remove'; sessionType: TrialSessionTypes }; trialLocations: { action: 'add' | 'remove'; trialLocation: string; @@ -28,10 +31,11 @@ export const setTrialSessionsFiltersAction = ({ } if (props.judges) { - if (props.judges.action === 'add') { - currentFilters.judges[props.judges.judge.userId] = props.judges.judge; + const { action, judge } = props.judges; + if (action === 'add') { + currentFilters.judges[judge.userId] = judge; } else { - delete currentFilters.judges[props.judges.judge.userId]; + delete currentFilters.judges[judge.userId]; } store.set(state.trialSessionsPage.filters.judges, currentFilters.judges); @@ -50,11 +54,21 @@ export const setTrialSessionsFiltersAction = ({ props.sessionStatus, ); } - // Update for Trial Sessions Page - if (props.sessionType) { - store.set(state.trialSessionsPage.filters.sessionType, props.sessionType); + + if (props.sessionTypes) { + const { action, sessionType } = props.sessionTypes; + if (action === 'add') { + currentFilters.sessionTypes[sessionType] = sessionType; + } else { + delete currentFilters.sessionTypes[sessionType]; + } + + store.set( + state.trialSessionsPage.filters.sessionTypes, + currentFilters.sessionTypes, + ); } - // Update for Trial Sessions Page + if (props.trialLocations) { const { action, trialLocation } = props.trialLocations; if (action === 'add') { diff --git a/web-client/src/presenter/computeds/trialSessionsHelper.test.ts b/web-client/src/presenter/computeds/trialSessionsHelper.test.ts index 952177f5f08..f4da90fbc14 100644 --- a/web-client/src/presenter/computeds/trialSessionsHelper.test.ts +++ b/web-client/src/presenter/computeds/trialSessionsHelper.test.ts @@ -432,7 +432,7 @@ describe('trialSessionsHelper', () => { it('should show regular trial sessions when session type filter is regular', () => { trialSession1.sessionType = SESSION_TYPES.regular; trialSession2.sessionType = SESSION_TYPES.hybridSmall; - trialSessionsPageState.filters.sessionType = SESSION_TYPES.regular; + trialSessionsPageState.filters.sessionTypes = SESSION_TYPES.regular; trialSessionsPageState.trialSessions = [trialSession1, trialSession2]; const result = runCompute(trialSessionsHelper, { diff --git a/web-client/src/presenter/computeds/trialSessionsHelper.ts b/web-client/src/presenter/computeds/trialSessionsHelper.ts index 2489afc1536..66ecddf5f37 100644 --- a/web-client/src/presenter/computeds/trialSessionsHelper.ts +++ b/web-client/src/presenter/computeds/trialSessionsHelper.ts @@ -113,8 +113,8 @@ export const trialSessionsHelper = ( return filters.sessionStatus === trialSession.sessionStatus; }) .filter(trialSession => { - if (filters.sessionType === 'All') return true; - return filters.sessionType === trialSession.sessionType; + if (Object.values(filters.sessionTypes).length === 0) return true; + return !!filters.sessionTypes[trialSession.sessionType]; }) .filter(trialSession => { if (Object.values(filters.trialLocations).length === 0) return true; diff --git a/web-client/src/presenter/state/trialSessionsPageState.ts b/web-client/src/presenter/state/trialSessionsPageState.ts index 95d69df4891..a8a6a05dad6 100644 --- a/web-client/src/presenter/state/trialSessionsPageState.ts +++ b/web-client/src/presenter/state/trialSessionsPageState.ts @@ -1,12 +1,15 @@ import { TrialSessionInfoDTO } from '@shared/business/dto/trialSessions/TrialSessionInfoDTO'; -import { TrialSessionProceedingType } from '@shared/business/entities/EntityConstants'; +import { + TrialSessionProceedingType, + TrialSessionTypes, +} from '@shared/business/entities/EntityConstants'; const filters: TrialSessionsFilters = { currentTab: 'calendared' as 'calendared' | 'new', judges: {}, proceedingType: 'All' as TrialSessionProceedingType, sessionStatus: 'Open', - sessionType: 'All', + sessionTypes: {}, trialLocations: {}, }; @@ -20,6 +23,6 @@ export type TrialSessionsFilters = { judges: Record; proceedingType: TrialSessionProceedingType | 'All'; sessionStatus: string; - sessionType: string; + sessionTypes: Record; trialLocations: Record; }; diff --git a/web-client/src/views/TrialSessions/TrialSessions.tsx b/web-client/src/views/TrialSessions/TrialSessions.tsx index ff31e2b076f..f93ffce2830 100644 --- a/web-client/src/views/TrialSessions/TrialSessions.tsx +++ b/web-client/src/views/TrialSessions/TrialSessions.tsx @@ -266,23 +266,48 @@ const TrialSessionFilters = connect(
- - { - console.log('session type', inputValue); - }} - /> +
+ + { + setTrialSessionsFiltersSequence({ + sessionTypes: { + action: 'add', + sessionType: sessionType.value, + }, + }); + }} + /> +
+
+ {Object.values(trialSessionsPage.filters.sessionTypes).map( + sessionType => ( + { + setTrialSessionsFiltersSequence({ + sessionTypes: { + action: 'remove', + sessionType, + }, + }); + }} + /> + ), + )} +
-
+
@@ -325,7 +350,7 @@ const TrialSessionFilters = connect(
-
+
From e4ad45ff7f38df3f0871f329c9a91c2aafb7d712 Mon Sep 17 00:00:00 2001 From: Nechama Krigsman Date: Thu, 19 Sep 2024 00:07:18 -0400 Subject: [PATCH 48/59] 10409: add clear trial session filter button; --- .../resetTrialSessionsFiltersAction.test.ts | 4 ++-- .../TrialSession/resetTrialSessionsFiltersAction.ts | 5 ++++- web-client/src/presenter/presenter.ts | 2 ++ .../sequences/resetTrialSessionsFiltersSequence.ts | 5 +++++ .../src/presenter/state/trialSessionsPageState.ts | 5 +++-- web-client/src/views/TrialSessions/TrialSessions.tsx | 11 +++++++++++ 6 files changed, 27 insertions(+), 5 deletions(-) create mode 100644 web-client/src/presenter/sequences/resetTrialSessionsFiltersSequence.ts diff --git a/web-client/src/presenter/actions/TrialSession/resetTrialSessionsFiltersAction.test.ts b/web-client/src/presenter/actions/TrialSession/resetTrialSessionsFiltersAction.test.ts index 487f0db01e4..bd3bd8e4239 100644 --- a/web-client/src/presenter/actions/TrialSession/resetTrialSessionsFiltersAction.test.ts +++ b/web-client/src/presenter/actions/TrialSession/resetTrialSessionsFiltersAction.test.ts @@ -8,8 +8,8 @@ describe('resetTrialSessionsFiltersAction', () => { state: {}, }); - expect(result.state.trialSessionsPage).toEqual( - initialTrialSessionPageState, + expect(result.state.trialSessionsPage.filters).toEqual( + initialTrialSessionPageState.filters, ); }); }); diff --git a/web-client/src/presenter/actions/TrialSession/resetTrialSessionsFiltersAction.ts b/web-client/src/presenter/actions/TrialSession/resetTrialSessionsFiltersAction.ts index 57f6678c48e..41263650a1d 100644 --- a/web-client/src/presenter/actions/TrialSession/resetTrialSessionsFiltersAction.ts +++ b/web-client/src/presenter/actions/TrialSession/resetTrialSessionsFiltersAction.ts @@ -3,5 +3,8 @@ import { initialTrialSessionPageState } from '@web-client/presenter/state/trialS import { state } from '@web-client/presenter/app.cerebral'; export const resetTrialSessionsFiltersAction = ({ store }: ActionProps) => { - store.set(state.trialSessionsPage, cloneDeep(initialTrialSessionPageState)); + store.set( + state.trialSessionsPage.filters, + cloneDeep(initialTrialSessionPageState.filters), + ); }; diff --git a/web-client/src/presenter/presenter.ts b/web-client/src/presenter/presenter.ts index 2d0f96387bf..7e309c474a7 100644 --- a/web-client/src/presenter/presenter.ts +++ b/web-client/src/presenter/presenter.ts @@ -353,6 +353,7 @@ import { resetHeaderAccordionsSequence } from './sequences/resetHeaderAccordions import { resetIdleTimerSequence } from './sequences/resetIdleTimerSequence'; import { resetPasswordSequence } from '@web-client/presenter/sequences/Login/resetPasswordSequence'; import { resetSecondaryAddressSequence } from './sequences/resetSecondaryAddressSequence'; +import { resetTrialSessionsFiltersSequence } from '@web-client/presenter/sequences/resetTrialSessionsFiltersSequence'; import { retryAsyncRequestSequence } from './sequences/retryAsyncRequestSequence'; import { reviewCaseAssociationRequestSequence } from './sequences/reviewCaseAssociationRequestSequence'; import { reviewExternalDocumentInformationSequence } from './sequences/reviewExternalDocumentInformationSequence'; @@ -1196,6 +1197,7 @@ export const presenterSequences = { resetIdleTimerSequence: resetIdleTimerSequence as unknown as Function, resetPasswordSequence, resetSecondaryAddressSequence, + resetTrialSessionsFiltersSequence, retryAsyncRequestSequence: retryAsyncRequestSequence as unknown as Function, reviewCaseAssociationRequestSequence: reviewCaseAssociationRequestSequence as unknown as Function, diff --git a/web-client/src/presenter/sequences/resetTrialSessionsFiltersSequence.ts b/web-client/src/presenter/sequences/resetTrialSessionsFiltersSequence.ts new file mode 100644 index 00000000000..375941b2292 --- /dev/null +++ b/web-client/src/presenter/sequences/resetTrialSessionsFiltersSequence.ts @@ -0,0 +1,5 @@ +import { resetTrialSessionsFiltersAction } from '@web-client/presenter/actions/TrialSession/resetTrialSessionsFiltersAction'; + +export const resetTrialSessionsFiltersSequence = [ + resetTrialSessionsFiltersAction, +] as unknown as () => void; diff --git a/web-client/src/presenter/state/trialSessionsPageState.ts b/web-client/src/presenter/state/trialSessionsPageState.ts index a8a6a05dad6..6ef0a53653e 100644 --- a/web-client/src/presenter/state/trialSessionsPageState.ts +++ b/web-client/src/presenter/state/trialSessionsPageState.ts @@ -1,14 +1,15 @@ -import { TrialSessionInfoDTO } from '@shared/business/dto/trialSessions/TrialSessionInfoDTO'; import { + SESSION_STATUS_TYPES, TrialSessionProceedingType, TrialSessionTypes, } from '@shared/business/entities/EntityConstants'; +import { TrialSessionInfoDTO } from '@shared/business/dto/trialSessions/TrialSessionInfoDTO'; const filters: TrialSessionsFilters = { currentTab: 'calendared' as 'calendared' | 'new', judges: {}, proceedingType: 'All' as TrialSessionProceedingType, - sessionStatus: 'Open', + sessionStatus: SESSION_STATUS_TYPES.open, sessionTypes: {}, trialLocations: {}, }; diff --git a/web-client/src/views/TrialSessions/TrialSessions.tsx b/web-client/src/views/TrialSessions/TrialSessions.tsx index f93ffce2830..f7e6e3a06d1 100644 --- a/web-client/src/views/TrialSessions/TrialSessions.tsx +++ b/web-client/src/views/TrialSessions/TrialSessions.tsx @@ -92,11 +92,14 @@ export const TrialSessions = connect( const TrialSessionFilters = connect( { + resetTrialSessionsFiltersSequence: + sequences.resetTrialSessionsFiltersSequence, setTrialSessionsFiltersSequence: sequences.setTrialSessionsFiltersSequence, trialSessionsHelper: state.trialSessionsHelper, trialSessionsPage: state.trialSessionsPage, }, function TrialSessionFilters({ + resetTrialSessionsFiltersSequence, setTrialSessionsFiltersSequence, trialSessionsHelper, trialSessionsPage, @@ -388,6 +391,14 @@ const TrialSessionFilters = connect(
+ ); }, From 0713553e90d71483c840e8137ba12c5370c16972 Mon Sep 17 00:00:00 2001 From: Nechama Krigsman Date: Thu, 19 Sep 2024 10:23:30 -0400 Subject: [PATCH 49/59] 10409: disable clear filters button when no optional filters are selected; --- web-client/src/presenter/computeds/trialSessionsHelper.ts | 8 ++++++++ web-client/src/views/TrialSessions/TrialSessions.tsx | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/web-client/src/presenter/computeds/trialSessionsHelper.ts b/web-client/src/presenter/computeds/trialSessionsHelper.ts index 66ecddf5f37..76451ce9441 100644 --- a/web-client/src/presenter/computeds/trialSessionsHelper.ts +++ b/web-client/src/presenter/computeds/trialSessionsHelper.ts @@ -20,6 +20,7 @@ import { state } from '@web-client/presenter/app.cerebral'; export const trialSessionsHelper = ( get: Get, ): { + isClearFiltersDisabled: boolean; showNewTrialSession: boolean; showNoticeIssued: boolean; showSessionStatus: boolean; @@ -129,7 +130,14 @@ export const trialSessionsHelper = ( trialSessions: filteredTrialSessions, }); + const isClearFiltersDisabled = ![ + ...Object.keys(filters.judges), + ...Object.keys(filters.sessionTypes), + ...Object.keys(filters.trialLocations), + ].length; + return { + isClearFiltersDisabled, searchableTrialLocationOptions, sessionTypeOptions, showNewTrialSession: permissions.CREATE_TRIAL_SESSION, diff --git a/web-client/src/views/TrialSessions/TrialSessions.tsx b/web-client/src/views/TrialSessions/TrialSessions.tsx index f7e6e3a06d1..498b3ac4225 100644 --- a/web-client/src/views/TrialSessions/TrialSessions.tsx +++ b/web-client/src/views/TrialSessions/TrialSessions.tsx @@ -393,7 +393,7 @@ const TrialSessionFilters = connect(
); From 30e8ecaee24fc97d6b0af76ab46c2eaf12e1ecd8 Mon Sep 17 00:00:00 2001 From: Zachary Rogers Date: Thu, 19 Sep 2024 11:30:19 -0700 Subject: [PATCH 53/59] 10409: fix warnings --- web-client/src/ustc-ui/Tabs/Tabs.tsx | 2 +- .../src/views/TrialSessions/TrialSessions.tsx | 2 + .../TrialSessions/TrialSessionsTable.tsx | 119 +++++++++--------- 3 files changed, 60 insertions(+), 63 deletions(-) diff --git a/web-client/src/ustc-ui/Tabs/Tabs.tsx b/web-client/src/ustc-ui/Tabs/Tabs.tsx index 10d09f3a8dc..52c2726101d 100644 --- a/web-client/src/ustc-ui/Tabs/Tabs.tsx +++ b/web-client/src/ustc-ui/Tabs/Tabs.tsx @@ -82,7 +82,7 @@ export function Tab(properties: { const HeadingElement = ({ children, level }) => { return React.createElement( `h${level}`, - { ariaHidden: 'false', className: 'sr-only' }, + { 'aria-hidden': 'false', className: 'sr-only' }, children, ); }; diff --git a/web-client/src/views/TrialSessions/TrialSessions.tsx b/web-client/src/views/TrialSessions/TrialSessions.tsx index 1a70b17cee6..8f6cb8ec955 100644 --- a/web-client/src/views/TrialSessions/TrialSessions.tsx +++ b/web-client/src/views/TrialSessions/TrialSessions.tsx @@ -67,6 +67,7 @@ export const TrialSessions = connect( @@ -77,6 +78,7 @@ export const TrialSessions = connect( diff --git a/web-client/src/views/TrialSessions/TrialSessionsTable.tsx b/web-client/src/views/TrialSessions/TrialSessionsTable.tsx index f97331bc764..4cda7a2b5a2 100644 --- a/web-client/src/views/TrialSessions/TrialSessionsTable.tsx +++ b/web-client/src/views/TrialSessions/TrialSessionsTable.tsx @@ -1,9 +1,6 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { connect } from '@web-client/presenter/shared.cerebral'; -import { - isTrialSessionRow, - isTrialSessionWeek, -} from '@web-client/presenter/computeds/trialSessionsHelper'; +import { isTrialSessionWeek } from '@web-client/presenter/computeds/trialSessionsHelper'; import { state } from '@web-client/presenter/app.cerebral'; import React from 'react'; @@ -34,10 +31,10 @@ export const TrialSessionsTable = connect( {trialSessionsHelper.showSessionStatus && Session Status} - {trialSessionsHelper.trialSessionRows.map(row => ( - <> - {isTrialSessionWeek(row) && ( - + {trialSessionsHelper.trialSessionRows.map(row => { + if (isTrialSessionWeek(row)) { + return ( +

@@ -47,62 +44,60 @@ export const TrialSessionsTable = connect( - )} - {isTrialSessionRow(row) && ( - - - - {row.showAlertForNOTTReminder && ( - - )} - {row.formattedStartDate} - - {row.formattedEstimatedEndDate} - - {row.swingSession && ( - - )} - - - - {row.trialLocation} - - - {row.proceedingType} - {row.sessionType} - {row.judge && row.judge.name} - {trialSessionsHelper.showNoticeIssued && ( - {row.formattedNoticeIssuedDate} + ); + } + return ( + + + + {row.showAlertForNOTTReminder && ( + )} - {trialSessionsHelper.showSessionStatus && ( - {row.sessionStatus} + {row.formattedStartDate} + + {row.formattedEstimatedEndDate} + + {row.swingSession && ( + )} - - - )} - - ))} + + + + {row.trialLocation} + + + {row.proceedingType} + {row.sessionType} + {row.judge && row.judge.name} + {trialSessionsHelper.showNoticeIssued && ( + {row.formattedNoticeIssuedDate} + )} + {trialSessionsHelper.showSessionStatus && ( + {row.sessionStatus} + )} + + + ); + })} {trialSessionsHelper.trialSessionRows.length === 0 && (

There are no trial sessions for the selected filters.

From d7b43ea3a52e1381cf2fdd208c0438b9b911d773 Mon Sep 17 00:00:00 2001 From: Zachary Rogers Date: Thu, 19 Sep 2024 12:00:38 -0700 Subject: [PATCH 54/59] 10409: fix reseet filters on tab change --- .../resetTrialSessionsFiltersAction.ts | 9 ++++++++- .../resetTrialSessionsFiltersSequence.ts | 8 +++++++- .../src/views/TrialSessions/TrialSessions.tsx | 15 +++++++++++---- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/web-client/src/presenter/actions/TrialSession/resetTrialSessionsFiltersAction.ts b/web-client/src/presenter/actions/TrialSession/resetTrialSessionsFiltersAction.ts index 41263650a1d..ae70b2b33e2 100644 --- a/web-client/src/presenter/actions/TrialSession/resetTrialSessionsFiltersAction.ts +++ b/web-client/src/presenter/actions/TrialSession/resetTrialSessionsFiltersAction.ts @@ -1,10 +1,17 @@ +import { ResetTrialSessionsFiltersSequence } from '@web-client/presenter/sequences/resetTrialSessionsFiltersSequence'; import { cloneDeep } from 'lodash'; import { initialTrialSessionPageState } from '@web-client/presenter/state/trialSessionsPageState'; import { state } from '@web-client/presenter/app.cerebral'; -export const resetTrialSessionsFiltersAction = ({ store }: ActionProps) => { +export const resetTrialSessionsFiltersAction = ({ + props, + store, +}: ActionProps) => { store.set( state.trialSessionsPage.filters, cloneDeep(initialTrialSessionPageState.filters), ); + if (props?.currentTab) { + store.set(state.trialSessionsPage.filters.currentTab, props.currentTab); + } }; diff --git a/web-client/src/presenter/sequences/resetTrialSessionsFiltersSequence.ts b/web-client/src/presenter/sequences/resetTrialSessionsFiltersSequence.ts index 375941b2292..f9ac27dac2f 100644 --- a/web-client/src/presenter/sequences/resetTrialSessionsFiltersSequence.ts +++ b/web-client/src/presenter/sequences/resetTrialSessionsFiltersSequence.ts @@ -2,4 +2,10 @@ import { resetTrialSessionsFiltersAction } from '@web-client/presenter/actions/T export const resetTrialSessionsFiltersSequence = [ resetTrialSessionsFiltersAction, -] as unknown as () => void; +] as unknown as (props?: ResetTrialSessionsFiltersSequence) => void; + +export type ResetTrialSessionsFiltersSequence = + | undefined + | { + currentTab: 'calendared' | 'new'; + }; diff --git a/web-client/src/views/TrialSessions/TrialSessions.tsx b/web-client/src/views/TrialSessions/TrialSessions.tsx index 8f6cb8ec955..a2d6bc6f7f7 100644 --- a/web-client/src/views/TrialSessions/TrialSessions.tsx +++ b/web-client/src/views/TrialSessions/TrialSessions.tsx @@ -21,12 +21,13 @@ export const TrialSessions = connect( { openTrialSessionPlanningModalSequence: sequences.openTrialSessionPlanningModalSequence, - setTrialSessionsFiltersSequence: sequences.setTrialSessionsFiltersSequence, + resetTrialSessionsFiltersSequence: + sequences.resetTrialSessionsFiltersSequence, trialSessionsHelper: state.trialSessionsHelper, }, function TrialSessions({ openTrialSessionPlanningModalSequence, - setTrialSessionsFiltersSequence, + resetTrialSessionsFiltersSequence, trialSessionsHelper, }) { return ( @@ -41,7 +42,7 @@ export const TrialSessions = connect( headingLevel="2" id="trial-sessions-tabs" onSelect={tabName => { - setTrialSessionsFiltersSequence({ currentTab: tabName }); + resetTrialSessionsFiltersSequence({ currentTab: tabName }); }} >
@@ -245,6 +246,12 @@ const TrialSessionFilters = connect( + Last start date{' '} + (optional) + + } endName="trialSessionStartDate" endValue={trialSessionsPage.filters.endDate} formGroupCls="margin-bottom-0" @@ -253,7 +260,7 @@ const TrialSessionFilters = connect( startDateErrorText={''} startLabel={ - Trial Start Date range{' '} + First start date{' '} (optional) } From 1d1a0e652ac55e67e315201ddfc2968c81ab6918 Mon Sep 17 00:00:00 2001 From: Nechama Krigsman Date: Thu, 19 Sep 2024 15:27:23 -0400 Subject: [PATCH 55/59] 10409: add trial session count; --- web-client/src/presenter/computeds/trialSessionsHelper.ts | 3 ++- web-client/src/views/TrialSessions/TrialSessionsTable.tsx | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/web-client/src/presenter/computeds/trialSessionsHelper.ts b/web-client/src/presenter/computeds/trialSessionsHelper.ts index 6f5346de6fd..c3e2285cb7f 100644 --- a/web-client/src/presenter/computeds/trialSessionsHelper.ts +++ b/web-client/src/presenter/computeds/trialSessionsHelper.ts @@ -32,6 +32,7 @@ export const trialSessionsHelper = ( sessionTypeOptions: InputOption[]; searchableTrialLocationOptions: InputOption[]; trialCitiesByState: InputOption[]; + trialSessionsCount: number; } => { const permissions = get(state.permissions)!; const trialSessions = get(state.trialSessionsPage.trialSessions); @@ -140,7 +141,6 @@ export const trialSessionsHelper = ( .sort((sessionA, sessionB) => { return sessionA.startDate.localeCompare(sessionB.startDate); }); - const trialSessionRows = formatTrialSessions({ judgeAssociatedToUser: judge, trialSessions: filteredTrialSessions, @@ -168,6 +168,7 @@ export const trialSessionsHelper = ( trialCitiesByState: states, trialSessionJudgeOptions, trialSessionRows, + trialSessionsCount: filteredTrialSessions.length, }; }; diff --git a/web-client/src/views/TrialSessions/TrialSessionsTable.tsx b/web-client/src/views/TrialSessions/TrialSessionsTable.tsx index 4cda7a2b5a2..ed3b0b41087 100644 --- a/web-client/src/views/TrialSessions/TrialSessionsTable.tsx +++ b/web-client/src/views/TrialSessions/TrialSessionsTable.tsx @@ -12,6 +12,12 @@ export const TrialSessionsTable = connect( function TrialSessionsTable({ trialSessionsHelper, trialSessionsPage }) { return ( <> +
+ Count:{' '} + + {trialSessionsHelper.trialSessionsCount} + +
Date: Thu, 19 Sep 2024 17:03:48 -0400 Subject: [PATCH 56/59] 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 }); + }} + /> ); }, From 6965f657d13b2b86bcd254e4507c5316075b9db0 Mon Sep 17 00:00:00 2001 From: Zachary Rogers Date: Thu, 19 Sep 2024 15:08:13 -0700 Subject: [PATCH 57/59] 10409: Add pagination support for trial sessions --- .../computeds/trialSessionsHelper.ts | 90 +++++++++++-------- 1 file changed, 53 insertions(+), 37 deletions(-) diff --git a/web-client/src/presenter/computeds/trialSessionsHelper.ts b/web-client/src/presenter/computeds/trialSessionsHelper.ts index aacd345fd45..6317aa738b7 100644 --- a/web-client/src/presenter/computeds/trialSessionsHelper.ts +++ b/web-client/src/presenter/computeds/trialSessionsHelper.ts @@ -15,7 +15,10 @@ import { } from '@shared/business/entities/EntityConstants'; import { TrialSession } from '@shared/business/entities/trialSessions/TrialSession'; import { TrialSessionInfoDTO } from '@shared/business/dto/trialSessions/TrialSessionInfoDTO'; -import { initialTrialSessionPageState } from '@web-client/presenter/state/trialSessionsPageState'; +import { + TrialSessionsFilters, + initialTrialSessionPageState, +} from '@web-client/presenter/state/trialSessionsPageState'; import { sortBy } from 'lodash'; import { state } from '@web-client/presenter/app.cerebral'; @@ -53,6 +56,17 @@ export const trialSessionsHelper = ( trialSessionJudges = get(state.legacyAndCurrentJudges); } + const userHasSelectedAFilter = + filters.proceedingType !== + initialTrialSessionPageState.filters.proceedingType || + filters.sessionStatus !== + initialTrialSessionPageState.filters.sessionStatus || + Object.keys(filters.judges).length > 0 || + Object.keys(filters.sessionTypes).length > 0 || + Object.keys(filters.trialLocations).length > 0 || + !!filters.startDate || + !!filters.endDate; + const sessionTypeOptions = Object.values(SESSION_TYPES).map(sessionType => ({ label: sessionType, value: sessionType, @@ -91,7 +105,43 @@ export const trialSessionsHelper = ( [], ); - const filteredTrialSessions = trialSessions + const filteredTrialSessions = filterAndSortTrialSessions({ + filters, + trialSessions, + }); + const trialSessionPage = filteredTrialSessions.slice( + filters.pageNumber * pageSize, + filters.pageNumber * pageSize + pageSize, + ); + const trialSessionRows = formatTrialSessions({ + judgeAssociatedToUser: judge, + trialSessions: trialSessionPage, + }); + + return { + isResetFiltersDisabled: !userHasSelectedAFilter, + searchableTrialLocationOptions, + sessionTypeOptions, + showNewTrialSession: permissions.CREATE_TRIAL_SESSION, + showNoticeIssued: filters.currentTab === 'calendared', + showSessionStatus: filters.currentTab === 'calendared', + showUnassignedJudgeFilter: filters.currentTab === 'new', + totalPages: Math.ceil(filteredTrialSessions.length / pageSize), + trialCitiesByState: states, + trialSessionJudgeOptions, + trialSessionRows, + trialSessionsCount: filteredTrialSessions.length, + }; +}; + +const filterAndSortTrialSessions = ({ + filters, + trialSessions, +}: { + trialSessions: TrialSessionInfoDTO[]; + filters: TrialSessionsFilters; +}): TrialSessionInfoDTO[] => { + return trialSessions .filter(trialSession => { const isCalendaredFilter = filters.currentTab === 'calendared'; return trialSession.isCalendared === isCalendaredFilter; @@ -143,41 +193,7 @@ 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, - }); - - const userHasSelectedAFilter = - filters.proceedingType !== - initialTrialSessionPageState.filters.proceedingType || - filters.sessionStatus !== - initialTrialSessionPageState.filters.sessionStatus || - Object.keys(filters.judges).length > 0 || - Object.keys(filters.sessionTypes).length > 0 || - Object.keys(filters.trialLocations).length > 0 || - !!filters.startDate || - !!filters.endDate; - - return { - isResetFiltersDisabled: !userHasSelectedAFilter, - searchableTrialLocationOptions, - sessionTypeOptions, - showNewTrialSession: permissions.CREATE_TRIAL_SESSION, - showNoticeIssued: filters.currentTab === 'calendared', - showSessionStatus: filters.currentTab === 'calendared', - showUnassignedJudgeFilter: filters.currentTab === 'new', - totalPages: Math.ceil(filteredTrialSessions.length / pageSize), - trialCitiesByState: states, - trialSessionJudgeOptions, - trialSessionRows, - trialSessionsCount: filteredTrialSessions.length, - }; + }); }; const formatTrialSessions = ({ From 4618a77424fef641a16856bed99e9c195437ce34 Mon Sep 17 00:00:00 2001 From: Zachary Rogers Date: Thu, 19 Sep 2024 15:24:04 -0700 Subject: [PATCH 58/59] 10409: Change paginator location --- .../src/ustc-ui/Pagination/Paginator.tsx | 121 +++++++++--------- .../src/views/TrialSessions/TrialSessions.tsx | 8 -- .../TrialSessions/TrialSessionsTable.tsx | 17 ++- 3 files changed, 75 insertions(+), 71 deletions(-) diff --git a/web-client/src/ustc-ui/Pagination/Paginator.tsx b/web-client/src/ustc-ui/Pagination/Paginator.tsx index 7965e1f6317..6aa10397584 100644 --- a/web-client/src/ustc-ui/Pagination/Paginator.tsx +++ b/web-client/src/ustc-ui/Pagination/Paginator.tsx @@ -2,6 +2,64 @@ import React from 'react'; import classNames from 'classnames'; const numberOfPaginatorSlots = 7; + +/* +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; + totalPages: number; + onPageChange: (selectedPage: number) => any; +}) => { + const sevenDisplayedSlots: React.JSX.Element[] = []; + + for (let slotNumber = 0; slotNumber < numberOfPaginatorSlots; slotNumber++) { + if (slotNumber >= totalPages) { + continue; + } + const slotComponent = getSlotComponent({ + currentPageIndex, + onPageChange, + slotNumber, + totalPages, + }); + sevenDisplayedSlots.push(slotComponent); + } + + return ( + <> + + + ); +}; + +Paginator.displayName = 'Paginator'; + const PageButton = (props: { pageNumber: number; selected: boolean; @@ -185,65 +243,6 @@ function getSlotComponent({ /> ); } -} - -/* -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; - totalPages: number; - onPageChange: (selectedPage: number) => any; -}) => { - 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? - - for (let slotNumber = 0; slotNumber < numberOfPaginatorSlots; slotNumber++) { - if (slotNumber >= totalPages) { - continue; - } - const slotComponent = getSlotComponent({ - currentPageIndex, - onPageChange, - slotNumber, - totalPages, - }); - sevenDisplayedSlots.push(slotComponent); - } - - return ( - <> - - - ); -}; - -Paginator.displayName = 'Paginator'; + return <>; +} diff --git a/web-client/src/views/TrialSessions/TrialSessions.tsx b/web-client/src/views/TrialSessions/TrialSessions.tsx index a622d6c2c41..a2d6bc6f7f7 100644 --- a/web-client/src/views/TrialSessions/TrialSessions.tsx +++ b/web-client/src/views/TrialSessions/TrialSessions.tsx @@ -2,7 +2,6 @@ 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, @@ -412,13 +411,6 @@ const TrialSessionFilters = connect( > Reset Filters - { - setTrialSessionsFiltersSequence({ pageNumber: selectedPage }); - }} - /> ); }, diff --git a/web-client/src/views/TrialSessions/TrialSessionsTable.tsx b/web-client/src/views/TrialSessions/TrialSessionsTable.tsx index ed3b0b41087..357b2b00c7b 100644 --- a/web-client/src/views/TrialSessions/TrialSessionsTable.tsx +++ b/web-client/src/views/TrialSessions/TrialSessionsTable.tsx @@ -1,18 +1,31 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { Paginator } from '@web-client/ustc-ui/Pagination/Paginator'; import { connect } from '@web-client/presenter/shared.cerebral'; import { isTrialSessionWeek } from '@web-client/presenter/computeds/trialSessionsHelper'; -import { state } from '@web-client/presenter/app.cerebral'; +import { sequences, state } from '@web-client/presenter/app.cerebral'; import React from 'react'; export const TrialSessionsTable = connect( { + setTrialSessionsFiltersSequence: sequences.setTrialSessionsFiltersSequence, trialSessionsHelper: state.trialSessionsHelper, trialSessionsPage: state.trialSessionsPage, }, - function TrialSessionsTable({ trialSessionsHelper, trialSessionsPage }) { + function TrialSessionsTable({ + setTrialSessionsFiltersSequence, + trialSessionsHelper, + trialSessionsPage, + }) { return ( <>
    + { + setTrialSessionsFiltersSequence({ pageNumber: selectedPage }); + }} + /> Count:{' '} {trialSessionsHelper.trialSessionsCount} From 4b12b16805f2cc61075bff6cf02d711dd72152ac Mon Sep 17 00:00:00 2001 From: Zachary Rogers Date: Thu, 19 Sep 2024 16:00:43 -0700 Subject: [PATCH 59/59] 10409: Set page number whenever filters change --- .../setTrialSessionsFiltersAction.ts | 6 ++-- .../computeds/trialSessionsHelper.ts | 2 +- .../src/ustc-ui/Pagination/Paginator.tsx | 23 +++++++++++---- .../src/views/TrialSessions/TrialSessions.tsx | 2 +- .../TrialSessions/TrialSessionsTable.tsx | 29 +++++++++++-------- 5 files changed, 39 insertions(+), 23 deletions(-) diff --git a/web-client/src/presenter/actions/TrialSession/setTrialSessionsFiltersAction.ts b/web-client/src/presenter/actions/TrialSession/setTrialSessionsFiltersAction.ts index 868c0bc9e10..1e32cb67da6 100644 --- a/web-client/src/presenter/actions/TrialSession/setTrialSessionsFiltersAction.ts +++ b/web-client/src/presenter/actions/TrialSession/setTrialSessionsFiltersAction.ts @@ -86,14 +86,12 @@ 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); } if (props.endDate || props.endDate === '') { store.set(state.trialSessionsPage.filters.endDate, props.endDate); } + + store.set(state.trialSessionsPage.filters.pageNumber, props.pageNumber || 0); // Always reset page number to 0 }; diff --git a/web-client/src/presenter/computeds/trialSessionsHelper.ts b/web-client/src/presenter/computeds/trialSessionsHelper.ts index 6317aa738b7..184bbcd7ea4 100644 --- a/web-client/src/presenter/computeds/trialSessionsHelper.ts +++ b/web-client/src/presenter/computeds/trialSessionsHelper.ts @@ -43,7 +43,7 @@ export const trialSessionsHelper = ( const filters = get(state.trialSessionsPage.filters); const judge = get(state.judgeUser); - const pageSize = 5; + const pageSize = 1; const showCurrentJudgesOnly = filters.currentTab === 'new' || diff --git a/web-client/src/ustc-ui/Pagination/Paginator.tsx b/web-client/src/ustc-ui/Pagination/Paginator.tsx index 6aa10397584..1dea748b15d 100644 --- a/web-client/src/ustc-ui/Pagination/Paginator.tsx +++ b/web-client/src/ustc-ui/Pagination/Paginator.tsx @@ -5,8 +5,8 @@ const numberOfPaginatorSlots = 7; /* 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. +The totalPages and selected page work similarly to counting arrays. TotalPages is similar to array.length and currentPageIndex is 0 based indexing. +totalPages could be 20 but the maximum value currentPageIndex could be is 19 and the lowest pages is 0. */ export const Paginator = ({ @@ -18,6 +18,9 @@ export const Paginator = ({ totalPages: number; onPageChange: (selectedPage: number) => any; }) => { + if (totalPages === 0) { + return; + } const sevenDisplayedSlots: React.JSX.Element[] = []; for (let slotNumber = 0; slotNumber < numberOfPaginatorSlots; slotNumber++) { @@ -35,7 +38,10 @@ export const Paginator = ({ return ( <> -
    -
    +