Skip to content

Commit

Permalink
EASI-4589 Fix the requests table's status column sorting method (#2772)
Browse files Browse the repository at this point in the history
* SystemIntakeStatusRequesterIndex

* Condition for `lcid` prop inner sort

* Use a hash table for the status index
Shorten the lcid condition

* TRBRequestStatusIndex

* Mistake

* Tidy up

* SystemIntakeStatusAdmin column

* `parseSortIndex` deferred until sorting with once

* Homepage table combo type sorting
Restore original trb request status

* Check compare `LCID_RETIRED`
  • Loading branch information
adamodd authored Aug 21, 2024
1 parent a97a8b9 commit f2256f4
Show file tree
Hide file tree
Showing 6 changed files with 181 additions and 17 deletions.
21 changes: 21 additions & 0 deletions src/components/RequestRepository/useRequestTableColumns.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import { IconError } from '@trussworks/react-uswds';

import UswdsReactLink from 'components/LinkWrapper';
import TruncatedText from 'components/shared/TruncatedText';
import { SystemIntakeStatusAdmin } from 'types/graphql-global-types';
import { formatDateLocal, formatDateUtc } from 'utils/date';
import { SystemIntakeStatusAdminIndex } from 'utils/tableRequestStatusIndex';

import { SystemIntakeForTable } from './tableMap';

Expand Down Expand Up @@ -136,6 +138,25 @@ const useRequestTableColumns = (
lcid: obj.lcid
}
);
},
sortType: (a: Row<SystemIntakeForTable>, b: Row<SystemIntakeForTable>) => {
const astatus = a.original.statusAdmin;
const bstatus = b.original.statusAdmin;

if (
(astatus === SystemIntakeStatusAdmin.LCID_ISSUED &&
bstatus === SystemIntakeStatusAdmin.LCID_ISSUED) ||
(astatus === SystemIntakeStatusAdmin.LCID_EXPIRED &&
bstatus === SystemIntakeStatusAdmin.LCID_EXPIRED) ||
(astatus === SystemIntakeStatusAdmin.LCID_RETIRED &&
bstatus === SystemIntakeStatusAdmin.LCID_RETIRED)
) {
return (a.original.lcid || '') > (b.original.lcid || '') ? 1 : -1;
}

const ai = SystemIntakeStatusAdminIndex()[astatus];
const bi = SystemIntakeStatusAdminIndex()[bstatus];
return ai > bi ? 1 : -1;
}
};

Expand Down
91 changes: 91 additions & 0 deletions src/utils/tableRequestStatusIndex.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import { once } from 'lodash';

import {
SystemIntakeStatusAdmin,
SystemIntakeStatusRequester,
TRBRequestState,
TRBRequestStatus
} from 'types/graphql-global-types';

/**
* Get a hash table of status enum strings and their status order.
* Used for the request table status column sort compare fn.
*/
// Unfortunately the order of original enums from `schema.graphql` are lost
// when types are generated for the frontend in `global-types`.
// Generated enum strings are maintained in such a way here for react table column sorting.
function parseSortIndex(arr: string[]): () => { [v: string]: number } {
return once(() => Object.fromEntries(arr.map((v, i) => [v, i])));
}

export const SystemIntakeStatusRequesterIndex = parseSortIndex([
SystemIntakeStatusRequester.INITIAL_REQUEST_FORM_NEW,
SystemIntakeStatusRequester.INITIAL_REQUEST_FORM_IN_PROGRESS,
SystemIntakeStatusRequester.INITIAL_REQUEST_FORM_SUBMITTED,
SystemIntakeStatusRequester.INITIAL_REQUEST_FORM_EDITS_REQUESTED,
SystemIntakeStatusRequester.DRAFT_BUSINESS_CASE_IN_PROGRESS,
SystemIntakeStatusRequester.DRAFT_BUSINESS_CASE_SUBMITTED,
SystemIntakeStatusRequester.DRAFT_BUSINESS_CASE_EDITS_REQUESTED,
SystemIntakeStatusRequester.GRT_MEETING_READY,
SystemIntakeStatusRequester.GRT_MEETING_AWAITING_DECISION,
SystemIntakeStatusRequester.FINAL_BUSINESS_CASE_IN_PROGRESS,
SystemIntakeStatusRequester.FINAL_BUSINESS_CASE_SUBMITTED,
SystemIntakeStatusRequester.FINAL_BUSINESS_CASE_EDITS_REQUESTED,
SystemIntakeStatusRequester.GRB_MEETING_READY,
SystemIntakeStatusRequester.GRB_MEETING_AWAITING_DECISION,
SystemIntakeStatusRequester.LCID_ISSUED,
SystemIntakeStatusRequester.LCID_EXPIRED,
SystemIntakeStatusRequester.LCID_RETIRED,
SystemIntakeStatusRequester.NOT_GOVERNANCE,
SystemIntakeStatusRequester.NOT_APPROVED,
SystemIntakeStatusRequester.CLOSED
]);

export const SystemIntakeStatusAdminIndex = parseSortIndex([
SystemIntakeStatusAdmin.INITIAL_REQUEST_FORM_IN_PROGRESS,
SystemIntakeStatusAdmin.INITIAL_REQUEST_FORM_SUBMITTED,
SystemIntakeStatusAdmin.DRAFT_BUSINESS_CASE_IN_PROGRESS,
SystemIntakeStatusAdmin.DRAFT_BUSINESS_CASE_SUBMITTED,
SystemIntakeStatusAdmin.GRT_MEETING_READY,
SystemIntakeStatusAdmin.GRT_MEETING_COMPLETE,
SystemIntakeStatusAdmin.GRB_MEETING_READY,
SystemIntakeStatusAdmin.GRB_MEETING_COMPLETE,
SystemIntakeStatusAdmin.FINAL_BUSINESS_CASE_IN_PROGRESS,
SystemIntakeStatusAdmin.FINAL_BUSINESS_CASE_SUBMITTED,
SystemIntakeStatusAdmin.LCID_ISSUED,
SystemIntakeStatusAdmin.LCID_EXPIRED,
SystemIntakeStatusAdmin.LCID_RETIRED,
SystemIntakeStatusAdmin.NOT_GOVERNANCE,
SystemIntakeStatusAdmin.NOT_APPROVED,
SystemIntakeStatusAdmin.CLOSED
]);

export const TRBRequestStatusIndex = parseSortIndex([
TRBRequestStatus.NEW,
TRBRequestStatus.DRAFT_REQUEST_FORM,
TRBRequestStatus.REQUEST_FORM_COMPLETE,
TRBRequestStatus.READY_FOR_CONSULT,
TRBRequestStatus.CONSULT_SCHEDULED,
TRBRequestStatus.CONSULT_COMPLETE,
TRBRequestStatus.DRAFT_ADVICE_LETTER,
TRBRequestStatus.ADVICE_LETTER_IN_REVIEW,
TRBRequestStatus.ADVICE_LETTER_SENT,
TRBRequestStatus.FOLLOW_UP_REQUESTED,
TRBRequestState.CLOSED
]);

export function trbRequestStatusSortType(a: any, b: any) {
const astatus =
a.original.state === TRBRequestState.CLOSED
? a.original.state
: a.original.status;

const bstatus =
b.original.state === TRBRequestState.CLOSED
? b.original.state
: b.original.status;

return TRBRequestStatusIndex()[astatus] > TRBRequestStatusIndex()[bstatus]
? 1
: -1;
}
67 changes: 62 additions & 5 deletions src/views/MyRequests/Table/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,16 @@ import TablePagination from 'components/TablePagination';
import TableResults from 'components/TableResults';
import GetRequestsQuery from 'queries/GetRequestsQuery';
import { GetRequests, GetRequestsVariables } from 'queries/types/GetRequests';
import { RequestType } from 'types/graphql-global-types';
import {
RequestType,
SystemIntakeStatusRequester
} from 'types/graphql-global-types';
import { formatDateUtc } from 'utils/date';
import globalFilterCellText from 'utils/globalFilterCellText';
import {
SystemIntakeStatusRequesterIndex,
trbRequestStatusSortType
} from 'utils/tableRequestStatusIndex';
import {
currentTableSortDescription,
getColumnSortStatus,
Expand Down Expand Up @@ -81,7 +88,7 @@ const Table = ({
link = `/trb/task-list/${row.original.id}`;
} else {
switch (row.original.type) {
case t('requestsTable.types.GOVERNANCE_REQUEST'):
case 'IT Governance':
link = `/governance-task-list/${row.original.id}`;
break;
default:
Expand All @@ -105,17 +112,67 @@ const Table = ({
id: 'status',
accessor: (obj: any) => {
switch (obj.type) {
case t(`requestsTable.types.GOVERNANCE_REQUEST`):
case 'IT Governance':
return t(
`governanceReviewTeam:systemIntakeStatusRequester.${obj.statusRequester}`,
{ lcid: obj.lcid }
);
case t(`requestsTable.types.TRB`):
return obj.status;
case 'TRB':
return t(`table.requestStatus.${obj.status}`, {
ns: 'technicalAssistance'
});
default:
return '';
}
},
sortType: (a: any, b: any) => {
// Check for the 2 status types: trb requester and itgov requester
// Put IT Gov requests before TRB
if (
a.original.type === 'IT Governance' &&
b.original.type === 'TRB'
) {
return -1;
}
if (
a.original.type === 'TRB' &&
b.original.type === 'IT Governance'
) {
return 1;
}

// Compare IT Gov Requests
if (
a.original.type === 'IT Governance' &&
b.original.type === 'IT Governance'
) {
const astatus = a.original.statusRequester;
const bstatus = b.original.statusRequester;

// Check some matching statuses to further sort by lcid value
if (
(astatus === SystemIntakeStatusRequester.LCID_ISSUED &&
bstatus === SystemIntakeStatusRequester.LCID_ISSUED) ||
(astatus === SystemIntakeStatusRequester.LCID_EXPIRED &&
bstatus === SystemIntakeStatusRequester.LCID_EXPIRED) ||
(astatus === SystemIntakeStatusRequester.LCID_RETIRED &&
bstatus === SystemIntakeStatusRequester.LCID_RETIRED)
) {
return a.original.lcid > b.original.lcid ? 1 : -1;
}

const ai = SystemIntakeStatusRequesterIndex()[astatus];
const bi = SystemIntakeStatusRequesterIndex()[bstatus];
return ai > bi ? 1 : -1;
}

// Compare TRB Requests
if (a.original.type === 'TRB' && b.original.type === 'TRB') {
return trbRequestStatusSortType(a, b);
}

return 0;
},
width: '200px'
},
{
Expand Down
11 changes: 1 addition & 10 deletions src/views/MyRequests/Table/tableMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,19 +53,10 @@ const tableMap = (
? t(`requestsTable.types.${request.type}`)
: t(`requestsTable.types.TRB`);

let status = '';
if (isTRBRequestType(request)) {
// TRB status
status = t(`table.requestStatus.${request.status}`, {
ns: 'technicalAssistance'
});
}

return {
...request,
name,
type,
status
type
};
});

Expand Down
4 changes: 3 additions & 1 deletion src/views/TechnicalAssistance/Homepage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import { AppState } from 'reducers/rootReducer';
import { TRBRequestState } from 'types/graphql-global-types';
import { formatDateLocal } from 'utils/date';
import globalFilterCellText from 'utils/globalFilterCellText';
import { trbRequestStatusSortType } from 'utils/tableRequestStatusIndex';
import {
currentTableSortDescription,
getColumnSortStatus,
Expand Down Expand Up @@ -97,7 +98,8 @@ function Homepage() {
accessor: ({ status, state }) =>
state === TRBRequestState.CLOSED
? t(`table.requestState.${state}`)
: t(`table.requestStatus.${status}`)
: t(`table.requestStatus.${status}`),
sortType: trbRequestStatusSortType
},
{
Header: t<string>('table.header.submissionDate'),
Expand Down
4 changes: 3 additions & 1 deletion src/views/TechnicalAssistance/TrbAdminTeamHome.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import { formatDateLocal } from 'utils/date';
import formatContractNumbers from 'utils/formatContractNumbers';
import { getPersonNameAndComponentVal } from 'utils/getPersonNameAndComponent';
import globalFilterCellText from 'utils/globalFilterCellText';
import { trbRequestStatusSortType } from 'utils/tableRequestStatusIndex';
import {
currentTableSortDescription,
getColumnSortStatus,
Expand Down Expand Up @@ -379,7 +380,8 @@ function TrbExistingRequestsTable({ requests }: TrbRequestsTableProps) {
accessor: ({ status, state }) =>
state === TRBRequestState.CLOSED
? t(`table.requestState.${state}`)
: t(`table.requestStatus.${status}`)
: t(`table.requestStatus.${status}`),
sortType: trbRequestStatusSortType
},
{
Header: t<string>('table.header.trbConsultDate'),
Expand Down

0 comments on commit f2256f4

Please sign in to comment.