@ampath/esm-patient-registration-app 6.0.1-pre.7 → 6.0.1-pre.70
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/.turbo/turbo-build.log +23 -24
- package/dist/132.js +1 -0
- package/dist/197.js +1 -0
- package/dist/236.js +1 -0
- package/dist/{735.js.map → 236.js.map} +1 -1
- package/dist/300.js +1 -0
- package/dist/335.js +1 -0
- package/dist/372.js +1 -0
- package/dist/372.js.map +1 -0
- package/dist/41.js +2 -0
- package/dist/41.js.map +1 -0
- package/dist/449.js +1 -0
- package/dist/449.js.map +1 -0
- package/dist/464.js +1 -0
- package/dist/464.js.map +1 -0
- package/dist/495.js +1 -0
- package/dist/495.js.map +1 -0
- package/dist/55.js +1 -0
- package/dist/56.js +1 -0
- package/dist/56.js.map +1 -0
- package/dist/621.js +1 -1
- package/dist/621.js.map +1 -1
- package/dist/629.js +2 -0
- package/dist/629.js.LICENSE.txt +24 -0
- package/dist/629.js.map +1 -0
- package/dist/652.js +1 -0
- package/dist/661.js +1 -0
- package/dist/757.js +1 -1
- package/dist/757.js.map +1 -0
- package/dist/828.js +1 -0
- package/dist/828.js.map +1 -0
- package/dist/830.js +1 -0
- package/dist/830.js.map +1 -0
- package/dist/831.js +2 -0
- package/dist/831.js.map +1 -0
- package/dist/876.js +2 -0
- package/dist/876.js.map +1 -0
- package/dist/879.js +1 -1
- package/dist/913.js +2 -0
- package/dist/{591.js.LICENSE.txt → 913.js.LICENSE.txt} +23 -3
- package/dist/913.js.map +1 -0
- package/dist/927.js +1 -0
- package/dist/927.js.map +1 -0
- package/dist/99.js +1 -0
- package/dist/ampath-esm-patient-registration-app.js +1 -1
- package/dist/ampath-esm-patient-registration-app.js.buildmanifest.json +236 -191
- package/dist/ampath-esm-patient-registration-app.js.map +1 -1
- package/dist/main.js +1 -1
- package/dist/main.js.LICENSE.txt +0 -32
- package/dist/main.js.map +1 -1
- package/dist/routes.json +1 -1
- package/package.json +6 -9
- package/src/config-schema.ts +19 -10
- package/src/index.ts +11 -4
- package/src/offline.resources.ts +13 -18
- package/src/offline.ts +6 -4
- package/src/patient-photo.extension.tsx +9 -0
- package/src/patient-registration/field/address/custom-address-field.component.tsx +1 -0
- package/src/patient-registration/field/custom-field.component.tsx +6 -0
- package/src/patient-registration/field/dob/dob.component.tsx +17 -14
- package/src/patient-registration/field/field.resource.ts +3 -3
- package/src/patient-registration/field/person-attributes/coded-person-attribute-field.component.tsx +4 -0
- package/src/patient-registration/field/person-attributes/custom-person-attribute-field.component.tsx +56 -0
- package/src/patient-registration/field/person-attributes/person-attribute-field.component.tsx +22 -7
- package/src/patient-registration/field/person-attributes/person-attributes.resource.ts +2 -2
- package/src/patient-registration/field/phone/phone-field.component.tsx +1 -0
- package/src/patient-registration/form-manager.ts +13 -6
- package/src/patient-registration/patient-registration-hooks.ts +91 -9
- package/src/patient-registration/patient-registration.component.tsx +55 -13
- package/src/patient-registration/{patient-registration.resource.test.tsx → patient-registration.resource.testt.tsx} +3 -3
- package/src/patient-registration/patient-registration.resource.ts +15 -75
- package/src/patient-registration/patient-registration.scss +0 -8
- package/src/patient-registration/patient-registration.types.ts +7 -1
- package/src/patient-registration/section/patient-relationships/relationships-section.component.tsx +5 -1
- package/src/patient-registration/section/patient-relationships/relationships.resource.tsx +2 -2
- package/src/patient-verification/assets/counties.json +236 -0
- package/src/patient-verification/assets/verification-assets.ts +11 -0
- package/src/patient-verification/patient-verification-hook.tsx +176 -0
- package/src/patient-verification/patient-verification-utils.ts +179 -0
- package/src/patient-verification/patient-verification.component.tsx +124 -0
- package/src/patient-verification/patient-verification.scss +25 -0
- package/src/patient-verification/verification-modal/confirm-prompt.component.tsx +72 -0
- package/src/patient-verification/verification-modal/empty-prompt.component.tsx +35 -0
- package/src/patient-verification/verification-types.ts +50 -0
- package/src/routes.json +12 -3
- package/translations/am.json +26 -12
- package/translations/ar.json +26 -12
- package/translations/en.json +19 -5
- package/translations/es.json +10 -0
- package/translations/fr.json +6 -0
- package/translations/he.json +18 -0
- package/translations/km.json +18 -0
- package/translations/zh.json +30 -22
- package/translations/zh_CN.json +30 -22
- package/dist/130.js +0 -2
- package/dist/130.js.map +0 -1
- package/dist/152.js +0 -1
- package/dist/152.js.map +0 -1
- package/dist/249.js +0 -2
- package/dist/249.js.LICENSE.txt +0 -46
- package/dist/249.js.map +0 -1
- package/dist/255.js +0 -2
- package/dist/255.js.map +0 -1
- package/dist/271.js +0 -1
- package/dist/303.js +0 -1
- package/dist/303.js.map +0 -1
- package/dist/319.js +0 -1
- package/dist/365.js +0 -1
- package/dist/365.js.map +0 -1
- package/dist/460.js +0 -1
- package/dist/525.js +0 -1
- package/dist/525.js.map +0 -1
- package/dist/537.js +0 -1
- package/dist/537.js.map +0 -1
- package/dist/574.js +0 -1
- package/dist/591.js +0 -2
- package/dist/591.js.map +0 -1
- package/dist/644.js +0 -1
- package/dist/729.js +0 -1
- package/dist/729.js.map +0 -1
- package/dist/735.js +0 -1
- package/dist/784.js +0 -2
- package/dist/784.js.map +0 -1
- package/dist/788.js +0 -1
- package/dist/807.js +0 -1
- package/dist/833.js +0 -1
- package/dist/879.js.map +0 -1
- package/src/patient-registration/field/address/tests/address-hierarchy.test.tsx +0 -214
- package/src/patient-registration/field/address/tests/address-search-component.test.tsx +0 -135
- package/src/patient-registration/field/dob/dob.test.tsx +0 -75
- package/src/patient-registration/field/field.test.tsx +0 -294
- package/src/patient-registration/field/id/id-field.test.tsx +0 -107
- package/src/patient-registration/field/person-attributes/coded-attributes.component.tsx +0 -60
- package/src/patient-registration/field/person-attributes/coded-person-attribute-field.test.tsx +0 -127
- package/src/patient-registration/field/person-attributes/person-attribute-field.test.tsx +0 -187
- package/src/patient-registration/field/person-attributes/text-person-attribute-field.test.tsx +0 -88
- package/src/patient-registration/form-manager.test.ts +0 -67
- package/src/patient-registration/input/basic-input/select/select-input.test.tsx +0 -49
- package/src/patient-registration/input/custom-input/autosuggest/autosuggest.test.tsx +0 -132
- package/src/patient-registration/input/custom-input/identifier/identifier-input.test.tsx +0 -107
- package/src/patient-registration/patient-registration.test.tsx +0 -471
- package/src/patient-registration/section/death-info/death-info-section.test.tsx +0 -64
- package/src/patient-registration/section/demographics/demographics-section.test.tsx +0 -83
- package/src/patient-registration/section/patient-relationships/relationships-section.test.tsx +0 -100
- package/src/patient-verification/client-registry-constants.ts +0 -13
- package/src/patient-verification/client-registry.component.tsx +0 -66
- package/src/patient-verification/client-registry.scss +0 -1
- package/src/patient-verification/utils.tsx +0 -56
- package/src/patient-verification/verification-modal.scss +0 -20
- package/src/patient-verification/verification.component.tsx +0 -48
- package/src/root.test.tsx +0 -32
- package/src/widgets/cancel-patient-edit.test.tsx +0 -27
- package/src/widgets/display-photo.component.tsx +0 -30
- package/src/widgets/display-photo.test.tsx +0 -37
- package/src/widgets/edit-patient-details-button.test.tsx +0 -41
- /package/dist/{784.js.LICENSE.txt → 41.js.LICENSE.txt} +0 -0
- /package/dist/{130.js.LICENSE.txt → 831.js.LICENSE.txt} +0 -0
- /package/dist/{255.js.LICENSE.txt → 876.js.LICENSE.txt} +0 -0
- /package/src/patient-registration/input/custom-input/identifier/{utils.test.ts → utils.testt.ts} +0 -0
- /package/src/widgets/{delete-identifier-confirmation-modal.test.tsx → delete-identifier-confirmation-modal.testt.tsx} +0 -0
|
@@ -5,13 +5,16 @@ import {
|
|
|
5
5
|
openmrsFetch,
|
|
6
6
|
useConfig,
|
|
7
7
|
usePatient,
|
|
8
|
+
restBaseUrl,
|
|
8
9
|
} from '@openmrs/esm-framework';
|
|
10
|
+
import last from 'lodash-es/last';
|
|
9
11
|
import camelCase from 'lodash-es/camelCase';
|
|
10
12
|
import { type Dispatch, useEffect, useMemo, useState } from 'react';
|
|
11
13
|
import useSWR from 'swr';
|
|
12
14
|
import { v4 } from 'uuid';
|
|
13
15
|
import { type RegistrationConfig } from '../config-schema';
|
|
14
16
|
import { patientRegistration } from '../constants';
|
|
17
|
+
import { useConceptAnswers, useGlobalProperties } from '../patient-verification/patient-verification-hook';
|
|
15
18
|
import {
|
|
16
19
|
type FormValues,
|
|
17
20
|
type PatientRegistration,
|
|
@@ -19,6 +22,8 @@ import {
|
|
|
19
22
|
type PersonAttributeResponse,
|
|
20
23
|
type PatientIdentifierResponse,
|
|
21
24
|
type Encounter,
|
|
25
|
+
type ConceptAnswers,
|
|
26
|
+
type ObsResponse,
|
|
22
27
|
} from './patient-registration.types';
|
|
23
28
|
import {
|
|
24
29
|
getAddressFieldValuesFromFhirPatient,
|
|
@@ -31,12 +36,13 @@ import { useInitialPatientRelationships } from './section/patient-relationships/
|
|
|
31
36
|
import dayjs from 'dayjs';
|
|
32
37
|
|
|
33
38
|
export function useInitialFormValues(patientUuid: string): [FormValues, Dispatch<FormValues>] {
|
|
39
|
+
const { martialStatus, education, occupation, educationLoad } = useConcepts();
|
|
34
40
|
const { isLoading: isLoadingPatientToEdit, patient: patientToEdit } = usePatient(patientUuid);
|
|
35
41
|
const { data: attributes, isLoading: isLoadingAttributes } = useInitialPersonAttributes(patientUuid);
|
|
36
42
|
const { data: identifiers, isLoading: isLoadingIdentifiers } = useInitialPatientIdentifiers(patientUuid);
|
|
37
43
|
const { data: relationships, isLoading: isLoadingRelationships } = useInitialPatientRelationships(patientUuid);
|
|
38
|
-
const { data:
|
|
39
|
-
|
|
44
|
+
const { data: obs, isLoading: isLoadingObs, obs: observations } = usePatientObs(patientUuid);
|
|
45
|
+
const { data: token, isLoading: isLoadingToken } = useGlobalProperties();
|
|
40
46
|
const [initialFormValues, setInitialFormValues] = useState<FormValues>({
|
|
41
47
|
patientUuid: v4(),
|
|
42
48
|
givenName: '',
|
|
@@ -95,6 +101,14 @@ export function useInitialFormValues(patientUuid: string): [FormValues, Dispatch
|
|
|
95
101
|
})();
|
|
96
102
|
}, [isLoadingPatientToEdit, patientToEdit, patientUuid]);
|
|
97
103
|
|
|
104
|
+
// Setting authentication token
|
|
105
|
+
|
|
106
|
+
useEffect(() => {
|
|
107
|
+
if (!isLoadingToken && token) {
|
|
108
|
+
setInitialFormValues((initialFormValues) => ({ ...initialFormValues, token: String(token.access_token) }));
|
|
109
|
+
}
|
|
110
|
+
}, [isLoadingToken, token]);
|
|
111
|
+
|
|
98
112
|
// Set initial patient relationships
|
|
99
113
|
useEffect(() => {
|
|
100
114
|
if (!isLoadingRelationships && relationships) {
|
|
@@ -133,15 +147,24 @@ export function useInitialFormValues(patientUuid: string): [FormValues, Dispatch
|
|
|
133
147
|
}
|
|
134
148
|
}, [attributes, setInitialFormValues, isLoadingAttributes]);
|
|
135
149
|
|
|
136
|
-
// Set
|
|
150
|
+
// Set initial patient obs
|
|
151
|
+
|
|
152
|
+
useEffect(() => {
|
|
153
|
+
if (!isLoadingObs) {
|
|
154
|
+
setInitialFormValues((initialFormValues) => ({ ...initialFormValues, obs: obs, observation: observations }));
|
|
155
|
+
}
|
|
156
|
+
}, [isLoadingObs]);
|
|
157
|
+
|
|
158
|
+
// Set Initial encounter
|
|
159
|
+
|
|
137
160
|
useEffect(() => {
|
|
138
|
-
if (
|
|
161
|
+
if (!educationLoad) {
|
|
139
162
|
setInitialFormValues((initialFormValues) => ({
|
|
140
163
|
...initialFormValues,
|
|
141
|
-
|
|
164
|
+
concepts: [...occupation, ...martialStatus, ...education],
|
|
142
165
|
}));
|
|
143
166
|
}
|
|
144
|
-
}, [
|
|
167
|
+
}, [educationLoad]);
|
|
145
168
|
|
|
146
169
|
return [initialFormValues, setInitialFormValues];
|
|
147
170
|
}
|
|
@@ -210,7 +233,7 @@ export function useInitialPatientIdentifiers(patientUuid: string): {
|
|
|
210
233
|
|
|
211
234
|
const { data, error, isLoading } = useSWR<FetchResponse<{ results: Array<PatientIdentifierResponse> }>, Error>(
|
|
212
235
|
shouldFetch
|
|
213
|
-
?
|
|
236
|
+
? `${restBaseUrl}/patient/${patientUuid}/identifier?v=custom:(uuid,identifier,identifierType:(uuid,required,name),preferred)`
|
|
214
237
|
: null,
|
|
215
238
|
openmrsFetch,
|
|
216
239
|
);
|
|
@@ -247,7 +270,7 @@ function useInitialEncounters(patientUuid: string, patientToEdit: fhir.Patient)
|
|
|
247
270
|
const { registrationObs } = useConfig() as RegistrationConfig;
|
|
248
271
|
const { data, error, isLoading } = useSWR<FetchResponse<{ results: Array<Encounter> }>>(
|
|
249
272
|
patientToEdit && registrationObs.encounterTypeUuid
|
|
250
|
-
?
|
|
273
|
+
? `${restBaseUrl}/encounter?patient=${patientUuid}&v=custom:(encounterDatetime,obs:(concept:ref,value:ref))&encounterType=${registrationObs.encounterTypeUuid}`
|
|
251
274
|
: null,
|
|
252
275
|
openmrsFetch,
|
|
253
276
|
);
|
|
@@ -265,7 +288,7 @@ function useInitialPersonAttributes(personUuid: string) {
|
|
|
265
288
|
const shouldFetch = !!personUuid;
|
|
266
289
|
const { data, error, isLoading } = useSWR<FetchResponse<{ results: Array<PersonAttributeResponse> }>, Error>(
|
|
267
290
|
shouldFetch
|
|
268
|
-
?
|
|
291
|
+
? `${restBaseUrl}/person/${personUuid}/attribute?v=custom:(uuid,display,attributeType:(uuid,display,format),value)`
|
|
269
292
|
: null,
|
|
270
293
|
openmrsFetch,
|
|
271
294
|
);
|
|
@@ -285,3 +308,62 @@ function getPatientAttributeUuidMapForPatient(attributes: Array<PersonAttributeR
|
|
|
285
308
|
});
|
|
286
309
|
return attributeUuidMap;
|
|
287
310
|
}
|
|
311
|
+
|
|
312
|
+
export function usePatientObs(patientUuid: string) {
|
|
313
|
+
const {
|
|
314
|
+
registrationObs: { encounterTypeUuid },
|
|
315
|
+
} = useConfig() as RegistrationConfig;
|
|
316
|
+
const url = `/ws/rest/v1/encounter?patient=${patientUuid}&encounterType=${encounterTypeUuid}&v=custom:(obs:(uuid,display,concept:(uuid,display),value:(uuid,display)))`;
|
|
317
|
+
const { data, isLoading, error } = useSWR<{ data: ObsResponse }>(patientUuid ? url : null, openmrsFetch);
|
|
318
|
+
let obsObject = {};
|
|
319
|
+
const patientObs = last(data?.data?.results)?.obs?.forEach((ob) => {
|
|
320
|
+
Object.assign(obsObject, { [ob.concept.uuid]: ob.value.uuid });
|
|
321
|
+
});
|
|
322
|
+
return { data: obsObject, isLoading, error, obs: data?.data };
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
function useConcepts() {
|
|
326
|
+
const config = useConfig<RegistrationConfig>();
|
|
327
|
+
const { data: education, isLoading: educationLoad } = useConceptAnswers('a89e48ae-1350-11df-a1f1-0026b9348838');
|
|
328
|
+
const occupation: Array<ConceptAnswers> = [
|
|
329
|
+
{
|
|
330
|
+
uuid: '1538AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
|
|
331
|
+
display: 'Farmer',
|
|
332
|
+
},
|
|
333
|
+
{
|
|
334
|
+
uuid: '1540AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
|
|
335
|
+
display: 'Employee',
|
|
336
|
+
},
|
|
337
|
+
{
|
|
338
|
+
uuid: '1539AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
|
|
339
|
+
display: 'Trader',
|
|
340
|
+
},
|
|
341
|
+
{
|
|
342
|
+
uuid: '159465AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
|
|
343
|
+
display: 'Student',
|
|
344
|
+
},
|
|
345
|
+
{
|
|
346
|
+
uuid: '159466AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
|
|
347
|
+
display: 'Driver',
|
|
348
|
+
},
|
|
349
|
+
{
|
|
350
|
+
uuid: '1107AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
|
|
351
|
+
display: 'None',
|
|
352
|
+
},
|
|
353
|
+
{
|
|
354
|
+
uuid: '5622AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
|
|
355
|
+
display: 'Other',
|
|
356
|
+
},
|
|
357
|
+
];
|
|
358
|
+
const martialStatus: Array<ConceptAnswers> = [
|
|
359
|
+
{
|
|
360
|
+
uuid: '1538AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
|
|
361
|
+
display: 'Farmer',
|
|
362
|
+
},
|
|
363
|
+
];
|
|
364
|
+
//const martialStatus: Array<ConceptAnswers> = config.fieldDefinitions
|
|
365
|
+
// .find((fieldDefinition) => fieldDefinition.id === 'maritalStatus')
|
|
366
|
+
// .customConceptAnswers.map((concept) => ({ uuid: concept.uuid, display: concept.label }));
|
|
367
|
+
|
|
368
|
+
return { martialStatus, education, occupation, educationLoad };
|
|
369
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { useState, useEffect, useContext, useMemo, useRef } from 'react';
|
|
2
2
|
import classNames from 'classnames';
|
|
3
|
-
import { Button, Link, InlineLoading
|
|
4
|
-
import { XAxis } from '@carbon/react/icons';
|
|
3
|
+
import { Button, Link, InlineLoading } from '@carbon/react';
|
|
4
|
+
import { XAxis, ShareKnowledge } from '@carbon/react/icons';
|
|
5
5
|
import { useLocation, useParams } from 'react-router-dom';
|
|
6
6
|
import { useTranslation } from 'react-i18next';
|
|
7
7
|
import { Formik, Form, type FormikHelpers } from 'formik';
|
|
@@ -11,23 +11,32 @@ import {
|
|
|
11
11
|
useConfig,
|
|
12
12
|
interpolateUrl,
|
|
13
13
|
usePatient,
|
|
14
|
-
|
|
14
|
+
usePatientPhoto,
|
|
15
15
|
} from '@openmrs/esm-framework';
|
|
16
16
|
import { getValidationSchema } from './validation/patient-registration-validation';
|
|
17
17
|
import { type FormValues, type CapturePhotoProps } from './patient-registration.types';
|
|
18
18
|
import { PatientRegistrationContext } from './patient-registration-context';
|
|
19
19
|
import { type SavePatientForm, SavePatientTransactionManager } from './form-manager';
|
|
20
|
-
import { fetchPatientRecordFromClientRegistry, usePatientPhoto, fetchPerson } from './patient-registration.resource';
|
|
21
20
|
import { DummyDataInput } from './input/dummy-data/dummy-data-input.component';
|
|
22
|
-
import {
|
|
23
|
-
|
|
21
|
+
import {
|
|
22
|
+
cancelRegistration,
|
|
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';
|
|
24
33
|
import { ResourcesContext } from '../offline.resources';
|
|
25
34
|
import { builtInSections, type RegistrationConfig, type SectionDefinition } from '../config-schema';
|
|
26
35
|
import { SectionWrapper } from './section/section-wrapper.component';
|
|
27
36
|
import BeforeSavePrompt from './before-save-prompt';
|
|
28
37
|
import styles from './patient-registration.scss';
|
|
29
|
-
import
|
|
30
|
-
import {
|
|
38
|
+
import PatientVerification from '../patient-verification/patient-verification.component';
|
|
39
|
+
import { handleSavePatientToClientRegistry } from '../patient-verification/patient-verification-hook';
|
|
31
40
|
|
|
32
41
|
let exportedInitialFormValuesForTesting = {} as FormValues;
|
|
33
42
|
|
|
@@ -55,6 +64,9 @@ export const PatientRegistration: React.FC<PatientRegistrationProps> = ({ savePa
|
|
|
55
64
|
const savePatientTransactionManager = useRef(new SavePatientTransactionManager());
|
|
56
65
|
const fieldDefinition = config?.fieldDefinitions?.filter((def) => def.type === 'address');
|
|
57
66
|
const validationSchema = getValidationSchema(config);
|
|
67
|
+
const [enableClientRegistry, setEnableClientRegistry] = useState(
|
|
68
|
+
inEditMode ? initialFormValues.identifiers['nationalUniquePatientIdentifier']?.identifierValue : false,
|
|
69
|
+
);
|
|
58
70
|
|
|
59
71
|
useEffect(() => {
|
|
60
72
|
exportedInitialFormValuesForTesting = initialFormValues;
|
|
@@ -109,6 +121,26 @@ export const PatientRegistration: React.FC<PatientRegistrationProps> = ({ savePa
|
|
|
109
121
|
|
|
110
122
|
setTarget(redirectUrl);
|
|
111
123
|
} 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
|
+
|
|
112
144
|
if (error.responseBody?.error?.globalErrors) {
|
|
113
145
|
error.responseBody.error.globalErrors.forEach((error) => {
|
|
114
146
|
showSnackbar({
|
|
@@ -129,6 +161,7 @@ export const PatientRegistration: React.FC<PatientRegistrationProps> = ({ savePa
|
|
|
129
161
|
});
|
|
130
162
|
} else {
|
|
131
163
|
createErrorHandler()(error);
|
|
164
|
+
console.error(error);
|
|
132
165
|
}
|
|
133
166
|
|
|
134
167
|
helpers.setSubmitting(false);
|
|
@@ -173,6 +206,18 @@ export const PatientRegistration: React.FC<PatientRegistrationProps> = ({ savePa
|
|
|
173
206
|
</Link>
|
|
174
207
|
</div>
|
|
175
208
|
))}
|
|
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>
|
|
176
221
|
<Button
|
|
177
222
|
className={styles.submitButton}
|
|
178
223
|
type="submit"
|
|
@@ -180,7 +225,7 @@ export const PatientRegistration: React.FC<PatientRegistrationProps> = ({ savePa
|
|
|
180
225
|
// Current session and identifiers are required for patient registration.
|
|
181
226
|
// If currentSession or identifierTypes are not available, then the
|
|
182
227
|
// user should be blocked to register the patient.
|
|
183
|
-
disabled={!currentSession || !identifierTypes || props.isSubmitting}>
|
|
228
|
+
disabled={!currentSession || !identifierTypes || props.isSubmitting || !enableClientRegistry}>
|
|
184
229
|
{props.isSubmitting ? (
|
|
185
230
|
<InlineLoading
|
|
186
231
|
className={styles.spinner}
|
|
@@ -213,7 +258,7 @@ export const PatientRegistration: React.FC<PatientRegistrationProps> = ({ savePa
|
|
|
213
258
|
initialFormValues: props.initialValues,
|
|
214
259
|
setInitialFormValues,
|
|
215
260
|
}}>
|
|
216
|
-
<
|
|
261
|
+
<PatientVerification props={props} setInitialFormValues={setInitialFormValues} />
|
|
217
262
|
{sections.map((section, index) => (
|
|
218
263
|
<SectionWrapper
|
|
219
264
|
key={`registration-section-${section.id}`}
|
|
@@ -235,6 +280,3 @@ export const PatientRegistration: React.FC<PatientRegistrationProps> = ({ savePa
|
|
|
235
280
|
* Just exported for testing
|
|
236
281
|
*/
|
|
237
282
|
export { exportedInitialFormValuesForTesting as initialFormValues };
|
|
238
|
-
function dispose() {
|
|
239
|
-
throw new Error('Function not implemented.');
|
|
240
|
-
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { openmrsFetch } from '@openmrs/esm-framework';
|
|
1
|
+
import { openmrsFetch, restBaseUrl } from '@openmrs/esm-framework';
|
|
2
2
|
import { savePatient } from './patient-registration.resource';
|
|
3
3
|
|
|
4
4
|
const mockOpenmrsFetch = openmrsFetch as jest.Mock;
|
|
@@ -15,12 +15,12 @@ describe('savePatient', () => {
|
|
|
15
15
|
it('appends patient uuid in url if provided', () => {
|
|
16
16
|
mockOpenmrsFetch.mockImplementationOnce((url) => url);
|
|
17
17
|
savePatient(null, '1234');
|
|
18
|
-
expect(mockOpenmrsFetch.mock.calls[0][0]).toEqual(
|
|
18
|
+
expect(mockOpenmrsFetch.mock.calls[0][0]).toEqual(`${restBaseUrl}/patient/1234`);
|
|
19
19
|
});
|
|
20
20
|
|
|
21
21
|
it('does not append patient uuid in url', () => {
|
|
22
22
|
mockOpenmrsFetch.mockImplementationOnce(() => {});
|
|
23
23
|
savePatient(null);
|
|
24
|
-
expect(mockOpenmrsFetch.mock.calls[0][0]).toEqual(
|
|
24
|
+
expect(mockOpenmrsFetch.mock.calls[0][0]).toEqual(`${restBaseUrl}/patient/`);
|
|
25
25
|
});
|
|
26
26
|
});
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { openmrsFetch, useConfig } from '@openmrs/esm-framework';
|
|
1
|
+
import { openmrsFetch, restBaseUrl } from '@openmrs/esm-framework';
|
|
3
2
|
import { type Patient, type Relationship, type PatientIdentifier, type Encounter } from './patient-registration.types';
|
|
4
3
|
|
|
5
|
-
export const uuidIdentifier = '
|
|
6
|
-
export const uuidTelephoneNumber = '
|
|
4
|
+
export const uuidIdentifier = '58a4732e-1359-11df-a1f1-0026b9348838';
|
|
5
|
+
export const uuidTelephoneNumber = '72a759a8-1359-11df-a1f1-0026b9348838';
|
|
7
6
|
|
|
8
7
|
function dataURItoFile(dataURI: string) {
|
|
9
8
|
const byteString = atob(dataURI.split(',')[1]);
|
|
@@ -22,7 +21,7 @@ function dataURItoFile(dataURI: string) {
|
|
|
22
21
|
export function savePatient(patient: Patient | null, updatePatientUuid?: string) {
|
|
23
22
|
const abortController = new AbortController();
|
|
24
23
|
|
|
25
|
-
return openmrsFetch(
|
|
24
|
+
return openmrsFetch(`${restBaseUrl}/patient/${updatePatientUuid || ''}`, {
|
|
26
25
|
headers: {
|
|
27
26
|
'Content-Type': 'application/json',
|
|
28
27
|
},
|
|
@@ -35,7 +34,7 @@ export function savePatient(patient: Patient | null, updatePatientUuid?: string)
|
|
|
35
34
|
export function saveEncounter(encounter: Encounter) {
|
|
36
35
|
const abortController = new AbortController();
|
|
37
36
|
|
|
38
|
-
return openmrsFetch(
|
|
37
|
+
return openmrsFetch(`${restBaseUrl}/encounter`, {
|
|
39
38
|
headers: {
|
|
40
39
|
'Content-Type': 'application/json',
|
|
41
40
|
},
|
|
@@ -48,7 +47,7 @@ export function saveEncounter(encounter: Encounter) {
|
|
|
48
47
|
export function generateIdentifier(source: string) {
|
|
49
48
|
const abortController = new AbortController();
|
|
50
49
|
|
|
51
|
-
return openmrsFetch(
|
|
50
|
+
return openmrsFetch(`${restBaseUrl}/idgen/identifiersource/${source}/identifier`, {
|
|
52
51
|
headers: {
|
|
53
52
|
'Content-Type': 'application/json',
|
|
54
53
|
},
|
|
@@ -61,7 +60,7 @@ export function generateIdentifier(source: string) {
|
|
|
61
60
|
export function deletePersonName(nameUuid: string, personUuid: string) {
|
|
62
61
|
const abortController = new AbortController();
|
|
63
62
|
|
|
64
|
-
return openmrsFetch(
|
|
63
|
+
return openmrsFetch(`${restBaseUrl}/person/${personUuid}/name/${nameUuid}`, {
|
|
65
64
|
method: 'DELETE',
|
|
66
65
|
signal: abortController.signal,
|
|
67
66
|
});
|
|
@@ -70,7 +69,7 @@ export function deletePersonName(nameUuid: string, personUuid: string) {
|
|
|
70
69
|
export function saveRelationship(relationship: Relationship) {
|
|
71
70
|
const abortController = new AbortController();
|
|
72
71
|
|
|
73
|
-
return openmrsFetch(
|
|
72
|
+
return openmrsFetch(`${restBaseUrl}/relationship`, {
|
|
74
73
|
headers: {
|
|
75
74
|
'Content-Type': 'application/json',
|
|
76
75
|
},
|
|
@@ -83,7 +82,7 @@ export function saveRelationship(relationship: Relationship) {
|
|
|
83
82
|
export function updateRelationship(relationshipUuid, relationship: { relationshipType: string }) {
|
|
84
83
|
const abortController = new AbortController();
|
|
85
84
|
|
|
86
|
-
return openmrsFetch(
|
|
85
|
+
return openmrsFetch(`${restBaseUrl}/relationship/${relationshipUuid}`, {
|
|
87
86
|
headers: {
|
|
88
87
|
'Content-Type': 'application/json',
|
|
89
88
|
},
|
|
@@ -96,7 +95,7 @@ export function updateRelationship(relationshipUuid, relationship: { relationshi
|
|
|
96
95
|
export function deleteRelationship(relationshipUuid) {
|
|
97
96
|
const abortController = new AbortController();
|
|
98
97
|
|
|
99
|
-
return openmrsFetch(
|
|
98
|
+
return openmrsFetch(`${restBaseUrl}/relationship/${relationshipUuid}`, {
|
|
100
99
|
headers: {
|
|
101
100
|
'Content-Type': 'application/json',
|
|
102
101
|
},
|
|
@@ -134,57 +133,12 @@ export async function savePatientPhoto(
|
|
|
134
133
|
});
|
|
135
134
|
}
|
|
136
135
|
|
|
137
|
-
interface ObsFetchResponse {
|
|
138
|
-
results: Array<PhotoObs>;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
interface PhotoObs {
|
|
142
|
-
display: string;
|
|
143
|
-
obsDatetime: string;
|
|
144
|
-
uuid: string;
|
|
145
|
-
value: {
|
|
146
|
-
display: string;
|
|
147
|
-
links: {
|
|
148
|
-
rel: string;
|
|
149
|
-
uri: string;
|
|
150
|
-
};
|
|
151
|
-
};
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
interface UsePatientPhotoResult {
|
|
155
|
-
data: { dateTime: string; imageSrc: string } | null;
|
|
156
|
-
isError: Error;
|
|
157
|
-
isLoading: boolean;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
export function usePatientPhoto(patientUuid: string): UsePatientPhotoResult {
|
|
161
|
-
const {
|
|
162
|
-
concepts: { patientPhotoUuid },
|
|
163
|
-
} = useConfig();
|
|
164
|
-
const url = `/ws/rest/v1/obs?patient=${patientUuid}&concept=${patientPhotoUuid}&v=full`;
|
|
165
|
-
|
|
166
|
-
const { data, error, isLoading } = useSWR<{ data: ObsFetchResponse }, Error>(patientUuid ? url : null, openmrsFetch);
|
|
167
|
-
|
|
168
|
-
const item = data?.data?.results[0];
|
|
169
|
-
|
|
170
|
-
return {
|
|
171
|
-
data: item
|
|
172
|
-
? {
|
|
173
|
-
dateTime: item?.obsDatetime,
|
|
174
|
-
imageSrc: item?.value?.links?.uri,
|
|
175
|
-
}
|
|
176
|
-
: null,
|
|
177
|
-
isError: error,
|
|
178
|
-
isLoading,
|
|
179
|
-
};
|
|
180
|
-
}
|
|
181
|
-
|
|
182
136
|
export async function fetchPerson(query: string, abortController: AbortController) {
|
|
183
137
|
const [patientsRes, personsRes] = await Promise.all([
|
|
184
|
-
openmrsFetch(
|
|
138
|
+
openmrsFetch(`${restBaseUrl}/patient?q=${query}`, {
|
|
185
139
|
signal: abortController.signal,
|
|
186
140
|
}),
|
|
187
|
-
openmrsFetch(
|
|
141
|
+
openmrsFetch(`${restBaseUrl}/person?q=${query}`, {
|
|
188
142
|
signal: abortController.signal,
|
|
189
143
|
}),
|
|
190
144
|
]);
|
|
@@ -202,7 +156,7 @@ export async function fetchPerson(query: string, abortController: AbortControlle
|
|
|
202
156
|
|
|
203
157
|
export async function addPatientIdentifier(patientUuid: string, patientIdentifier: PatientIdentifier) {
|
|
204
158
|
const abortController = new AbortController();
|
|
205
|
-
return openmrsFetch(
|
|
159
|
+
return openmrsFetch(`${restBaseUrl}/patient/${patientUuid}/identifier/`, {
|
|
206
160
|
method: 'POST',
|
|
207
161
|
headers: {
|
|
208
162
|
'Content-Type': 'application/json',
|
|
@@ -214,7 +168,7 @@ export async function addPatientIdentifier(patientUuid: string, patientIdentifie
|
|
|
214
168
|
|
|
215
169
|
export async function updatePatientIdentifier(patientUuid: string, identifierUuid: string, identifier: string) {
|
|
216
170
|
const abortController = new AbortController();
|
|
217
|
-
return openmrsFetch(
|
|
171
|
+
return openmrsFetch(`${restBaseUrl}/patient/${patientUuid}/identifier/${identifierUuid}`, {
|
|
218
172
|
method: 'POST',
|
|
219
173
|
headers: {
|
|
220
174
|
'Content-Type': 'application/json',
|
|
@@ -226,7 +180,7 @@ export async function updatePatientIdentifier(patientUuid: string, identifierUui
|
|
|
226
180
|
|
|
227
181
|
export async function deletePatientIdentifier(patientUuid: string, patientIdentifierUuid: string) {
|
|
228
182
|
const abortController = new AbortController();
|
|
229
|
-
return openmrsFetch(
|
|
183
|
+
return openmrsFetch(`${restBaseUrl}/patient/${patientUuid}/identifier/${patientIdentifierUuid}?purge`, {
|
|
230
184
|
method: 'DELETE',
|
|
231
185
|
headers: {
|
|
232
186
|
'Content-Type': 'application/json',
|
|
@@ -234,17 +188,3 @@ export async function deletePatientIdentifier(patientUuid: string, patientIdenti
|
|
|
234
188
|
signal: abortController.signal,
|
|
235
189
|
});
|
|
236
190
|
}
|
|
237
|
-
export const fetchPatientRecordFromClientRegistry = (
|
|
238
|
-
patientIdentifier: string,
|
|
239
|
-
identifierType: string,
|
|
240
|
-
country: string,
|
|
241
|
-
) => {
|
|
242
|
-
const url = `
|
|
243
|
-
https://ngx.ampath.or.ke/registry/api/uno?uno=${patientIdentifier}&idType=${identifierType}&countryCode=${country}`;
|
|
244
|
-
|
|
245
|
-
return fetch(url)
|
|
246
|
-
.then((response) => {
|
|
247
|
-
return response.json();
|
|
248
|
-
})
|
|
249
|
-
.then((data) => data);
|
|
250
|
-
};
|
|
@@ -118,7 +118,7 @@ export type Patient = {
|
|
|
118
118
|
};
|
|
119
119
|
|
|
120
120
|
export interface Encounter {
|
|
121
|
-
encounterDatetime
|
|
121
|
+
encounterDatetime?: Date;
|
|
122
122
|
patient: string;
|
|
123
123
|
encounterType: string;
|
|
124
124
|
location: string;
|
|
@@ -184,6 +184,9 @@ export interface FormValues {
|
|
|
184
184
|
address: {
|
|
185
185
|
[addressField: string]: string;
|
|
186
186
|
};
|
|
187
|
+
observation?: ObsResponse;
|
|
188
|
+
concepts?: Array<ConceptAnswers>;
|
|
189
|
+
token?: string;
|
|
187
190
|
}
|
|
188
191
|
|
|
189
192
|
export interface PatientUuidMapType {
|
|
@@ -316,3 +319,6 @@ export interface RestAddressTemplate {
|
|
|
316
319
|
display: string;
|
|
317
320
|
value: string;
|
|
318
321
|
}
|
|
322
|
+
export interface ObsResponse {
|
|
323
|
+
results: Array<{ obs: Array<{ uuid: string; display: string; value: OpenmrsResource; concept: OpenmrsResource }> }>;
|
|
324
|
+
}
|
package/src/patient-registration/section/patient-relationships/relationships-section.component.tsx
CHANGED
|
@@ -177,7 +177,11 @@ export const RelationshipsSection = () => {
|
|
|
177
177
|
uuid: type.uuid,
|
|
178
178
|
direction: 'bIsToA',
|
|
179
179
|
};
|
|
180
|
-
aIsToB.display === bIsToA.display
|
|
180
|
+
aIsToB.display === bIsToA.display
|
|
181
|
+
? tmp.push(aIsToB)
|
|
182
|
+
: bIsToA.display === 'Patient'
|
|
183
|
+
? tmp.push(aIsToB, { display: `Patient (${aIsToB.display})`, uuid: type.uuid, direction: 'bIsToA' })
|
|
184
|
+
: tmp.push(aIsToB, bIsToA);
|
|
181
185
|
});
|
|
182
186
|
setDisplayRelationshipTypes(tmp);
|
|
183
187
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useMemo } from 'react';
|
|
2
2
|
import useSWR from 'swr';
|
|
3
|
-
import { type FetchResponse, openmrsFetch } from '@openmrs/esm-framework';
|
|
3
|
+
import { type FetchResponse, openmrsFetch, restBaseUrl } from '@openmrs/esm-framework';
|
|
4
4
|
import { type RelationshipValue } from '../../patient-registration.types';
|
|
5
5
|
import { personRelationshipRepresentation } from '../../../constants';
|
|
6
6
|
|
|
@@ -10,7 +10,7 @@ export function useInitialPatientRelationships(patientUuid: string): {
|
|
|
10
10
|
} {
|
|
11
11
|
const shouldFetch = !!patientUuid;
|
|
12
12
|
const { data, error, isLoading } = useSWR<FetchResponse<RelationshipsResponse>, Error>(
|
|
13
|
-
shouldFetch ?
|
|
13
|
+
shouldFetch ? `${restBaseUrl}/relationship?v=${personRelationshipRepresentation}&person=${patientUuid}` : null,
|
|
14
14
|
openmrsFetch,
|
|
15
15
|
);
|
|
16
16
|
|