@ampath/esm-patient-registration-app 6.0.1-pre.6 → 6.0.1-pre.66
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/constants.ts +1 -1
- 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 +14 -74
- 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
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":"
|
|
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":"patientPhotoExtension","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.66"}
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ampath/esm-patient-registration-app",
|
|
3
|
-
"version": "6.0.1-pre.
|
|
3
|
+
"version": "6.0.1-pre.66",
|
|
4
4
|
"description": "Patient registration microfrontend for the OpenMRS SPA",
|
|
5
5
|
"browser": "dist/ampath-esm-patient-registration-app.js",
|
|
6
6
|
"main": "src/index.ts",
|
|
7
7
|
"source": true,
|
|
8
8
|
"license": "MPL-2.0",
|
|
9
|
-
"homepage": "https://github.com/
|
|
9
|
+
"homepage": "https://github.com/openmrs/openmrs-esm-patient-management#readme",
|
|
10
10
|
"scripts": {
|
|
11
11
|
"start": "openmrs develop",
|
|
12
12
|
"serve": "webpack serve --mode=development",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"test:watch": "cross-env TZ=UTC jest --watch --config jest.config.js --color",
|
|
19
19
|
"coverage": "yarn test --coverage",
|
|
20
20
|
"typescript": "tsc",
|
|
21
|
-
"extract-translations": "i18next 'src/**/*.component.tsx' 'src/index.ts'"
|
|
21
|
+
"extract-translations": "i18next 'src/**/*.component.tsx' 'src/index.ts' --config ../../tools/i18next-parser.config.js"
|
|
22
22
|
},
|
|
23
23
|
"browserslist": [
|
|
24
24
|
"extends browserslist-config-openmrs"
|
|
@@ -31,18 +31,15 @@
|
|
|
31
31
|
},
|
|
32
32
|
"repository": {
|
|
33
33
|
"type": "git",
|
|
34
|
-
"url": "git+https://github.com/
|
|
34
|
+
"url": "git+https://github.com/openmrs/openmrs-esm-patient-management.git"
|
|
35
35
|
},
|
|
36
36
|
"bugs": {
|
|
37
|
-
"url": "https://github.com/
|
|
37
|
+
"url": "https://github.com/openmrs/openmrs-esm-patient-management/issues"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@carbon/react": "~1.37.0",
|
|
41
|
-
"core-js-pure": "^3.34.0",
|
|
42
41
|
"formik": "^2.1.5",
|
|
43
|
-
"geopattern": "^1.2.3",
|
|
44
42
|
"lodash-es": "^4.17.15",
|
|
45
|
-
"react-avatar": "^5.0.3",
|
|
46
43
|
"uuid": "^8.3.2",
|
|
47
44
|
"yup": "^0.29.1"
|
|
48
45
|
},
|
|
@@ -57,5 +54,5 @@
|
|
|
57
54
|
"devDependencies": {
|
|
58
55
|
"webpack": "^5.74.0"
|
|
59
56
|
},
|
|
60
|
-
"stableVersion": "6.0.0"
|
|
57
|
+
"stableVersion": "6.0.1-pre.1.0.6"
|
|
61
58
|
}
|
package/src/config-schema.ts
CHANGED
|
@@ -19,6 +19,11 @@ export interface FieldDefinition {
|
|
|
19
19
|
};
|
|
20
20
|
answerConceptSetUuid?: string;
|
|
21
21
|
customConceptAnswers?: Array<CustomConceptAnswer>;
|
|
22
|
+
showWhenExpression?: {
|
|
23
|
+
field: string;
|
|
24
|
+
value: string;
|
|
25
|
+
};
|
|
26
|
+
renderType?: string;
|
|
22
27
|
}
|
|
23
28
|
export interface CustomConceptAnswer {
|
|
24
29
|
uuid: string;
|
|
@@ -32,6 +37,7 @@ export interface Gender {
|
|
|
32
37
|
export interface RegistrationConfig {
|
|
33
38
|
sections: Array<string>;
|
|
34
39
|
sectionDefinitions: Array<SectionDefinition>;
|
|
40
|
+
|
|
35
41
|
fieldDefinitions: Array<FieldDefinition>;
|
|
36
42
|
fieldConfigurations: {
|
|
37
43
|
name: {
|
|
@@ -60,14 +66,15 @@ export interface RegistrationConfig {
|
|
|
60
66
|
};
|
|
61
67
|
phone: {
|
|
62
68
|
personAttributeUuid: string;
|
|
69
|
+
validation?: {
|
|
70
|
+
required: boolean;
|
|
71
|
+
matches?: string;
|
|
72
|
+
};
|
|
63
73
|
};
|
|
64
74
|
};
|
|
65
75
|
links: {
|
|
66
76
|
submitButton: string;
|
|
67
77
|
};
|
|
68
|
-
concepts: {
|
|
69
|
-
patientPhotoUuid: string;
|
|
70
|
-
};
|
|
71
78
|
defaultPatientIdentifierTypes: Array<string>;
|
|
72
79
|
registrationObs: {
|
|
73
80
|
encounterTypeUuid: string | null;
|
|
@@ -309,9 +316,17 @@ export const esmPatientRegistrationSchema = {
|
|
|
309
316
|
phone: {
|
|
310
317
|
personAttributeUuid: {
|
|
311
318
|
_type: Type.UUID,
|
|
312
|
-
_default: '
|
|
319
|
+
_default: '72a759a8-1359-11df-a1f1-0026b9348838',
|
|
313
320
|
_description: 'The UUID of the phone number person attribute type',
|
|
314
321
|
},
|
|
322
|
+
validation: {
|
|
323
|
+
required: { _type: Type.Boolean, _default: false },
|
|
324
|
+
matches: {
|
|
325
|
+
_type: Type.String,
|
|
326
|
+
_default: null,
|
|
327
|
+
_description: 'Optional RegEx for testing the validity of the input.',
|
|
328
|
+
},
|
|
329
|
+
},
|
|
315
330
|
},
|
|
316
331
|
},
|
|
317
332
|
links: {
|
|
@@ -321,12 +336,6 @@ export const esmPatientRegistrationSchema = {
|
|
|
321
336
|
_validators: [validators.isUrlWithTemplateParameters(['patientUuid'])],
|
|
322
337
|
},
|
|
323
338
|
},
|
|
324
|
-
concepts: {
|
|
325
|
-
patientPhotoUuid: {
|
|
326
|
-
_type: Type.ConceptUuid,
|
|
327
|
-
_default: '736e8771-e501-4615-bfa7-570c03f4bef5',
|
|
328
|
-
},
|
|
329
|
-
},
|
|
330
339
|
defaultPatientIdentifierTypes: {
|
|
331
340
|
_type: Type.Array,
|
|
332
341
|
_elements: {
|
package/src/constants.ts
CHANGED
|
@@ -6,7 +6,7 @@ export const personRelationshipRepresentation =
|
|
|
6
6
|
'personB:(age,display,birthdate,uuid),' +
|
|
7
7
|
'relationshipType:(uuid,display,description,aIsToB,bIsToA))';
|
|
8
8
|
|
|
9
|
-
export const moduleName = '@
|
|
9
|
+
export const moduleName = '@kenyaemr/esm-patient-registration-app';
|
|
10
10
|
export const patientRegistration = 'patient-registration';
|
|
11
11
|
|
|
12
12
|
export const cacheForOfflineHeaders: OmrsOfflineHttpHeaders = {
|
package/src/index.ts
CHANGED
|
@@ -4,9 +4,8 @@ import { moduleName, patientRegistration } from './constants';
|
|
|
4
4
|
import { setupOffline } from './offline';
|
|
5
5
|
import rootComponent from './root.component';
|
|
6
6
|
import addPatientLinkComponent from './add-patient-link';
|
|
7
|
-
import patientPhotoComponent from './widgets/display-photo.component';
|
|
8
7
|
import editPatientDetailsButtonComponent from './widgets/edit-patient-details-button.component';
|
|
9
|
-
import
|
|
8
|
+
import { PatientPhotoExtension } from './patient-photo.extension';
|
|
10
9
|
|
|
11
10
|
export const importTranslation = require.context('../translations', false, /.json$/, 'lazy');
|
|
12
11
|
|
|
@@ -56,7 +55,7 @@ export const cancelPatientEditModal = getAsyncLifecycle(
|
|
|
56
55
|
options,
|
|
57
56
|
);
|
|
58
57
|
|
|
59
|
-
export const
|
|
58
|
+
export const patientPhotoExtension = getSyncLifecycle(PatientPhotoExtension, options);
|
|
60
59
|
|
|
61
60
|
export const editPatientDetailsButton = getSyncLifecycle(editPatientDetailsButtonComponent, {
|
|
62
61
|
featureName: 'edit-patient-details',
|
|
@@ -68,4 +67,12 @@ export const deleteIdentifierConfirmationModal = getAsyncLifecycle(
|
|
|
68
67
|
options,
|
|
69
68
|
);
|
|
70
69
|
|
|
71
|
-
export const
|
|
70
|
+
export const confirmClientRegistryModal = getAsyncLifecycle(
|
|
71
|
+
() => import('./patient-verification/verification-modal/confirm-prompt.component'),
|
|
72
|
+
options,
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
export const emptyClientRegistryModal = getAsyncLifecycle(
|
|
76
|
+
() => import('./patient-verification/verification-modal/empty-prompt.component'),
|
|
77
|
+
options,
|
|
78
|
+
);
|
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) {
|
|
@@ -103,14 +105,7 @@ async function fetchPatientIdentifierTypes(): Promise<Array<FetchedPatientIdenti
|
|
|
103
105
|
|
|
104
106
|
const primaryIdentifierTypeUuid = primaryIdentifierTypeResponse?.data?.results?.[0]?.metadataUuid;
|
|
105
107
|
|
|
106
|
-
let identifierTypes =
|
|
107
|
-
? [
|
|
108
|
-
mapPatientIdentifierType(
|
|
109
|
-
patientIdentifierTypes?.find((type) => type.uuid === primaryIdentifierTypeUuid),
|
|
110
|
-
true,
|
|
111
|
-
),
|
|
112
|
-
]
|
|
113
|
-
: [];
|
|
108
|
+
let identifierTypes = [];
|
|
114
109
|
|
|
115
110
|
patientIdentifierTypes.forEach((type) => {
|
|
116
111
|
if (type.uuid !== primaryIdentifierTypeUuid) {
|
|
@@ -124,11 +119,11 @@ async function fetchPatientIdentifierTypes(): Promise<Array<FetchedPatientIdenti
|
|
|
124
119
|
}
|
|
125
120
|
|
|
126
121
|
async function fetchIdentifierSources(identifierType: string) {
|
|
127
|
-
return await cacheAndFetch(
|
|
122
|
+
return await cacheAndFetch(`${restBaseUrl}/idgen/identifiersource?v=default&identifierType=${identifierType}`);
|
|
128
123
|
}
|
|
129
124
|
|
|
130
125
|
async function fetchAutoGenerationOptions(abortController?: AbortController) {
|
|
131
|
-
return await cacheAndFetch(
|
|
126
|
+
return await cacheAndFetch(`${restBaseUrl}/idgen/autogenerationoption?v=full`);
|
|
132
127
|
}
|
|
133
128
|
|
|
134
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
|
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { PatientPhoto, type PatientPhotoProps } from '@openmrs/esm-framework';
|
|
3
|
+
|
|
4
|
+
export function PatientPhotoExtension(props: PatientPhotoProps) {
|
|
5
|
+
console.warn(
|
|
6
|
+
'Using the patient-photo extension (or patient-photo-slot slot) is deprecated. Please use the PatientPhoto component from @openmrs/esm-framework.',
|
|
7
|
+
);
|
|
8
|
+
return <PatientPhoto {...props} />;
|
|
9
|
+
}
|
|
@@ -21,6 +21,7 @@ export const AddressField: React.FC<AddressFieldProps> = ({ fieldDefinition }) =
|
|
|
21
21
|
<Input
|
|
22
22
|
id={fieldDefinition.id}
|
|
23
23
|
labelText={t(`${fieldDefinition.label}`, `${fieldDefinition.label}`)}
|
|
24
|
+
required={fieldDefinition?.validation?.required ?? false}
|
|
24
25
|
{...field}
|
|
25
26
|
/>
|
|
26
27
|
);
|
|
@@ -4,6 +4,7 @@ import { type RegistrationConfig } from '../../config-schema';
|
|
|
4
4
|
import { AddressField } from './address/custom-address-field.component';
|
|
5
5
|
import { ObsField } from './obs/obs-field.component';
|
|
6
6
|
import { PersonAttributeField } from './person-attributes/person-attribute-field.component';
|
|
7
|
+
import { useField } from 'formik';
|
|
7
8
|
|
|
8
9
|
export interface CustomFieldProps {
|
|
9
10
|
name: string;
|
|
@@ -13,6 +14,11 @@ export function CustomField({ name }: CustomFieldProps) {
|
|
|
13
14
|
const config = useConfig() as RegistrationConfig;
|
|
14
15
|
const fieldDefinition = config.fieldDefinitions.filter((def) => def.id == name)[0];
|
|
15
16
|
|
|
17
|
+
const [{ value }] = useField(`attributes.${fieldDefinition.showWhenExpression?.field}`);
|
|
18
|
+
if (fieldDefinition.showWhenExpression && value !== fieldDefinition.showWhenExpression.value) {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
|
|
16
22
|
if (fieldDefinition.type === 'person attribute') {
|
|
17
23
|
return <PersonAttributeField fieldDefinition={fieldDefinition} />;
|
|
18
24
|
} else if (fieldDefinition.type === 'obs') {
|
|
@@ -4,7 +4,7 @@ import { useTranslation } from 'react-i18next';
|
|
|
4
4
|
import { useField } from 'formik';
|
|
5
5
|
import { generateFormatting } from '../../date-util';
|
|
6
6
|
import { PatientRegistrationContext } from '../../patient-registration-context';
|
|
7
|
-
import { useConfig } from '@openmrs/esm-framework';
|
|
7
|
+
import { OpenmrsDatePicker, useConfig } from '@openmrs/esm-framework';
|
|
8
8
|
import { type RegistrationConfig } from '../../../config-schema';
|
|
9
9
|
import styles from '../field.scss';
|
|
10
10
|
|
|
@@ -46,8 +46,8 @@ export const DobField: React.FC = () => {
|
|
|
46
46
|
);
|
|
47
47
|
|
|
48
48
|
const onDateChange = useCallback(
|
|
49
|
-
(birthdate: Date
|
|
50
|
-
setFieldValue('birthdate', birthdate
|
|
49
|
+
(birthdate: Date) => {
|
|
50
|
+
setFieldValue('birthdate', birthdate);
|
|
51
51
|
},
|
|
52
52
|
[setFieldValue],
|
|
53
53
|
);
|
|
@@ -101,17 +101,20 @@ export const DobField: React.FC = () => {
|
|
|
101
101
|
<Layer>
|
|
102
102
|
{!dobUnknown ? (
|
|
103
103
|
<div className={styles.dobField}>
|
|
104
|
-
<
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
104
|
+
<OpenmrsDatePicker
|
|
105
|
+
id="birthdate"
|
|
106
|
+
{...birthdate}
|
|
107
|
+
dateFormat={dateFormat}
|
|
108
|
+
onChange={onDateChange}
|
|
109
|
+
//maxDate={today}
|
|
110
|
+
labelText={t('dateOfBirthLabelText', 'Date of Birth')}
|
|
111
|
+
invalid={!!(birthdateMeta.touched && birthdateMeta.error)}
|
|
112
|
+
invalidText={birthdateMeta.error && t(birthdateMeta.error)}
|
|
113
|
+
value={birthdate.value}
|
|
114
|
+
carbonOptions={{
|
|
115
|
+
placeholder: placeHolder,
|
|
116
|
+
}}
|
|
117
|
+
/>
|
|
115
118
|
</div>
|
|
116
119
|
) : (
|
|
117
120
|
<div className={styles.grid}>
|
|
@@ -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
|
@@ -14,6 +14,7 @@ export interface CodedPersonAttributeFieldProps {
|
|
|
14
14
|
answerConceptSetUuid: string;
|
|
15
15
|
label?: string;
|
|
16
16
|
customConceptAnswers: Array<{ uuid: string; label?: string }>;
|
|
17
|
+
required: boolean;
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
export function CodedPersonAttributeField({
|
|
@@ -22,10 +23,12 @@ export function CodedPersonAttributeField({
|
|
|
22
23
|
answerConceptSetUuid,
|
|
23
24
|
label,
|
|
24
25
|
customConceptAnswers,
|
|
26
|
+
required,
|
|
25
27
|
}: CodedPersonAttributeFieldProps) {
|
|
26
28
|
const { data: conceptAnswers, isLoading: isLoadingConceptAnswers } = useConceptAnswers(
|
|
27
29
|
customConceptAnswers.length ? '' : answerConceptSetUuid,
|
|
28
30
|
);
|
|
31
|
+
|
|
29
32
|
const { t } = useTranslation();
|
|
30
33
|
const fieldName = `attributes.${personAttributeType.uuid}`;
|
|
31
34
|
const [error, setError] = useState(false);
|
|
@@ -99,6 +102,7 @@ export function CodedPersonAttributeField({
|
|
|
99
102
|
name={`person-attribute-${personAttributeType.uuid}`}
|
|
100
103
|
labelText={label ?? personAttributeType?.display}
|
|
101
104
|
invalid={errors[fieldName] && touched[fieldName]}
|
|
105
|
+
required={required}
|
|
102
106
|
{...field}>
|
|
103
107
|
<SelectItem value={''} text={t('selectAnOption', 'Select an option')} />
|
|
104
108
|
{answers.map((answer) => (
|
package/src/patient-registration/field/person-attributes/custom-person-attribute-field.component.tsx
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Field } from 'formik';
|
|
3
|
+
import { Layer, Select, SelectItem } from '@carbon/react';
|
|
4
|
+
import { type PersonAttributeTypeResponse } from '../../patient-registration.types';
|
|
5
|
+
import { useTranslation } from 'react-i18next';
|
|
6
|
+
import styles from './../field.scss';
|
|
7
|
+
import classNames from 'classnames';
|
|
8
|
+
|
|
9
|
+
type CustomPersonAttributeFieldProps = {
|
|
10
|
+
id: string;
|
|
11
|
+
personAttributeType: PersonAttributeTypeResponse;
|
|
12
|
+
answerConceptSetUuid: string;
|
|
13
|
+
label?: string;
|
|
14
|
+
customConceptAnswers: Array<{ uuid: string; label?: string }>;
|
|
15
|
+
required: boolean;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const CustomPersonAttributeField: React.FC<CustomPersonAttributeFieldProps> = ({
|
|
19
|
+
personAttributeType,
|
|
20
|
+
required,
|
|
21
|
+
id,
|
|
22
|
+
label,
|
|
23
|
+
customConceptAnswers,
|
|
24
|
+
}) => {
|
|
25
|
+
const { t } = useTranslation();
|
|
26
|
+
const fieldName = `attributes.${personAttributeType.uuid}`;
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<div className={classNames(styles.customField, styles.halfWidthInDesktopView)}>
|
|
30
|
+
<Layer>
|
|
31
|
+
<Field name={fieldName}>
|
|
32
|
+
{({ field, form: { touched, errors }, meta }) => {
|
|
33
|
+
return (
|
|
34
|
+
<>
|
|
35
|
+
<Select
|
|
36
|
+
id={id}
|
|
37
|
+
name={`person-attribute-${personAttributeType.uuid}`}
|
|
38
|
+
labelText={label ?? personAttributeType?.display}
|
|
39
|
+
invalid={errors[fieldName] && touched[fieldName]}
|
|
40
|
+
required={required}
|
|
41
|
+
{...field}>
|
|
42
|
+
<SelectItem value={''} text={t('selectAnOption', 'Select an option')} />
|
|
43
|
+
{customConceptAnswers.map((answer) => (
|
|
44
|
+
<SelectItem key={answer.uuid} value={answer.uuid} text={answer.uuid} />
|
|
45
|
+
))}
|
|
46
|
+
</Select>
|
|
47
|
+
</>
|
|
48
|
+
);
|
|
49
|
+
}}
|
|
50
|
+
</Field>
|
|
51
|
+
</Layer>
|
|
52
|
+
</div>
|
|
53
|
+
);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export default CustomPersonAttributeField;
|
package/src/patient-registration/field/person-attributes/person-attribute-field.component.tsx
CHANGED
|
@@ -6,6 +6,7 @@ import { usePersonAttributeType } from './person-attributes.resource';
|
|
|
6
6
|
import { TextPersonAttributeField } from './text-person-attribute-field.component';
|
|
7
7
|
import { useTranslation } from 'react-i18next';
|
|
8
8
|
import styles from '../field.scss';
|
|
9
|
+
import CustomPersonAttributeField from './custom-person-attribute-field.component';
|
|
9
10
|
|
|
10
11
|
export interface PersonAttributeFieldProps {
|
|
11
12
|
fieldDefinition: FieldDefinition;
|
|
@@ -22,13 +23,26 @@ export function PersonAttributeField({ fieldDefinition }: PersonAttributeFieldPr
|
|
|
22
23
|
switch (personAttributeType.format) {
|
|
23
24
|
case 'java.lang.String':
|
|
24
25
|
return (
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
26
|
+
<>
|
|
27
|
+
{fieldDefinition.renderType === 'select' ? (
|
|
28
|
+
<CustomPersonAttributeField
|
|
29
|
+
personAttributeType={personAttributeType}
|
|
30
|
+
answerConceptSetUuid={fieldDefinition.answerConceptSetUuid}
|
|
31
|
+
label={fieldDefinition.label}
|
|
32
|
+
id={fieldDefinition?.id}
|
|
33
|
+
customConceptAnswers={fieldDefinition.customConceptAnswers ?? []}
|
|
34
|
+
required={fieldDefinition.validation?.required ?? false}
|
|
35
|
+
/>
|
|
36
|
+
) : (
|
|
37
|
+
<TextPersonAttributeField
|
|
38
|
+
personAttributeType={personAttributeType}
|
|
39
|
+
validationRegex={fieldDefinition.validation?.matches ?? ''}
|
|
40
|
+
label={fieldDefinition.label}
|
|
41
|
+
required={fieldDefinition.validation?.required ?? false}
|
|
42
|
+
id={fieldDefinition?.id}
|
|
43
|
+
/>
|
|
44
|
+
)}
|
|
45
|
+
</>
|
|
32
46
|
);
|
|
33
47
|
case 'org.openmrs.Concept':
|
|
34
48
|
return (
|
|
@@ -38,6 +52,7 @@ export function PersonAttributeField({ fieldDefinition }: PersonAttributeFieldPr
|
|
|
38
52
|
label={fieldDefinition.label}
|
|
39
53
|
id={fieldDefinition?.id}
|
|
40
54
|
customConceptAnswers={fieldDefinition.customConceptAnswers ?? []}
|
|
55
|
+
required={fieldDefinition.validation?.required ?? false}
|
|
41
56
|
/>
|
|
42
57
|
);
|
|
43
58
|
default:
|
|
@@ -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
|
|
|
@@ -10,6 +10,7 @@ export function PhoneField() {
|
|
|
10
10
|
id: 'phone',
|
|
11
11
|
type: 'person attribute',
|
|
12
12
|
uuid: config.fieldConfigurations.phone.personAttributeUuid,
|
|
13
|
+
validation: config.fieldConfigurations.phone.validation,
|
|
13
14
|
showHeading: false,
|
|
14
15
|
};
|
|
15
16
|
return <PersonAttributeField fieldDefinition={fieldDefinition} />;
|
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
type FetchResponse,
|
|
3
|
+
openmrsFetch,
|
|
4
|
+
queueSynchronizationItem,
|
|
5
|
+
type Session,
|
|
6
|
+
restBaseUrl,
|
|
7
|
+
getConfig,
|
|
8
|
+
} from '@openmrs/esm-framework';
|
|
2
9
|
import { patientRegistration } from '../constants';
|
|
3
10
|
import {
|
|
4
11
|
type FormValues,
|
|
@@ -124,13 +131,14 @@ export class FormManager {
|
|
|
124
131
|
|
|
125
132
|
await this.saveObservations(values.obs, savePatientResponse, currentLocation, currentUser, config);
|
|
126
133
|
|
|
127
|
-
|
|
134
|
+
const { patientPhotoUuid } = await getConfig('@openmrs/esm-styleguide');
|
|
135
|
+
if (patientPhotoUuid && capturePhotoProps?.imageData) {
|
|
128
136
|
await savePatientPhoto(
|
|
129
137
|
savePatientResponse.data.uuid,
|
|
130
138
|
capturePhotoProps.imageData,
|
|
131
|
-
|
|
139
|
+
`${restBaseUrl}/obs`,
|
|
132
140
|
capturePhotoProps.dateTime || new Date().toISOString(),
|
|
133
|
-
|
|
141
|
+
patientPhotoUuid,
|
|
134
142
|
);
|
|
135
143
|
}
|
|
136
144
|
}
|
|
@@ -181,7 +189,6 @@ export class FormManager {
|
|
|
181
189
|
);
|
|
182
190
|
} else {
|
|
183
191
|
const encounterToSave: Encounter = {
|
|
184
|
-
encounterDatetime: new Date(),
|
|
185
192
|
patient: savePatientResponse.data.uuid,
|
|
186
193
|
encounterType: config.registrationObs.encounterTypeUuid,
|
|
187
194
|
location: currentLocation,
|
|
@@ -354,7 +361,7 @@ export class FormManager {
|
|
|
354
361
|
.filter(([, value]) => !value)
|
|
355
362
|
.forEach(async ([key]) => {
|
|
356
363
|
const attributeUuid = patientUuidMap[`attribute.${key}`];
|
|
357
|
-
await openmrsFetch(
|
|
364
|
+
await openmrsFetch(`${restBaseUrl}/person/${values.patientUuid}/attribute/${attributeUuid}`, {
|
|
358
365
|
method: 'DELETE',
|
|
359
366
|
}).catch((err) => {
|
|
360
367
|
console.error(err);
|