Skip to content

Commit 6f32157

Browse files
[PRMP-860] Refactor upload components to link doc types
1 parent 1fee1e1 commit 6f32157

File tree

26 files changed

+1322
-530
lines changed

26 files changed

+1322
-530
lines changed

app/src/components/blocks/_admin/reviewsPage/ReviewsPage.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,8 @@ export const ReviewsPage = (): React.JSX.Element => {
108108
return {
109109
id: dto.id,
110110
nhsNumber,
111-
recordType: getConfigForDocType(dto.document_snomed_code_type).content.reviewList as string,
111+
recordType: getConfigForDocType(dto.document_snomed_code_type).content
112+
.reviewList as string,
112113
snomedCode: dto.document_snomed_code_type,
113114
uploader: dto.odsCode,
114115
dateUploaded: dto.dateUploaded,

app/src/components/blocks/_documentUpload/documentSelectOrderStage/DocumentSelectOrderStage.test.tsx

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { fileUploadErrorMessages } from '../../../../helpers/utils/fileUploadErr
1010
import { buildDocumentConfig, buildLgFile } from '../../../../helpers/test/testBuilders';
1111
import { Mock } from 'vitest';
1212
import { DOCUMENT_TYPE, DOCUMENT_TYPE_CONFIG } from '../../../../helpers/utils/documentType';
13+
import { SetStateAction } from 'react';
1314

1415
const mockNavigate = vi.fn();
1516
const mockSetDocuments = vi.fn();
@@ -75,6 +76,7 @@ describe('DocumentSelectOrderStage', () => {
7576

7677
afterEach(() => {
7778
vi.clearAllMocks();
79+
vi.resetAllMocks();
7880
});
7981

8082
describe('Rendering', () => {
@@ -171,7 +173,7 @@ describe('DocumentSelectOrderStage', () => {
171173

172174
it('updates document position when dropdown value changes', async () => {
173175
const user = userEvent.setup();
174-
const multipleDocuments = [
176+
let multipleDocuments = [
175177
{
176178
docType: DOCUMENT_TYPE.LLOYD_GEORGE,
177179
id: '1',
@@ -190,14 +192,63 @@ describe('DocumentSelectOrderStage', () => {
190192
numPages: 3,
191193
position: 2,
192194
},
195+
{
196+
docType: DOCUMENT_TYPE.EHR,
197+
id: '3',
198+
file: buildLgFile(2),
199+
attempts: 0,
200+
state: DOCUMENT_UPLOAD_STATE.SELECTED,
201+
numPages: 3,
202+
position: 0,
203+
}
193204
];
194205

195-
renderSut(multipleDocuments);
206+
const expectedDocs = [
207+
{
208+
docType: DOCUMENT_TYPE.LLOYD_GEORGE,
209+
id: '1',
210+
file: buildLgFile(1),
211+
attempts: 0,
212+
state: DOCUMENT_UPLOAD_STATE.SELECTED,
213+
numPages: 5,
214+
position: 2,
215+
},
216+
{
217+
docType: DOCUMENT_TYPE.LLOYD_GEORGE,
218+
id: '2',
219+
file: buildLgFile(2),
220+
attempts: 0,
221+
state: DOCUMENT_UPLOAD_STATE.SELECTED,
222+
numPages: 3,
223+
position: 2,
224+
},
225+
{
226+
docType: DOCUMENT_TYPE.EHR,
227+
id: '3',
228+
file: buildLgFile(2),
229+
attempts: 0,
230+
state: DOCUMENT_UPLOAD_STATE.SELECTED,
231+
numPages: 3,
232+
position: 0,
233+
}
234+
];
235+
236+
mockSetDocuments.mockImplementationOnce((arg) => {
237+
if (typeof arg === 'function') {
238+
multipleDocuments = arg(multipleDocuments);
239+
} else {
240+
multipleDocuments = arg;
241+
}
242+
multipleDocuments = arg(multipleDocuments);
243+
});
244+
245+
renderSut(multipleDocuments.filter((doc) => doc.docType === DOCUMENT_TYPE.LLOYD_GEORGE));
196246

197247
const positionSelect = screen.getByTestId('1');
198248
await user.selectOptions(positionSelect, '2');
199249

200250
expect(mockSetDocuments).toHaveBeenCalled();
251+
expect(multipleDocuments).toEqual(expectedDocs);
201252
});
202253
});
203254

app/src/components/blocks/_documentUpload/documentSelectOrderStage/DocumentSelectOrderStage.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,10 @@ const DocumentSelectOrderStage = ({
166166

167167
if (docToRemove.position) {
168168
updatedDocList = updatedDocList.map((doc) => {
169+
if (doc.docType !== docToRemove.docType) {
170+
return doc;
171+
}
172+
169173
if (doc.position && +doc.position > +docToRemove.position!) {
170174
doc.position = +doc.position - 1;
171175
}
@@ -182,10 +186,15 @@ const DocumentSelectOrderStage = ({
182186

183187
const updatedDocuments = documents.map((doc) => ({
184188
...doc,
185-
position: fieldValues[documentPositionKey(doc.id)]!,
189+
position: +fieldValues[documentPositionKey(doc.id)]!,
186190
}));
187191

188-
setDocuments(updatedDocuments);
192+
setDocuments((previousState) => {
193+
return previousState.map((doc) => {
194+
const updatedDoc = updatedDocuments.find((d) => d.id === doc.id);
195+
return updatedDoc ?? doc;
196+
});
197+
});
189198
};
190199

191200
const submitDocuments = (): void => {
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
.document-select-stage {
2+
.action-buttons {
3+
display: flex;
4+
align-items: center;
5+
6+
.continue-button {
7+
margin-bottom: 0;
8+
}
9+
}
10+
}

app/src/components/blocks/_documentUpload/documentSelectStage/DocumentSelectStage.tsx

Lines changed: 71 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1-
import { Button, Fieldset, Table, TextInput, WarningCallout } from 'nhsuk-react-components';
1+
import {
2+
BackLink,
3+
Button,
4+
Fieldset,
5+
Table,
6+
TextInput,
7+
WarningCallout,
8+
} from 'nhsuk-react-components';
29
import { getDocument } from 'pdfjs-dist';
310
import { JSX, RefObject, useEffect, useRef, useState } from 'react';
411
import { v4 as uuidv4 } from 'uuid';
@@ -17,7 +24,6 @@ import {
1724
SetUploadDocuments,
1825
UploadDocument,
1926
} from '../../../../types/pages/UploadDocumentsPage/types';
20-
import BackButton from '../../../generic/backButton/BackButton';
2127
import LinkButton from '../../../generic/linkButton/LinkButton';
2228
import PatientSummary, { PatientInfo } from '../../../generic/patientSummary/PatientSummary';
2329
import ErrorBox from '../../../layout/errorBox/ErrorBox';
@@ -32,6 +38,9 @@ export type Props = {
3238
documentType: DOCUMENT_TYPE;
3339
filesErrorRef: RefObject<boolean>;
3440
documentConfig: DOCUMENT_TYPE_CONFIG;
41+
goToNextDocType?: () => void;
42+
goToPreviousDocType?: () => void;
43+
showSkiplink?: boolean;
3544
};
3645

3746
type UploadFilesError = ErrorMessageListItem<UPLOAD_FILE_ERROR_TYPE>;
@@ -42,6 +51,9 @@ const DocumentSelectStage = ({
4251
documentType,
4352
filesErrorRef,
4453
documentConfig,
54+
goToNextDocType,
55+
goToPreviousDocType,
56+
showSkiplink,
4557
}: Props): JSX.Element => {
4658
const fileInputRef = useRef<HTMLInputElement | null>(null);
4759
const [noFilesSelected, setNoFilesSelected] = useState<boolean>(false);
@@ -196,34 +208,59 @@ const DocumentSelectStage = ({
196208

197209
setNoFilesSelected(sortedDocs.length === 0);
198210

199-
setDocuments(sortedDocs);
211+
setDocuments((previousState) => {
212+
const docs = previousState.filter((doc) => doc.docType !== documentType);
213+
return [...docs, ...sortedDocs];
214+
});
200215
};
201216

202217
const validateDocuments = (): boolean => {
203218
setNoFilesSelected(documents.length === 0);
204219

205220
documents?.forEach((doc) => (doc.validated = true));
206221

207-
setDocuments([...documents]);
222+
setDocuments((previousState) => {
223+
previousState.forEach((doc) => {
224+
if (doc.docType === documentType) {
225+
doc.validated = true;
226+
}
227+
});
228+
return [...previousState];
229+
});
208230

209231
return (
210232
documents.length > 0 &&
211233
documents.every((doc) => doc.state !== DOCUMENT_UPLOAD_STATE.FAILED)
212234
);
213235
};
214236

237+
const navigateToNextStep = (): void => {
238+
if (documentConfig.stitched) {
239+
navigate.withParams(routeChildren.DOCUMENT_UPLOAD_SELECT_ORDER);
240+
return;
241+
}
242+
243+
navigate.withParams(routeChildren.DOCUMENT_UPLOAD_CONFIRMATION);
244+
};
245+
215246
const continueClicked = (): void => {
216247
if (!validateDocuments()) {
217248
scrollToRef.current?.scrollIntoView({ behavior: 'smooth' });
218249
return;
219250
}
220251

221-
if (documentConfig.stitched) {
222-
navigate.withParams(routeChildren.DOCUMENT_UPLOAD_SELECT_ORDER);
223-
return;
252+
skipClicked();
253+
};
254+
255+
const skipClicked = (): void => {
256+
if (goToNextDocType) {
257+
goToNextDocType();
258+
window.scrollTo(0, 0);
259+
} else {
260+
navigateToNextStep();
224261
}
225262

226-
navigate.withParams(routeChildren.DOCUMENT_UPLOAD_CONFIRMATION);
263+
resetErrors();
227264
};
228265

229266
const DocumentRow = (document: UploadDocument, index: number): JSX.Element => {
@@ -298,9 +335,25 @@ const DocumentSelectStage = ({
298335
return errors;
299336
};
300337

338+
const resetErrors = (): void => {
339+
setNoFilesSelected(false);
340+
setTooManyFilesAdded(false);
341+
};
342+
343+
const backClicked = (): void => {
344+
if (goToPreviousDocType) {
345+
goToPreviousDocType();
346+
resetErrors();
347+
} else {
348+
navigate(routes.VERIFY_PATIENT);
349+
}
350+
};
351+
301352
return (
302-
<>
303-
<BackButton toLocation={routes.VERIFY_PATIENT} dataTestid="back-button" />
353+
<div className="document-select-stage">
354+
<BackLink onClick={backClicked} data-testid="back-button">
355+
Go back
356+
</BackLink>
304357

305358
{(errorDocs().length > 0 || noFilesSelected || tooManyFilesAdded) && (
306359
<ErrorBox
@@ -461,17 +514,23 @@ const DocumentSelectStage = ({
461514
)}
462515
</>
463516
)}
464-
<div className="lloydgeorge_upload-submission">
517+
<div className="action-buttons">
465518
<Button
466519
type="button"
467520
id="continue-button"
468521
data-testid="continue-button"
469522
onClick={continueClicked}
523+
className="continue-button mr-4"
470524
>
471525
Continue
472526
</Button>
527+
{showSkiplink && (
528+
<LinkButton data-testid="skip-link" onClick={skipClicked}>
529+
{documentConfig.content.skipDocumentLinkText}
530+
</LinkButton>
531+
)}
473532
</div>
474-
</>
533+
</div>
475534
);
476535
};
477536

0 commit comments

Comments
 (0)