From 4a800af4614f5acd74fd2542ca312acd83db2c17 Mon Sep 17 00:00:00 2001 From: Jan Markus Milan Date: Fri, 17 Jul 2020 13:50:14 -0400 Subject: [PATCH] feat(new): warn about potential duplicate patient during creation process (#2187) --- .../new/DuplicateNewPatientModal.test.tsx | 107 ++++++++++++++++++ src/patients/new/DuplicateNewPatientModal.tsx | 54 +++++++++ src/patients/new/NewPatient.tsx | 40 ++++++- 3 files changed, 200 insertions(+), 1 deletion(-) create mode 100644 src/__tests__/patients/new/DuplicateNewPatientModal.test.tsx create mode 100644 src/patients/new/DuplicateNewPatientModal.tsx diff --git a/src/__tests__/patients/new/DuplicateNewPatientModal.test.tsx b/src/__tests__/patients/new/DuplicateNewPatientModal.test.tsx new file mode 100644 index 0000000000..407ca4d5fb --- /dev/null +++ b/src/__tests__/patients/new/DuplicateNewPatientModal.test.tsx @@ -0,0 +1,107 @@ +import { Modal } from '@hospitalrun/components' +import { act } from '@testing-library/react' +import { mount } from 'enzyme' +import React from 'react' +import { Provider } from 'react-redux' +import createMockStore from 'redux-mock-store' +import thunk from 'redux-thunk' + +import DuplicateNewPatientModal from '../../../patients/new/DuplicateNewPatientModal' +import { RootState } from '../../../shared/store' + +const mockStore = createMockStore([thunk]) + +describe('Duplicate New Patient Modal', () => { + it('should render a modal with the correct labels', () => { + const store = mockStore({ + patient: { + patient: { + id: '1234', + }, + }, + } as any) + const wrapper = mount( + + + , + ) + wrapper.update() + const modal = wrapper.find(Modal) + expect(modal).toHaveLength(1) + expect(modal.prop('title')).toEqual('Warning') + expect(modal.prop('closeButton')?.children).toEqual('actions.cancel') + expect(modal.prop('closeButton')?.color).toEqual('danger') + expect(modal.prop('successButton')?.children).toEqual('Continue') + expect(modal.prop('successButton')?.color).toEqual('success') + }) + + describe('cancel', () => { + it('should call the onCloseButtonClick function when the close button is clicked', () => { + const onCloseButtonClickSpy = jest.fn() + const store = mockStore({ + patient: { + patient: { + id: '1234', + }, + }, + } as any) + const wrapper = mount( + + + , + ) + wrapper.update() + + act(() => { + const modal = wrapper.find(Modal) + const { onClick } = modal.prop('closeButton') as any + onClick() + }) + + expect(onCloseButtonClickSpy).toHaveBeenCalledTimes(1) + }) + }) + + describe('on save', () => { + it('should call the onContinueButtonClick function when the continue button is clicked', () => { + const onContinueButtonClickSpy = jest.fn() + const store = mockStore({ + patient: { + patient: { + id: '1234', + }, + }, + } as any) + + const wrapper = mount( + + + , + ) + wrapper.update() + + act(() => { + const modal = wrapper.find(Modal) + const { onClick } = modal.prop('successButton') as any + onClick() + }) + + expect(onContinueButtonClickSpy).toHaveBeenCalledTimes(1) + }) + }) +}) diff --git a/src/patients/new/DuplicateNewPatientModal.tsx b/src/patients/new/DuplicateNewPatientModal.tsx new file mode 100644 index 0000000000..6f5abc1a38 --- /dev/null +++ b/src/patients/new/DuplicateNewPatientModal.tsx @@ -0,0 +1,54 @@ +import { Modal } from '@hospitalrun/components' +import React from 'react' +import { Link } from 'react-router-dom' + +import useTranslator from '../../shared/hooks/useTranslator' +import Patient from '../../shared/model/Patient' + +interface Props { + duplicatePatient?: Patient + show: boolean + toggle: () => void + onCloseButtonClick: () => void + onContinueButtonClick: () => void +} + +const DuplicateNewPatientModal = (props: Props) => { + const { t } = useTranslator() + const { duplicatePatient, show, toggle, onCloseButtonClick, onContinueButtonClick } = props + + const body = ( +
+
+

+ Possible duplicate of:{' '} + {duplicatePatient !== undefined && ( + {duplicatePatient.fullName} + )} +

+

Are you sure you want to create this patient?

+
+
+ ) + + return ( + + ) +} + +export default DuplicateNewPatientModal diff --git a/src/patients/new/NewPatient.tsx b/src/patients/new/NewPatient.tsx index 7cd7b52fdf..84b213b3ce 100644 --- a/src/patients/new/NewPatient.tsx +++ b/src/patients/new/NewPatient.tsx @@ -10,6 +10,7 @@ import Patient from '../../shared/model/Patient' import { RootState } from '../../shared/store' import GeneralInformation from '../GeneralInformation' import { createPatient } from '../patient-slice' +import DuplicateNewPatientModal from './DuplicateNewPatientModal' const breadcrumbs = [ { i18nKey: 'patients.label', location: '/patients' }, @@ -21,8 +22,11 @@ const NewPatient = () => { const history = useHistory() const dispatch = useDispatch() const { createError } = useSelector((state: RootState) => state.patient) + const { patients } = Object(useSelector((state: RootState) => state.patients)) const [patient, setPatient] = useState({} as Patient) + const [duplicatePatient, setDuplicatePatient] = useState({} as Patient) + const [showDuplicateNewPatientModal, setShowDuplicateNewPatientModal] = useState(false) useTitle(t('patients.newPatient')) useAddBreadcrumbs(breadcrumbs, true) @@ -41,13 +45,39 @@ const NewPatient = () => { } const onSave = () => { - dispatch(createPatient(patient, onSuccessfulSave)) + let isDuplicatePatient = false + const patientsObj = {} + Object.assign(patientsObj, patients) + Object.keys(patientsObj).forEach((patientInfo: any) => { + const loggedPatient = patients[patientInfo] + if ( + loggedPatient.givenName === patient.givenName && + loggedPatient.familyName === patient.familyName && + loggedPatient.sex === patient.sex && + loggedPatient.dateOfBirth === patient.dateOfBirth + ) { + setShowDuplicateNewPatientModal(true) + setDuplicatePatient(loggedPatient as Patient) + isDuplicatePatient = true + } + }) + if (!isDuplicatePatient) { + dispatch(createPatient(patient, onSuccessfulSave)) + } } const onPatientChange = (newPatient: Partial) => { setPatient(newPatient as Patient) } + const createDuplicateNewPatient = () => { + dispatch(createPatient(patient, onSuccessfulSave)) + } + + const closeDuplicateNewPatientModal = () => { + setShowDuplicateNewPatientModal(false) + } + return (
{
+ + ) }