From 8e1a8aa634bef773e51ded913809734402d3408a Mon Sep 17 00:00:00 2001 From: Rio Knightley Date: Tue, 13 Feb 2024 11:07:42 +0000 Subject: [PATCH 01/15] Move arf components --- .../completeStage/CompleteStage.test.tsx | 8 ++++---- .../{ => _arf}/completeStage/CompleteStage.tsx | 2 +- .../documentInputForm/DocumentInputForm.tsx | 4 ++-- .../DocumentSearchResults.test.tsx | 6 +++--- .../DocumentSearchResults.tsx | 4 ++-- .../DocumentSearchResultsOptions.test.tsx | 10 +++++----- .../DocumentSearchResultsOptions.tsx | 16 ++++++++-------- .../{ => _arf}/selectStage/SelectStage.test.tsx | 12 ++++++------ .../{ => _arf}/selectStage/SelectStage.tsx | 6 +++--- .../uploadSummary/UploadSummary.test.tsx | 12 ++++++------ .../{ => _arf}/uploadSummary/UploadSummary.tsx | 10 +++++----- .../uploadingStage/UploadingStage.test.tsx | 4 ++-- .../{ => _arf}/uploadingStage/UploadingStage.tsx | 4 ++-- .../DocumentSearchResultsPage.tsx | 4 ++-- .../uploadDocumentsPage/UploadDocumentsPage.tsx | 6 +++--- 15 files changed, 54 insertions(+), 54 deletions(-) rename app/src/components/blocks/{ => _arf}/completeStage/CompleteStage.test.tsx (91%) rename app/src/components/blocks/{ => _arf}/completeStage/CompleteStage.tsx (90%) rename app/src/components/blocks/{ => _arf}/documentInputForm/DocumentInputForm.tsx (97%) rename app/src/components/blocks/{ => _arf}/documentSearchResults/DocumentSearchResults.test.tsx (90%) rename app/src/components/blocks/{ => _arf}/documentSearchResults/DocumentSearchResults.tsx (93%) rename app/src/components/blocks/{ => _arf}/documentSearchResultsOptions/DocumentSearchResultsOptions.test.tsx (95%) rename app/src/components/blocks/{ => _arf}/documentSearchResultsOptions/DocumentSearchResultsOptions.tsx (85%) rename app/src/components/blocks/{ => _arf}/selectStage/SelectStage.test.tsx (97%) rename app/src/components/blocks/{ => _arf}/selectStage/SelectStage.tsx (97%) rename app/src/components/blocks/{ => _arf}/uploadSummary/UploadSummary.test.tsx (95%) rename app/src/components/blocks/{ => _arf}/uploadSummary/UploadSummary.tsx (94%) rename app/src/components/blocks/{ => _arf}/uploadingStage/UploadingStage.test.tsx (97%) rename app/src/components/blocks/{ => _arf}/uploadingStage/UploadingStage.tsx (95%) diff --git a/app/src/components/blocks/completeStage/CompleteStage.test.tsx b/app/src/components/blocks/_arf/completeStage/CompleteStage.test.tsx similarity index 91% rename from app/src/components/blocks/completeStage/CompleteStage.test.tsx rename to app/src/components/blocks/_arf/completeStage/CompleteStage.test.tsx index b5c3ba682..e2edf6ef4 100644 --- a/app/src/components/blocks/completeStage/CompleteStage.test.tsx +++ b/app/src/components/blocks/_arf/completeStage/CompleteStage.test.tsx @@ -4,14 +4,14 @@ import { DOCUMENT_TYPE, DOCUMENT_UPLOAD_STATE as documentUploadStates, UploadDocument, -} from '../../../types/pages/UploadDocumentsPage/types'; -import { buildPatientDetails, buildTextFile } from '../../../helpers/test/testBuilders'; +} from '../../../../types/pages/UploadDocumentsPage/types'; +import { buildPatientDetails, buildTextFile } from '../../../../helpers/test/testBuilders'; import CompleteStage from './CompleteStage'; import { useNavigate } from 'react-router'; -import usePatient from '../../../helpers/hooks/usePatient'; +import usePatient from '../../../../helpers/hooks/usePatient'; jest.mock('react-router'); -jest.mock('../../../helpers/hooks/usePatient'); +jest.mock('../../../../helpers/hooks/usePatient'); const mockedUsePatient = usePatient as jest.Mock; const mockPatientDetails = buildPatientDetails(); diff --git a/app/src/components/blocks/completeStage/CompleteStage.tsx b/app/src/components/blocks/_arf/completeStage/CompleteStage.tsx similarity index 90% rename from app/src/components/blocks/completeStage/CompleteStage.tsx rename to app/src/components/blocks/_arf/completeStage/CompleteStage.tsx index c1ac70498..ed1d9d51f 100644 --- a/app/src/components/blocks/completeStage/CompleteStage.tsx +++ b/app/src/components/blocks/_arf/completeStage/CompleteStage.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { Button } from 'nhsuk-react-components'; import { useNavigate } from 'react-router'; -import { UploadDocument } from '../../../types/pages/UploadDocumentsPage/types'; +import { UploadDocument } from '../../../../types/pages/UploadDocumentsPage/types'; import UploadSummary from '../uploadSummary/UploadSummary'; interface Props { documents: Array; diff --git a/app/src/components/blocks/documentInputForm/DocumentInputForm.tsx b/app/src/components/blocks/_arf/documentInputForm/DocumentInputForm.tsx similarity index 97% rename from app/src/components/blocks/documentInputForm/DocumentInputForm.tsx rename to app/src/components/blocks/_arf/documentInputForm/DocumentInputForm.tsx index 25d381759..f837869ea 100644 --- a/app/src/components/blocks/documentInputForm/DocumentInputForm.tsx +++ b/app/src/components/blocks/_arf/documentInputForm/DocumentInputForm.tsx @@ -4,8 +4,8 @@ import { DOCUMENT_TYPE, FileInputEvent, UploadDocument, -} from '../../../types/pages/UploadDocumentsPage/types'; -import formatFileSize from '../../../helpers/utils/formatFileSize'; +} from '../../../../types/pages/UploadDocumentsPage/types'; +import formatFileSize from '../../../../helpers/utils/formatFileSize'; import { FieldValues, UseControllerReturn } from 'react-hook-form'; type Props = { diff --git a/app/src/components/blocks/documentSearchResults/DocumentSearchResults.test.tsx b/app/src/components/blocks/_arf/documentSearchResults/DocumentSearchResults.test.tsx similarity index 90% rename from app/src/components/blocks/documentSearchResults/DocumentSearchResults.test.tsx rename to app/src/components/blocks/_arf/documentSearchResults/DocumentSearchResults.test.tsx index 8724aa1e8..07f6fb8c6 100644 --- a/app/src/components/blocks/documentSearchResults/DocumentSearchResults.test.tsx +++ b/app/src/components/blocks/_arf/documentSearchResults/DocumentSearchResults.test.tsx @@ -1,6 +1,6 @@ -import { buildSearchResult } from '../../../helpers/test/testBuilders'; -import { getFormattedDatetime } from '../../../helpers/utils/formatDatetime'; -import { SearchResult } from '../../../types/generic/searchResult'; +import { buildSearchResult } from '../../../../helpers/test/testBuilders'; +import { getFormattedDatetime } from '../../../../helpers/utils/formatDatetime'; +import { SearchResult } from '../../../../types/generic/searchResult'; import DocumentSearchResults from './DocumentSearchResults'; import { render, screen, within } from '@testing-library/react'; diff --git a/app/src/components/blocks/documentSearchResults/DocumentSearchResults.tsx b/app/src/components/blocks/_arf/documentSearchResults/DocumentSearchResults.tsx similarity index 93% rename from app/src/components/blocks/documentSearchResults/DocumentSearchResults.tsx rename to app/src/components/blocks/_arf/documentSearchResults/DocumentSearchResults.tsx index 4568dacfc..e9238cc35 100644 --- a/app/src/components/blocks/documentSearchResults/DocumentSearchResults.tsx +++ b/app/src/components/blocks/_arf/documentSearchResults/DocumentSearchResults.tsx @@ -1,7 +1,7 @@ import { Table } from 'nhsuk-react-components'; -import { SearchResult } from '../../../types/generic/searchResult'; +import { SearchResult } from '../../../../types/generic/searchResult'; import { useState } from 'react'; -import { getFormattedDatetime } from '../../../helpers/utils/formatDatetime'; +import { getFormattedDatetime } from '../../../../helpers/utils/formatDatetime'; type Props = { searchResults: Array; diff --git a/app/src/components/blocks/documentSearchResultsOptions/DocumentSearchResultsOptions.test.tsx b/app/src/components/blocks/_arf/documentSearchResultsOptions/DocumentSearchResultsOptions.test.tsx similarity index 95% rename from app/src/components/blocks/documentSearchResultsOptions/DocumentSearchResultsOptions.test.tsx rename to app/src/components/blocks/_arf/documentSearchResultsOptions/DocumentSearchResultsOptions.test.tsx index 3d170916a..fc30f0b93 100644 --- a/app/src/components/blocks/documentSearchResultsOptions/DocumentSearchResultsOptions.test.tsx +++ b/app/src/components/blocks/_arf/documentSearchResultsOptions/DocumentSearchResultsOptions.test.tsx @@ -3,13 +3,13 @@ import { render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import axios from 'axios'; import DocumentSearchResultsOptions from './DocumentSearchResultsOptions'; -import { SUBMISSION_STATE } from '../../../types/pages/documentSearchResultsPage/types'; -import { routes } from '../../../types/generic/routes'; -import { buildPatientDetails } from '../../../helpers/test/testBuilders'; +import { SUBMISSION_STATE } from '../../../../types/pages/documentSearchResultsPage/types'; +import { routes } from '../../../../types/generic/routes'; +import { buildPatientDetails } from '../../../../helpers/test/testBuilders'; const mockedUseNavigate = jest.fn(); -jest.mock('../../../helpers/hooks/useBaseAPIHeaders'); -jest.mock('../../../helpers/hooks/useBaseAPIUrl'); +jest.mock('../../../../helpers/hooks/useBaseAPIHeaders'); +jest.mock('../../../../helpers/hooks/useBaseAPIUrl'); jest.mock('axios'); jest.mock('react-router', () => ({ useNavigate: () => mockedUseNavigate, diff --git a/app/src/components/blocks/documentSearchResultsOptions/DocumentSearchResultsOptions.tsx b/app/src/components/blocks/_arf/documentSearchResultsOptions/DocumentSearchResultsOptions.tsx similarity index 85% rename from app/src/components/blocks/documentSearchResultsOptions/DocumentSearchResultsOptions.tsx rename to app/src/components/blocks/_arf/documentSearchResultsOptions/DocumentSearchResultsOptions.tsx index 3668ec9bf..4f60e49ae 100644 --- a/app/src/components/blocks/documentSearchResultsOptions/DocumentSearchResultsOptions.tsx +++ b/app/src/components/blocks/_arf/documentSearchResultsOptions/DocumentSearchResultsOptions.tsx @@ -1,15 +1,15 @@ import { Button, ButtonLink } from 'nhsuk-react-components'; -import SpinnerButton from '../../generic/spinnerButton/SpinnerButton'; -import { routes } from '../../../types/generic/routes'; -import { SUBMISSION_STATE } from '../../../types/pages/documentSearchResultsPage/types'; +import SpinnerButton from '../../../generic/spinnerButton/SpinnerButton'; +import { routes } from '../../../../types/generic/routes'; +import { SUBMISSION_STATE } from '../../../../types/pages/documentSearchResultsPage/types'; import { useNavigate } from 'react-router-dom'; -import getPresignedUrlForZip from '../../../helpers/requests/getPresignedUrlForZip'; +import getPresignedUrlForZip from '../../../../helpers/requests/getPresignedUrlForZip'; import { AxiosError } from 'axios'; import { Dispatch, SetStateAction, useEffect, useRef, useState } from 'react'; -import useBaseAPIHeaders from '../../../helpers/hooks/useBaseAPIHeaders'; -import { DOCUMENT_TYPE } from '../../../types/pages/UploadDocumentsPage/types'; -import useBaseAPIUrl from '../../../helpers/hooks/useBaseAPIUrl'; -import { errorToParams } from '../../../helpers/utils/errorToParams'; +import useBaseAPIHeaders from '../../../../helpers/hooks/useBaseAPIHeaders'; +import { DOCUMENT_TYPE } from '../../../../types/pages/UploadDocumentsPage/types'; +import useBaseAPIUrl from '../../../../helpers/hooks/useBaseAPIUrl'; +import { errorToParams } from '../../../../helpers/utils/errorToParams'; type Props = { nhsNumber: string; diff --git a/app/src/components/blocks/selectStage/SelectStage.test.tsx b/app/src/components/blocks/_arf/selectStage/SelectStage.test.tsx similarity index 97% rename from app/src/components/blocks/selectStage/SelectStage.test.tsx rename to app/src/components/blocks/_arf/selectStage/SelectStage.test.tsx index 8a8870a6b..f22199b95 100644 --- a/app/src/components/blocks/selectStage/SelectStage.test.tsx +++ b/app/src/components/blocks/_arf/selectStage/SelectStage.test.tsx @@ -4,19 +4,19 @@ import { buildPatientDetails, buildTextFile, buildLgFile, -} from '../../../helpers/test/testBuilders'; +} from '../../../../helpers/test/testBuilders'; import userEvent from '@testing-library/user-event'; -import { DOCUMENT_UPLOAD_STATE as documentUploadStates } from '../../../types/pages/UploadDocumentsPage/types'; +import { DOCUMENT_UPLOAD_STATE as documentUploadStates } from '../../../../types/pages/UploadDocumentsPage/types'; import { act } from 'react-dom/test-utils'; -import { PatientDetails } from '../../../types/generic/patientDetails'; -import usePatient from '../../../helpers/hooks/usePatient'; +import { PatientDetails } from '../../../../types/generic/patientDetails'; +import usePatient from '../../../../helpers/hooks/usePatient'; -jest.mock('../../../helpers/utils/toFileList', () => ({ +jest.mock('../../../../helpers/utils/toFileList', () => ({ __esModule: true, default: () => [], })); -jest.mock('../../../helpers/hooks/usePatient'); jest.mock('react-router'); +jest.mock('../../../../helpers/hooks/usePatient'); const mockedUsePatient = usePatient as jest.Mock; const mockPatient = buildPatientDetails(); diff --git a/app/src/components/blocks/selectStage/SelectStage.tsx b/app/src/components/blocks/_arf/selectStage/SelectStage.tsx similarity index 97% rename from app/src/components/blocks/selectStage/SelectStage.tsx rename to app/src/components/blocks/_arf/selectStage/SelectStage.tsx index 435ca5a77..c9aa62d8e 100644 --- a/app/src/components/blocks/selectStage/SelectStage.tsx +++ b/app/src/components/blocks/_arf/selectStage/SelectStage.tsx @@ -5,11 +5,11 @@ import { FileInputEvent, SetUploadDocuments, UploadDocument, -} from '../../../types/pages/UploadDocumentsPage/types'; +} from '../../../../types/pages/UploadDocumentsPage/types'; import { Button, Fieldset } from 'nhsuk-react-components'; import { useController, useForm } from 'react-hook-form'; -import toFileList from '../../../helpers/utils/toFileList'; -import PatientSummary from '../../generic/patientSummary/PatientSummary'; +import toFileList from '../../../../helpers/utils/toFileList'; +import PatientSummary from '../../../generic/patientSummary/PatientSummary'; import DocumentInputForm from '../documentInputForm/DocumentInputForm'; interface Props { diff --git a/app/src/components/blocks/uploadSummary/UploadSummary.test.tsx b/app/src/components/blocks/_arf/uploadSummary/UploadSummary.test.tsx similarity index 95% rename from app/src/components/blocks/uploadSummary/UploadSummary.test.tsx rename to app/src/components/blocks/_arf/uploadSummary/UploadSummary.test.tsx index 243ae80dd..be11397f8 100644 --- a/app/src/components/blocks/uploadSummary/UploadSummary.test.tsx +++ b/app/src/components/blocks/_arf/uploadSummary/UploadSummary.test.tsx @@ -4,17 +4,17 @@ import UploadSummary, { Props } from './UploadSummary'; import { DOCUMENT_UPLOAD_STATE as documentUploadStates, UploadDocument, -} from '../../../types/pages/UploadDocumentsPage/types'; -import { formatFileSize as formatSize } from '../../../helpers/utils/formatFileSize'; -import { getFormattedDate } from '../../../helpers/utils/formatDate'; +} from '../../../../types/pages/UploadDocumentsPage/types'; +import { formatFileSize as formatSize } from '../../../../helpers/utils/formatFileSize'; +import { getFormattedDate } from '../../../../helpers/utils/formatDate'; import { buildDocument, buildPatientDetails, buildTextFile, -} from '../../../helpers/test/testBuilders'; -import usePatient from '../../../helpers/hooks/usePatient'; +} from '../../../../helpers/test/testBuilders'; +import usePatient from '../../../../helpers/hooks/usePatient'; -jest.mock('../../../helpers/hooks/usePatient'); +jest.mock('../../../../helpers/hooks/usePatient'); const mockedUsePatient = usePatient as jest.Mock; const mockPatient = buildPatientDetails(); diff --git a/app/src/components/blocks/uploadSummary/UploadSummary.tsx b/app/src/components/blocks/_arf/uploadSummary/UploadSummary.tsx similarity index 94% rename from app/src/components/blocks/uploadSummary/UploadSummary.tsx rename to app/src/components/blocks/_arf/uploadSummary/UploadSummary.tsx index e9c355b36..71de2a4fc 100644 --- a/app/src/components/blocks/uploadSummary/UploadSummary.tsx +++ b/app/src/components/blocks/_arf/uploadSummary/UploadSummary.tsx @@ -3,11 +3,11 @@ import React from 'react'; import { DOCUMENT_UPLOAD_STATE, UploadDocument, -} from '../../../types/pages/UploadDocumentsPage/types'; -import formatFileSize from '../../../helpers/utils/formatFileSize'; -import { getFormattedDate } from '../../../helpers/utils/formatDate'; -import ErrorBox from '../../layout/errorBox/ErrorBox'; -import PatientSummary from '../../generic/patientSummary/PatientSummary'; +} from '../../../../types/pages/UploadDocumentsPage/types'; +import formatFileSize from '../../../../helpers/utils/formatFileSize'; +import { getFormattedDate } from '../../../../helpers/utils/formatDate'; +import ErrorBox from '../../../layout/errorBox/ErrorBox'; +import PatientSummary from '../../../generic/patientSummary/PatientSummary'; export interface Props { documents: Array; diff --git a/app/src/components/blocks/uploadingStage/UploadingStage.test.tsx b/app/src/components/blocks/_arf/uploadingStage/UploadingStage.test.tsx similarity index 97% rename from app/src/components/blocks/uploadingStage/UploadingStage.test.tsx rename to app/src/components/blocks/_arf/uploadingStage/UploadingStage.test.tsx index b0d649e7e..772d64120 100644 --- a/app/src/components/blocks/uploadingStage/UploadingStage.test.tsx +++ b/app/src/components/blocks/_arf/uploadingStage/UploadingStage.test.tsx @@ -5,8 +5,8 @@ import { DOCUMENT_UPLOAD_STATE, DOCUMENT_UPLOAD_STATE as documentUploadStates, UploadDocument, -} from '../../../types/pages/UploadDocumentsPage/types'; -import { buildTextFile } from '../../../helpers/test/testBuilders'; +} from '../../../../types/pages/UploadDocumentsPage/types'; +import { buildTextFile } from '../../../../helpers/test/testBuilders'; import UploadingStage from './UploadingStage'; describe('', () => { diff --git a/app/src/components/blocks/uploadingStage/UploadingStage.tsx b/app/src/components/blocks/_arf/uploadingStage/UploadingStage.tsx similarity index 95% rename from app/src/components/blocks/uploadingStage/UploadingStage.tsx rename to app/src/components/blocks/_arf/uploadingStage/UploadingStage.tsx index 51b895cba..a9d37ba9c 100644 --- a/app/src/components/blocks/uploadingStage/UploadingStage.tsx +++ b/app/src/components/blocks/_arf/uploadingStage/UploadingStage.tsx @@ -2,9 +2,9 @@ import React from 'react'; import { UploadDocument, DOCUMENT_UPLOAD_STATE, -} from '../../../types/pages/UploadDocumentsPage/types'; +} from '../../../../types/pages/UploadDocumentsPage/types'; import { Table, WarningCallout } from 'nhsuk-react-components'; -import formatFileSize from '../../../helpers/utils/formatFileSize'; +import formatFileSize from '../../../../helpers/utils/formatFileSize'; interface Props { documents: Array; diff --git a/app/src/pages/documentSearchResultsPage/DocumentSearchResultsPage.tsx b/app/src/pages/documentSearchResultsPage/DocumentSearchResultsPage.tsx index 14eaf27a8..918892c77 100644 --- a/app/src/pages/documentSearchResultsPage/DocumentSearchResultsPage.tsx +++ b/app/src/pages/documentSearchResultsPage/DocumentSearchResultsPage.tsx @@ -1,14 +1,14 @@ import React, { useEffect, useRef, useState } from 'react'; import PatientSummary from '../../components/generic/patientSummary/PatientSummary'; import { SearchResult } from '../../types/generic/searchResult'; -import DocumentSearchResults from '../../components/blocks/documentSearchResults/DocumentSearchResults'; +import DocumentSearchResults from '../../components/blocks/_arf/documentSearchResults/DocumentSearchResults'; import { useNavigate } from 'react-router'; import { routes } from '../../types/generic/routes'; import { Link } from 'react-router-dom'; import { SUBMISSION_STATE } from '../../types/pages/documentSearchResultsPage/types'; import ProgressBar from '../../components/generic/progressBar/ProgressBar'; import ServiceError from '../../components/layout/serviceErrorBox/ServiceErrorBox'; -import DocumentSearchResultsOptions from '../../components/blocks/documentSearchResultsOptions/DocumentSearchResultsOptions'; +import DocumentSearchResultsOptions from '../../components/blocks/_arf/documentSearchResultsOptions/DocumentSearchResultsOptions'; import { AxiosError } from 'axios'; import getDocumentSearchResults from '../../helpers/requests/getDocumentSearchResults'; import useBaseAPIHeaders from '../../helpers/hooks/useBaseAPIHeaders'; diff --git a/app/src/pages/uploadDocumentsPage/UploadDocumentsPage.tsx b/app/src/pages/uploadDocumentsPage/UploadDocumentsPage.tsx index ce5a32006..3dda00c05 100644 --- a/app/src/pages/uploadDocumentsPage/UploadDocumentsPage.tsx +++ b/app/src/pages/uploadDocumentsPage/UploadDocumentsPage.tsx @@ -6,9 +6,9 @@ import { UploadDocument, } from '../../types/pages/UploadDocumentsPage/types'; import uploadDocument from '../../helpers/requests/uploadDocument'; -import SelectStage from '../../components/blocks/selectStage/SelectStage'; -import UploadingStage from '../../components/blocks/uploadingStage/UploadingStage'; -import CompleteStage from '../../components/blocks/completeStage/CompleteStage'; +import SelectStage from '../../components/blocks/_arf/selectStage/SelectStage'; +import UploadingStage from '../../components/blocks/_arf/uploadingStage/UploadingStage'; +import CompleteStage from '../../components/blocks/_arf/completeStage/CompleteStage'; import useBaseAPIHeaders from '../../helpers/hooks/useBaseAPIHeaders'; import usePatient from '../../helpers/hooks/usePatient'; import useBaseAPIUrl from '../../helpers/hooks/useBaseAPIUrl'; From e4509ae2647c8a164e1f8854c103bff69541f6ba Mon Sep 17 00:00:00 2001 From: Rio Knightley Date: Tue, 13 Feb 2024 12:14:28 +0000 Subject: [PATCH 02/15] Add lloyd george upload page --- .../LloydGeorgeUploadingStage.tsx | 59 +++++++++++++++++++ .../LloydGeorgeUploadPage.tsx | 10 ++++ .../PatientResultPage.test.tsx | 4 +- .../patientResultPage/PatientResultPage.tsx | 5 +- app/src/router/AppRouter.tsx | 29 +++++---- app/src/types/generic/routes.ts | 5 +- 6 files changed, 95 insertions(+), 17 deletions(-) create mode 100644 app/src/components/blocks/lloydGeorgeUploadingStage/LloydGeorgeUploadingStage.tsx create mode 100644 app/src/pages/lloydGeorgeUploadPage/LloydGeorgeUploadPage.tsx diff --git a/app/src/components/blocks/lloydGeorgeUploadingStage/LloydGeorgeUploadingStage.tsx b/app/src/components/blocks/lloydGeorgeUploadingStage/LloydGeorgeUploadingStage.tsx new file mode 100644 index 000000000..559d40a68 --- /dev/null +++ b/app/src/components/blocks/lloydGeorgeUploadingStage/LloydGeorgeUploadingStage.tsx @@ -0,0 +1,59 @@ +import React from 'react'; +import { buildDocument, buildTextFile } from '../../../helpers/test/testBuilders'; +import { DOCUMENT_UPLOAD_STATE } from '../../../types/pages/UploadDocumentsPage/types'; +import { Table } from 'nhsuk-react-components'; +import formatFileSize from '../../../helpers/utils/formatFileSize'; + +type Props = {}; + +function LloydGeorgeUploadStage({}: Props) { + const files = [buildTextFile('one', 100), buildTextFile('two', 101)]; + const documents = files.map((file) => buildDocument(file, DOCUMENT_UPLOAD_STATE.SUCCEEDED)); + const getUploadMessage = (type: DOCUMENT_UPLOAD_STATE) => { + if (type === DOCUMENT_UPLOAD_STATE.SELECTED) return 'Waiting...'; + else if (type === DOCUMENT_UPLOAD_STATE.UPLOADING) return 'Uploading...'; + else if (type === DOCUMENT_UPLOAD_STATE.SUCCEEDED) return 'Uploaded'; + else if (type === DOCUMENT_UPLOAD_STATE.FAILED) return 'Upload failed'; + }; + return ( + + + + File Name + File Size + File Upload Progress + + + + {documents.map((document) => ( + + {document.file.name} + {formatFileSize(document.file.size)} + + +

+ {document.state === DOCUMENT_UPLOAD_STATE.UPLOADING ? ( + <> {Math.round(document.progress)}% uploaded... + ) : ( + <>{getUploadMessage(document.state)} + )} +

+
+
+ ))} +
+
+ ); +} + +export default LloydGeorgeUploadStage; diff --git a/app/src/pages/lloydGeorgeUploadPage/LloydGeorgeUploadPage.tsx b/app/src/pages/lloydGeorgeUploadPage/LloydGeorgeUploadPage.tsx new file mode 100644 index 000000000..a54f0a9e8 --- /dev/null +++ b/app/src/pages/lloydGeorgeUploadPage/LloydGeorgeUploadPage.tsx @@ -0,0 +1,10 @@ +import React from 'react'; +import LloydGeorgeUploadStage from '../../components/blocks/lloydGeorgeUploadingStage/LloydGeorgeUploadingStage'; + +type Props = {}; + +function LloydGeorgeUploadPage({}: Props) { + return ; +} + +export default LloydGeorgeUploadPage; diff --git a/app/src/pages/patientResultPage/PatientResultPage.test.tsx b/app/src/pages/patientResultPage/PatientResultPage.test.tsx index e8bad6098..1ab77b15a 100644 --- a/app/src/pages/patientResultPage/PatientResultPage.test.tsx +++ b/app/src/pages/patientResultPage/PatientResultPage.test.tsx @@ -195,7 +195,7 @@ describe('PatientResultPage', () => { }); await waitFor(() => { - expect(mockedUseNavigate).toHaveBeenCalledWith(routes.UPLOAD_DOCUMENTS); + expect(mockedUseNavigate).toHaveBeenCalledWith(routes.ARF_UPLOAD_DOCUMENTS); }); }, ); @@ -230,7 +230,7 @@ describe('PatientResultPage', () => { userEvent.click(screen.getByRole('button', { name: 'Accept details are correct' })); await waitFor(() => { - expect(mockedUseNavigate).toHaveBeenCalledWith(routes.DOWNLOAD_DOCUMENTS); + expect(mockedUseNavigate).toHaveBeenCalledWith(routes.ARF_DOWNLOAD_DOCUMENTS); }); }); }); diff --git a/app/src/pages/patientResultPage/PatientResultPage.tsx b/app/src/pages/patientResultPage/PatientResultPage.tsx index 3dcc2a026..b699a4568 100644 --- a/app/src/pages/patientResultPage/PatientResultPage.tsx +++ b/app/src/pages/patientResultPage/PatientResultPage.tsx @@ -30,14 +30,15 @@ function PatientResultPage() { if (patientDetails?.active) { navigate(routes.LLOYD_GEORGE); } else { - navigate(routes.UPLOAD_DOCUMENTS); + // TODO: What do we use to decide ARF route or LG route ? + navigate(routes.ARF_UPLOAD_DOCUMENTS); } } // PCSE Role else if (userIsPCSE) { // Make PDS and Dynamo document store search request to download documents from patient - navigate(routes.DOWNLOAD_DOCUMENTS); + navigate(routes.ARF_DOWNLOAD_DOCUMENTS); } }; const showWarning = patientDetails?.superseded || patientDetails?.restricted; diff --git a/app/src/router/AppRouter.tsx b/app/src/router/AppRouter.tsx index 5d7a147e1..a37b2b899 100644 --- a/app/src/router/AppRouter.tsx +++ b/app/src/router/AppRouter.tsx @@ -10,8 +10,8 @@ import UnauthorisedPage from '../pages/unauthorisedPage/UnauthorisedPage'; import LogoutPage from '../pages/logoutPage/LogoutPage'; import PatientSearchPage from '../pages/patientSearchPage/PatientSearchPage'; import PatientResultPage from '../pages/patientResultPage/PatientResultPage'; -import UploadDocumentsPage from '../pages/uploadDocumentsPage/UploadDocumentsPage'; -import DocumentSearchResultsPage from '../pages/documentSearchResultsPage/DocumentSearchResultsPage'; +import ArfUploadDocumentsPage from '../pages/uploadDocumentsPage/UploadDocumentsPage'; +import ArfSearchResultsPage from '../pages/documentSearchResultsPage/DocumentSearchResultsPage'; import LloydGeorgeRecordPage from '../pages/lloydGeorgeRecordPage/LloydGeorgeRecordPage'; import AuthGuard from './guards/authGuard/AuthGuard'; import PatientGuard from './guards/patientGuard/PatientGuard'; @@ -23,6 +23,7 @@ import FeedbackPage from '../pages/feedbackPage/FeedbackPage'; import ServerErrorPage from '../pages/serverErrorPage/ServerErrorPage'; import PrivacyPage from '../pages/privacyPage/PrivacyPage'; import useFeatureFlags from '../helpers/hooks/useFeatureFlags'; +import LloydGeorgeUploadPage from '../pages/lloydGeorgeUploadPage/LloydGeorgeUploadPage'; const { START, @@ -35,12 +36,13 @@ const { SERVER_ERROR, FEEDBACK, LOGOUT, - DOWNLOAD_DOCUMENTS, - LLOYD_GEORGE, SEARCH_PATIENT, VERIFY_PATIENT, - UPLOAD_DOCUMENTS, PRIVACY_POLICY, + LLOYD_GEORGE, + LLOYD_GEORGE_UPLOAD, + ARF_DOWNLOAD_DOCUMENTS, + ARF_UPLOAD_DOCUMENTS, } = routes; type Routes = { @@ -104,18 +106,23 @@ export const routeMap: Routes = { page: , type: ROUTE_TYPE.PATIENT, }, - [UPLOAD_DOCUMENTS]: { - page: , + [LLOYD_GEORGE]: { + page: , type: ROUTE_TYPE.PATIENT, unauthorized: [REPOSITORY_ROLE.PCSE], }, - [DOWNLOAD_DOCUMENTS]: { - page: , + [LLOYD_GEORGE_UPLOAD]: { + page: , + type: ROUTE_TYPE.PATIENT, + unauthorized: [REPOSITORY_ROLE.PCSE], + }, + [ARF_DOWNLOAD_DOCUMENTS]: { + page: , type: ROUTE_TYPE.PATIENT, unauthorized: [REPOSITORY_ROLE.GP_ADMIN, REPOSITORY_ROLE.GP_CLINICAL], }, - [LLOYD_GEORGE]: { - page: , + [ARF_UPLOAD_DOCUMENTS]: { + page: , type: ROUTE_TYPE.PATIENT, unauthorized: [REPOSITORY_ROLE.PCSE], }, diff --git a/app/src/types/generic/routes.ts b/app/src/types/generic/routes.ts index 2cea76a7c..02dd00d84 100644 --- a/app/src/types/generic/routes.ts +++ b/app/src/types/generic/routes.ts @@ -15,8 +15,9 @@ export enum routes { SEARCH_PATIENT = '/search/patient', VERIFY_PATIENT = '/search/patient/verify', LLOYD_GEORGE = '/patient/view/lloyd-george-record', - DOWNLOAD_DOCUMENTS = '/patient/download', - UPLOAD_DOCUMENTS = '/patient/upload', + LLOYD_GEORGE_UPLOAD = '/patient/upload/lloyd-george-record', + ARF_DOWNLOAD_DOCUMENTS = '/patient/download', + ARF_UPLOAD_DOCUMENTS = '/patient/upload', } export enum ROUTE_TYPE { From d068fdc81b22a454c47c63784d496d4fd6d6df8f Mon Sep 17 00:00:00 2001 From: Rio Knightley Date: Tue, 13 Feb 2024 15:54:42 +0000 Subject: [PATCH 03/15] Lloyd george upload stage --- .../LloydGeorgeRecordError.tsx | 7 +- .../LloydGeorgeUploadingStage.test.tsx | 137 ++++++++++++++++++ .../LloydGeorgeUploadingStage.tsx | 118 ++++++++------- .../LloydGeorgeUploadPage.tsx | 50 ++++++- 4 files changed, 260 insertions(+), 52 deletions(-) create mode 100644 app/src/components/blocks/lloydGeorgeUploadingStage/LloydGeorgeUploadingStage.test.tsx diff --git a/app/src/components/blocks/lloydGeorgeRecordError/LloydGeorgeRecordError.tsx b/app/src/components/blocks/lloydGeorgeRecordError/LloydGeorgeRecordError.tsx index a660519a5..2cb1ccbdb 100644 --- a/app/src/components/blocks/lloydGeorgeRecordError/LloydGeorgeRecordError.tsx +++ b/app/src/components/blocks/lloydGeorgeRecordError/LloydGeorgeRecordError.tsx @@ -53,7 +53,12 @@ function LloydGeorgeRecordError({ downloadStage, setStage }: Props) { once the record is uploaded.

- + { + navigate(routes.LLOYD_GEORGE_UPLOAD); + }} + > Upload patient record
diff --git a/app/src/components/blocks/lloydGeorgeUploadingStage/LloydGeorgeUploadingStage.test.tsx b/app/src/components/blocks/lloydGeorgeUploadingStage/LloydGeorgeUploadingStage.test.tsx new file mode 100644 index 000000000..462132e59 --- /dev/null +++ b/app/src/components/blocks/lloydGeorgeUploadingStage/LloydGeorgeUploadingStage.test.tsx @@ -0,0 +1,137 @@ +import { render, screen } from '@testing-library/react'; +import { act } from 'react-dom/test-utils'; +import { + DOCUMENT_TYPE, + DOCUMENT_UPLOAD_STATE, + UploadDocument, +} from '../../../types/pages/UploadDocumentsPage/types'; +import { buildTextFile } from '../../../helpers/test/testBuilders'; +import LloydGeorgeUploadStage from './LloydGeorgeUploadingStage'; +const mockSetStage = jest.fn(); +describe('', () => { + describe('with NHS number', () => { + const triggerUploadStateChange = ( + document: UploadDocument, + state: DOCUMENT_UPLOAD_STATE, + progress: number, + ) => { + act(() => { + document.state = state; + document.progress = progress; + }); + }; + + it('uploads documents and displays the progress', async () => { + const documentOne = { + file: buildTextFile('one', 100), + state: DOCUMENT_UPLOAD_STATE.UPLOADING, + id: '1', + progress: 50, + docType: DOCUMENT_TYPE.LLOYD_GEORGE, + }; + render(); + + triggerUploadStateChange(documentOne, DOCUMENT_UPLOAD_STATE.UPLOADING, 0); + + expect(screen.queryByTestId('upload-document-form')).not.toBeInTheDocument(); + expect( + screen.getByText( + 'Do not close or navigate away from this browser until upload is complete. Each file will be uploaded and combined into one record.', + ), + ).toBeInTheDocument(); + expect(screen.getByText('50% uploaded...')).toBeInTheDocument(); + }); + + it('progress bar reflect the upload progress', async () => { + const documentOne = { + file: buildTextFile('one', 100), + state: DOCUMENT_UPLOAD_STATE.SELECTED, + id: '1', + progress: 0, + docType: DOCUMENT_TYPE.ARF, + }; + const documentTwo = { + file: buildTextFile('two', 200), + state: DOCUMENT_UPLOAD_STATE.SELECTED, + id: '2', + progress: 0, + docType: DOCUMENT_TYPE.ARF, + }; + const documentThree = { + file: buildTextFile('three', 100), + state: DOCUMENT_UPLOAD_STATE.SELECTED, + id: '3', + progress: 0, + docType: DOCUMENT_TYPE.ARF, + }; + + const { rerender } = render( + , + ); + const getProgressBarValue = (document: UploadDocument) => { + const progressBar: HTMLProgressElement = screen.getByRole('progressbar', { + name: `Uploading ${document.file.name}`, + }); + return progressBar.value; + }; + const getProgressText = (document: UploadDocument) => { + return screen.getByRole('status', { + name: `${document.file.name} upload status`, + }).textContent; + }; + + triggerUploadStateChange(documentOne, DOCUMENT_UPLOAD_STATE.UPLOADING, 10); + rerender( + , + ); + expect(getProgressBarValue(documentOne)).toEqual(10); + expect(getProgressText(documentOne)).toContain('10% uploaded...'); + + triggerUploadStateChange(documentOne, DOCUMENT_UPLOAD_STATE.UPLOADING, 70); + rerender( + , + ); + expect(getProgressBarValue(documentOne)).toEqual(70); + expect(getProgressText(documentOne)).toContain('70% uploaded...'); + + triggerUploadStateChange(documentTwo, DOCUMENT_UPLOAD_STATE.UPLOADING, 20); + rerender( + , + ); + expect(getProgressBarValue(documentTwo)).toEqual(20); + expect(getProgressText(documentTwo)).toContain('20% uploaded...'); + + triggerUploadStateChange(documentTwo, DOCUMENT_UPLOAD_STATE.SUCCEEDED, 100); + rerender( + , + ); + expect(getProgressBarValue(documentTwo)).toEqual(100); + expect(getProgressText(documentTwo)).toContain('Upload successful'); + + triggerUploadStateChange(documentOne, DOCUMENT_UPLOAD_STATE.FAILED, 0); + rerender( + , + ); + expect(getProgressBarValue(documentOne)).toEqual(0); + expect(getProgressText(documentOne)).toContain('Upload failed'); + }); + }); +}); diff --git a/app/src/components/blocks/lloydGeorgeUploadingStage/LloydGeorgeUploadingStage.tsx b/app/src/components/blocks/lloydGeorgeUploadingStage/LloydGeorgeUploadingStage.tsx index 559d40a68..6af717d8a 100644 --- a/app/src/components/blocks/lloydGeorgeUploadingStage/LloydGeorgeUploadingStage.tsx +++ b/app/src/components/blocks/lloydGeorgeUploadingStage/LloydGeorgeUploadingStage.tsx @@ -1,58 +1,78 @@ -import React from 'react'; -import { buildDocument, buildTextFile } from '../../../helpers/test/testBuilders'; -import { DOCUMENT_UPLOAD_STATE } from '../../../types/pages/UploadDocumentsPage/types'; -import { Table } from 'nhsuk-react-components'; +import React, { Dispatch, SetStateAction } from 'react'; +import { + DOCUMENT_UPLOAD_STATE, + UploadDocument, +} from '../../../types/pages/UploadDocumentsPage/types'; +import { Table, WarningCallout } from 'nhsuk-react-components'; import formatFileSize from '../../../helpers/utils/formatFileSize'; +import { LG_UPLOAD_STAGE } from '../../../pages/lloydGeorgeUploadPage/LloydGeorgeUploadPage'; -type Props = {}; +type Props = { + documents: Array; + setStage: Dispatch>; +}; -function LloydGeorgeUploadStage({}: Props) { - const files = [buildTextFile('one', 100), buildTextFile('two', 101)]; - const documents = files.map((file) => buildDocument(file, DOCUMENT_UPLOAD_STATE.SUCCEEDED)); - const getUploadMessage = (type: DOCUMENT_UPLOAD_STATE) => { - if (type === DOCUMENT_UPLOAD_STATE.SELECTED) return 'Waiting...'; - else if (type === DOCUMENT_UPLOAD_STATE.UPLOADING) return 'Uploading...'; - else if (type === DOCUMENT_UPLOAD_STATE.SUCCEEDED) return 'Uploaded'; - else if (type === DOCUMENT_UPLOAD_STATE.FAILED) return 'Upload failed'; +function LloydGeorgeUploadStage({ documents, setStage }: Props) { + const getUploadMessage = (document: UploadDocument) => { + if (document.state === DOCUMENT_UPLOAD_STATE.SELECTED) return 'Waiting...'; + else if (document.state === DOCUMENT_UPLOAD_STATE.UPLOADING) + return `${Math.round(document.progress)}% uploaded...`; + else if (document.state === DOCUMENT_UPLOAD_STATE.SUCCEEDED) return 'Upload successful'; + else if (document.state === DOCUMENT_UPLOAD_STATE.FAILED) return 'Upload failed'; }; return ( - - - - File Name - File Size - File Upload Progress - - - - {documents.map((document) => ( - - {document.file.name} - {formatFileSize(document.file.size)} - - -

- {document.state === DOCUMENT_UPLOAD_STATE.UPLOADING ? ( - <> {Math.round(document.progress)}% uploaded... - ) : ( - <>{getUploadMessage(document.state)} - )} -

-
+ <> + +

Uploading record

+ + Stay on this page +

+ Do not close or navigate away from this browser until upload is complete. Each + file will be uploaded and combined into one record. +

+
+
+ + + Filename + Size + Upload Progress - ))} - -
+ + + {documents.map((document) => ( + + {document.file.name} + + {formatFileSize(document.file.size)} + + + +

+ {getUploadMessage(document)} +

+
+
+ ))} +
+ + ); } diff --git a/app/src/pages/lloydGeorgeUploadPage/LloydGeorgeUploadPage.tsx b/app/src/pages/lloydGeorgeUploadPage/LloydGeorgeUploadPage.tsx index a54f0a9e8..f9d8ce30c 100644 --- a/app/src/pages/lloydGeorgeUploadPage/LloydGeorgeUploadPage.tsx +++ b/app/src/pages/lloydGeorgeUploadPage/LloydGeorgeUploadPage.tsx @@ -1,10 +1,56 @@ -import React from 'react'; +import React, { useState } from 'react'; import LloydGeorgeUploadStage from '../../components/blocks/lloydGeorgeUploadingStage/LloydGeorgeUploadingStage'; +import { buildDocument, buildTextFile } from '../../helpers/test/testBuilders'; +import { DOCUMENT_UPLOAD_STATE } from '../../types/pages/UploadDocumentsPage/types'; type Props = {}; +export enum LG_UPLOAD_STAGE { + SELECT = 0, + UPLOAD = 1, + COMPLETE = 2, +} + function LloydGeorgeUploadPage({}: Props) { - return ; + const [stage, setStage] = useState(LG_UPLOAD_STAGE.SELECT); + const files = [ + buildTextFile('1of3_Lloyd_George_Record_[Barry ONEIL]_[9730182000]_[23-10-2018]', 100), + buildTextFile('2of3_Lloyd_George_Record_[Barry ONEIL]_[9730182000]_[23-10-2018]', 101), + ]; + const documents = files.map((file) => { + return { + ...buildDocument(file, DOCUMENT_UPLOAD_STATE.SUCCEEDED), + progress: 100, + }; + }); + switch (stage) { + case LG_UPLOAD_STAGE.SELECT: + return ( + // TODO, ADD FILE SELECT STAGE +
+ +
select files
+
+ ); + case LG_UPLOAD_STAGE.UPLOAD: + return ; + case LG_UPLOAD_STAGE.COMPLETE: + return ( + // TODO, ADD UPLOAD COMPLETE STAGE +
+ +
upload complete
+
+ ); + default: + return null; + } } export default LloydGeorgeUploadPage; From c4228b2b81f45eedbcab28c8e036bdcbba07feb6 Mon Sep 17 00:00:00 2001 From: Rio Knightley Date: Wed, 14 Feb 2024 15:01:50 +0000 Subject: [PATCH 04/15] Add file input stage for lg upload --- .../blocks/_arf/selectStage/SelectStage.tsx | 2 +- .../LloydGeorgeFileInputStage.tsx | 244 ++++++++++++++++++ .../LloydGeorgeUploadingStage.test.tsx | 2 +- .../LloydGeorgeUploadPage.tsx | 39 +-- 4 files changed, 266 insertions(+), 21 deletions(-) create mode 100644 app/src/components/blocks/lloydGeorgeFileInputStage/LloydGeorgeFileInputStage.tsx diff --git a/app/src/components/blocks/_arf/selectStage/SelectStage.tsx b/app/src/components/blocks/_arf/selectStage/SelectStage.tsx index cb20f998a..2e1618f61 100644 --- a/app/src/components/blocks/_arf/selectStage/SelectStage.tsx +++ b/app/src/components/blocks/_arf/selectStage/SelectStage.tsx @@ -11,7 +11,7 @@ import { useController, useForm } from 'react-hook-form'; import toFileList from '../../../../helpers/utils/toFileList'; import PatientSummary from '../../../generic/patientSummary/PatientSummary'; import DocumentInputForm from '../documentInputForm/DocumentInputForm'; -import { ARFFormConfig, lloydGeorgeFormConfig } from '../../../helpers/utils/formConfig'; +import { ARFFormConfig, lloydGeorgeFormConfig } from '../../../../helpers/utils/formConfig'; interface Props { uploadDocuments: () => void; diff --git a/app/src/components/blocks/lloydGeorgeFileInputStage/LloydGeorgeFileInputStage.tsx b/app/src/components/blocks/lloydGeorgeFileInputStage/LloydGeorgeFileInputStage.tsx new file mode 100644 index 000000000..4da1b61ea --- /dev/null +++ b/app/src/components/blocks/lloydGeorgeFileInputStage/LloydGeorgeFileInputStage.tsx @@ -0,0 +1,244 @@ +import React, { Dispatch, SetStateAction, useRef } from 'react'; +import BackButton from '../../../components/generic/backButton/BackButton'; +import { formatNhsNumber } from '../../../helpers/utils/formatNhsNumber'; +import { getFormattedDate } from '../../../helpers/utils/formatDate'; +import { buildPatientDetails } from '../../../helpers/test/testBuilders'; +import { Input, Button, Fieldset, InsetText, Table } from 'nhsuk-react-components'; +import { ReactComponent as FileSVG } from '../../../styles/file-input.svg'; +import { + DOCUMENT_TYPE, + DOCUMENT_UPLOAD_STATE, + FileInputEvent, + UploadDocument, +} from '../../../types/pages/UploadDocumentsPage/types'; +import { useController, useForm } from 'react-hook-form'; +import formatFileSize from '../../../helpers/utils/formatFileSize'; +import { lloydGeorgeFormConfig } from '../../../helpers/utils/formConfig'; +import uploadDocument from '../../../helpers/requests/uploadDocument'; +import useBaseAPIUrl from '../../../helpers/hooks/useBaseAPIUrl'; +import useBaseAPIHeaders from '../../../helpers/hooks/useBaseAPIHeaders'; +import { LG_UPLOAD_STAGE } from '../../../pages/lloydGeorgeUploadPage/LloydGeorgeUploadPage'; + +type Props = { + documents: Array; + setDocuments: Dispatch>>; + setStage: Dispatch>; +}; + +function LloydGeorgeFileInputStage({ documents, setDocuments, setStage }: Props) { + const patientDetails = buildPatientDetails(); + const nhsNumber: string = patientDetails?.nhsNumber || ''; + const formattedNhsNumber = formatNhsNumber(nhsNumber); + const dob: String = patientDetails?.birthDate + ? getFormattedDate(new Date(patientDetails.birthDate)) + : ''; + let fileInputRef = useRef(null); + + const { handleSubmit, control, formState } = useForm(); + const lgController = useController(lloydGeorgeFormConfig(control)); + + const hasFileInput = documents.length; + const baseUrl = useBaseAPIUrl(); + const baseHeaders = useBaseAPIHeaders(); + + const uploadDocuments = async () => { + try { + if (patientDetails) { + setStage(LG_UPLOAD_STAGE.UPLOAD); + await uploadDocument({ + nhsNumber: patientDetails.nhsNumber, + setDocuments, + documents: documents, + baseUrl, + baseHeaders, + }); + } + } catch (e) {} + }; + const updateFileList = (fileArray: File[]) => { + const documentMap: Array = fileArray.map((file) => ({ + id: Math.floor(Math.random() * 1000000).toString(), + file, + state: DOCUMENT_UPLOAD_STATE.SELECTED, + progress: 0, + docType: DOCUMENT_TYPE.LLOYD_GEORGE, + })); + const updatedDocList = [...documentMap, ...documents]; + setDocuments(updatedDocList); + lgController.field.onChange(updatedDocList); + }; + const onFileDrop = (e: React.DragEvent) => { + e.preventDefault(); + e.stopPropagation(); + let fileArray: File[] = []; + if (e.dataTransfer.items) { + [...e.dataTransfer.items].forEach((item) => { + const file = item.getAsFile(); + + if (item.kind === 'file' && file) { + fileArray.push(file); + } + }); + } else if (e.dataTransfer.files) { + fileArray = [...e.dataTransfer.files]; + } + if (fileArray) { + updateFileList(fileArray); + } + }; + const onInput = (e: FileInputEvent) => { + const fileArray = Array.from(e.target.files ?? new FileList()); + updateFileList(fileArray); + }; + const onRemove = (index: number) => { + let updatedDocList: UploadDocument[] = []; + if (index >= 0) { + updatedDocList = [...documents.slice(0, index), ...documents.slice(index + 1)]; + } + setDocuments(updatedDocList); + lgController.field.onChange(updatedDocList); + }; + + return ( +
+
+ +

Upload a Lloyd George record

+
+

+ {`${patientDetails?.givenName} ${patientDetails?.familyName}`} +

+

NHS number: {formattedNhsNumber}

+

Date of birth: {dob}

+
+
+

Before you upload a Lloyd George patient record:

+
    +
  • The patient details must match the record you are uploading
  • +
  • The patient record must be in a PDF file or multiple PDFs
  • +
  • Your PDF file(s) should be named in this format:
  • +

    + [PDFnumber]_Lloyd_George_Record_[Patient Name]_[NHS Number]_[D.O.B].PDF +

    +
+ +

For example:

+

1of2_Lloyd_George_Record_[Joe Bloggs]_[1234567890]_[25-12-2019].PDF

+

2of2_Lloyd_George_Record_[Joe Bloggs]_[1234567890]_[25-12-2019].PDF

+
+

+

+ It's recommended to upload the entire record in one go, as each file will be + combined together based on the file names. +

+

You will not be able to view a partially uploaded record.

+
+ Select the files you wish to upload +
+
{ + e.preventDefault(); + }} + onDrop={onFileDrop} + className={'lloydgeorge_drag-and-drop'} + > + + Drag and drop a file or multiple files here + +
+ +
+
+ { + onInput(e); + e.target.value = ''; + }} + onBlur={lgController.field.onBlur} + // @ts-ignore The NHS Component library is outdated and does not allow for any reference other than a blank MutableRefObject + inputRef={(e: HTMLInputElement) => { + lgController.field.ref(e); + fileInputRef.current = e; + }} + /> + +
+
+
+ {documents && documents.length > 0 && ( + + + + Filename + Size + Remove + + + + + {documents.map((document: UploadDocument, index: number) => ( + + {document.file.name} + {formatFileSize(document.file.size)} + + + + + ))} + +
+ )} +
+ + +
+ +
+ ); +} + +export default LloydGeorgeFileInputStage; diff --git a/app/src/components/blocks/lloydGeorgeUploadingStage/LloydGeorgeUploadingStage.test.tsx b/app/src/components/blocks/lloydGeorgeUploadingStage/LloydGeorgeUploadingStage.test.tsx index 462132e59..df4442b16 100644 --- a/app/src/components/blocks/lloydGeorgeUploadingStage/LloydGeorgeUploadingStage.test.tsx +++ b/app/src/components/blocks/lloydGeorgeUploadingStage/LloydGeorgeUploadingStage.test.tsx @@ -8,7 +8,7 @@ import { import { buildTextFile } from '../../../helpers/test/testBuilders'; import LloydGeorgeUploadStage from './LloydGeorgeUploadingStage'; const mockSetStage = jest.fn(); -describe('', () => { +describe('', () => { describe('with NHS number', () => { const triggerUploadStateChange = ( document: UploadDocument, diff --git a/app/src/pages/lloydGeorgeUploadPage/LloydGeorgeUploadPage.tsx b/app/src/pages/lloydGeorgeUploadPage/LloydGeorgeUploadPage.tsx index f9d8ce30c..0ba88dacb 100644 --- a/app/src/pages/lloydGeorgeUploadPage/LloydGeorgeUploadPage.tsx +++ b/app/src/pages/lloydGeorgeUploadPage/LloydGeorgeUploadPage.tsx @@ -1,7 +1,7 @@ import React, { useState } from 'react'; -import LloydGeorgeUploadStage from '../../components/blocks/lloydGeorgeUploadingStage/LloydGeorgeUploadingStage'; -import { buildDocument, buildTextFile } from '../../helpers/test/testBuilders'; -import { DOCUMENT_UPLOAD_STATE } from '../../types/pages/UploadDocumentsPage/types'; +import LloydGeorgeUploadingStage from '../../components/blocks/lloydGeorgeUploadingStage/LloydGeorgeUploadingStage'; +import { UploadDocument } from '../../types/pages/UploadDocumentsPage/types'; +import LloydGeorgeFileInputStage from '../../components/blocks/lloydGeorgeFileInputStage/LloydGeorgeFileInputStage'; type Props = {}; @@ -13,27 +13,28 @@ export enum LG_UPLOAD_STAGE { function LloydGeorgeUploadPage({}: Props) { const [stage, setStage] = useState(LG_UPLOAD_STAGE.SELECT); - const files = [ - buildTextFile('1of3_Lloyd_George_Record_[Barry ONEIL]_[9730182000]_[23-10-2018]', 100), - buildTextFile('2of3_Lloyd_George_Record_[Barry ONEIL]_[9730182000]_[23-10-2018]', 101), - ]; - const documents = files.map((file) => { - return { - ...buildDocument(file, DOCUMENT_UPLOAD_STATE.SUCCEEDED), - progress: 100, - }; - }); + const [documents, setDocuments] = useState>([]); + // const files = [ + // buildTextFile('1of3_Lloyd_George_Record_[Barry ONEIL]_[9730182000]_[23-10-2018]', 100), + // buildTextFile('2of3_Lloyd_George_Record_[Barry ONEIL]_[9730182000]_[23-10-2018]', 101), + // ]; + // const documents = files.map((file) => { + // return { + // ...buildDocument(file, DOCUMENT_UPLOAD_STATE.SUCCEEDED), + // progress: 100, + // }; + // }); switch (stage) { case LG_UPLOAD_STAGE.SELECT: return ( - // TODO, ADD FILE SELECT STAGE -
- -
select files
-
+ ); case LG_UPLOAD_STAGE.UPLOAD: - return ; + return ; case LG_UPLOAD_STAGE.COMPLETE: return ( // TODO, ADD UPLOAD COMPLETE STAGE From f6da6858e33017a81fa2f1ef421b6ad9eaf2c070 Mon Sep 17 00:00:00 2001 From: Rio Knightley Date: Wed, 14 Feb 2024 15:24:14 +0000 Subject: [PATCH 05/15] Add jiggins lane fake pds patient --- .../pds_patient_9000000004_M85143_gp.json | 399 ++++++++++++++++++ lambdas/services/mock_pds_service.py | 2 + 2 files changed, 401 insertions(+) create mode 100644 lambdas/services/mock_data/pds_patient_9000000004_M85143_gp.json diff --git a/lambdas/services/mock_data/pds_patient_9000000004_M85143_gp.json b/lambdas/services/mock_data/pds_patient_9000000004_M85143_gp.json new file mode 100644 index 000000000..3b213b7f6 --- /dev/null +++ b/lambdas/services/mock_data/pds_patient_9000000004_M85143_gp.json @@ -0,0 +1,399 @@ +{ + "resourceType": "Patient", + "id": "9000000004", + "identifier": [ + { + "system": "https://fhir.nhs.uk/Id/nhs-number", + "value": "9000000004", + "extension": [ + { + "url": "https://fhir.hl7.org.uk/StructureDefinition/Extension-UKCore-NHSNumberVerificationStatus", + "valueCodeableConcept": { + "coding": [ + { + "system": "https://fhir.hl7.org.uk/CodeSystem/UKCore-NHSNumberVerificationStatus", + "version": "1.0.0", + "code": "01", + "display": "Number present and verified" + } + ] + } + } + ] + } + ], + "meta": { + "versionId": "2", + "security": [ + { + "system": "http://terminology.hl7.org/CodeSystem/v3-Confidentiality", + "code": "U", + "display": "unrestricted" + } + ] + }, + "name": [ + { + "id": "123", + "use": "usual", + "period": { + "start": "2020-01-01", + "end": "2025-12-31" + }, + "given": ["Jane"], + "family": "Smith", + "prefix": ["Mrs"], + "suffix": ["MBE"] + }, + { + "id": "1234", + "use": "other", + "period": { + "start": "2020-01-01", + "end": "2025-12-31" + }, + "given": ["Jim"], + "family": "Stevens", + "prefix": ["Mr"], + "suffix": ["MBE"] + } + ], + "gender": "female", + "birthDate": "2010-10-22", + "multipleBirthInteger": 1, + "deceasedDateTime": "2010-10-22T00:00:00+00:00", + "generalPractitioner": [ + { + "id": "254406A3", + "type": "Organization", + "identifier": { + "system": "https://fhir.nhs.uk/Id/ods-organization-code", + "value": "M85143", + "period": { + "start": "2020-01-01", + "end": "2025-12-31" + } + } + } + ], + "managingOrganization": { + "type": "Organization", + "identifier": { + "system": "https://fhir.nhs.uk/Id/ods-organization-code", + "value": "M85143", + "period": { + "start": "2020-01-01", + "end": "2025-12-31" + } + } + }, + "extension": [ + { + "url": "https://fhir.hl7.org.uk/StructureDefinition/Extension-UKCore-NominatedPharmacy", + "valueReference": { + "identifier": { + "system": "https://fhir.nhs.uk/Id/ods-organization-code", + "value": "M85143" + } + } + }, + { + "url": "https://fhir.hl7.org.uk/StructureDefinition/Extension-UKCore-PreferredDispenserOrganization", + "valueReference": { + "identifier": { + "system": "https://fhir.nhs.uk/Id/ods-organization-code", + "value": "M85143" + } + } + }, + { + "url": "https://fhir.hl7.org.uk/StructureDefinition/Extension-UKCore-MedicalApplianceSupplier", + "valueReference": { + "identifier": { + "system": "https://fhir.nhs.uk/Id/ods-organization-code", + "value": "M85143" + } + } + }, + { + "url": "https://fhir.hl7.org.uk/StructureDefinition/Extension-UKCore-DeathNotificationStatus", + "extension": [ + { + "url": "deathNotificationStatus", + "valueCodeableConcept": { + "coding": [ + { + "system": "https://fhir.hl7.org.uk/CodeSystem/UKCore-DeathNotificationStatus", + "version": "1.0.0", + "code": "2", + "display": "Formal - death notice received from Registrar of Deaths" + } + ] + } + }, + { + "url": "systemEffectiveDate", + "valueDateTime": "2010-10-22T00:00:00+00:00" + } + ] + }, + { + "url": "https://fhir.hl7.org.uk/StructureDefinition/Extension-UKCore-NHSCommunication", + "extension": [ + { + "url": "language", + "valueCodeableConcept": { + "coding": [ + { + "system": "https://fhir.hl7.org.uk/CodeSystem/UKCore-HumanLanguage", + "version": "1.0.0", + "code": "fr", + "display": "French" + } + ] + } + }, + { + "url": "interpreterRequired", + "valueBoolean": true + } + ] + }, + { + "url": "https://fhir.hl7.org.uk/StructureDefinition/Extension-UKCore-ContactPreference", + "extension": [ + { + "url": "PreferredWrittenCommunicationFormat", + "valueCodeableConcept": { + "coding": [ + { + "system": "https://fhir.hl7.org.uk/CodeSystem/UKCore-PreferredWrittenCommunicationFormat", + "code": "12", + "display": "Braille" + } + ] + } + }, + { + "url": "PreferredContactMethod", + "valueCodeableConcept": { + "coding": [ + { + "system": "https://fhir.hl7.org.uk/CodeSystem/UKCore-PreferredContactMethod", + "code": "1", + "display": "Letter" + } + ] + } + }, + { + "url": "PreferredContactTimes", + "valueString": "Not after 7pm" + } + ] + }, + { + "url": "http://hl7.org/fhir/StructureDefinition/patient-birthPlace", + "valueAddress": { + "city": "Manchester", + "district": "Greater Manchester", + "country": "GBR" + } + }, + { + "url": "https://fhir.nhs.uk/StructureDefinition/Extension-PDS-RemovalFromRegistration", + "extension": [ + { + "url": "removalFromRegistrationCode", + "valueCodeableConcept": { + "coding": [ + { + "system": "https://fhir.nhs.uk/CodeSystem/PDS-RemovalReasonExitCode", + "code": "SCT", + "display": "Transferred to Scotland" + } + ] + } + }, + { + "url": "effectiveTime", + "valuePeriod": { + "start": "2020-01-01T00:00:00+00:00", + "end": "2025-12-31T00:00:00+00:00" + } + } + ] + } + ], + "telecom": [ + { + "id": "789", + "period": { + "start": "2020-01-01", + "end": "2025-12-31" + }, + "system": "phone", + "value": "01632960587", + "use": "home" + }, + { + "id": "790", + "period": { + "start": "2019-01-01", + "end": "2022-12-31" + }, + "system": "email", + "value": "jane.smith@example.com", + "use": "home" + }, + { + "id": "OC789", + "period": { + "start": "2020-01-01", + "end": "2025-12-31" + }, + "system": "other", + "value": "01632960587", + "use": "home", + "extension": [ + { + "url": "https://fhir.hl7.org.uk/StructureDefinition/Extension-UKCore-OtherContactSystem", + "valueCoding": { + "system": "https://fhir.hl7.org.uk/CodeSystem/UKCore-OtherContactSystem", + "code": "textphone", + "display": "Minicom (Textphone)" + } + } + ] + } + ], + "contact": [ + { + "id": "C123", + "period": { + "start": "2020-01-01", + "end": "2025-12-31" + }, + "relationship": [ + { + "coding": [ + { + "system": "http://terminology.hl7.org/CodeSystem/v2-0131", + "code": "C", + "display": "Emergency Contact" + } + ] + } + ], + "telecom": [ + { + "system": "phone", + "value": "01632960587" + } + ] + } + ], + "address": [ + { + "id": "456", + "period": { + "start": "2020-01-01", + "end": "2025-12-31" + }, + "use": "home", + "line": [ + "1 Trevelyan Square", + "Boar Lane", + "City Centre", + "Leeds", + "West Yorkshire" + ], + "postalCode": "LS1 6AE", + "extension": [ + { + "url": "https://fhir.hl7.org.uk/StructureDefinition/Extension-UKCore-AddressKey", + "extension": [ + { + "url": "type", + "valueCoding": { + "system": "https://fhir.hl7.org.uk/CodeSystem/UKCore-AddressKeyType", + "code": "PAF" + } + }, + { + "url": "value", + "valueString": "12345678" + } + ] + }, + { + "url": "https://fhir.hl7.org.uk/StructureDefinition/Extension-UKCore-AddressKey", + "extension": [ + { + "url": "type", + "valueCoding": { + "system": "https://fhir.hl7.org.uk/CodeSystem/UKCore-AddressKeyType", + "code": "UPRN" + } + }, + { + "url": "value", + "valueString": "123456789012" + } + ] + } + ] + }, + { + "id": "T456", + "period": { + "start": "2020-01-01", + "end": "2025-12-31" + }, + "use": "temp", + "text": "Student Accommodation", + "line": [ + "1 Trevelyan Square", + "Boar Lane", + "City Centre", + "Leeds", + "West Yorkshire" + ], + "postalCode": "LS1 6AE", + "extension": [ + { + "url": "https://fhir.hl7.org.uk/StructureDefinition/Extension-UKCore-AddressKey", + "extension": [ + { + "url": "type", + "valueCoding": { + "system": "https://fhir.hl7.org.uk/CodeSystem/UKCore-AddressKeyType", + "code": "PAF" + } + }, + { + "url": "value", + "valueString": "12345678" + } + ] + }, + { + "url": "https://fhir.hl7.org.uk/StructureDefinition/Extension-UKCore-AddressKey", + "extension": [ + { + "url": "type", + "valueCoding": { + "system": "https://fhir.hl7.org.uk/CodeSystem/UKCore-AddressKeyType", + "code": "UPRN" + } + }, + { + "url": "value", + "valueString": "123456789012" + } + ] + } + ] + } + ] +} diff --git a/lambdas/services/mock_pds_service.py b/lambdas/services/mock_pds_service.py index 6cce0e751..202664add 100644 --- a/lambdas/services/mock_pds_service.py +++ b/lambdas/services/mock_pds_service.py @@ -27,6 +27,8 @@ def pds_request(self, nhs_number: str, *args, **kwargs) -> Response: mock_pds_results.append(json.load(f)) with open("services/mock_data/pds_patient_9000000003_H85686_gp.json") as f: mock_pds_results.append(json.load(f)) + with open("services/mock_data/pds_patient_9000000004_M85143_gp.json") as f: + mock_pds_results.append(json.load(f)) with open("services/mock_data/pds_patient_9000000025_restricted.json") as f: mock_pds_results.append(json.load(f)) From 7925e54dddd88567d6dbc44999db24b5358c8f0d Mon Sep 17 00:00:00 2001 From: Rio Knightley Date: Wed, 14 Feb 2024 16:06:41 +0000 Subject: [PATCH 06/15] Add stage complete to upload --- .../lloydGeorgeFileInputStage/LloydGeorgeFileInputStage.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/src/components/blocks/lloydGeorgeFileInputStage/LloydGeorgeFileInputStage.tsx b/app/src/components/blocks/lloydGeorgeFileInputStage/LloydGeorgeFileInputStage.tsx index 4da1b61ea..e6f3c1cfc 100644 --- a/app/src/components/blocks/lloydGeorgeFileInputStage/LloydGeorgeFileInputStage.tsx +++ b/app/src/components/blocks/lloydGeorgeFileInputStage/LloydGeorgeFileInputStage.tsx @@ -2,7 +2,6 @@ import React, { Dispatch, SetStateAction, useRef } from 'react'; import BackButton from '../../../components/generic/backButton/BackButton'; import { formatNhsNumber } from '../../../helpers/utils/formatNhsNumber'; import { getFormattedDate } from '../../../helpers/utils/formatDate'; -import { buildPatientDetails } from '../../../helpers/test/testBuilders'; import { Input, Button, Fieldset, InsetText, Table } from 'nhsuk-react-components'; import { ReactComponent as FileSVG } from '../../../styles/file-input.svg'; import { @@ -18,6 +17,7 @@ import uploadDocument from '../../../helpers/requests/uploadDocument'; import useBaseAPIUrl from '../../../helpers/hooks/useBaseAPIUrl'; import useBaseAPIHeaders from '../../../helpers/hooks/useBaseAPIHeaders'; import { LG_UPLOAD_STAGE } from '../../../pages/lloydGeorgeUploadPage/LloydGeorgeUploadPage'; +import usePatient from '../../../helpers/hooks/usePatient'; type Props = { documents: Array; @@ -26,7 +26,7 @@ type Props = { }; function LloydGeorgeFileInputStage({ documents, setDocuments, setStage }: Props) { - const patientDetails = buildPatientDetails(); + const patientDetails = usePatient(); const nhsNumber: string = patientDetails?.nhsNumber || ''; const formattedNhsNumber = formatNhsNumber(nhsNumber); const dob: String = patientDetails?.birthDate @@ -52,6 +52,7 @@ function LloydGeorgeFileInputStage({ documents, setDocuments, setStage }: Props) baseUrl, baseHeaders, }); + setStage(LG_UPLOAD_STAGE.COMPLETE); } } catch (e) {} }; From 81b3fc181a8eeb5ce1fd1f0f3288ebc54d3f3e77 Mon Sep 17 00:00:00 2001 From: Rio Knightley Date: Wed, 14 Feb 2024 16:08:59 +0000 Subject: [PATCH 07/15] Add lloyd george complete view --- .../LloydGeorgeUploadPage.tsx | 26 +++---------------- 1 file changed, 3 insertions(+), 23 deletions(-) diff --git a/app/src/pages/lloydGeorgeUploadPage/LloydGeorgeUploadPage.tsx b/app/src/pages/lloydGeorgeUploadPage/LloydGeorgeUploadPage.tsx index 0ba88dacb..fe3c7056e 100644 --- a/app/src/pages/lloydGeorgeUploadPage/LloydGeorgeUploadPage.tsx +++ b/app/src/pages/lloydGeorgeUploadPage/LloydGeorgeUploadPage.tsx @@ -2,6 +2,7 @@ import React, { useState } from 'react'; import LloydGeorgeUploadingStage from '../../components/blocks/lloydGeorgeUploadingStage/LloydGeorgeUploadingStage'; import { UploadDocument } from '../../types/pages/UploadDocumentsPage/types'; import LloydGeorgeFileInputStage from '../../components/blocks/lloydGeorgeFileInputStage/LloydGeorgeFileInputStage'; +import LloydGeorgeUploadComplete from '../../components/blocks/lloydGeorgeUploadComplete/LloydGeorgeUploadComplete'; type Props = {}; @@ -14,16 +15,7 @@ export enum LG_UPLOAD_STAGE { function LloydGeorgeUploadPage({}: Props) { const [stage, setStage] = useState(LG_UPLOAD_STAGE.SELECT); const [documents, setDocuments] = useState>([]); - // const files = [ - // buildTextFile('1of3_Lloyd_George_Record_[Barry ONEIL]_[9730182000]_[23-10-2018]', 100), - // buildTextFile('2of3_Lloyd_George_Record_[Barry ONEIL]_[9730182000]_[23-10-2018]', 101), - // ]; - // const documents = files.map((file) => { - // return { - // ...buildDocument(file, DOCUMENT_UPLOAD_STATE.SUCCEEDED), - // progress: 100, - // }; - // }); + switch (stage) { case LG_UPLOAD_STAGE.SELECT: return ( @@ -36,19 +28,7 @@ function LloydGeorgeUploadPage({}: Props) { case LG_UPLOAD_STAGE.UPLOAD: return ; case LG_UPLOAD_STAGE.COMPLETE: - return ( - // TODO, ADD UPLOAD COMPLETE STAGE -
- -
upload complete
-
- ); + return ; default: return null; } From 6d54a3323877ac9e7614683bdc9645042a0c6a8a Mon Sep 17 00:00:00 2001 From: Rio Knightley Date: Wed, 14 Feb 2024 16:57:58 +0000 Subject: [PATCH 08/15] Add lloyd george upload stages --- .../LloydGeorgeFileInputStage.test.tsx} | 107 ++++---- .../LloydGeorgeFileInputStage.tsx | 2 +- .../UploadLloydGeorgeRecordPage.tsx | 235 ------------------ 3 files changed, 65 insertions(+), 279 deletions(-) rename app/src/{pages/uploadLloydGeorgeRecordPage/UploadLloydGeorgeRecordPage.test.tsx => components/blocks/lloydGeorgeFileInputStage/LloydGeorgeFileInputStage.test.tsx} (87%) delete mode 100644 app/src/pages/uploadLloydGeorgeRecordPage/UploadLloydGeorgeRecordPage.tsx diff --git a/app/src/pages/uploadLloydGeorgeRecordPage/UploadLloydGeorgeRecordPage.test.tsx b/app/src/components/blocks/lloydGeorgeFileInputStage/LloydGeorgeFileInputStage.test.tsx similarity index 87% rename from app/src/pages/uploadLloydGeorgeRecordPage/UploadLloydGeorgeRecordPage.test.tsx rename to app/src/components/blocks/lloydGeorgeFileInputStage/LloydGeorgeFileInputStage.test.tsx index e1a65339e..c7dd7526b 100644 --- a/app/src/pages/uploadLloydGeorgeRecordPage/UploadLloydGeorgeRecordPage.test.tsx +++ b/app/src/components/blocks/lloydGeorgeFileInputStage/LloydGeorgeFileInputStage.test.tsx @@ -1,25 +1,38 @@ import { fireEvent, render, screen } from '@testing-library/react'; -import { buildPatientDetails, buildLgFile } from '../../helpers/test/testBuilders'; -import { DOCUMENT_UPLOAD_STATE as documentUploadStates } from '../../types/pages/UploadDocumentsPage/types'; -import { PatientDetails } from '../../types/generic/patientDetails'; -import usePatient from '../../helpers/hooks/usePatient'; -import UploadLloydGeorgeRecordPage from './UploadLloydGeorgeRecordPage'; -import { formatNhsNumber } from '../../helpers/utils/formatNhsNumber'; +import { + buildPatientDetails, + buildLgFile, + buildDocument, +} from '../../../helpers/test/testBuilders'; +import usePatient from '../../../helpers/hooks/usePatient'; +import { formatNhsNumber } from '../../../helpers/utils/formatNhsNumber'; import { act } from 'react-dom/test-utils'; import userEvent from '@testing-library/user-event'; - -jest.mock('../../helpers/utils/toFileList', () => ({ +import LloydGeorgeFileInputStage, { Props } from './LloydGeorgeFileInputStage'; +import { + DOCUMENT_UPLOAD_STATE, + UploadDocument, +} from '../../../types/pages/UploadDocumentsPage/types'; +import { useState } from 'react'; + +jest.mock('../../../helpers/utils/toFileList', () => ({ __esModule: true, default: () => [], })); -jest.mock('../../helpers/hooks/usePatient'); +jest.mock('../../../helpers/hooks/usePatient'); jest.mock('react-router'); -jest.mock('../../helpers/hooks/useBaseAPIHeaders'); - +jest.mock('../../../helpers/hooks/useBaseAPIHeaders'); +const setStageMock = jest.fn(); const mockedUsePatient = usePatient as jest.Mock; const mockPatient = buildPatientDetails(); - -describe('', () => { +const lgDocumentOne = buildLgFile(1, 2); +const lgDocumentTwo = buildLgFile(2, 2); +const lgFiles = [lgDocumentOne, lgDocumentTwo]; +const uploadFiles = [ + buildDocument(lgDocumentOne, DOCUMENT_UPLOAD_STATE.UPLOADING), + buildDocument(lgDocumentTwo, DOCUMENT_UPLOAD_STATE.UPLOADING), +]; +describe('', () => { beforeEach(() => { process.env.REACT_APP_ENVIRONMENT = 'jest'; mockedUsePatient.mockReturnValue(mockPatient); @@ -29,25 +42,14 @@ describe('', () => { }); describe('upload documents with an NHS number', () => { - const lgDocumentOne = buildLgFile(1, 2); - const lgDocumentTwo = buildLgFile(2, 2); - const lgFiles = [lgDocumentOne, lgDocumentTwo]; - const setDocumentMock = jest.fn(); - setDocumentMock.mockImplementation((document) => { - document.state = documentUploadStates.SELECTED; - document.id = '1'; - }); - - const mockPatientDetails: PatientDetails = buildPatientDetails(); - it('renders the page', async () => { - render(); + renderApp(); expect( screen.getByRole('heading', { name: 'Upload a Lloyd George record' }), ).toBeInTheDocument(); expect( - screen.getByText('NHS number: ' + formatNhsNumber(mockPatientDetails.nhsNumber)), + screen.getByText('NHS number: ' + formatNhsNumber(mockPatient.nhsNumber)), ).toBeInTheDocument(); expect(screen.getByRole('button', { name: 'Select files' })).toBeInTheDocument(); @@ -57,13 +59,13 @@ describe('', () => { }); it('can upload documents to LG forms using button', async () => { - render(); + renderApp(); expect( screen.getByRole('heading', { name: 'Upload a Lloyd George record' }), ).toBeInTheDocument(); expect( - screen.getByText('NHS number: ' + formatNhsNumber(mockPatientDetails.nhsNumber)), + screen.getByText('NHS number: ' + formatNhsNumber(mockPatient.nhsNumber)), ).toBeInTheDocument(); expect(screen.getByRole('button', { name: 'Upload' })).toBeInTheDocument(); @@ -78,15 +80,17 @@ describe('', () => { expect(screen.getByRole('button', { name: 'Upload' })).toBeEnabled(); }); + it('can upload documents to LG forms using drag and drop when dataTransfer type is files', async () => { - render(); + renderApp(); + const dropzone = screen.getByTestId('dropzone'); expect( screen.getByRole('heading', { name: 'Upload a Lloyd George record' }), ).toBeInTheDocument(); expect( - screen.getByText('NHS number: ' + formatNhsNumber(mockPatientDetails.nhsNumber)), + screen.getByText('NHS number: ' + formatNhsNumber(mockPatient.nhsNumber)), ).toBeInTheDocument(); expect(screen.getByRole('button', { name: 'Upload' })).toBeInTheDocument(); @@ -103,14 +107,14 @@ describe('', () => { expect(screen.getByRole('button', { name: 'Upload' })).toBeEnabled(); }); it('can upload documents to LG forms using drag and drop when dataTransfer type is items', async () => { - render(); + renderApp(); const dropzone = screen.getByTestId('dropzone'); expect( screen.getByRole('heading', { name: 'Upload a Lloyd George record' }), ).toBeInTheDocument(); expect( - screen.getByText('NHS number: ' + formatNhsNumber(mockPatientDetails.nhsNumber)), + screen.getByText('NHS number: ' + formatNhsNumber(mockPatient.nhsNumber)), ).toBeInTheDocument(); expect(screen.getByRole('button', { name: 'Upload' })).toBeInTheDocument(); @@ -134,7 +138,7 @@ describe('', () => { expect(screen.getByRole('button', { name: 'Upload' })).toBeEnabled(); }); it('can upload documents to LG forms using drag and drop and button', async () => { - render(); + renderApp(); const dropzone = screen.getByTestId('dropzone'); expect( @@ -157,7 +161,7 @@ describe('', () => { expect(screen.getByRole('button', { name: 'Upload' })).toBeEnabled(); }); it('does upload and then remove a file', async () => { - render(); + renderApp(); act(() => { userEvent.upload(screen.getByTestId('button-input'), lgFiles); @@ -177,7 +181,7 @@ describe('', () => { expect(screen.getByText(lgDocumentTwo.name)).toBeInTheDocument(); }); it('does upload and then remove all a files', async () => { - render(); + renderApp(); act(() => { userEvent.upload(screen.getByTestId('button-input'), lgFiles); @@ -198,7 +202,7 @@ describe('', () => { expect(screen.queryByText(lgDocumentTwo.name)).not.toBeInTheDocument(); }); it('does not upload either forms if selected file is more than 5GB', async () => { - render(); + renderApp(); const documentBig = buildLgFile(3, 2, 6 * Math.pow(1024, 3)); @@ -218,7 +222,7 @@ describe('', () => { }); it('does not upload LG form if selected file is not PDF', async () => { - render(); + renderApp(); const lgFileWithBadType = new File( ['test'], @@ -246,7 +250,7 @@ describe('', () => { }); it('does not upload LG form if total number of file does not match file name', async () => { - render(); + renderApp(); const lgExtraFile = buildLgFile(3, 3); @@ -268,7 +272,7 @@ describe('', () => { }); it('does not upload LG form if selected file does not match naming conventions', async () => { - render(); + renderApp(); const pdfFileWithBadName = new File(['test'], `test_not_up_to_naming_conventions.pdf`, { type: 'application/pdf', @@ -291,7 +295,7 @@ describe('', () => { }); it('does not upload LG form if selected file number is bigger than number of total files', async () => { - render(); + renderApp(); const pdfFileWithBadNumber = buildLgFile(2, 1); act(() => { @@ -312,7 +316,7 @@ describe('', () => { }); it('does not upload LG form if files do not match each other', async () => { - render(); + renderApp(); const joeBloggsFile = new File( ['test'], @@ -351,7 +355,7 @@ describe('', () => { it('does not upload LG form if two or more files match name/size', async () => { const duplicateFileWarning = 'There are two or more documents with the same name.'; - render(); + renderApp(); act(() => { userEvent.upload(screen.getByTestId(`button-input`), [ @@ -375,7 +379,7 @@ describe('', () => { }); it("does allow the user to add the same file again if they remove for '%s' input", async () => { - render(); + renderApp(); act(() => { userEvent.upload(screen.getByTestId(`button-input`), [ @@ -398,4 +402,21 @@ describe('', () => { expect(await screen.findByText(lgDocumentOne.name)).toBeInTheDocument(); }); }); + + const TestApp = (props: Partial) => { + const [documents, setDocuments] = useState>([]); + + return ( + + ); + }; + + const renderApp = (props?: Partial) => { + render(); + }; }); diff --git a/app/src/components/blocks/lloydGeorgeFileInputStage/LloydGeorgeFileInputStage.tsx b/app/src/components/blocks/lloydGeorgeFileInputStage/LloydGeorgeFileInputStage.tsx index e6f3c1cfc..c081fa6a9 100644 --- a/app/src/components/blocks/lloydGeorgeFileInputStage/LloydGeorgeFileInputStage.tsx +++ b/app/src/components/blocks/lloydGeorgeFileInputStage/LloydGeorgeFileInputStage.tsx @@ -19,7 +19,7 @@ import useBaseAPIHeaders from '../../../helpers/hooks/useBaseAPIHeaders'; import { LG_UPLOAD_STAGE } from '../../../pages/lloydGeorgeUploadPage/LloydGeorgeUploadPage'; import usePatient from '../../../helpers/hooks/usePatient'; -type Props = { +export type Props = { documents: Array; setDocuments: Dispatch>>; setStage: Dispatch>; diff --git a/app/src/pages/uploadLloydGeorgeRecordPage/UploadLloydGeorgeRecordPage.tsx b/app/src/pages/uploadLloydGeorgeRecordPage/UploadLloydGeorgeRecordPage.tsx deleted file mode 100644 index 8d7392a69..000000000 --- a/app/src/pages/uploadLloydGeorgeRecordPage/UploadLloydGeorgeRecordPage.tsx +++ /dev/null @@ -1,235 +0,0 @@ -import React, { useRef, useState } from 'react'; -import BackButton from '../../components/generic/backButton/BackButton'; -import { formatNhsNumber } from '../../helpers/utils/formatNhsNumber'; -import { getFormattedDate } from '../../helpers/utils/formatDate'; -import { buildPatientDetails } from '../../helpers/test/testBuilders'; -import { Input, Button, Fieldset, InsetText, Table } from 'nhsuk-react-components'; -import { ReactComponent as FileSVG } from '../../styles/file-input.svg'; -import { - DOCUMENT_TYPE, - DOCUMENT_UPLOAD_STATE, - FileInputEvent, - UploadDocument, -} from '../../types/pages/UploadDocumentsPage/types'; -import { useController, useForm } from 'react-hook-form'; -import formatFileSize from '../../helpers/utils/formatFileSize'; -import { lloydGeorgeFormConfig } from '../../helpers/utils/formConfig'; -import uploadDocument from '../../helpers/requests/uploadDocument'; -import useBaseAPIUrl from '../../helpers/hooks/useBaseAPIUrl'; -import useBaseAPIHeaders from '../../helpers/hooks/useBaseAPIHeaders'; - -function UploadLloydGeorgeRecordPage() { - const patientDetails = buildPatientDetails(); - const nhsNumber: string = patientDetails?.nhsNumber || ''; - const formattedNhsNumber = formatNhsNumber(nhsNumber); - const dob: String = patientDetails?.birthDate - ? getFormattedDate(new Date(patientDetails.birthDate)) - : ''; - let fileInputRef = useRef(null); - const [lgDocuments, setLgDocuments] = useState>([]); - - const { handleSubmit, control, formState } = useForm(); - const lgController = useController(lloydGeorgeFormConfig(control)); - - const hasFileInput = lgDocuments.length; - const baseUrl = useBaseAPIUrl(); - const baseHeaders = useBaseAPIHeaders(); - - const uploadDocuments = async () => { - if (patientDetails) { - await uploadDocument({ - nhsNumber: patientDetails.nhsNumber, - setDocuments: setLgDocuments, - documents: lgDocuments, - baseUrl, - baseHeaders, - }); - } - }; - const updateFileList = (fileArray: File[]) => { - const documentMap: Array = fileArray.map((file) => ({ - id: Math.floor(Math.random() * 1000000).toString(), - file, - state: DOCUMENT_UPLOAD_STATE.SELECTED, - progress: 0, - docType: DOCUMENT_TYPE.LLOYD_GEORGE, - })); - const updatedDocList = [...documentMap, ...lgDocuments]; - setLgDocuments(updatedDocList); - lgController.field.onChange(updatedDocList); - }; - const onFileDrop = (e: React.DragEvent) => { - e.preventDefault(); - e.stopPropagation(); - let fileArray: File[] = []; - if (e.dataTransfer.items) { - [...e.dataTransfer.items].forEach((item) => { - const file = item.getAsFile(); - - if (item.kind === 'file' && file) { - fileArray.push(file); - } - }); - } else if (e.dataTransfer.files) { - fileArray = [...e.dataTransfer.files]; - } - if (fileArray) { - updateFileList(fileArray); - } - }; - const onInput = (e: FileInputEvent) => { - const fileArray = Array.from(e.target.files ?? new FileList()); - updateFileList(fileArray); - }; - const onRemove = (index: number) => { - let updatedDocList: UploadDocument[] = []; - if (index >= 0) { - updatedDocList = [...lgDocuments.slice(0, index), ...lgDocuments.slice(index + 1)]; - } - setLgDocuments(updatedDocList); - lgController.field.onChange(updatedDocList); - }; - - return ( -
-
- -

Upload a Lloyd George record

-
-

- {`${patientDetails?.givenName} ${patientDetails?.familyName}`} -

-

NHS number: {formattedNhsNumber}

-

Date of birth: {dob}

-
-
-

Before you upload a Lloyd George patient record:

-
    -
  • The patient details must match the record you are uploading
  • -
  • The patient record must be in a PDF file or multiple PDFs
  • -
  • Your PDF file(s) should be named in this format:
  • -

    - [PDFnumber]_Lloyd_George_Record_[Patient Name]_[NHS Number]_[D.O.B].PDF -

    -
- -

For example:

-

1of2_Lloyd_George_Record_[Joe Bloggs]_[1234567890]_[25-12-2019].PDF

-

2of2_Lloyd_George_Record_[Joe Bloggs]_[1234567890]_[25-12-2019].PDF

-
-

-

- It's recommended to upload the entire record in one go, as each file will be - combined together based on the file names. -

-

You will not be able to view a partially uploaded record.

-
- Select the files you wish to upload -
-
{ - e.preventDefault(); - }} - onDrop={onFileDrop} - className={'lloydgeorge_drag-and-drop'} - > - - Drag and drop a file or multiple files here - -
- -
-
- { - onInput(e); - e.target.value = ''; - }} - onBlur={lgController.field.onBlur} - // @ts-ignore The NHS Component library is outdated and does not allow for any reference other than a blank MutableRefObject - inputRef={(e: HTMLInputElement) => { - lgController.field.ref(e); - fileInputRef.current = e; - }} - /> - -
-
-
- {lgDocuments && lgDocuments.length > 0 && ( - - - - Filename - Size - Remove - - - - - {lgDocuments.map((document: UploadDocument, index: number) => ( - - {document.file.name} - {formatFileSize(document.file.size)} - - - - - ))} - -
- )} -
- - -
- -
- ); -} - -export default UploadLloydGeorgeRecordPage; From 8c91a5e3bfdf97e81636ac6ae9cad4c509a04fb4 Mon Sep 17 00:00:00 2001 From: Rio Knightley Date: Thu, 15 Feb 2024 12:19:06 +0000 Subject: [PATCH 09/15] Fix sonarcloud issue --- .../DocumentSearchResultsOptions.tsx | 8 +- .../blocks/_arf/selectStage/SelectStage.tsx | 82 +++++++++---------- .../_arf/uploadSummary/UploadSummary.tsx | 74 ++++++++--------- .../_arf/uploadingStage/UploadingStage.tsx | 6 +- .../DeleteDocumentsStage.tsx | 4 +- .../LloydGeorgeFileInputStage.tsx | 3 +- .../LloydGeorgeRecordStage.tsx | 2 +- .../LloydGeorgeUploadingStage.tsx | 6 +- .../LloydGeorgeUploadPage.tsx | 2 +- .../PatientResultPage.test.tsx | 2 +- .../patientResultPage/PatientResultPage.tsx | 3 +- 11 files changed, 93 insertions(+), 99 deletions(-) diff --git a/app/src/components/blocks/_arf/documentSearchResultsOptions/DocumentSearchResultsOptions.tsx b/app/src/components/blocks/_arf/documentSearchResultsOptions/DocumentSearchResultsOptions.tsx index 4f60e49ae..ceb278d2d 100644 --- a/app/src/components/blocks/_arf/documentSearchResultsOptions/DocumentSearchResultsOptions.tsx +++ b/app/src/components/blocks/_arf/documentSearchResultsOptions/DocumentSearchResultsOptions.tsx @@ -1,4 +1,4 @@ -import { Button, ButtonLink } from 'nhsuk-react-components'; +import { Button } from 'nhsuk-react-components'; import SpinnerButton from '../../../generic/spinnerButton/SpinnerButton'; import { routes } from '../../../../types/generic/routes'; import { SUBMISSION_STATE } from '../../../../types/pages/documentSearchResultsPage/types'; @@ -15,7 +15,6 @@ type Props = { nhsNumber: string; downloadState: string; updateDownloadState: (newState: SUBMISSION_STATE) => void; - numberOfFiles: number; setIsDeletingDocuments: Dispatch>; }; @@ -97,15 +96,14 @@ const DocumentSearchResultsOptions = (props: Props) => { > Download Manifest URL - Delete All Documents - + {props.downloadState === SUBMISSION_STATE.SUCCEEDED && (

diff --git a/app/src/components/blocks/_arf/selectStage/SelectStage.tsx b/app/src/components/blocks/_arf/selectStage/SelectStage.tsx index 2e1618f61..f2ccff971 100644 --- a/app/src/components/blocks/_arf/selectStage/SelectStage.tsx +++ b/app/src/components/blocks/_arf/selectStage/SelectStage.tsx @@ -81,49 +81,47 @@ function SelectStage({ uploadDocuments, setDocuments }: Props) { }; return ( - <> -

- - Upload documents - - + + + Upload documents + + -
-

Electronic health records

- -
-
-

Lloyd George records

- -
- - - +
+

Electronic health records

+ +
+
+

Lloyd George records

+ +
+ + ); } diff --git a/app/src/components/blocks/_arf/uploadSummary/UploadSummary.tsx b/app/src/components/blocks/_arf/uploadSummary/UploadSummary.tsx index 71de2a4fc..092aeeefa 100644 --- a/app/src/components/blocks/_arf/uploadSummary/UploadSummary.tsx +++ b/app/src/components/blocks/_arf/uploadSummary/UploadSummary.tsx @@ -75,45 +75,43 @@ const UploadSummary = ({ documents }: Props) => { )} {successfulUploads.length > 0 && ( - <> -
- + + View successfully uploaded documents + + + - View successfully uploaded documents - - -
- - - File Name - File Size - - - - {successfulUploads.map((document) => { - return ( - - {document.file.name} - - {formatFileSize(document.file.size)} - - - ); - })} - -
-
-
- + + + File Name + File Size + + + + {successfulUploads.map((document) => { + return ( + + {document.file.name} + + {formatFileSize(document.file.size)} + + + ); + })} + + + + )} diff --git a/app/src/components/blocks/_arf/uploadingStage/UploadingStage.tsx b/app/src/components/blocks/_arf/uploadingStage/UploadingStage.tsx index a9d37ba9c..3c158946d 100644 --- a/app/src/components/blocks/_arf/uploadingStage/UploadingStage.tsx +++ b/app/src/components/blocks/_arf/uploadingStage/UploadingStage.tsx @@ -32,7 +32,7 @@ function UploadingStage({ documents }: Props) { className: 'nhsuk-u-visually-hidden', }} > - + File Name File Size @@ -50,13 +50,13 @@ function UploadingStage({ documents }: Props) { max="100" value={document.progress} > -

+ {document.state === DOCUMENT_UPLOAD_STATE.UPLOADING ? ( <> {Math.round(document.progress)}% uploaded... ) : ( <>{getUploadMessage(document.state)} )} -

+
))} diff --git a/app/src/components/blocks/deleteDocumentsStage/DeleteDocumentsStage.tsx b/app/src/components/blocks/deleteDocumentsStage/DeleteDocumentsStage.tsx index f3a1da7b8..3726968e0 100644 --- a/app/src/components/blocks/deleteDocumentsStage/DeleteDocumentsStage.tsx +++ b/app/src/components/blocks/deleteDocumentsStage/DeleteDocumentsStage.tsx @@ -52,10 +52,10 @@ function DeleteDocumentsStage({ const baseHeaders = useBaseAPIHeaders(); const navigate = useNavigate(); const featureFlags = useFeatureFlags(); - const nhsNumber: string = patientDetails?.nhsNumber || ''; + const nhsNumber: string = patientDetails?.nhsNumber ?? ''; const formattedNhsNumber = formatNhsNumber(nhsNumber); - const dob: String = patientDetails?.birthDate + const dob: string = patientDetails?.birthDate ? getFormattedDate(new Date(patientDetails.birthDate)) : ''; diff --git a/app/src/components/blocks/lloydGeorgeFileInputStage/LloydGeorgeFileInputStage.tsx b/app/src/components/blocks/lloydGeorgeFileInputStage/LloydGeorgeFileInputStage.tsx index c081fa6a9..35475616b 100644 --- a/app/src/components/blocks/lloydGeorgeFileInputStage/LloydGeorgeFileInputStage.tsx +++ b/app/src/components/blocks/lloydGeorgeFileInputStage/LloydGeorgeFileInputStage.tsx @@ -29,7 +29,7 @@ function LloydGeorgeFileInputStage({ documents, setDocuments, setStage }: Props) const patientDetails = usePatient(); const nhsNumber: string = patientDetails?.nhsNumber || ''; const formattedNhsNumber = formatNhsNumber(nhsNumber); - const dob: String = patientDetails?.birthDate + const dob: string = patientDetails?.birthDate ? getFormattedDate(new Date(patientDetails.birthDate)) : ''; let fileInputRef = useRef(null); @@ -141,6 +141,7 @@ function LloydGeorgeFileInputStage({ documents, setDocuments, setStage }: Props) Select the files you wish to upload
{ e.preventDefault(); diff --git a/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx b/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx index 05ffd5bb2..b0a22c15e 100644 --- a/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx +++ b/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx @@ -49,7 +49,7 @@ function LloydGeorgeRecordStage({ const [fullScreen, setFullScreen] = useState(false); const [downloadRemoveButtonClicked, setDownloadRemoveButtonClicked] = useState(false); const patientDetails = usePatient(); - const dob: String = patientDetails?.birthDate + const dob: string = patientDetails?.birthDate ? getFormattedDate(new Date(patientDetails.birthDate)) : ''; diff --git a/app/src/components/blocks/lloydGeorgeUploadingStage/LloydGeorgeUploadingStage.tsx b/app/src/components/blocks/lloydGeorgeUploadingStage/LloydGeorgeUploadingStage.tsx index 6af717d8a..e21966d70 100644 --- a/app/src/components/blocks/lloydGeorgeUploadingStage/LloydGeorgeUploadingStage.tsx +++ b/app/src/components/blocks/lloydGeorgeUploadingStage/LloydGeorgeUploadingStage.tsx @@ -44,7 +44,7 @@ function LloydGeorgeUploadStage({ documents, setStage }: Props) { className: 'nhsuk-u-visually-hidden', }} > - + Filename Size @@ -64,9 +64,9 @@ function LloydGeorgeUploadStage({ documents, setStage }: Props) { max="100" value={document.progress} > -

+ {getUploadMessage(document)} -

+
))} diff --git a/app/src/pages/lloydGeorgeUploadPage/LloydGeorgeUploadPage.tsx b/app/src/pages/lloydGeorgeUploadPage/LloydGeorgeUploadPage.tsx index fe3c7056e..696ffa695 100644 --- a/app/src/pages/lloydGeorgeUploadPage/LloydGeorgeUploadPage.tsx +++ b/app/src/pages/lloydGeorgeUploadPage/LloydGeorgeUploadPage.tsx @@ -30,7 +30,7 @@ function LloydGeorgeUploadPage({}: Props) { case LG_UPLOAD_STAGE.COMPLETE: return ; default: - return null; + return
; } } diff --git a/app/src/pages/patientResultPage/PatientResultPage.test.tsx b/app/src/pages/patientResultPage/PatientResultPage.test.tsx index 1ab77b15a..2e05e77fe 100644 --- a/app/src/pages/patientResultPage/PatientResultPage.test.tsx +++ b/app/src/pages/patientResultPage/PatientResultPage.test.tsx @@ -195,7 +195,7 @@ describe('PatientResultPage', () => { }); await waitFor(() => { - expect(mockedUseNavigate).toHaveBeenCalledWith(routes.ARF_UPLOAD_DOCUMENTS); + expect(mockedUseNavigate).toHaveBeenCalledWith(routes.LLOYD_GEORGE_UPLOAD); }); }, ); diff --git a/app/src/pages/patientResultPage/PatientResultPage.tsx b/app/src/pages/patientResultPage/PatientResultPage.tsx index b699a4568..aec7db5eb 100644 --- a/app/src/pages/patientResultPage/PatientResultPage.tsx +++ b/app/src/pages/patientResultPage/PatientResultPage.tsx @@ -30,8 +30,7 @@ function PatientResultPage() { if (patientDetails?.active) { navigate(routes.LLOYD_GEORGE); } else { - // TODO: What do we use to decide ARF route or LG route ? - navigate(routes.ARF_UPLOAD_DOCUMENTS); + navigate(routes.LLOYD_GEORGE_UPLOAD); } } From 9a8d7ef56ee4cb54be192237be54f795c362d9b8 Mon Sep 17 00:00:00 2001 From: Rio Knightley Date: Thu, 15 Feb 2024 13:43:30 +0000 Subject: [PATCH 10/15] Fix remaining sonarcloud issues --- .../documentInputForm/DocumentInputForm.tsx | 4 +- .../DocumentSearchResults.tsx | 64 +++++++++---------- .../DocumentSearchResultsOptions.test.tsx | 1 - .../DeletionConfirmationStage.tsx | 2 +- .../LloydGeorgeFileInputStage.tsx | 3 +- .../LloydGeorgeRecordStage.tsx | 2 +- .../reducedPatientInfo/ReducedPatientInfo.tsx | 2 +- .../DocumentSearchResultsPage.tsx | 3 +- .../LloydGeorgeRecordPage.tsx | 2 +- .../LloydGeorgeUploadPage.tsx | 4 +- .../patientProvider/PatientProvider.test.tsx | 2 +- 11 files changed, 41 insertions(+), 48 deletions(-) diff --git a/app/src/components/blocks/_arf/documentInputForm/DocumentInputForm.tsx b/app/src/components/blocks/_arf/documentInputForm/DocumentInputForm.tsx index f837869ea..b72c462e2 100644 --- a/app/src/components/blocks/_arf/documentInputForm/DocumentInputForm.tsx +++ b/app/src/components/blocks/_arf/documentInputForm/DocumentInputForm.tsx @@ -72,7 +72,7 @@ const DocumentInputForm = ({ > Primary Care Support England - . + {'.'} )} {formType === DOCUMENT_TYPE.LLOYD_GEORGE && ( @@ -89,7 +89,7 @@ const DocumentInputForm = ({ } /> -
+
{documents && documents.length > 0 && ( diff --git a/app/src/components/blocks/_arf/documentSearchResults/DocumentSearchResults.tsx b/app/src/components/blocks/_arf/documentSearchResults/DocumentSearchResults.tsx index a1a683040..e1787310a 100644 --- a/app/src/components/blocks/_arf/documentSearchResults/DocumentSearchResults.tsx +++ b/app/src/components/blocks/_arf/documentSearchResults/DocumentSearchResults.tsx @@ -1,6 +1,5 @@ import { Table } from 'nhsuk-react-components'; import { SearchResult } from '../../../../types/generic/searchResult'; -import { useState } from 'react'; import { getFormattedDatetime } from '../../../../helpers/utils/formatDatetime'; type Props = { @@ -12,42 +11,39 @@ const DocumentSearchResults = (props: Props) => { new Date(a.created) < new Date(b.created) ? 1 : -1; const orderedResults = props.searchResults.sort(sortMethod); - const [searchResults, ,] = useState(orderedResults); const tableCaption =

List of documents available

; return ( - <> -
- - - Filename - Uploaded At - - - - {searchResults.map((result, index) => ( - + + + Filename + Uploaded At + + + + {orderedResults.map((result, index) => ( + + + {result.fileName} + + - - {result.fileName} - - - {getFormattedDatetime(new Date(result.created))} - - - ))} - -
- + {getFormattedDatetime(new Date(result.created))} + + + ))} + + ); }; diff --git a/app/src/components/blocks/_arf/documentSearchResultsOptions/DocumentSearchResultsOptions.test.tsx b/app/src/components/blocks/_arf/documentSearchResultsOptions/DocumentSearchResultsOptions.test.tsx index fc30f0b93..96d2f8491 100644 --- a/app/src/components/blocks/_arf/documentSearchResultsOptions/DocumentSearchResultsOptions.test.tsx +++ b/app/src/components/blocks/_arf/documentSearchResultsOptions/DocumentSearchResultsOptions.test.tsx @@ -186,7 +186,6 @@ const renderDocumentSearchResultsOptions = (downloadState: SUBMISSION_STATE) => nhsNumber={patient.nhsNumber} downloadState={downloadState} updateDownloadState={updateDownloadState} - numberOfFiles={7} setIsDeletingDocuments={mockSetIsDeletingDocuments} />, ); diff --git a/app/src/components/blocks/deletionConfirmationStage/DeletionConfirmationStage.tsx b/app/src/components/blocks/deletionConfirmationStage/DeletionConfirmationStage.tsx index ef747a152..039ff466f 100644 --- a/app/src/components/blocks/deletionConfirmationStage/DeletionConfirmationStage.tsx +++ b/app/src/components/blocks/deletionConfirmationStage/DeletionConfirmationStage.tsx @@ -19,7 +19,7 @@ export type Props = { function DeletionConfirmationStage({ numberOfFiles, setStage, setDownloadStage }: Props) { const navigate = useNavigate(); const patientDetails = usePatient(); - const nhsNumber: string = patientDetails?.nhsNumber || ''; + const nhsNumber: string = patientDetails?.nhsNumber ?? ''; const formattedNhsNumber = formatNhsNumber(nhsNumber); const role = useRole(); const handleClick = () => { diff --git a/app/src/components/blocks/lloydGeorgeFileInputStage/LloydGeorgeFileInputStage.tsx b/app/src/components/blocks/lloydGeorgeFileInputStage/LloydGeorgeFileInputStage.tsx index 35475616b..42635a152 100644 --- a/app/src/components/blocks/lloydGeorgeFileInputStage/LloydGeorgeFileInputStage.tsx +++ b/app/src/components/blocks/lloydGeorgeFileInputStage/LloydGeorgeFileInputStage.tsx @@ -27,7 +27,7 @@ export type Props = { function LloydGeorgeFileInputStage({ documents, setDocuments, setStage }: Props) { const patientDetails = usePatient(); - const nhsNumber: string = patientDetails?.nhsNumber || ''; + const nhsNumber: string = patientDetails?.nhsNumber ?? ''; const formattedNhsNumber = formatNhsNumber(nhsNumber); const dob: string = patientDetails?.birthDate ? getFormattedDate(new Date(patientDetails.birthDate)) @@ -142,6 +142,7 @@ function LloydGeorgeFileInputStage({ documents, setDocuments, setStage }: Props)
{ e.preventDefault(); diff --git a/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx b/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx index b0a22c15e..e45084071 100644 --- a/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx +++ b/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx @@ -60,7 +60,7 @@ function LloydGeorgeRecordStage({ required: true, }); - const nhsNumber: string = patientDetails?.nhsNumber || ''; + const nhsNumber: string = patientDetails?.nhsNumber ?? ''; const formattedNhsNumber = formatNhsNumber(nhsNumber); const role = useRole(); diff --git a/app/src/components/generic/reducedPatientInfo/ReducedPatientInfo.tsx b/app/src/components/generic/reducedPatientInfo/ReducedPatientInfo.tsx index 318e84bf2..f8f6ecabd 100644 --- a/app/src/components/generic/reducedPatientInfo/ReducedPatientInfo.tsx +++ b/app/src/components/generic/reducedPatientInfo/ReducedPatientInfo.tsx @@ -8,7 +8,7 @@ interface Props { const ReducedPatientInfo = ({ className }: Props) => { const patientDetails = usePatient(); - const nhsNumber: string = patientDetails?.nhsNumber || ''; + const nhsNumber: string = patientDetails?.nhsNumber ?? ''; const formattedNhsNumber = formatNhsNumber(nhsNumber); return ( diff --git a/app/src/pages/documentSearchResultsPage/DocumentSearchResultsPage.tsx b/app/src/pages/documentSearchResultsPage/DocumentSearchResultsPage.tsx index 918892c77..25c548ca4 100644 --- a/app/src/pages/documentSearchResultsPage/DocumentSearchResultsPage.tsx +++ b/app/src/pages/documentSearchResultsPage/DocumentSearchResultsPage.tsx @@ -22,7 +22,7 @@ import { errorToParams } from '../../helpers/utils/errorToParams'; function DocumentSearchResultsPage() { const patientDetails = usePatient(); - const nhsNumber: string = patientDetails?.nhsNumber || ''; + const nhsNumber: string = patientDetails?.nhsNumber ?? ''; const [searchResults, setSearchResults] = useState>([]); const [submissionState, setSubmissionState] = useState(SUBMISSION_STATE.INITIAL); const [downloadState, setDownloadState] = useState(SUBMISSION_STATE.INITIAL); @@ -98,7 +98,6 @@ function DocumentSearchResultsPage() { nhsNumber={nhsNumber} downloadState={downloadState} updateDownloadState={handleUpdateDownloadState} - numberOfFiles={searchResults.length} setIsDeletingDocuments={setIsDeletingDocuments} /> diff --git a/app/src/pages/lloydGeorgeRecordPage/LloydGeorgeRecordPage.tsx b/app/src/pages/lloydGeorgeRecordPage/LloydGeorgeRecordPage.tsx index 576cfe0cb..ec73e3b76 100644 --- a/app/src/pages/lloydGeorgeRecordPage/LloydGeorgeRecordPage.tsx +++ b/app/src/pages/lloydGeorgeRecordPage/LloydGeorgeRecordPage.tsx @@ -54,7 +54,7 @@ function LloydGeorgeRecordPage() { }; const onPageLoad = async () => { - const nhsNumber: string = patientDetails?.nhsNumber || ''; + const nhsNumber: string = patientDetails?.nhsNumber ?? ''; try { const { number_of_files, total_file_size_in_byte, last_updated, presign_url } = await getLloydGeorgeRecord({ diff --git a/app/src/pages/lloydGeorgeUploadPage/LloydGeorgeUploadPage.tsx b/app/src/pages/lloydGeorgeUploadPage/LloydGeorgeUploadPage.tsx index 696ffa695..66a901d1e 100644 --- a/app/src/pages/lloydGeorgeUploadPage/LloydGeorgeUploadPage.tsx +++ b/app/src/pages/lloydGeorgeUploadPage/LloydGeorgeUploadPage.tsx @@ -4,15 +4,13 @@ import { UploadDocument } from '../../types/pages/UploadDocumentsPage/types'; import LloydGeorgeFileInputStage from '../../components/blocks/lloydGeorgeFileInputStage/LloydGeorgeFileInputStage'; import LloydGeorgeUploadComplete from '../../components/blocks/lloydGeorgeUploadComplete/LloydGeorgeUploadComplete'; -type Props = {}; - export enum LG_UPLOAD_STAGE { SELECT = 0, UPLOAD = 1, COMPLETE = 2, } -function LloydGeorgeUploadPage({}: Props) { +function LloydGeorgeUploadPage() { const [stage, setStage] = useState(LG_UPLOAD_STAGE.SELECT); const [documents, setDocuments] = useState>([]); diff --git a/app/src/providers/patientProvider/PatientProvider.test.tsx b/app/src/providers/patientProvider/PatientProvider.test.tsx index 7c1f0cdff..a4614193e 100644 --- a/app/src/providers/patientProvider/PatientProvider.test.tsx +++ b/app/src/providers/patientProvider/PatientProvider.test.tsx @@ -35,7 +35,7 @@ const TestComponent = (props: TestProps) => { return ( <> -

NHS Number: {patientDetails?.nhsNumber || 'Null'}

+

NHS Number: {patientDetails?.nhsNumber ?? 'Null'}

Family Name: {patientDetails?.familyName || 'Null'}