Skip to content
This repository has been archived by the owner on Oct 23, 2021. It is now read-only.

Commit

Permalink
MF-502: add blocking modal on registration (#99)
Browse files Browse the repository at this point in the history
  • Loading branch information
seankwon authored May 4, 2021
1 parent b2a78fe commit cb85226
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 4 deletions.
54 changes: 54 additions & 0 deletions src/patient-registration/before-save-prompt.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import React, { useEffect } from 'react';
import Modal from 'carbon-components-react/es/components/Modal';
import { useTranslation } from 'react-i18next';

const noop = () => {};

interface BeforeSavePromptProps {
when: boolean;
open: boolean;
cancelNavFn: EventListener;
onRequestClose: Function;
onRequestSubmit: Function;
}

const BeforeSavePrompt: React.FC<BeforeSavePromptProps> = ({
when,
open,
cancelNavFn,
onRequestClose,
onRequestSubmit,
}) => {
const { t } = useTranslation();

useEffect(() => {
if (when) {
window.addEventListener('single-spa:before-routing-event', cancelNavFn);
window.onbeforeunload = () => {
return 'do you want to leave?';
};
}

return () => {
window.onbeforeunload = noop;
window.removeEventListener('single-spa:before-routing-event', cancelNavFn);
};
}, [when, cancelNavFn]);

return (
<Modal
{...{
open,
danger: true,
modalHeading: t('discardModalHeader'),
primaryButtonText: t('discard'),
secondaryButtonText: t('cancel'),
onRequestClose,
onRequestSubmit,
}}>
{t('discardModalBody')}
</Modal>
);
};

export default BeforeSavePrompt;
42 changes: 40 additions & 2 deletions src/patient-registration/patient-registration.component.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import React, { useState, useEffect } from 'react';
import React, { useState, useEffect, useCallback } from 'react';
import XAxis16 from '@carbon/icons-react/es/x-axis/16';
import styles from './patient-registration.scss';
import camelCase from 'lodash-es/camelCase';
import capitalize from 'lodash-es/capitalize';
import Button from 'carbon-components-react/es/components/Button';
import Link from 'carbon-components-react/es/components/Link';
import { useLocation } from 'react-router-dom';
import { useLocation, useHistory } from 'react-router-dom';
import { Formik, Form } from 'formik';
import { Grid, Row, Column } from 'carbon-components-react/es/components/Grid';
import { validationSchema as initialSchema } from './validation/patient-registration-validation';
import { PatientIdentifierType, FormValues, CapturePhotoProps, PatientUuidMapType } from './patient-registration-types';
import { PatientRegistrationContext } from './patient-registration-context';
import FormManager, { SavePatientForm } from './form-manager';
import BeforeSavePrompt from './before-save-prompt';
import {
fetchCurrentSession,
fetchAddressTemplate,
Expand Down Expand Up @@ -68,6 +69,7 @@ const blankFormValues: FormValues = {

// If a patient is fetched, this will be updated with their information
const initialFormValues: FormValues = { ...blankFormValues };
const getUrlWithoutPrefix = url => url.split(window['getOpenmrsSpaBase']())?.[1];

export interface PatientRegistrationProps {
savePatientForm: SavePatientForm;
Expand All @@ -78,6 +80,9 @@ export const PatientRegistration: React.FC<PatientRegistrationProps> = ({ savePa
const { search } = useLocation();
const config = useConfig();
const { patientUuid } = match.params;
const history = useHistory();
const [open, setModalOpen] = useState(false);
const [newUrl, setNewUrl] = useState(undefined);
const [location, setLocation] = useState('');
const [sections, setSections] = useState([]);
const [identifierTypes, setIdentifierTypes] = useState(new Array<PatientIdentifierType>());
Expand All @@ -89,6 +94,28 @@ export const PatientRegistration: React.FC<PatientRegistrationProps> = ({ savePa
const [fieldConfigs, setFieldConfigs] = useState({});
const [currentPhoto, setCurrentPhoto] = useState(null);
const inEditMode = !!(patientUuid && patient);
const cancelNavFn = useCallback(
(evt: CustomEvent) => {
if (!open && !evt.detail.navigationIsCanceled) {
evt.detail.cancelNavigation();
setNewUrl(evt.detail.newUrl);
setModalOpen(true);

// once the listener is run, we want to remove it immediately in case an infinite loop occurs due
// to constant redirects
evt.target.removeEventListener('single-spa:before-routing-event', cancelNavFn);
}
},
[open],
);
const onRequestClose = useCallback(() => {
setModalOpen(false);
// add the route blocked when
window.addEventListener('single-spa:before-routing-event', cancelNavFn);
}, []);
const onRequestSubmit = useCallback(() => {
history.push(`/${getUrlWithoutPrefix(newUrl)}`);
}, [newUrl]);

useEffect(() => {
if (config?.sections) {
Expand Down Expand Up @@ -270,6 +297,7 @@ export const PatientRegistration: React.FC<PatientRegistrationProps> = ({ savePa
if (patientUuid) {
const redirectUrl =
new URLSearchParams(search).get('afterUrl') || interpolateString(config.links.submitButton, { patientUuid });
window.removeEventListener('single-spa:before-routing-event', cancelNavFn);
navigate({ to: redirectUrl });
}
} catch (error) {
Expand All @@ -296,6 +324,16 @@ export const PatientRegistration: React.FC<PatientRegistrationProps> = ({ savePa
}}>
{props => (
<Form className={styles.form}>
<BeforeSavePrompt
{...{
when: props.dirty,
open,
newUrl,
cancelNavFn,
onRequestClose,
onRequestSubmit,
}}
/>
<Grid>
<Row>
<Column lg={2} md={2} sm={1}>
Expand Down
7 changes: 5 additions & 2 deletions translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,8 @@
"registrationSuccessToastTitle":"New Patient Created",
"registrationSuccessToastDescription":"The patient can now be found by searching for them using their name or ID number",
"updationSuccessToastTitle":"Patient Details Updated",
"updationSuccessToastDescription":"The patient's information has been successfully updated"
}
"updationSuccessToastDescription":"The patient's information has been successfully updated",
"discardModalHeader": "Confirm Discard Changes?",
"discardModalBody": "The changes you made to this patient's details have not been saved. Discard changes?",
"discard": "Discard"
}

0 comments on commit cb85226

Please sign in to comment.