Skip to content

Commit 67f10f5

Browse files
authored
Merge pull request #2670 from flexion/9600-practitioner-consolidated-card
9600 Petitioner: Add Consolidated Card to Case Information Screen [skip ci]
2 parents 75c361c + c78a51a commit 67f10f5

File tree

8 files changed

+222
-31
lines changed

8 files changed

+222
-31
lines changed

shared/src/authorization/authorizationClientService.js

+4
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ const ROLE_PERMISSIONS = {
6363
UPDATE_CASE_CONTEXT: 'UPDATE_CASE_CONTEXT',
6464
UPDATE_CONTACT_INFO: 'UPDATE_CONTACT_INFO',
6565
UPLOAD_DOCUMENT: 'UPLOAD_DOCUMENT',
66+
VIEW_CONSOLIDATED_CASES_CARD: 'VIEW_CONSOLIDATED_CASES_CARD',
6667
VIEW_DOCUMENTS: 'VIEW_DOCUMENTS',
6768
VIEW_MESSAGES: 'VIEW_MESSAGES',
6869
VIEW_PRACTITIONER_CASE_LIST: 'VIEW_PRACTITIONER_CASE_LIST',
@@ -190,6 +191,7 @@ const AUTHORIZATION_MAP = {
190191
ROLE_PERMISSIONS.GET_USER_PENDING_EMAIL_STATUS,
191192
ROLE_PERMISSIONS.UPDATE_CONTACT_INFO,
192193
ROLE_PERMISSIONS.UPLOAD_DOCUMENT,
194+
ROLE_PERMISSIONS.VIEW_CONSOLIDATED_CASES_CARD,
193195
ROLE_PERMISSIONS.VIEW_DOCUMENTS,
194196
],
195197
irsSuperuser: [
@@ -217,6 +219,7 @@ const AUTHORIZATION_MAP = {
217219
ROLE_PERMISSIONS.UPDATE_CONTACT_INFO,
218220
ROLE_PERMISSIONS.UPLOAD_DOCUMENT,
219221
ROLE_PERMISSIONS.VIEW_DOCUMENTS,
222+
ROLE_PERMISSIONS.VIEW_CONSOLIDATED_CASES_CARD,
220223
],
221224
petitionsclerk: petitionsClerkPermissions,
222225
privatePractitioner: [
@@ -230,6 +233,7 @@ const AUTHORIZATION_MAP = {
230233
ROLE_PERMISSIONS.PETITION,
231234
ROLE_PERMISSIONS.UPDATE_CONTACT_INFO,
232235
ROLE_PERMISSIONS.UPLOAD_DOCUMENT,
236+
ROLE_PERMISSIONS.VIEW_CONSOLIDATED_CASES_CARD,
233237
ROLE_PERMISSIONS.VIEW_DOCUMENTS,
234238
],
235239
reportersOffice: allInternalUserPermissions,

web-api/storage/fixtures/seed/efcms-local.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@
7171
"entityName": "Petitioner",
7272
"name": "Astra Santiago",
7373
"state": "NY",
74-
"email": "petitioner@example.com"
74+
"email": "petitioner2@example.com"
7575
}
7676
],
7777
"initialDocketNumberSuffix": "L",

web-client/src/presenter/computeds/caseDetailHelper.js

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/* eslint-disable complexity */
12
import { isEmpty } from 'lodash';
23
import { state } from 'cerebral';
34

@@ -67,8 +68,15 @@ export const caseDetailHelper = (get, applicationContext) => {
6768
user.role === USER_ROLES.irsPractitioner ||
6869
user.role === USER_ROLES.privatePractitioner;
6970

71+
const isPetitioner = user.role === USER_ROLES.petitioner;
72+
7073
const showSealedCaseView =
71-
isPractitioner && !!caseDetail.isSealed && !userAssociatedWithCase;
74+
(isPractitioner || isPetitioner) &&
75+
!!caseDetail.isSealed &&
76+
!userAssociatedWithCase;
77+
78+
const showConsolidatedCasesCard =
79+
permissions.VIEW_CONSOLIDATED_CASES_CARD && !!caseDetail.leadDocketNumber;
7280

7381
return {
7482
caseDeadlines,
@@ -83,6 +91,7 @@ export const caseDetailHelper = (get, applicationContext) => {
8391
showCaseDeadlinesInternal,
8492
showCaseDeadlinesInternalEmpty,
8593
showCaseInformationExternal: isExternalUser,
94+
showConsolidatedCasesCard,
8695
showDocketRecordInProgressState: !isExternalUser,
8796
showEditCaseDetailsButton: permissions.EDIT_CASE_DETAILS,
8897
showFileDocumentButton,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
import {
2+
adcUser,
3+
irsPractitionerUser,
4+
petitionerUser,
5+
privatePractitionerUser,
6+
} from '../../../../shared/src/test/mockUsers';
7+
import { applicationContextForClient as applicationContext } from '../../../../shared/src/business/test/createTestApplicationContext';
8+
import { caseDetailHelper as caseDetailHelperComputed } from './caseDetailHelper';
9+
import { getUserPermissions } from '../../../../shared/src/authorization/getUserPermissions';
10+
import { runCompute } from 'cerebral/test';
11+
import { withAppContextDecorator } from '../../withAppContext';
12+
13+
const caseDetailHelper = withAppContextDecorator(caseDetailHelperComputed, {
14+
...applicationContext,
15+
getCurrentUser: () => {
16+
return globalUser;
17+
},
18+
});
19+
20+
let globalUser;
21+
22+
const getBaseState = user => {
23+
globalUser = user;
24+
return {
25+
permissions: getUserPermissions(user),
26+
};
27+
};
28+
29+
describe('showConsolidatedCasesCard', () => {
30+
it('should be true when the user is a petitioner and the case is in a consolidated group', () => {
31+
const user = petitionerUser;
32+
33+
const result = runCompute(caseDetailHelper, {
34+
state: {
35+
...getBaseState(user),
36+
caseDetail: {
37+
docketEntries: [],
38+
leadDocketNumber: '101-22F',
39+
},
40+
},
41+
});
42+
expect(result.showConsolidatedCasesCard).toEqual(true);
43+
});
44+
45+
it('should be true when the user is a private practitioner and the case is in a consolidated group', () => {
46+
const user = privatePractitionerUser;
47+
48+
const result = runCompute(caseDetailHelper, {
49+
state: {
50+
...getBaseState(user),
51+
caseDetail: {
52+
docketEntries: [],
53+
leadDocketNumber: '101-22F',
54+
},
55+
},
56+
});
57+
expect(result.showConsolidatedCasesCard).toEqual(true);
58+
});
59+
60+
it('should be true when the user is an IRS practitioner and the case is in a consolidated group', () => {
61+
const user = irsPractitionerUser;
62+
63+
const result = runCompute(caseDetailHelper, {
64+
state: {
65+
...getBaseState(user),
66+
caseDetail: {
67+
docketEntries: [],
68+
leadDocketNumber: '101-22F',
69+
},
70+
},
71+
});
72+
expect(result.showConsolidatedCasesCard).toEqual(true);
73+
});
74+
75+
it('should be false when the user is a non practitioner/petitioner user and the case is in a consolidated group', () => {
76+
const user = adcUser;
77+
78+
const result = runCompute(caseDetailHelper, {
79+
state: {
80+
...getBaseState(user),
81+
caseDetail: {
82+
docketEntries: [],
83+
leadDocketNumber: '101-22F',
84+
},
85+
},
86+
});
87+
88+
expect(result.showConsolidatedCasesCard).toEqual(false);
89+
});
90+
91+
it('should be false when the case is not in a consolidated group and the user has VIEW_CONSOLIDATED_CASES_CARD permission', () => {
92+
const user = petitionerUser;
93+
94+
const result = runCompute(caseDetailHelper, {
95+
state: {
96+
...getBaseState(user),
97+
caseDetail: {
98+
docketEntries: [],
99+
leadDocketNumber: undefined,
100+
},
101+
},
102+
});
103+
104+
expect(result.showConsolidatedCasesCard).toEqual(false);
105+
});
106+
});

web-client/src/presenter/computeds/caseDetailHelper.showSealedCaseView.test.js

+51-23
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
import { applicationContextForClient as applicationContext } from '../../../../shared/src/business/test/createTestApplicationContext';
22
import { caseDetailHelper as caseDetailHelperComputed } from './caseDetailHelper';
3+
import { getUserPermissions } from '../../../../shared/src/authorization/getUserPermissions';
34
import {
4-
docketClerkUser,
55
irsPractitionerUser,
66
petitionerUser,
7-
petitionsClerkUser,
87
privatePractitionerUser,
98
} from '../../../../shared/src/test/mockUsers';
10-
import { getUserPermissions } from '../../../../shared/src/authorization/getUserPermissions';
119
import { runCompute } from 'cerebral/test';
1210
import { withAppContextDecorator } from '../../withAppContext';
1311

@@ -62,29 +60,59 @@ describe('showSealedCaseView', () => {
6260
expect(result.showSealedCaseView).toEqual(false);
6361
});
6462

65-
const nonPractitionerUsers = [
66-
docketClerkUser,
67-
petitionerUser,
68-
petitionsClerkUser,
69-
];
63+
it('should be true for a unassociated private practitioner user with a sealed case', () => {
64+
const result = runCompute(caseDetailHelper, {
65+
state: {
66+
...getBaseState(privatePractitionerUser),
67+
caseDetail: {
68+
docketEntries: [],
69+
isSealed: true,
70+
privatePractitioners: [],
71+
},
72+
screenMetadata: {
73+
isAssociated: false,
74+
},
75+
},
76+
});
77+
78+
expect(result.showSealedCaseView).toEqual(true);
79+
});
7080

71-
nonPractitionerUsers.forEach(user => {
72-
it(`should be false for a non practitioner ${user} user`, () => {
73-
const result = runCompute(caseDetailHelper, {
74-
state: {
75-
...getBaseState(user),
76-
caseDetail: {
77-
docketEntries: [],
78-
isSealed: true,
79-
privatePractitioners: [],
80-
},
81-
screenMetadata: {
82-
isAssociated: false,
83-
},
81+
it('should be true for a unassociated IRS practitioner user with a sealed case', () => {
82+
const result = runCompute(caseDetailHelper, {
83+
state: {
84+
...getBaseState(irsPractitionerUser),
85+
caseDetail: {
86+
docketEntries: [],
87+
isSealed: true,
88+
privatePractitioners: [],
89+
},
90+
screenMetadata: {
91+
isAssociated: false,
8492
},
85-
});
93+
},
94+
});
95+
96+
expect(result.showSealedCaseView).toEqual(true);
97+
});
8698

87-
expect(result.showSealedCaseView).toEqual(false);
99+
it('should be true for an unassociated petitioner associated with a different case in the consolidated group', () => {
100+
const result = runCompute(caseDetailHelper, {
101+
state: {
102+
...getBaseState(petitionerUser),
103+
caseDetail: {
104+
docketEntries: [],
105+
docketNumber: '198-23',
106+
isSealed: true,
107+
leadDocketNumber: '199-23',
108+
privatePractitioners: [],
109+
},
110+
screenMetadata: {
111+
isAssociated: false,
112+
},
113+
},
88114
});
115+
116+
expect(result.showSealedCaseView).toEqual(true);
89117
});
90118
});

web-client/src/styles/custom.scss

+4
Original file line numberDiff line numberDiff line change
@@ -2023,3 +2023,7 @@ button.change-scanner-button {
20232023
.width-180 {
20242024
width: 180px;
20252025
}
2026+
2027+
.align-items-baseline {
2028+
align-items: baseline;
2029+
}

web-client/src/views/CaseDetail/CaseInformation/ConsolidatedCases.jsx

+19-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { CaseLink } from '../../../ustc-ui/CaseLink/CaseLink';
2+
import { Mobile, NonMobile } from '../../../ustc-ui/Responsive/Responsive';
23
import { connect } from '@cerebral/react';
34
import { props } from 'cerebral';
45
import React from 'react';
@@ -12,16 +13,28 @@ export const ConsolidatedCases = connect(
1213
return (
1314
<>
1415
{!caseDetailHelper.hasConsolidatedCases && <p>Not consolidated</p>}
15-
<div className="grid-container padding-left-0">
16+
<div className="grid-container padding-left-0 margin-bottom-2">
1617
{caseDetail.consolidatedCases.map(consolidatedCase => (
1718
<div
18-
className="grid-row margin-top-3"
19+
className="grid-row margin-top-3 align-items-baseline"
1920
key={consolidatedCase.docketNumber}
2021
>
21-
<div className="grid-col-2">
22-
<CaseLink formattedCase={consolidatedCase} />
23-
</div>
24-
<div className="grid-col-10">{consolidatedCase.caseTitle}</div>
22+
<NonMobile>
23+
<div className="tablet:grid-col-3 desktop:grid-col-2">
24+
<CaseLink formattedCase={consolidatedCase} />
25+
</div>
26+
<div className="tablet:grid-col-9 desktop:grid-col-10">
27+
{consolidatedCase.caseTitle}
28+
</div>
29+
</NonMobile>
30+
<Mobile>
31+
<div className="grid-col-4">
32+
<CaseLink formattedCase={consolidatedCase} />
33+
</div>
34+
<div className="grid-col-8 margin-left-neg-2">
35+
{consolidatedCase.caseTitle}
36+
</div>
37+
</Mobile>
2538
</div>
2639
))}
2740
</div>

web-client/src/views/CaseDetail/CaseInformationExternal.jsx

+27
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Button } from '../../ustc-ui/Button/Button';
2+
import { ConsolidatedCases } from './CaseInformation/ConsolidatedCases';
23
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
34
import { If } from '../../ustc-ui/If/If';
45
import { Mobile, NonMobile } from '../../ustc-ui/Responsive/Responsive';
@@ -124,6 +125,21 @@ export const CaseInformationExternal = connect(
124125
</div>
125126
</div>
126127
</div>
128+
<div className="grid-row grid-gap margin-top-4">
129+
<div className="tablet:grid-col-6">
130+
{caseDetailHelper.showConsolidatedCasesCard && (
131+
<div className="card height-full">
132+
<div className="content-wrapper">
133+
<h3 className="underlined">Consolidated Cases</h3>
134+
<ConsolidatedCases
135+
caseDetail={formattedCaseDetail}
136+
caseDetailHelper={caseDetailHelper}
137+
/>
138+
</div>
139+
</div>
140+
)}
141+
</div>
142+
</div>
127143
</div>
128144
</NonMobile>
129145
<Mobile>
@@ -160,6 +176,17 @@ export const CaseInformationExternal = connect(
160176
<TrialInformation caseDetail={formattedCaseDetail} />
161177
</div>
162178
</div>
179+
{caseDetailHelper.showConsolidatedCasesCard && (
180+
<div className="margin-top-2">
181+
<div className="case-info-card">
182+
<h3>Consolidated Cases</h3>
183+
<ConsolidatedCases
184+
caseDetail={formattedCaseDetail}
185+
caseDetailHelper={caseDetailHelper}
186+
/>
187+
</div>
188+
</div>
189+
)}
163190
</div>
164191
</Mobile>
165192
</div>

0 commit comments

Comments
 (0)