@ampath/esm-patient-registration-app 6.0.1-pre.98 → 9.2.0-next.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/1119.js +1 -0
- package/dist/1197.js +1 -0
- package/dist/21.js +1 -0
- package/dist/21.js.map +1 -0
- package/dist/2146.js +1 -0
- package/dist/2372.js +1 -0
- package/dist/2372.js.map +1 -0
- package/dist/2470.js +1 -0
- package/dist/2470.js.map +1 -0
- package/dist/2690.js +1 -0
- package/dist/2913.js +2 -0
- package/dist/{913.js.LICENSE.txt → 2913.js.LICENSE.txt} +3 -23
- package/dist/2913.js.map +1 -0
- package/dist/3093.js +1 -0
- package/dist/3093.js.map +1 -0
- package/dist/3099.js +1 -0
- package/dist/3144.js +2 -0
- package/dist/3144.js.LICENSE.txt +19 -0
- package/dist/3144.js.map +1 -0
- package/dist/320.js +2 -0
- package/dist/{876.js.LICENSE.txt → 320.js.LICENSE.txt} +2 -3
- package/dist/320.js.map +1 -0
- package/dist/3464.js +1 -0
- package/dist/3464.js.map +1 -0
- package/dist/3474.js +2 -0
- package/dist/3474.js.LICENSE.txt +8 -0
- package/dist/3474.js.map +1 -0
- package/dist/3584.js +1 -0
- package/dist/4041.js +2 -0
- package/dist/4041.js.map +1 -0
- package/dist/4055.js +1 -0
- package/dist/4132.js +1 -0
- package/dist/4300.js +1 -0
- package/dist/4335.js +1 -0
- package/dist/4463.js +1 -0
- package/dist/4463.js.map +1 -0
- package/dist/4618.js +1 -0
- package/dist/4652.js +1 -0
- package/dist/4944.js +1 -0
- package/dist/5173.js +1 -0
- package/dist/5220.js +2 -0
- package/dist/5220.js.LICENSE.txt +29 -0
- package/dist/5220.js.map +1 -0
- package/dist/5241.js +1 -0
- package/dist/5442.js +1 -0
- package/dist/5661.js +1 -0
- package/dist/6022.js +1 -0
- package/dist/6078.js +2 -0
- package/dist/6078.js.LICENSE.txt +9 -0
- package/dist/6078.js.map +1 -0
- package/dist/627.js +1 -0
- package/dist/627.js.map +1 -0
- package/dist/6276.js +1 -0
- package/dist/6276.js.map +1 -0
- package/dist/6468.js +1 -0
- package/dist/6679.js +1 -0
- package/dist/6737.js +2 -0
- package/dist/6737.js.LICENSE.txt +9 -0
- package/dist/6737.js.map +1 -0
- package/dist/6840.js +1 -0
- package/dist/6859.js +1 -0
- package/dist/7092.js +1 -0
- package/dist/7092.js.map +1 -0
- package/dist/7097.js +1 -0
- package/dist/7159.js +1 -0
- package/dist/723.js +1 -0
- package/dist/7495.js +2 -0
- package/dist/7495.js.LICENSE.txt +9 -0
- package/dist/7495.js.map +1 -0
- package/dist/7617.js +1 -0
- package/dist/795.js +1 -0
- package/dist/8163.js +1 -0
- package/dist/8349.js +1 -0
- package/dist/8404.js +2 -0
- package/dist/{629.js.LICENSE.txt → 8404.js.LICENSE.txt} +9 -3
- package/dist/8404.js.map +1 -0
- package/dist/8434.js +1 -0
- package/dist/8434.js.map +1 -0
- package/dist/8618.js +1 -0
- package/dist/89.js +2 -0
- package/dist/89.js.LICENSE.txt +9 -0
- package/dist/89.js.map +1 -0
- package/dist/890.js +1 -0
- package/dist/9214.js +1 -0
- package/dist/9538.js +1 -0
- package/dist/9569.js +1 -0
- package/dist/986.js +1 -0
- package/dist/9876.js +1 -0
- package/dist/9876.js.map +1 -0
- package/dist/9879.js +1 -0
- package/dist/9895.js +1 -0
- package/dist/9900.js +1 -0
- package/dist/9913.js +1 -0
- package/dist/main.js +1 -1
- package/dist/main.js.LICENSE.txt +36 -1
- package/dist/main.js.map +1 -1
- package/dist/openmrs-esm-patient-registration-app.js +1 -0
- package/dist/openmrs-esm-patient-registration-app.js.buildmanifest.json +1576 -0
- package/dist/openmrs-esm-patient-registration-app.js.map +1 -0
- package/dist/routes.json +1 -1
- package/package.json +16 -15
- package/src/{add-patient-link.tsx → add-patient-link.extension.tsx} +4 -2
- package/src/add-patient-link.test.tsx +6 -10
- package/src/config-schema.ts +109 -55
- package/src/constants.ts +1 -1
- package/src/declarations.d.ts +5 -4
- package/src/index.ts +10 -29
- package/src/nav-link.test.tsx +3 -3
- package/src/offline.resources.ts +26 -18
- package/src/patient-photo.extension.tsx +3 -1
- package/src/patient-registration/field/address/address-field.component.tsx +58 -37
- package/src/patient-registration/field/address/address-hierarchy-levels.component.tsx +16 -18
- package/src/patient-registration/field/address/address-hierarchy.resource.tsx +3 -3
- package/src/patient-registration/field/address/address-hierarchy.test.tsx +290 -0
- package/src/patient-registration/field/address/address-search.component.tsx +7 -5
- package/src/patient-registration/field/address/address-search.scss +5 -5
- package/src/patient-registration/field/address/address-search.test.tsx +140 -0
- package/src/patient-registration/field/cause-of-death/cause-of-death.component.tsx +98 -0
- package/src/patient-registration/field/custom-field.component.tsx +3 -9
- package/src/patient-registration/field/date-and-time-of-death/date-and-time-of-death.component.tsx +84 -0
- package/src/patient-registration/field/dob/dob.component.tsx +55 -50
- package/src/patient-registration/field/dob/dob.test.tsx +90 -0
- package/src/patient-registration/field/field.component.tsx +12 -6
- package/src/patient-registration/field/field.resource.ts +11 -4
- package/src/patient-registration/field/field.scss +69 -25
- package/src/patient-registration/field/field.test.tsx +329 -0
- package/src/patient-registration/field/gender/gender-field.component.tsx +14 -9
- package/src/patient-registration/field/gender/gender-field.test.tsx +73 -33
- package/src/patient-registration/field/id/id-field.component.tsx +24 -23
- package/src/patient-registration/field/id/id-field.test.tsx +147 -0
- package/src/patient-registration/field/id/identifier-selection-overlay.component.tsx +12 -10
- package/src/patient-registration/field/id/identifier-selection.scss +12 -8
- package/src/patient-registration/field/name/name-field.component.tsx +10 -5
- package/src/patient-registration/field/obs/obs-field.component.tsx +59 -2
- package/src/patient-registration/field/obs/obs-field.test.tsx +133 -39
- package/src/patient-registration/field/person-attributes/coded-person-attribute-field.component.tsx +3 -3
- package/src/patient-registration/field/person-attributes/coded-person-attribute-field.test.tsx +141 -0
- package/src/patient-registration/field/person-attributes/location-person-attribute-field.component.tsx +105 -0
- package/src/patient-registration/field/person-attributes/location-person-attribute-field.resource.tsx +48 -0
- package/src/patient-registration/field/person-attributes/person-attribute-field.component.tsx +19 -22
- package/src/patient-registration/field/person-attributes/person-attribute-field.test.tsx +193 -0
- package/src/patient-registration/field/person-attributes/text-person-attribute-field.test.tsx +90 -0
- package/src/patient-registration/form-manager.test.ts +91 -0
- package/src/patient-registration/form-manager.ts +49 -23
- package/src/patient-registration/input/basic-input/input/input.component.tsx +6 -2
- package/src/patient-registration/input/basic-input/select/select-input.test.tsx +49 -0
- package/src/patient-registration/input/custom-input/autosuggest/autosuggest.scss +5 -5
- package/src/patient-registration/input/custom-input/autosuggest/autosuggest.test.tsx +164 -0
- package/src/patient-registration/input/custom-input/identifier/identifier-input.component.tsx +73 -36
- package/src/patient-registration/input/custom-input/identifier/identifier-input.test.tsx +335 -0
- package/src/patient-registration/input/dummy-data/dummy-data-input.component.tsx +3 -0
- package/src/patient-registration/input/dummy-data/dummy-data-input.test.tsx +2 -11
- package/src/patient-registration/input/input.scss +17 -13
- package/src/patient-registration/patient-registration-context.ts +22 -11
- package/src/patient-registration/patient-registration-hooks.ts +158 -193
- package/src/patient-registration/patient-registration-utils.test.ts +33 -0
- package/src/patient-registration/patient-registration-utils.ts +11 -13
- package/src/patient-registration/patient-registration.component.tsx +87 -103
- package/src/patient-registration/{patient-registration.resource.testt.tsx → patient-registration.resource.test.tsx} +0 -4
- package/src/patient-registration/patient-registration.resource.ts +27 -3
- package/src/patient-registration/patient-registration.scss +27 -38
- package/src/patient-registration/patient-registration.test.tsx +579 -0
- package/src/patient-registration/patient-registration.types.ts +23 -25
- package/src/patient-registration/section/death-info/death-info-section.component.tsx +22 -17
- package/src/patient-registration/section/death-info/death-info-section.test.tsx +47 -0
- package/src/patient-registration/section/demographics/demographics-section.component.tsx +5 -5
- package/src/patient-registration/section/demographics/demographics-section.test.tsx +98 -0
- package/src/patient-registration/section/patient-relationships/relationships-section.component.tsx +8 -7
- package/src/patient-registration/section/patient-relationships/relationships-section.test.tsx +113 -0
- package/src/patient-registration/section/patient-relationships/relationships.resource.tsx +28 -28
- package/src/patient-registration/section/patient-relationships/relationships.scss +4 -4
- package/src/patient-registration/section/section-wrapper.component.tsx +1 -1
- package/src/patient-registration/section/section.component.tsx +1 -1
- package/src/patient-registration/section/section.scss +21 -1
- package/src/patient-registration/ui-components/overlay/overlay.scss +8 -8
- package/src/patient-registration/validation/{patient-registration-validation.test.tsx → patient-registration-validation.test.ts} +71 -23
- package/src/patient-registration/validation/patient-registration-validation.ts +123 -0
- package/src/resources-context.ts +14 -0
- package/src/root.component.tsx +3 -3
- package/src/routes.json +10 -24
- package/src/widgets/cancel-patient-edit.modal.tsx +33 -0
- package/src/widgets/cancel-patient-edit.test.tsx +22 -0
- package/src/widgets/delete-identifier-confirmation.modal.tsx +48 -0
- package/src/widgets/{delete-identifier-confirmation-modal.testt.tsx → delete-identifier-confirmation.test.tsx} +5 -7
- package/src/widgets/edit-patient-details-button.component.tsx +0 -1
- package/src/widgets/edit-patient-details-button.test.tsx +35 -0
- package/translations/am.json +43 -35
- package/translations/ar.json +41 -33
- package/translations/ar_SY.json +119 -0
- package/translations/bn.json +119 -0
- package/translations/de.json +119 -0
- package/translations/en.json +44 -42
- package/translations/en_US.json +119 -0
- package/translations/es.json +69 -57
- package/translations/es_MX.json +119 -0
- package/translations/fr.json +74 -58
- package/translations/he.json +44 -40
- package/translations/hi.json +119 -0
- package/translations/hi_IN.json +119 -0
- package/translations/id.json +119 -0
- package/translations/it.json +119 -0
- package/translations/ka.json +119 -0
- package/translations/km.json +44 -40
- package/translations/ku.json +119 -0
- package/translations/ky.json +119 -0
- package/translations/lg.json +119 -0
- package/translations/ne.json +119 -0
- package/translations/pl.json +119 -0
- package/translations/pt.json +119 -0
- package/translations/pt_BR.json +119 -0
- package/translations/qu.json +119 -0
- package/translations/ro_RO.json +119 -0
- package/translations/ru_RU.json +119 -0
- package/translations/si.json +119 -0
- package/translations/sw.json +119 -0
- package/translations/sw_KE.json +119 -0
- package/translations/tr.json +119 -0
- package/translations/tr_TR.json +119 -0
- package/translations/uk.json +119 -0
- package/translations/uz.json +119 -0
- package/translations/uz@Latn.json +119 -0
- package/translations/uz_UZ.json +119 -0
- package/translations/vi.json +119 -0
- package/translations/zh.json +45 -23
- package/translations/zh_CN.json +39 -17
- package/.turbo/turbo-build.log +0 -40
- package/dist/132.js +0 -1
- package/dist/197.js +0 -1
- package/dist/236.js +0 -1
- package/dist/236.js.map +0 -1
- package/dist/300.js +0 -1
- package/dist/335.js +0 -1
- package/dist/372.js +0 -1
- package/dist/372.js.map +0 -1
- package/dist/41.js +0 -2
- package/dist/41.js.map +0 -1
- package/dist/449.js +0 -1
- package/dist/449.js.map +0 -1
- package/dist/464.js +0 -1
- package/dist/464.js.map +0 -1
- package/dist/495.js +0 -1
- package/dist/495.js.map +0 -1
- package/dist/55.js +0 -1
- package/dist/56.js +0 -1
- package/dist/56.js.map +0 -1
- package/dist/621.js +0 -1
- package/dist/621.js.map +0 -1
- package/dist/629.js +0 -2
- package/dist/629.js.map +0 -1
- package/dist/652.js +0 -1
- package/dist/661.js +0 -1
- package/dist/757.js +0 -1
- package/dist/757.js.map +0 -1
- package/dist/828.js +0 -1
- package/dist/828.js.map +0 -1
- package/dist/830.js +0 -1
- package/dist/830.js.map +0 -1
- package/dist/831.js +0 -2
- package/dist/831.js.LICENSE.txt +0 -3
- package/dist/831.js.map +0 -1
- package/dist/876.js +0 -2
- package/dist/876.js.map +0 -1
- package/dist/879.js +0 -1
- package/dist/913.js +0 -2
- package/dist/913.js.map +0 -1
- package/dist/927.js +0 -1
- package/dist/927.js.map +0 -1
- package/dist/99.js +0 -1
- package/dist/ampath-esm-patient-registration-app.js +0 -1
- package/dist/ampath-esm-patient-registration-app.js.buildmanifest.json +0 -694
- package/dist/ampath-esm-patient-registration-app.js.map +0 -1
- package/src/patient-registration/date-util.ts +0 -52
- package/src/patient-registration/field/person-attributes/custom-person-attribute-field.component.tsx +0 -56
- package/src/patient-registration/validation/patient-registration-validation.tsx +0 -60
- package/src/patient-verification/assets/counties.json +0 -236
- package/src/patient-verification/assets/verification-assets.ts +0 -11
- package/src/patient-verification/patient-verification-hook.tsx +0 -176
- package/src/patient-verification/patient-verification-utils.ts +0 -179
- package/src/patient-verification/patient-verification.component.tsx +0 -124
- package/src/patient-verification/patient-verification.scss +0 -25
- package/src/patient-verification/verification-modal/confirm-prompt.component.tsx +0 -72
- package/src/patient-verification/verification-modal/empty-prompt.component.tsx +0 -35
- package/src/patient-verification/verification-types.ts +0 -50
- package/src/widgets/cancel-patient-edit.component.tsx +0 -37
- package/src/widgets/delete-identifier-confirmation-modal.tsx +0 -41
- package/src/widgets/delete-identifier-modal.scss +0 -34
- /package/dist/{41.js.LICENSE.txt → 4041.js.LICENSE.txt} +0 -0
- /package/src/patient-registration/input/custom-input/identifier/{utils.testt.ts → utils.test.ts} +0 -0
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import * as Yup from 'yup';
|
|
2
|
+
import camelCase from 'lodash-es/camelCase';
|
|
3
|
+
import { parseDate } from '@openmrs/esm-framework';
|
|
2
4
|
import {
|
|
3
5
|
type AddressValidationSchemaType,
|
|
6
|
+
type Encounter,
|
|
4
7
|
type FormValues,
|
|
5
8
|
type PatientIdentifier,
|
|
6
|
-
type PatientUuidMapType,
|
|
7
9
|
type PatientIdentifierValue,
|
|
8
|
-
type
|
|
10
|
+
type PatientUuidMapType,
|
|
9
11
|
} from './patient-registration.types';
|
|
10
|
-
import { parseDate } from '@openmrs/esm-framework';
|
|
11
|
-
import camelCase from 'lodash-es/camelCase';
|
|
12
|
-
import capitalize from 'lodash-es/capitalize';
|
|
13
12
|
|
|
14
13
|
export function parseAddressTemplateXml(addressTemplate: string) {
|
|
15
14
|
const templateXmlDoc = new DOMParser().parseFromString(addressTemplate, 'text/xml');
|
|
@@ -48,6 +47,7 @@ export function parseAddressTemplateXml(addressTemplate: string) {
|
|
|
48
47
|
addressValidationSchema,
|
|
49
48
|
};
|
|
50
49
|
}
|
|
50
|
+
|
|
51
51
|
export function parseAddressTemplateXmlOld(addressTemplate: string) {
|
|
52
52
|
const templateXmlDoc = new DOMParser().parseFromString(addressTemplate, 'text/xml');
|
|
53
53
|
const nameMappings = templateXmlDoc.querySelector('nameMappings').querySelectorAll('property');
|
|
@@ -124,11 +124,6 @@ export function getFormValuesFromFhirPatient(patient: fhir.Patient) {
|
|
|
124
124
|
result.birthdate = patient.birthDate ? parseDate(patient.birthDate) : undefined;
|
|
125
125
|
result.telephoneNumber = patient.telecom ? patient.telecom[0].value : '';
|
|
126
126
|
|
|
127
|
-
if (patient.deceasedBoolean || patient.deceasedDateTime) {
|
|
128
|
-
result.isDead = true;
|
|
129
|
-
result.deathDate = patient.deceasedDateTime ? patient.deceasedDateTime.split('T')[0] : '';
|
|
130
|
-
}
|
|
131
|
-
|
|
132
127
|
return {
|
|
133
128
|
...result,
|
|
134
129
|
...patient.identifier.map((identifier) => {
|
|
@@ -205,10 +200,13 @@ export function getPhonePersonAttributeValueFromFhirPatient(patient: fhir.Patien
|
|
|
205
200
|
return result;
|
|
206
201
|
}
|
|
207
202
|
|
|
208
|
-
|
|
203
|
+
type IdentifierMap = { [identifierFieldName: string]: PatientIdentifierValue };
|
|
204
|
+
export const filterOutUndefinedPatientIdentifiers = (patientIdentifiers: IdentifierMap): IdentifierMap =>
|
|
209
205
|
Object.fromEntries(
|
|
210
|
-
Object.entries
|
|
211
|
-
([key, value]) =>
|
|
206
|
+
Object.entries(patientIdentifiers).filter(
|
|
207
|
+
([key, value]) =>
|
|
208
|
+
(value.autoGeneration && value.selectedSource.autoGenerationOption.manualEntryEnabled) ||
|
|
209
|
+
value.identifierValue !== undefined,
|
|
212
210
|
),
|
|
213
211
|
);
|
|
214
212
|
|
|
@@ -1,42 +1,30 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
2
2
|
import classNames from 'classnames';
|
|
3
|
-
import { Button,
|
|
4
|
-
import { XAxis
|
|
3
|
+
import { Button, InlineLoading, Link } from '@carbon/react';
|
|
4
|
+
import { XAxis } from '@carbon/react/icons';
|
|
5
5
|
import { useLocation, useParams } from 'react-router-dom';
|
|
6
6
|
import { useTranslation } from 'react-i18next';
|
|
7
|
-
import {
|
|
7
|
+
import { Form, Formik, type FormikHelpers } from 'formik';
|
|
8
8
|
import {
|
|
9
9
|
createErrorHandler,
|
|
10
|
+
interpolateUrl,
|
|
10
11
|
showSnackbar,
|
|
11
12
|
useConfig,
|
|
12
|
-
interpolateUrl,
|
|
13
13
|
usePatient,
|
|
14
14
|
usePatientPhoto,
|
|
15
15
|
} from '@openmrs/esm-framework';
|
|
16
|
+
import { builtInSections, type RegistrationConfig, type SectionDefinition } from '../config-schema';
|
|
17
|
+
import { cancelRegistration, filterOutUndefinedPatientIdentifiers, scrollIntoView } from './patient-registration-utils';
|
|
16
18
|
import { getValidationSchema } from './validation/patient-registration-validation';
|
|
17
|
-
import { type FormValues, type CapturePhotoProps } from './patient-registration.types';
|
|
18
|
-
import { PatientRegistrationContext } from './patient-registration-context';
|
|
19
|
-
import { type SavePatientForm, SavePatientTransactionManager } from './form-manager';
|
|
20
19
|
import { DummyDataInput } from './input/dummy-data/dummy-data-input.component';
|
|
21
|
-
import {
|
|
22
|
-
|
|
23
|
-
filterUndefinedPatientIdenfier,
|
|
24
|
-
parseAddressTemplateXml,
|
|
25
|
-
scrollIntoView,
|
|
26
|
-
} from './patient-registration-utils';
|
|
27
|
-
import {
|
|
28
|
-
useInitialAddressFieldValues,
|
|
29
|
-
useInitialFormValues,
|
|
30
|
-
usePatientObs,
|
|
31
|
-
usePatientUuidMap,
|
|
32
|
-
} from './patient-registration-hooks';
|
|
33
|
-
import { ResourcesContext } from '../offline.resources';
|
|
34
|
-
import { builtInSections, type RegistrationConfig, type SectionDefinition } from '../config-schema';
|
|
20
|
+
import { PatientRegistrationContextProvider } from './patient-registration-context';
|
|
21
|
+
import { useResourcesContext } from '../resources-context';
|
|
35
22
|
import { SectionWrapper } from './section/section-wrapper.component';
|
|
23
|
+
import { type CapturePhotoProps, type FormValues } from './patient-registration.types';
|
|
24
|
+
import { type SavePatientForm, SavePatientTransactionManager } from './form-manager';
|
|
25
|
+
import { useInitialAddressFieldValues, useInitialFormValues, usePatientUuidMap } from './patient-registration-hooks';
|
|
36
26
|
import BeforeSavePrompt from './before-save-prompt';
|
|
37
27
|
import styles from './patient-registration.scss';
|
|
38
|
-
import PatientVerification from '../patient-verification/patient-verification.component';
|
|
39
|
-
import { handleSavePatientToClientRegistry } from '../patient-verification/patient-verification-hook';
|
|
40
28
|
|
|
41
29
|
let exportedInitialFormValuesForTesting = {} as FormValues;
|
|
42
30
|
|
|
@@ -46,27 +34,36 @@ export interface PatientRegistrationProps {
|
|
|
46
34
|
}
|
|
47
35
|
|
|
48
36
|
export const PatientRegistration: React.FC<PatientRegistrationProps> = ({ savePatientForm, isOffline }) => {
|
|
49
|
-
const {
|
|
50
|
-
const {
|
|
51
|
-
const config = useConfig() as RegistrationConfig;
|
|
52
|
-
const [target, setTarget] = useState<undefined | string>();
|
|
37
|
+
const { t } = useTranslation();
|
|
38
|
+
const { currentSession, identifierTypes } = useResourcesContext();
|
|
53
39
|
const { patientUuid: uuidOfPatientToEdit } = useParams();
|
|
40
|
+
const { search } = useLocation();
|
|
54
41
|
const { isLoading: isLoadingPatientToEdit, patient: patientToEdit } = usePatient(uuidOfPatientToEdit);
|
|
55
|
-
const
|
|
42
|
+
const config = useConfig<RegistrationConfig>();
|
|
43
|
+
|
|
44
|
+
const [initialFormValues, setInitialFormValues] = useInitialFormValues(
|
|
45
|
+
isLoadingPatientToEdit,
|
|
46
|
+
patientToEdit,
|
|
47
|
+
uuidOfPatientToEdit,
|
|
48
|
+
);
|
|
49
|
+
const [initialAddressFieldValues] = useInitialAddressFieldValues(
|
|
50
|
+
{},
|
|
51
|
+
isLoadingPatientToEdit,
|
|
52
|
+
patientToEdit,
|
|
53
|
+
uuidOfPatientToEdit,
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
const [patientUuidMap] = usePatientUuidMap({}, isLoadingPatientToEdit, patientToEdit, uuidOfPatientToEdit);
|
|
57
|
+
|
|
58
|
+
const [target, setTarget] = useState<undefined | string>();
|
|
56
59
|
const [capturePhotoProps, setCapturePhotoProps] = useState<CapturePhotoProps | null>(null);
|
|
57
|
-
|
|
58
|
-
const [initialAddressFieldValues] = useInitialAddressFieldValues(uuidOfPatientToEdit);
|
|
59
|
-
const [patientUuidMap] = usePatientUuidMap(uuidOfPatientToEdit);
|
|
60
|
+
|
|
60
61
|
const location = currentSession?.sessionLocation?.uuid;
|
|
61
62
|
const inEditMode = isLoadingPatientToEdit ? undefined : !!(uuidOfPatientToEdit && patientToEdit);
|
|
62
63
|
const showDummyData = useMemo(() => localStorage.getItem('openmrs:devtools') === 'true' && !inEditMode, [inEditMode]);
|
|
63
64
|
const { data: photo } = usePatientPhoto(patientToEdit?.id);
|
|
64
65
|
const savePatientTransactionManager = useRef(new SavePatientTransactionManager());
|
|
65
|
-
const
|
|
66
|
-
const validationSchema = getValidationSchema(config);
|
|
67
|
-
const [enableClientRegistry, setEnableClientRegistry] = useState(
|
|
68
|
-
inEditMode ? initialFormValues.identifiers['nationalUniquePatientIdentifier']?.identifierValue : false,
|
|
69
|
-
);
|
|
66
|
+
const validationSchema = getValidationSchema(config, t);
|
|
70
67
|
|
|
71
68
|
useEffect(() => {
|
|
72
69
|
exportedInitialFormValuesForTesting = initialFormValues;
|
|
@@ -86,7 +83,7 @@ export const PatientRegistration: React.FC<PatientRegistrationProps> = ({ savePa
|
|
|
86
83
|
const abortController = new AbortController();
|
|
87
84
|
helpers.setSubmitting(true);
|
|
88
85
|
|
|
89
|
-
const updatedFormValues = { ...values, identifiers:
|
|
86
|
+
const updatedFormValues = { ...values, identifiers: filterOutUndefinedPatientIdentifiers(values.identifiers) };
|
|
90
87
|
try {
|
|
91
88
|
await savePatientForm(
|
|
92
89
|
!inEditMode,
|
|
@@ -121,26 +118,6 @@ export const PatientRegistration: React.FC<PatientRegistrationProps> = ({ savePa
|
|
|
121
118
|
|
|
122
119
|
setTarget(redirectUrl);
|
|
123
120
|
} catch (error) {
|
|
124
|
-
const fieldErrors = Object.entries(error.responseBody?.error?.fieldErrors || {}) as Array<
|
|
125
|
-
[string, Array<{ code: string; message: string }>]
|
|
126
|
-
>;
|
|
127
|
-
|
|
128
|
-
if (savePatientTransactionManager.current.patientSaved) {
|
|
129
|
-
fieldErrors.forEach(([field, error]) => {
|
|
130
|
-
const errorMessage = error.map((e) => e.message).join(', ');
|
|
131
|
-
showSnackbar({
|
|
132
|
-
subtitle: errorMessage,
|
|
133
|
-
title: `Patient registration successful, with errors for registration encounter`,
|
|
134
|
-
kind: 'warning',
|
|
135
|
-
timeoutInMs: 8000,
|
|
136
|
-
});
|
|
137
|
-
});
|
|
138
|
-
const afterUrl = new URLSearchParams(search).get('afterUrl');
|
|
139
|
-
const redirectUrl = interpolateUrl(afterUrl || config.links.submitButton, { patientUuid: values.patientUuid });
|
|
140
|
-
|
|
141
|
-
setTarget(redirectUrl);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
121
|
if (error.responseBody?.error?.globalErrors) {
|
|
145
122
|
error.responseBody.error.globalErrors.forEach((error) => {
|
|
146
123
|
showSnackbar({
|
|
@@ -161,41 +138,74 @@ export const PatientRegistration: React.FC<PatientRegistrationProps> = ({ savePa
|
|
|
161
138
|
});
|
|
162
139
|
} else {
|
|
163
140
|
createErrorHandler()(error);
|
|
164
|
-
console.error(error);
|
|
165
141
|
}
|
|
166
142
|
|
|
167
143
|
helpers.setSubmitting(false);
|
|
168
144
|
}
|
|
169
145
|
};
|
|
170
146
|
|
|
147
|
+
const getDescription = (errors) => {
|
|
148
|
+
return (
|
|
149
|
+
<ul style={{ listStyle: 'inside' }}>
|
|
150
|
+
{Object.keys(errors).map((error, index) => {
|
|
151
|
+
return <li key={index}>{t(`${error}LabelText`, error)}</li>;
|
|
152
|
+
})}
|
|
153
|
+
</ul>
|
|
154
|
+
);
|
|
155
|
+
};
|
|
156
|
+
|
|
171
157
|
const displayErrors = (errors) => {
|
|
172
158
|
if (errors && typeof errors === 'object' && !!Object.keys(errors).length) {
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
isLowContrast: true,
|
|
179
|
-
timeoutInMs: 5000,
|
|
180
|
-
});
|
|
159
|
+
showSnackbar({
|
|
160
|
+
isLowContrast: true,
|
|
161
|
+
kind: 'warning',
|
|
162
|
+
title: t('fieldsWithErrors', 'The following fields have errors:'),
|
|
163
|
+
subtitle: <>{getDescription(errors)}</>,
|
|
181
164
|
});
|
|
182
165
|
}
|
|
183
166
|
};
|
|
184
167
|
|
|
168
|
+
const createContextValue = useCallback(
|
|
169
|
+
(formikProps) => ({
|
|
170
|
+
identifierTypes,
|
|
171
|
+
validationSchema,
|
|
172
|
+
values: formikProps.values,
|
|
173
|
+
inEditMode,
|
|
174
|
+
setFieldValue: formikProps.setFieldValue,
|
|
175
|
+
setFieldTouched: formikProps.setFieldTouched,
|
|
176
|
+
setCapturePhotoProps,
|
|
177
|
+
currentPhoto: photo?.imageSrc,
|
|
178
|
+
isOffline,
|
|
179
|
+
initialFormValues: formikProps.initialValues,
|
|
180
|
+
setInitialFormValues,
|
|
181
|
+
}),
|
|
182
|
+
[
|
|
183
|
+
identifierTypes,
|
|
184
|
+
validationSchema,
|
|
185
|
+
inEditMode,
|
|
186
|
+
setCapturePhotoProps,
|
|
187
|
+
photo?.imageSrc,
|
|
188
|
+
isOffline,
|
|
189
|
+
setInitialFormValues,
|
|
190
|
+
],
|
|
191
|
+
);
|
|
192
|
+
|
|
185
193
|
return (
|
|
186
194
|
<Formik
|
|
187
195
|
enableReinitialize
|
|
188
196
|
initialValues={initialFormValues}
|
|
189
|
-
|
|
190
|
-
|
|
197
|
+
onSubmit={onFormSubmit}
|
|
198
|
+
validationSchema={validationSchema}>
|
|
191
199
|
{(props) => (
|
|
192
200
|
<Form className={styles.form}>
|
|
193
|
-
<BeforeSavePrompt when={props.
|
|
201
|
+
<BeforeSavePrompt when={Object.keys(props.touched).length > 0} redirect={target} />
|
|
194
202
|
<div className={styles.formContainer}>
|
|
195
203
|
<div>
|
|
196
204
|
<div className={styles.stickyColumn}>
|
|
197
205
|
<h4>
|
|
198
|
-
{inEditMode
|
|
206
|
+
{inEditMode
|
|
207
|
+
? t('editPatientDetails', 'Edit patient details')
|
|
208
|
+
: t('createNewPatient', 'Create new patient')}
|
|
199
209
|
</h4>
|
|
200
210
|
{showDummyData && <DummyDataInput setValues={props.setValues} />}
|
|
201
211
|
<p className={styles.label01}>{t('jumpTo', 'Jump to')}</p>
|
|
@@ -206,18 +216,6 @@ export const PatientRegistration: React.FC<PatientRegistrationProps> = ({ savePa
|
|
|
206
216
|
</Link>
|
|
207
217
|
</div>
|
|
208
218
|
))}
|
|
209
|
-
<Button
|
|
210
|
-
renderIcon={ShareKnowledge}
|
|
211
|
-
disabled={!currentSession || !identifierTypes}
|
|
212
|
-
onClick={() => {
|
|
213
|
-
setEnableClientRegistry(true);
|
|
214
|
-
props.isValid
|
|
215
|
-
? handleSavePatientToClientRegistry(props.values, props.setValues, inEditMode)
|
|
216
|
-
: props.validateForm().then((errors) => displayErrors(errors));
|
|
217
|
-
}}
|
|
218
|
-
className={styles.submitButton}>
|
|
219
|
-
{t('postToRegistry', 'Post to registry')}
|
|
220
|
-
</Button>
|
|
221
219
|
<Button
|
|
222
220
|
className={styles.submitButton}
|
|
223
221
|
type="submit"
|
|
@@ -225,40 +223,26 @@ export const PatientRegistration: React.FC<PatientRegistrationProps> = ({ savePa
|
|
|
225
223
|
// Current session and identifiers are required for patient registration.
|
|
226
224
|
// If currentSession or identifierTypes are not available, then the
|
|
227
225
|
// user should be blocked to register the patient.
|
|
228
|
-
disabled={!currentSession || !identifierTypes || props.isSubmitting
|
|
226
|
+
disabled={!currentSession || !identifierTypes || props.isSubmitting}>
|
|
229
227
|
{props.isSubmitting ? (
|
|
230
228
|
<InlineLoading
|
|
231
229
|
className={styles.spinner}
|
|
232
230
|
description={`${t('submitting', 'Submitting')} ...`}
|
|
233
231
|
iconDescription="submitting"
|
|
234
|
-
status="active"
|
|
235
232
|
/>
|
|
236
233
|
) : inEditMode ? (
|
|
237
|
-
t('updatePatient', 'Update
|
|
234
|
+
t('updatePatient', 'Update patient')
|
|
238
235
|
) : (
|
|
239
|
-
t('registerPatient', 'Register
|
|
236
|
+
t('registerPatient', 'Register patient')
|
|
240
237
|
)}
|
|
241
238
|
</Button>
|
|
242
|
-
<Button className={styles.cancelButton} kind="
|
|
239
|
+
<Button className={styles.cancelButton} kind="secondary" onClick={cancelRegistration}>
|
|
243
240
|
{t('cancel', 'Cancel')}
|
|
244
241
|
</Button>
|
|
245
242
|
</div>
|
|
246
243
|
</div>
|
|
247
244
|
<div className={styles.infoGrid}>
|
|
248
|
-
<
|
|
249
|
-
value={{
|
|
250
|
-
identifierTypes: identifierTypes,
|
|
251
|
-
validationSchema,
|
|
252
|
-
values: props.values,
|
|
253
|
-
inEditMode,
|
|
254
|
-
setFieldValue: props.setFieldValue,
|
|
255
|
-
setCapturePhotoProps,
|
|
256
|
-
currentPhoto: photo?.imageSrc,
|
|
257
|
-
isOffline,
|
|
258
|
-
initialFormValues: props.initialValues,
|
|
259
|
-
setInitialFormValues,
|
|
260
|
-
}}>
|
|
261
|
-
<PatientVerification props={props} setInitialFormValues={setInitialFormValues} />
|
|
245
|
+
<PatientRegistrationContextProvider value={createContextValue(props)}>
|
|
262
246
|
{sections.map((section, index) => (
|
|
263
247
|
<SectionWrapper
|
|
264
248
|
key={`registration-section-${section.id}`}
|
|
@@ -266,7 +250,7 @@ export const PatientRegistration: React.FC<PatientRegistrationProps> = ({ savePa
|
|
|
266
250
|
index={index}
|
|
267
251
|
/>
|
|
268
252
|
))}
|
|
269
|
-
</
|
|
253
|
+
</PatientRegistrationContextProvider>
|
|
270
254
|
</div>
|
|
271
255
|
</div>
|
|
272
256
|
</Form>
|
|
@@ -8,10 +8,6 @@ jest.mock('@openmrs/esm-framework', () => ({
|
|
|
8
8
|
}));
|
|
9
9
|
|
|
10
10
|
describe('savePatient', () => {
|
|
11
|
-
afterEach(() => {
|
|
12
|
-
jest.resetAllMocks();
|
|
13
|
-
});
|
|
14
|
-
|
|
15
11
|
it('appends patient uuid in url if provided', () => {
|
|
16
12
|
mockOpenmrsFetch.mockImplementationOnce((url) => url);
|
|
17
13
|
savePatient(null, '1234');
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { openmrsFetch, restBaseUrl } from '@openmrs/esm-framework';
|
|
2
2
|
import { type Patient, type Relationship, type PatientIdentifier, type Encounter } from './patient-registration.types';
|
|
3
|
+
import dayjs from 'dayjs';
|
|
3
4
|
|
|
4
|
-
export const uuidIdentifier = '
|
|
5
|
-
export const uuidTelephoneNumber = '
|
|
5
|
+
export const uuidIdentifier = '05a29f94-c0ed-11e2-94be-8c13b969e334';
|
|
6
|
+
export const uuidTelephoneNumber = '14d4f066-15f5-102d-96e4-000c29c2a5d7';
|
|
6
7
|
|
|
7
8
|
function dataURItoFile(dataURI: string) {
|
|
8
|
-
const byteString = atob(dataURI.split(',')[1]);
|
|
9
|
+
const byteString = window.atob(dataURI.split(',')[1]);
|
|
9
10
|
const mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
|
|
10
11
|
// write the bytes of the string to a typed array
|
|
11
12
|
const buffer = new Uint8Array(byteString.length);
|
|
@@ -57,6 +58,22 @@ export function generateIdentifier(source: string) {
|
|
|
57
58
|
});
|
|
58
59
|
}
|
|
59
60
|
|
|
61
|
+
export async function generateAmrsUniversalIdentifier() {
|
|
62
|
+
const abortController = new AbortController();
|
|
63
|
+
const resp = await openmrsFetch(`https://ngx.ampath.or.ke/amrs-id-generator/generateidentifier`, {
|
|
64
|
+
headers: {
|
|
65
|
+
'Content-Type': 'application/json',
|
|
66
|
+
},
|
|
67
|
+
method: 'POST',
|
|
68
|
+
body: {
|
|
69
|
+
user: 1,
|
|
70
|
+
},
|
|
71
|
+
signal: abortController.signal,
|
|
72
|
+
});
|
|
73
|
+
const data = await resp.json();
|
|
74
|
+
return data['identifier'] ?? '';
|
|
75
|
+
}
|
|
76
|
+
|
|
60
77
|
export function deletePersonName(nameUuid: string, personUuid: string) {
|
|
61
78
|
const abortController = new AbortController();
|
|
62
79
|
|
|
@@ -188,3 +205,10 @@ export async function deletePatientIdentifier(patientUuid: string, patientIdenti
|
|
|
188
205
|
signal: abortController.signal,
|
|
189
206
|
});
|
|
190
207
|
}
|
|
208
|
+
|
|
209
|
+
export function getDatetime(date: Date | string, time: string, timeFormat: 'AM' | 'PM') {
|
|
210
|
+
const datetime = new Date(date);
|
|
211
|
+
const [hours, minutes] = time.split(':').map(Number);
|
|
212
|
+
const fullHours = timeFormat === 'PM' ? (hours % 12) + 12 : hours % 12;
|
|
213
|
+
return dayjs(datetime).hour(fullHours).minute(minutes).second(0).millisecond(0).toDate();
|
|
214
|
+
}
|
|
@@ -1,13 +1,9 @@
|
|
|
1
|
-
@use '@carbon/
|
|
2
|
-
@use '@carbon/
|
|
3
|
-
@
|
|
4
|
-
|
|
5
|
-
.title {
|
|
6
|
-
color: var(--omrs-color-brand-teal);
|
|
7
|
-
}
|
|
1
|
+
@use '@carbon/layout';
|
|
2
|
+
@use '@carbon/type';
|
|
3
|
+
@use '@openmrs/esm-styleguide/src/vars' as *;
|
|
8
4
|
|
|
9
5
|
.submit {
|
|
10
|
-
width:
|
|
6
|
+
width: 15.625rem;
|
|
11
7
|
}
|
|
12
8
|
|
|
13
9
|
.submit:hover {
|
|
@@ -19,34 +15,34 @@
|
|
|
19
15
|
}
|
|
20
16
|
|
|
21
17
|
.submitButton {
|
|
22
|
-
margin-bottom:
|
|
18
|
+
margin-bottom: layout.$spacing-05;
|
|
23
19
|
width: 11.688rem;
|
|
24
20
|
display: block;
|
|
25
21
|
}
|
|
26
22
|
|
|
27
23
|
.infoGrid {
|
|
28
24
|
width: 100%;
|
|
29
|
-
padding-left:
|
|
25
|
+
padding-left: layout.$spacing-07;
|
|
30
26
|
margin-bottom: 40vh;
|
|
31
|
-
margin-top:
|
|
27
|
+
margin-top: layout.$spacing-05;
|
|
32
28
|
max-width: 50rem;
|
|
33
29
|
}
|
|
34
30
|
|
|
35
|
-
.
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
color: $ui-04;
|
|
31
|
+
:global(.omrs-breakpoint-lt-desktop) {
|
|
32
|
+
.infoGrid {
|
|
33
|
+
max-width: unset;
|
|
34
|
+
}
|
|
40
35
|
}
|
|
41
36
|
|
|
42
|
-
.
|
|
43
|
-
@include type.type-style('
|
|
44
|
-
|
|
45
|
-
|
|
37
|
+
.label01 {
|
|
38
|
+
@include type.type-style('label-01');
|
|
39
|
+
margin-top: layout.$spacing-05;
|
|
40
|
+
margin-bottom: layout.$spacing-05;
|
|
41
|
+
color: $ui-05;
|
|
46
42
|
}
|
|
47
43
|
|
|
48
44
|
.space05 {
|
|
49
|
-
margin:
|
|
45
|
+
margin: layout.$spacing-05 0;
|
|
50
46
|
}
|
|
51
47
|
|
|
52
48
|
.formContainer {
|
|
@@ -56,9 +52,9 @@
|
|
|
56
52
|
|
|
57
53
|
.stickyColumn {
|
|
58
54
|
position: sticky;
|
|
59
|
-
margin-top:
|
|
60
|
-
//
|
|
61
|
-
top:
|
|
55
|
+
margin-top: layout.$spacing-05;
|
|
56
|
+
// layout.$spacing-09 for the nav height and layout.$spacing-05 for top margin
|
|
57
|
+
top: layout.$spacing-10;
|
|
62
58
|
}
|
|
63
59
|
|
|
64
60
|
.touchTarget a:active {
|
|
@@ -68,7 +64,7 @@
|
|
|
68
64
|
.linkName {
|
|
69
65
|
color: $color-gray-70;
|
|
70
66
|
line-height: 1.38;
|
|
71
|
-
font-size:
|
|
67
|
+
font-size: layout.$spacing-05;
|
|
72
68
|
font-weight: 600;
|
|
73
69
|
|
|
74
70
|
&:active {
|
|
@@ -83,19 +79,12 @@
|
|
|
83
79
|
}
|
|
84
80
|
}
|
|
85
81
|
|
|
86
|
-
.main {
|
|
87
|
-
background-color: white;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
:global(.omrs-breakpoint-lt-desktop) {
|
|
91
|
-
.infoGrid {
|
|
92
|
-
max-width: unset;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
82
|
.spinner {
|
|
97
|
-
|
|
98
|
-
|
|
83
|
+
min-height: layout.$spacing-05;
|
|
84
|
+
width: max-content;
|
|
85
|
+
|
|
86
|
+
:global(.cds--inline-loading__text) {
|
|
87
|
+
@include type.type-style('body-01');
|
|
99
88
|
}
|
|
100
89
|
}
|
|
101
90
|
|
|
@@ -109,6 +98,6 @@ html[dir='rtl'] {
|
|
|
109
98
|
|
|
110
99
|
.infoGrid {
|
|
111
100
|
padding-left: unset;
|
|
112
|
-
padding-right:
|
|
101
|
+
padding-right: layout.$spacing-07;
|
|
113
102
|
}
|
|
114
103
|
}
|