Skip to content

Commit 32a68f0

Browse files
[PRMP-860] Refactor upload components to link doc types
1 parent 7ec5923 commit 32a68f0

21 files changed

Lines changed: 679 additions & 393 deletions

File tree

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

Lines changed: 10 additions & 1 deletion
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
}
@@ -185,7 +189,12 @@ const DocumentSelectOrderStage = ({
185189
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 ? 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: 61 additions & 13 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,57 @@ 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;
224-
}
252+
skipClicked();
253+
};
225254

226-
navigate.withParams(routeChildren.DOCUMENT_UPLOAD_CONFIRMATION);
255+
const skipClicked = (): void => {
256+
if (goToNextDocType) {
257+
goToNextDocType();
258+
window.scrollTo(0, 0);
259+
} else {
260+
navigateToNextStep();
261+
}
227262
};
228263

229264
const DocumentRow = (document: UploadDocument, index: number): JSX.Element => {
@@ -299,8 +334,15 @@ const DocumentSelectStage = ({
299334
};
300335

301336
return (
302-
<>
303-
<BackButton toLocation={routes.VERIFY_PATIENT} dataTestid="back-button" />
337+
<div className="document-select-stage">
338+
<BackLink
339+
onClick={() =>
340+
goToPreviousDocType ? goToPreviousDocType() : navigate(routes.VERIFY_PATIENT)
341+
}
342+
data-testid="back-button"
343+
>
344+
Go back
345+
</BackLink>
304346

305347
{(errorDocs().length > 0 || noFilesSelected || tooManyFilesAdded) && (
306348
<ErrorBox
@@ -461,17 +503,23 @@ const DocumentSelectStage = ({
461503
)}
462504
</>
463505
)}
464-
<div className="lloydgeorge_upload-submission">
506+
<div className="action-buttons">
465507
<Button
466508
type="button"
467509
id="continue-button"
468510
data-testid="continue-button"
469511
onClick={continueClicked}
512+
className="continue-button mr-4"
470513
>
471514
Continue
472515
</Button>
516+
{showSkiplink && goToNextDocType && documents.length === 0 && (
517+
<LinkButton onClick={skipClicked}>
518+
{documentConfig.content.skipDocumentLinkText}
519+
</LinkButton>
520+
)}
473521
</div>
474-
</>
522+
</div>
475523
);
476524
};
477525

app/src/components/blocks/_documentUpload/documentUploadConfirmStage/DocumentUploadConfirmStage.test.tsx

Lines changed: 21 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,22 @@ vi.mock('react-router-dom', async () => {
3434

3535
const mockedUseNavigate = vi.fn();
3636

37+
vi.mock('./components/DocumentList', async () => {
38+
const actual = await vi.importActual('./components/DocumentList');
39+
return {
40+
...actual,
41+
default: ({ documents }: { documents: UploadDocument[] }): React.JSX.Element => {
42+
return (
43+
<div data-testid="document-list">
44+
Document List with
45+
<span data-testid="document-list-count">{documents.length}</span>
46+
documents
47+
</div>
48+
);
49+
},
50+
};
51+
});
52+
3753
vi.mock('../documentUploadLloydGeorgePreview/DocumentUploadLloydGeorgePreview', () => ({
3854
default: ({
3955
documents,
@@ -67,7 +83,7 @@ let history = createMemoryHistory({
6783
let docConfig = buildDocumentConfig();
6884
const mockConfirmFiles = vi.fn();
6985

70-
describe('DocumentUploadCompleteStage', () => {
86+
describe('DocumentUploadConfirmStage', () => {
7187
beforeEach(() => {
7288
vi.mocked(usePatient).mockReturnValue(patientDetails);
7389

@@ -82,7 +98,7 @@ describe('DocumentUploadCompleteStage', () => {
8298
renderApp(history, 1);
8399

84100
await waitFor(async () => {
85-
expect(screen.getByText('Check your files before uploading')).toBeInTheDocument();
101+
expect(screen.getByText('Check files are for the correct patient')).toBeInTheDocument();
86102
});
87103
});
88104

@@ -96,15 +112,6 @@ describe('DocumentUploadCompleteStage', () => {
96112
});
97113
});
98114

99-
it('should render pagination when doc count is high enough', async () => {
100-
renderApp(history, 15);
101-
102-
await waitFor(async () => {
103-
expect(await screen.findByTestId('page-1-button')).toBeInTheDocument();
104-
expect(await screen.findByTestId('page-2-button')).toBeInTheDocument();
105-
});
106-
});
107-
108115
it.each([
109116
{ fileCount: 3, expectedPreviewCount: 3, stitched: true },
110117
{ fileCount: 1, expectedPreviewCount: 1, stitched: false },
@@ -126,49 +133,6 @@ describe('DocumentUploadCompleteStage', () => {
126133
},
127134
);
128135

129-
it.each([
130-
{
131-
stitched: false,
132-
multifile: true,
133-
journey: '',
134-
expectedText: `Each file will be uploaded as a separate ${docConfig.displayName} for this patient.`,
135-
},
136-
{
137-
stitched: false,
138-
multifile: false,
139-
journey: '',
140-
expectedText: `This file will be uploaded as a new ${docConfig.displayName} for this patient.`,
141-
},
142-
{
143-
stitched: true,
144-
multifile: true,
145-
journey: 'update',
146-
expectedText: `Files will be added to the existing ${docConfig.displayName} to create a single PDF document.`,
147-
},
148-
{
149-
stitched: true,
150-
multifile: true,
151-
journey: '',
152-
expectedText: `Files will be combined into a single PDF document to create a ${docConfig.displayName} record for this patient.`,
153-
},
154-
])(
155-
'renders correct text for file result: %s',
156-
async ({ stitched, multifile, journey, expectedText }) => {
157-
docConfig = buildDocumentConfig({
158-
multifileUpload: multifile,
159-
multifileReview: multifile,
160-
stitched,
161-
});
162-
vi.mocked(getJourney).mockReturnValueOnce(journey as any);
163-
164-
renderApp(history, 1);
165-
166-
await waitFor(async () => {
167-
expect(screen.getByText(expectedText)).toBeInTheDocument();
168-
});
169-
},
170-
);
171-
172136
describe('Navigation', () => {
173137
it('should navigate to previous screen when go back is clicked', async () => {
174138
renderApp(history, 1);
@@ -180,19 +144,6 @@ describe('DocumentUploadCompleteStage', () => {
180144
});
181145
});
182146

183-
it('should navigate to the file selection page when change files is clicked', async () => {
184-
renderApp(history, 1);
185-
186-
userEvent.click(await screen.findByTestId('change-files-button'));
187-
188-
await waitFor(() => {
189-
expect(mockedUseNavigate).toHaveBeenCalledWith({
190-
pathname: routeChildren.DOCUMENT_UPLOAD_SELECT_FILES,
191-
search: '',
192-
});
193-
});
194-
});
195-
196147
it('renders patient summary fields is inset', async () => {
197148
renderApp(history, 1);
198149

@@ -227,49 +178,15 @@ describe('DocumentUploadCompleteStage', () => {
227178
});
228179
});
229180

230-
it('renders correct text for update journey', async () => {
181+
it('should still render all page elements correctly', async () => {
231182
renderApp(history, 1);
232183

233184
await waitFor(async () => {
234185
expect(
235-
screen.getByText(
236-
`Files will be added to the existing ${docConfig.displayName} to create a single PDF document.`,
237-
),
186+
screen.getByText('Check files are for the correct patient'),
238187
).toBeInTheDocument();
239-
});
240-
});
241-
242-
it('should navigate with journey param when change files is clicked', async () => {
243-
renderApp(history, 1);
244-
245-
userEvent.click(await screen.findByTestId('change-files-button'));
246-
247-
await waitFor(() => {
248-
expect(mockedUseNavigate).toHaveBeenCalledWith({
249-
pathname: routeChildren.DOCUMENT_UPLOAD_SELECT_FILES,
250-
search: 'journey=update',
251-
});
252-
});
253-
});
254-
255-
it('should still render all page elements correctly', async () => {
256-
renderApp(history, 1);
257-
258-
await waitFor(async () => {
259-
expect(screen.getByText('Check your files before uploading')).toBeInTheDocument();
260188
expect(screen.getByTestId('go-back-link')).toBeInTheDocument();
261-
expect(screen.getByTestId('change-files-button')).toBeInTheDocument();
262189
expect(screen.getByTestId('confirm-button')).toBeInTheDocument();
263-
expect(screen.getByText('Files to be uploaded')).toBeInTheDocument();
264-
});
265-
});
266-
267-
it('should render pagination when doc count is high enough in update journey', async () => {
268-
renderApp(history, 15);
269-
270-
await waitFor(async () => {
271-
expect(await screen.findByTestId('page-1-button')).toBeInTheDocument();
272-
expect(await screen.findByTestId('page-2-button')).toBeInTheDocument();
273190
});
274191
});
275192
});
@@ -288,11 +205,7 @@ describe('DocumentUploadCompleteStage', () => {
288205

289206
return render(
290207
<ReactRouter.Router navigator={history} location={history.location}>
291-
<DocumentUploadConfirmStage
292-
documents={documents}
293-
documentConfig={docConfig}
294-
confirmFiles={mockConfirmFiles}
295-
/>
208+
<DocumentUploadConfirmStage documents={documents} confirmFiles={mockConfirmFiles} />
296209
</ReactRouter.Router>,
297210
);
298211
};

0 commit comments

Comments
 (0)