@kenyaemr/esm-patient-registration-app 5.2.3 → 6.0.1-pre.1.0.0
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/130.js +1 -1
- package/dist/130.js.map +1 -1
- package/dist/271.js +1 -1
- package/dist/319.js +1 -1
- package/dist/330.js +1 -1
- package/dist/460.js +1 -1
- package/dist/537.js +1 -1
- package/dist/537.js.map +1 -1
- package/dist/574.js +1 -1
- package/dist/59.js +1 -1
- package/dist/59.js.map +1 -1
- package/dist/619.js +1 -0
- package/dist/619.js.map +1 -0
- package/dist/644.js +1 -1
- package/dist/735.js +1 -1
- package/dist/757.js +1 -1
- package/dist/788.js +1 -1
- package/dist/895.js +2 -0
- package/dist/{431.js.LICENSE.txt → 895.js.LICENSE.txt} +4 -2
- package/dist/895.js.map +1 -0
- package/dist/kenyaemr-esm-patient-registration-app.js +1 -1
- package/dist/kenyaemr-esm-patient-registration-app.js.buildmanifest.json +89 -89
- package/dist/kenyaemr-esm-patient-registration-app.js.map +1 -1
- package/dist/main.js +1 -1
- package/dist/main.js.LICENSE.txt +4 -2
- package/dist/main.js.map +1 -1
- package/dist/routes.json +1 -1
- package/package.json +5 -4
- package/src/offline.resources.ts +12 -10
- package/src/offline.ts +6 -4
- package/src/patient-registration/field/field.resource.ts +3 -3
- package/src/patient-registration/field/person-attributes/coded-person-attribute-field.component.tsx +8 -5
- package/src/patient-registration/field/person-attributes/person-attributes.resource.ts +2 -2
- package/src/patient-registration/form-manager.ts +9 -3
- package/src/patient-registration/input/custom-input/identifier/identifier-input.component.tsx +1 -1
- package/src/patient-registration/patient-registration-hooks.ts +13 -8
- package/src/patient-registration/patient-registration.component.tsx +1 -1
- package/src/patient-registration/patient-registration.resource.test.tsx +3 -3
- package/src/patient-registration/patient-registration.resource.ts +14 -14
- package/src/patient-registration/patient-registration.types.ts +2 -1
- package/src/patient-registration/section/patient-relationships/relationships.resource.tsx +2 -2
- package/src/patient-verification/patient-verification-hook.tsx +13 -4
- package/src/patient-verification/patient-verification-utils.ts +20 -12
- package/src/patient-verification/patient-verification.component.tsx +13 -6
- package/src/patient-verification/patient-verification.scss +0 -1
- package/src/patient-verification/verification-modal/confirm-prompt.component.tsx +3 -12
- package/translations/am.json +12 -16
- package/translations/ar.json +12 -16
- package/translations/en.json +3 -3
- package/translations/es.json +24 -32
- package/translations/fr.json +42 -54
- package/translations/zh.json +29 -21
- package/translations/zh_CN.json +29 -21
- package/dist/102.js +0 -1
- package/dist/102.js.map +0 -1
- package/dist/431.js +0 -2
- package/dist/431.js.map +0 -1
- package/dist.tar.gz +0 -0
package/dist/routes.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"$schema":"https://json.openmrs.org/routes.schema.json","backendDependencies":{"webservices.rest":"^2.24.0"},"pages":[{"component":"root","route":"patient-registration","online":true,"offline":true},{"component":"editPatient","routeRegex":"patient\\/([a-zA-Z0-9\\-]+)\\/edit","online":true,"offline":true}],"extensions":[{"component":"addPatientLink","name":"add-patient-action","slot":"top-nav-actions-slot","online":true,"offline":true},{"component":"cancelPatientEditModal","name":"cancel-patient-edit-modal","online":true,"offline":true},{"component":"patientPhoto","name":"patient-photo-widget","slot":"patient-photo-slot","online":true,"offline":true},{"component":"editPatientDetailsButton","name":"edit-patient-details-button","slot":"patient-actions-slot","online":true,"offline":true},{"component":"editPatientDetailsButton","name":"edit-patient-details-button","slot":"patient-search-actions-slot","online":true,"offline":true},{"component":"deleteIdentifierConfirmationModal","name":"delete-identifier-confirmation-modal","online":true,"offline":true},{"component":"emptyClientRegistryModal","name":"empty-client-registry-modal","online":true,"offline":true},{"component":"confirmClientRegistryModal","name":"confirm-client-registry-modal","online":true,"offline":true}],"version":"
|
|
1
|
+
{"$schema":"https://json.openmrs.org/routes.schema.json","backendDependencies":{"webservices.rest":"^2.24.0"},"pages":[{"component":"root","route":"patient-registration","online":true,"offline":true},{"component":"editPatient","routeRegex":"patient\\/([a-zA-Z0-9\\-]+)\\/edit","online":true,"offline":true}],"extensions":[{"component":"addPatientLink","name":"add-patient-action","slot":"top-nav-actions-slot","online":true,"offline":true},{"component":"cancelPatientEditModal","name":"cancel-patient-edit-modal","online":true,"offline":true},{"component":"patientPhoto","name":"patient-photo-widget","slot":"patient-photo-slot","online":true,"offline":true},{"component":"editPatientDetailsButton","name":"edit-patient-details-button","slot":"patient-actions-slot","online":true,"offline":true},{"component":"editPatientDetailsButton","name":"edit-patient-details-button","slot":"patient-search-actions-slot","online":true,"offline":true},{"component":"deleteIdentifierConfirmationModal","name":"delete-identifier-confirmation-modal","online":true,"offline":true},{"component":"emptyClientRegistryModal","name":"empty-client-registry-modal","online":true,"offline":true},{"component":"confirmClientRegistryModal","name":"confirm-client-registry-modal","online":true,"offline":true}],"version":"6.0.1-pre.1.0.0"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kenyaemr/esm-patient-registration-app",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.0.1-pre.1.0.0",
|
|
4
4
|
"description": "Patient registration microfrontend for the OpenMRS SPA",
|
|
5
5
|
"browser": "dist/kenyaemr-esm-patient-registration-app.js",
|
|
6
6
|
"main": "src/index.ts",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"debug": "npm run serve",
|
|
14
14
|
"build": "webpack --mode production",
|
|
15
15
|
"analyze": "webpack --mode=production --env.analyze=true",
|
|
16
|
-
"lint": "cross-env
|
|
16
|
+
"lint": "cross-env eslint src --ext ts,tsx",
|
|
17
17
|
"test": "cross-env TZ=UTC jest --config jest.config.js --verbose false --passWithNoTests --color",
|
|
18
18
|
"test:watch": "cross-env TZ=UTC jest --watch --config jest.config.js --color",
|
|
19
19
|
"coverage": "yarn test --coverage",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"url": "https://github.com/openmrs/openmrs-esm-patient-management/issues"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@carbon/react": "
|
|
40
|
+
"@carbon/react": "~1.37.0",
|
|
41
41
|
"core-js-pure": "^3.34.0",
|
|
42
42
|
"formik": "^2.1.5",
|
|
43
43
|
"geopattern": "^1.2.3",
|
|
@@ -56,5 +56,6 @@
|
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"webpack": "^5.74.0"
|
|
59
|
-
}
|
|
59
|
+
},
|
|
60
|
+
"stableVersion": "6.0.0"
|
|
60
61
|
}
|
package/src/offline.resources.ts
CHANGED
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import find from 'lodash-es/find';
|
|
3
3
|
import camelCase from 'lodash-es/camelCase';
|
|
4
4
|
import escapeRegExp from 'lodash-es/escapeRegExp';
|
|
5
|
-
import { getConfig, messageOmrsServiceWorker, openmrsFetch, type Session } from '@openmrs/esm-framework';
|
|
5
|
+
import { getConfig, messageOmrsServiceWorker, openmrsFetch, restBaseUrl, type Session } from '@openmrs/esm-framework';
|
|
6
6
|
import type {
|
|
7
7
|
PatientIdentifierType,
|
|
8
8
|
FetchedPatientIdentifierType,
|
|
@@ -20,17 +20,17 @@ export interface Resources {
|
|
|
20
20
|
export const ResourcesContext = React.createContext<Resources>(null);
|
|
21
21
|
|
|
22
22
|
export async function fetchCurrentSession(): Promise<Session> {
|
|
23
|
-
const { data } = await cacheAndFetch<Session>(
|
|
23
|
+
const { data } = await cacheAndFetch<Session>(`${restBaseUrl}/session`);
|
|
24
24
|
return data;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
export async function fetchAddressTemplate() {
|
|
28
|
-
const { data } = await cacheAndFetch<AddressTemplate>(
|
|
28
|
+
const { data } = await cacheAndFetch<AddressTemplate>(`${restBaseUrl}/addresstemplate`);
|
|
29
29
|
return data;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
export async function fetchAllRelationshipTypes() {
|
|
33
|
-
const { data } = await cacheAndFetch(
|
|
33
|
+
const { data } = await cacheAndFetch(`${restBaseUrl}/relationshiptype?v=default`);
|
|
34
34
|
return data;
|
|
35
35
|
}
|
|
36
36
|
|
|
@@ -59,11 +59,11 @@ async function fetchFieldDefinitionType(fieldDefinition) {
|
|
|
59
59
|
let apiUrl = '';
|
|
60
60
|
|
|
61
61
|
if (fieldDefinition.type === 'person attribute') {
|
|
62
|
-
apiUrl =
|
|
62
|
+
apiUrl = `${restBaseUrl}/personattributetype/${fieldDefinition.uuid}`;
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
if (fieldDefinition.answerConceptSetUuid) {
|
|
66
|
-
await cacheAndFetch(
|
|
66
|
+
await cacheAndFetch(`${restBaseUrl}/concept/${fieldDefinition.answerConceptSetUuid}`);
|
|
67
67
|
}
|
|
68
68
|
const { data } = await cacheAndFetch(apiUrl);
|
|
69
69
|
return data;
|
|
@@ -93,8 +93,10 @@ export async function fetchPatientIdentifierTypesWithSources(): Promise<Array<Pa
|
|
|
93
93
|
|
|
94
94
|
async function fetchPatientIdentifierTypes(): Promise<Array<FetchedPatientIdentifierType>> {
|
|
95
95
|
const [patientIdentifierTypesResponse, primaryIdentifierTypeResponse] = await Promise.all([
|
|
96
|
-
cacheAndFetch(
|
|
97
|
-
|
|
96
|
+
cacheAndFetch(
|
|
97
|
+
`${restBaseUrl}/patientidentifiertype?v=custom:(display,uuid,name,format,required,uniquenessBehavior)`,
|
|
98
|
+
),
|
|
99
|
+
cacheAndFetch(`${restBaseUrl}/metadatamapping/termmapping?v=full&code=emr.primaryIdentifierType`),
|
|
98
100
|
]);
|
|
99
101
|
|
|
100
102
|
if (patientIdentifierTypesResponse.ok) {
|
|
@@ -117,11 +119,11 @@ async function fetchPatientIdentifierTypes(): Promise<Array<FetchedPatientIdenti
|
|
|
117
119
|
}
|
|
118
120
|
|
|
119
121
|
async function fetchIdentifierSources(identifierType: string) {
|
|
120
|
-
return await cacheAndFetch(
|
|
122
|
+
return await cacheAndFetch(`${restBaseUrl}/idgen/identifiersource?v=default&identifierType=${identifierType}`);
|
|
121
123
|
}
|
|
122
124
|
|
|
123
125
|
async function fetchAutoGenerationOptions(abortController?: AbortController) {
|
|
124
|
-
return await cacheAndFetch(
|
|
126
|
+
return await cacheAndFetch(`${restBaseUrl}/idgen/autogenerationoption?v=full`);
|
|
125
127
|
}
|
|
126
128
|
|
|
127
129
|
async function cacheAndFetch<T = any>(url?: string) {
|
package/src/offline.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
|
+
fhirBaseUrl,
|
|
2
3
|
makeUrl,
|
|
3
4
|
messageOmrsServiceWorker,
|
|
4
5
|
navigate,
|
|
6
|
+
restBaseUrl,
|
|
5
7
|
setupDynamicOfflineDataHandler,
|
|
6
8
|
setupOfflineSync,
|
|
7
9
|
type SyncProcessOptions,
|
|
@@ -54,10 +56,10 @@ export function setupOffline() {
|
|
|
54
56
|
|
|
55
57
|
function getPatientUrlsToBeCached(patientUuid: string) {
|
|
56
58
|
return [
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
`${fhirBaseUrl}/Patient/${patientUuid}`,
|
|
60
|
+
`${restBaseUrl}/relationship?v=${personRelationshipRepresentation}&person=${patientUuid}`,
|
|
61
|
+
`${restBaseUrl}/person/${patientUuid}/attribute`,
|
|
62
|
+
`${restBaseUrl}/patient/${patientUuid}/identifier?v=custom:(uuid,identifier,identifierType:(uuid,required,name),preferred)`,
|
|
61
63
|
].map((url) => window.origin + makeUrl(url));
|
|
62
64
|
}
|
|
63
65
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { type FetchResponse, openmrsFetch, showSnackbar } from '@openmrs/esm-framework';
|
|
1
|
+
import { type FetchResponse, openmrsFetch, showSnackbar, restBaseUrl } from '@openmrs/esm-framework';
|
|
2
2
|
import useSWRImmutable from 'swr/immutable';
|
|
3
3
|
import { type ConceptAnswers, type ConceptResponse } from '../patient-registration.types';
|
|
4
4
|
|
|
5
5
|
export function useConcept(conceptUuid: string): { data: ConceptResponse; isLoading: boolean } {
|
|
6
6
|
const shouldFetch = typeof conceptUuid === 'string' && conceptUuid !== '';
|
|
7
7
|
const { data, error, isLoading } = useSWRImmutable<FetchResponse<ConceptResponse>, Error>(
|
|
8
|
-
shouldFetch ?
|
|
8
|
+
shouldFetch ? `${restBaseUrl}/concept/${conceptUuid}` : null,
|
|
9
9
|
openmrsFetch,
|
|
10
10
|
);
|
|
11
11
|
if (error) {
|
|
@@ -21,7 +21,7 @@ export function useConcept(conceptUuid: string): { data: ConceptResponse; isLoad
|
|
|
21
21
|
export function useConceptAnswers(conceptUuid: string): { data: Array<ConceptAnswers>; isLoading: boolean } {
|
|
22
22
|
const shouldFetch = typeof conceptUuid === 'string' && conceptUuid !== '';
|
|
23
23
|
const { data, error, isLoading } = useSWRImmutable<FetchResponse<ConceptResponse>, Error>(
|
|
24
|
-
shouldFetch ?
|
|
24
|
+
shouldFetch ? `${restBaseUrl}/concept/${conceptUuid}` : null,
|
|
25
25
|
openmrsFetch,
|
|
26
26
|
);
|
|
27
27
|
if (error) {
|
package/src/patient-registration/field/person-attributes/coded-person-attribute-field.component.tsx
CHANGED
|
@@ -26,12 +26,13 @@ export function CodedPersonAttributeField({
|
|
|
26
26
|
const { data: conceptAnswers, isLoading: isLoadingConceptAnswers } = useConceptAnswers(
|
|
27
27
|
customConceptAnswers.length ? '' : answerConceptSetUuid,
|
|
28
28
|
);
|
|
29
|
+
|
|
29
30
|
const { t } = useTranslation();
|
|
30
31
|
const fieldName = `attributes.${personAttributeType.uuid}`;
|
|
31
32
|
const [error, setError] = useState(false);
|
|
32
33
|
|
|
33
34
|
useEffect(() => {
|
|
34
|
-
if (!answerConceptSetUuid) {
|
|
35
|
+
if (!answerConceptSetUuid && !customConceptAnswers.length) {
|
|
35
36
|
reportError(
|
|
36
37
|
t(
|
|
37
38
|
'codedPersonAttributeNoAnswerSet',
|
|
@@ -41,10 +42,10 @@ export function CodedPersonAttributeField({
|
|
|
41
42
|
);
|
|
42
43
|
setError(true);
|
|
43
44
|
}
|
|
44
|
-
}, [answerConceptSetUuid]);
|
|
45
|
+
}, [answerConceptSetUuid, customConceptAnswers]);
|
|
45
46
|
|
|
46
47
|
useEffect(() => {
|
|
47
|
-
if (!isLoadingConceptAnswers) {
|
|
48
|
+
if (!isLoadingConceptAnswers && !customConceptAnswers.length) {
|
|
48
49
|
if (!conceptAnswers) {
|
|
49
50
|
reportError(
|
|
50
51
|
t(
|
|
@@ -69,7 +70,7 @@ export function CodedPersonAttributeField({
|
|
|
69
70
|
setError(true);
|
|
70
71
|
}
|
|
71
72
|
}
|
|
72
|
-
}, [isLoadingConceptAnswers, conceptAnswers]);
|
|
73
|
+
}, [isLoadingConceptAnswers, conceptAnswers, customConceptAnswers]);
|
|
73
74
|
|
|
74
75
|
const answers = useMemo(() => {
|
|
75
76
|
if (customConceptAnswers.length) {
|
|
@@ -77,7 +78,9 @@ export function CodedPersonAttributeField({
|
|
|
77
78
|
}
|
|
78
79
|
return isLoadingConceptAnswers || !conceptAnswers
|
|
79
80
|
? []
|
|
80
|
-
: conceptAnswers
|
|
81
|
+
: conceptAnswers
|
|
82
|
+
.map((answer) => ({ ...answer, label: answer.display }))
|
|
83
|
+
.sort((a, b) => a.label.localeCompare(b.label));
|
|
81
84
|
}, [customConceptAnswers, conceptAnswers, isLoadingConceptAnswers]);
|
|
82
85
|
|
|
83
86
|
if (error) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type FetchResponse, openmrsFetch } from '@openmrs/esm-framework';
|
|
1
|
+
import { type FetchResponse, openmrsFetch, restBaseUrl } from '@openmrs/esm-framework';
|
|
2
2
|
import useSWRImmutable from 'swr/immutable';
|
|
3
3
|
import { type PersonAttributeTypeResponse } from '../../patient-registration.types';
|
|
4
4
|
|
|
@@ -8,7 +8,7 @@ export function usePersonAttributeType(personAttributeTypeUuid: string): {
|
|
|
8
8
|
error: any;
|
|
9
9
|
} {
|
|
10
10
|
const { data, error, isLoading } = useSWRImmutable<FetchResponse<PersonAttributeTypeResponse>>(
|
|
11
|
-
|
|
11
|
+
`${restBaseUrl}/personattributetype/${personAttributeTypeUuid}`,
|
|
12
12
|
openmrsFetch,
|
|
13
13
|
);
|
|
14
14
|
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
type FetchResponse,
|
|
3
|
+
openmrsFetch,
|
|
4
|
+
queueSynchronizationItem,
|
|
5
|
+
type Session,
|
|
6
|
+
restBaseUrl,
|
|
7
|
+
} from '@openmrs/esm-framework';
|
|
2
8
|
import { patientRegistration } from '../constants';
|
|
3
9
|
import {
|
|
4
10
|
type FormValues,
|
|
@@ -128,7 +134,7 @@ export class FormManager {
|
|
|
128
134
|
await savePatientPhoto(
|
|
129
135
|
savePatientResponse.data.uuid,
|
|
130
136
|
capturePhotoProps.imageData,
|
|
131
|
-
|
|
137
|
+
`${restBaseUrl}/obs`,
|
|
132
138
|
capturePhotoProps.dateTime || new Date().toISOString(),
|
|
133
139
|
config.concepts.patientPhotoUuid,
|
|
134
140
|
);
|
|
@@ -354,7 +360,7 @@ export class FormManager {
|
|
|
354
360
|
.filter(([, value]) => !value)
|
|
355
361
|
.forEach(async ([key]) => {
|
|
356
362
|
const attributeUuid = patientUuidMap[`attribute.${key}`];
|
|
357
|
-
await openmrsFetch(
|
|
363
|
+
await openmrsFetch(`${restBaseUrl}/person/${values.patientUuid}/attribute/${attributeUuid}`, {
|
|
358
364
|
method: 'DELETE',
|
|
359
365
|
}).catch((err) => {
|
|
360
366
|
console.error(err);
|
package/src/patient-registration/input/custom-input/identifier/identifier-input.component.tsx
CHANGED
|
@@ -141,7 +141,7 @@ export const IdentifierInput: React.FC<IdentifierInputProps> = ({ patientIdentif
|
|
|
141
141
|
<UserHasAccess privilege="Delete Patient Identifiers">
|
|
142
142
|
<Button
|
|
143
143
|
size="md"
|
|
144
|
-
kind="
|
|
144
|
+
kind="ghost"
|
|
145
145
|
onClick={handleDelete}
|
|
146
146
|
iconDescription={t('deleteIdentifierTooltip', 'Delete')}
|
|
147
147
|
disabled={disabled}
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
openmrsFetch,
|
|
6
6
|
useConfig,
|
|
7
7
|
usePatient,
|
|
8
|
+
restBaseUrl,
|
|
8
9
|
} from '@openmrs/esm-framework';
|
|
9
10
|
import last from 'lodash-es/last';
|
|
10
11
|
import camelCase from 'lodash-es/camelCase';
|
|
@@ -35,7 +36,7 @@ import { useInitialPatientRelationships } from './section/patient-relationships/
|
|
|
35
36
|
import dayjs from 'dayjs';
|
|
36
37
|
|
|
37
38
|
export function useInitialFormValues(patientUuid: string): [FormValues, Dispatch<FormValues>] {
|
|
38
|
-
const { martialStatus, education, occupation, educationLoad
|
|
39
|
+
const { martialStatus, education, occupation, educationLoad } = useConcepts();
|
|
39
40
|
const { isLoading: isLoadingPatientToEdit, patient: patientToEdit } = usePatient(patientUuid);
|
|
40
41
|
const { data: attributes, isLoading: isLoadingAttributes } = useInitialPersonAttributes(patientUuid);
|
|
41
42
|
const { data: identifiers, isLoading: isLoadingIdentifiers } = useInitialPatientIdentifiers(patientUuid);
|
|
@@ -157,13 +158,13 @@ export function useInitialFormValues(patientUuid: string): [FormValues, Dispatch
|
|
|
157
158
|
// Set Initial encounter
|
|
158
159
|
|
|
159
160
|
useEffect(() => {
|
|
160
|
-
if (!educationLoad
|
|
161
|
+
if (!educationLoad) {
|
|
161
162
|
setInitialFormValues((initialFormValues) => ({
|
|
162
163
|
...initialFormValues,
|
|
163
164
|
concepts: [...occupation, ...martialStatus, ...education],
|
|
164
165
|
}));
|
|
165
166
|
}
|
|
166
|
-
}, [educationLoad
|
|
167
|
+
}, [educationLoad]);
|
|
167
168
|
|
|
168
169
|
return [initialFormValues, setInitialFormValues];
|
|
169
170
|
}
|
|
@@ -232,7 +233,7 @@ export function useInitialPatientIdentifiers(patientUuid: string): {
|
|
|
232
233
|
|
|
233
234
|
const { data, error, isLoading } = useSWR<FetchResponse<{ results: Array<PatientIdentifierResponse> }>, Error>(
|
|
234
235
|
shouldFetch
|
|
235
|
-
?
|
|
236
|
+
? `${restBaseUrl}/patient/${patientUuid}/identifier?v=custom:(uuid,identifier,identifierType:(uuid,required,name),preferred)`
|
|
236
237
|
: null,
|
|
237
238
|
openmrsFetch,
|
|
238
239
|
);
|
|
@@ -269,7 +270,7 @@ function useInitialEncounters(patientUuid: string, patientToEdit: fhir.Patient)
|
|
|
269
270
|
const { registrationObs } = useConfig() as RegistrationConfig;
|
|
270
271
|
const { data, error, isLoading } = useSWR<FetchResponse<{ results: Array<Encounter> }>>(
|
|
271
272
|
patientToEdit && registrationObs.encounterTypeUuid
|
|
272
|
-
?
|
|
273
|
+
? `${restBaseUrl}/encounter?patient=${patientUuid}&v=custom:(encounterDatetime,obs:(concept:ref,value:ref))&encounterType=${registrationObs.encounterTypeUuid}`
|
|
273
274
|
: null,
|
|
274
275
|
openmrsFetch,
|
|
275
276
|
);
|
|
@@ -287,7 +288,7 @@ function useInitialPersonAttributes(personUuid: string) {
|
|
|
287
288
|
const shouldFetch = !!personUuid;
|
|
288
289
|
const { data, error, isLoading } = useSWR<FetchResponse<{ results: Array<PersonAttributeResponse> }>, Error>(
|
|
289
290
|
shouldFetch
|
|
290
|
-
?
|
|
291
|
+
? `${restBaseUrl}/person/${personUuid}/attribute?v=custom:(uuid,display,attributeType:(uuid,display,format),value)`
|
|
291
292
|
: null,
|
|
292
293
|
openmrsFetch,
|
|
293
294
|
);
|
|
@@ -322,7 +323,7 @@ export function usePatientObs(patientUuid: string) {
|
|
|
322
323
|
}
|
|
323
324
|
|
|
324
325
|
function useConcepts() {
|
|
325
|
-
const
|
|
326
|
+
const config = useConfig<RegistrationConfig>();
|
|
326
327
|
const { data: education, isLoading: educationLoad } = useConceptAnswers('1712AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA');
|
|
327
328
|
const occupation: Array<ConceptAnswers> = [
|
|
328
329
|
{
|
|
@@ -355,5 +356,9 @@ function useConcepts() {
|
|
|
355
356
|
},
|
|
356
357
|
];
|
|
357
358
|
|
|
358
|
-
|
|
359
|
+
const martialStatus: Array<ConceptAnswers> = config.fieldDefinitions
|
|
360
|
+
.find((fieldDefinition) => fieldDefinition.id === 'maritalStatus')
|
|
361
|
+
.customConceptAnswers.map((concept) => ({ uuid: concept.uuid, display: concept.label }));
|
|
362
|
+
|
|
363
|
+
return { martialStatus, education, occupation, educationLoad };
|
|
359
364
|
}
|
|
@@ -231,7 +231,7 @@ export const PatientRegistration: React.FC<PatientRegistrationProps> = ({ savePa
|
|
|
231
231
|
initialFormValues: props.initialValues,
|
|
232
232
|
setInitialFormValues,
|
|
233
233
|
}}>
|
|
234
|
-
<PatientVerification props={props} />
|
|
234
|
+
<PatientVerification props={props} setInitialFormValues={setInitialFormValues} />
|
|
235
235
|
{sections.map((section, index) => (
|
|
236
236
|
<SectionWrapper
|
|
237
237
|
key={`registration-section-${section.id}`}
|
|
@@ -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,5 +1,5 @@
|
|
|
1
1
|
import useSWR from 'swr';
|
|
2
|
-
import { openmrsFetch, useConfig } from '@openmrs/esm-framework';
|
|
2
|
+
import { openmrsFetch, restBaseUrl, useConfig } from '@openmrs/esm-framework';
|
|
3
3
|
import { type Patient, type Relationship, type PatientIdentifier, type Encounter } from './patient-registration.types';
|
|
4
4
|
|
|
5
5
|
export const uuidIdentifier = '05a29f94-c0ed-11e2-94be-8c13b969e334';
|
|
@@ -22,7 +22,7 @@ function dataURItoFile(dataURI: string) {
|
|
|
22
22
|
export function savePatient(patient: Patient | null, updatePatientUuid?: string) {
|
|
23
23
|
const abortController = new AbortController();
|
|
24
24
|
|
|
25
|
-
return openmrsFetch(
|
|
25
|
+
return openmrsFetch(`${restBaseUrl}/patient/${updatePatientUuid || ''}`, {
|
|
26
26
|
headers: {
|
|
27
27
|
'Content-Type': 'application/json',
|
|
28
28
|
},
|
|
@@ -35,7 +35,7 @@ export function savePatient(patient: Patient | null, updatePatientUuid?: string)
|
|
|
35
35
|
export function saveEncounter(encounter: Encounter) {
|
|
36
36
|
const abortController = new AbortController();
|
|
37
37
|
|
|
38
|
-
return openmrsFetch(
|
|
38
|
+
return openmrsFetch(`${restBaseUrl}/encounter`, {
|
|
39
39
|
headers: {
|
|
40
40
|
'Content-Type': 'application/json',
|
|
41
41
|
},
|
|
@@ -48,7 +48,7 @@ export function saveEncounter(encounter: Encounter) {
|
|
|
48
48
|
export function generateIdentifier(source: string) {
|
|
49
49
|
const abortController = new AbortController();
|
|
50
50
|
|
|
51
|
-
return openmrsFetch(
|
|
51
|
+
return openmrsFetch(`${restBaseUrl}/idgen/identifiersource/${source}/identifier`, {
|
|
52
52
|
headers: {
|
|
53
53
|
'Content-Type': 'application/json',
|
|
54
54
|
},
|
|
@@ -61,7 +61,7 @@ export function generateIdentifier(source: string) {
|
|
|
61
61
|
export function deletePersonName(nameUuid: string, personUuid: string) {
|
|
62
62
|
const abortController = new AbortController();
|
|
63
63
|
|
|
64
|
-
return openmrsFetch(
|
|
64
|
+
return openmrsFetch(`${restBaseUrl}/person/${personUuid}/name/${nameUuid}`, {
|
|
65
65
|
method: 'DELETE',
|
|
66
66
|
signal: abortController.signal,
|
|
67
67
|
});
|
|
@@ -70,7 +70,7 @@ export function deletePersonName(nameUuid: string, personUuid: string) {
|
|
|
70
70
|
export function saveRelationship(relationship: Relationship) {
|
|
71
71
|
const abortController = new AbortController();
|
|
72
72
|
|
|
73
|
-
return openmrsFetch(
|
|
73
|
+
return openmrsFetch(`${restBaseUrl}/relationship`, {
|
|
74
74
|
headers: {
|
|
75
75
|
'Content-Type': 'application/json',
|
|
76
76
|
},
|
|
@@ -83,7 +83,7 @@ export function saveRelationship(relationship: Relationship) {
|
|
|
83
83
|
export function updateRelationship(relationshipUuid, relationship: { relationshipType: string }) {
|
|
84
84
|
const abortController = new AbortController();
|
|
85
85
|
|
|
86
|
-
return openmrsFetch(
|
|
86
|
+
return openmrsFetch(`${restBaseUrl}/relationship/${relationshipUuid}`, {
|
|
87
87
|
headers: {
|
|
88
88
|
'Content-Type': 'application/json',
|
|
89
89
|
},
|
|
@@ -96,7 +96,7 @@ export function updateRelationship(relationshipUuid, relationship: { relationshi
|
|
|
96
96
|
export function deleteRelationship(relationshipUuid) {
|
|
97
97
|
const abortController = new AbortController();
|
|
98
98
|
|
|
99
|
-
return openmrsFetch(
|
|
99
|
+
return openmrsFetch(`${restBaseUrl}/relationship/${relationshipUuid}`, {
|
|
100
100
|
headers: {
|
|
101
101
|
'Content-Type': 'application/json',
|
|
102
102
|
},
|
|
@@ -161,7 +161,7 @@ export function usePatientPhoto(patientUuid: string): UsePatientPhotoResult {
|
|
|
161
161
|
const {
|
|
162
162
|
concepts: { patientPhotoUuid },
|
|
163
163
|
} = useConfig();
|
|
164
|
-
const url =
|
|
164
|
+
const url = `${restBaseUrl}/obs?patient=${patientUuid}&concept=${patientPhotoUuid}&v=full`;
|
|
165
165
|
|
|
166
166
|
const { data, error, isLoading } = useSWR<{ data: ObsFetchResponse }, Error>(patientUuid ? url : null, openmrsFetch);
|
|
167
167
|
|
|
@@ -181,10 +181,10 @@ export function usePatientPhoto(patientUuid: string): UsePatientPhotoResult {
|
|
|
181
181
|
|
|
182
182
|
export async function fetchPerson(query: string, abortController: AbortController) {
|
|
183
183
|
const [patientsRes, personsRes] = await Promise.all([
|
|
184
|
-
openmrsFetch(
|
|
184
|
+
openmrsFetch(`${restBaseUrl}/patient?q=${query}`, {
|
|
185
185
|
signal: abortController.signal,
|
|
186
186
|
}),
|
|
187
|
-
openmrsFetch(
|
|
187
|
+
openmrsFetch(`${restBaseUrl}/person?q=${query}`, {
|
|
188
188
|
signal: abortController.signal,
|
|
189
189
|
}),
|
|
190
190
|
]);
|
|
@@ -202,7 +202,7 @@ export async function fetchPerson(query: string, abortController: AbortControlle
|
|
|
202
202
|
|
|
203
203
|
export async function addPatientIdentifier(patientUuid: string, patientIdentifier: PatientIdentifier) {
|
|
204
204
|
const abortController = new AbortController();
|
|
205
|
-
return openmrsFetch(
|
|
205
|
+
return openmrsFetch(`${restBaseUrl}/patient/${patientUuid}/identifier/`, {
|
|
206
206
|
method: 'POST',
|
|
207
207
|
headers: {
|
|
208
208
|
'Content-Type': 'application/json',
|
|
@@ -214,7 +214,7 @@ export async function addPatientIdentifier(patientUuid: string, patientIdentifie
|
|
|
214
214
|
|
|
215
215
|
export async function updatePatientIdentifier(patientUuid: string, identifierUuid: string, identifier: string) {
|
|
216
216
|
const abortController = new AbortController();
|
|
217
|
-
return openmrsFetch(
|
|
217
|
+
return openmrsFetch(`${restBaseUrl}/patient/${patientUuid}/identifier/${identifierUuid}`, {
|
|
218
218
|
method: 'POST',
|
|
219
219
|
headers: {
|
|
220
220
|
'Content-Type': 'application/json',
|
|
@@ -226,7 +226,7 @@ export async function updatePatientIdentifier(patientUuid: string, identifierUui
|
|
|
226
226
|
|
|
227
227
|
export async function deletePatientIdentifier(patientUuid: string, patientIdentifierUuid: string) {
|
|
228
228
|
const abortController = new AbortController();
|
|
229
|
-
return openmrsFetch(
|
|
229
|
+
return openmrsFetch(`${restBaseUrl}/patient/${patientUuid}/identifier/${patientIdentifierUuid}?purge`, {
|
|
230
230
|
method: 'DELETE',
|
|
231
231
|
headers: {
|
|
232
232
|
'Content-Type': 'application/json',
|
|
@@ -317,7 +317,8 @@ export interface RestAddressTemplate {
|
|
|
317
317
|
description: string;
|
|
318
318
|
property: string;
|
|
319
319
|
display: string;
|
|
320
|
-
value: string;
|
|
320
|
+
value: string;
|
|
321
|
+
}
|
|
321
322
|
export interface ObsResponse {
|
|
322
323
|
results: Array<{ obs: Array<{ uuid: string; display: string; value: OpenmrsResource; concept: OpenmrsResource }> }>;
|
|
323
324
|
}
|
|
@@ -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
|
|
|
@@ -1,11 +1,20 @@
|
|
|
1
|
-
import { FetchResponse, openmrsFetch, showNotification, showToast } from '@openmrs/esm-framework';
|
|
1
|
+
import { type FetchResponse, openmrsFetch, showNotification, showToast } from '@openmrs/esm-framework';
|
|
2
2
|
import { generateNUPIPayload, handleClientRegistryResponse } from './patient-verification-utils';
|
|
3
3
|
import useSWR from 'swr';
|
|
4
4
|
import useSWRImmutable from 'swr/immutable';
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
type ConceptAnswers,
|
|
7
|
+
type ConceptResponse,
|
|
8
|
+
type FormValues,
|
|
9
|
+
} from '../patient-registration/patient-registration.types';
|
|
6
10
|
|
|
7
|
-
export function searchClientRegistry(
|
|
8
|
-
|
|
11
|
+
export function searchClientRegistry(
|
|
12
|
+
identifierType: string,
|
|
13
|
+
searchTerm: string,
|
|
14
|
+
token: string,
|
|
15
|
+
countryCode: string = 'KE',
|
|
16
|
+
) {
|
|
17
|
+
const url = `https://afyakenyaapi.health.go.ke/partners/registry/search/${countryCode}/${identifierType}/${searchTerm}`;
|
|
9
18
|
return fetch(url, { headers: { Authorization: `Bearer ${token}` } }).then((r) => r.json());
|
|
10
19
|
}
|
|
11
20
|
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { showModal } from '@openmrs/esm-framework';
|
|
2
|
-
import { FormikProps } from 'formik';
|
|
3
|
-
import { ClientRegistryPatient, RegistryPatient } from './verification-types';
|
|
2
|
+
import { type FormikProps } from 'formik';
|
|
3
|
+
import { type ClientRegistryPatient, type RegistryPatient } from './verification-types';
|
|
4
4
|
import counties from './assets/counties.json';
|
|
5
|
-
import { FormValues } from '../patient-registration/patient-registration.types';
|
|
5
|
+
import { type FormValues } from '../patient-registration/patient-registration.types';
|
|
6
|
+
import { capitalize } from 'lodash-es';
|
|
6
7
|
|
|
7
8
|
export function handleClientRegistryResponse(
|
|
8
9
|
clientResponse: ClientRegistryPatient,
|
|
@@ -83,7 +84,7 @@ export function handleClientRegistryResponse(
|
|
|
83
84
|
familyName: lastName,
|
|
84
85
|
middleName: middleName,
|
|
85
86
|
givenName: firstName,
|
|
86
|
-
gender: gender
|
|
87
|
+
gender: clientResponse.client.gender,
|
|
87
88
|
birthdate: new Date(dateOfBirth),
|
|
88
89
|
isDead: !isAlive,
|
|
89
90
|
attributes: {
|
|
@@ -94,9 +95,9 @@ export function handleClientRegistryResponse(
|
|
|
94
95
|
address: {
|
|
95
96
|
address1: residence?.address,
|
|
96
97
|
address2: '',
|
|
97
|
-
address4: residence?.ward,
|
|
98
|
+
address4: capitalize(residence?.ward ?? ''),
|
|
98
99
|
cityVillage: residence?.village,
|
|
99
|
-
stateProvince: residence?.subCounty,
|
|
100
|
+
stateProvince: capitalize(residence?.subCounty ?? ''),
|
|
100
101
|
countyDistrict: counties.find((county) => county.code === parseInt(residence?.county))?.name,
|
|
101
102
|
country: 'Kenya',
|
|
102
103
|
postalCode: residence?.address,
|
|
@@ -104,14 +105,21 @@ export function handleClientRegistryResponse(
|
|
|
104
105
|
identifiers: { ...props.values.identifiers, ...nupiIdentifiers },
|
|
105
106
|
obs: {
|
|
106
107
|
'1054AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA':
|
|
107
|
-
props.values.concepts.find(
|
|
108
|
-
|
|
108
|
+
props.values.concepts.find(
|
|
109
|
+
(concept) =>
|
|
110
|
+
concept.display?.toLowerCase()?.includes(clientResponse.client.maritalStatus?.toLowerCase()),
|
|
111
|
+
)?.uuid ?? '',
|
|
109
112
|
'1712AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA':
|
|
110
|
-
props.values.concepts.find(
|
|
111
|
-
|
|
113
|
+
props.values.concepts.find(
|
|
114
|
+
(concept) =>
|
|
115
|
+
concept.display?.toLowerCase()?.includes(clientResponse.client.educationLevel?.toLowerCase()),
|
|
116
|
+
)?.uuid ?? '',
|
|
112
117
|
'1542AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA':
|
|
113
|
-
|
|
114
|
-
|
|
118
|
+
clientResponse.client.occupation === undefined || clientResponse.client.occupation === null
|
|
119
|
+
? '1107AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
|
|
120
|
+
: props.values.concepts.find(
|
|
121
|
+
(concept) => concept.display?.toLowerCase() === clientResponse.client.occupation?.toLowerCase(),
|
|
122
|
+
)?.uuid ?? '5622AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
|
|
115
123
|
},
|
|
116
124
|
});
|
|
117
125
|
dispose();
|