@ampath/esm-patient-registration-app 6.0.1-pre.17 → 6.0.1-pre.172

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.
Files changed (124) hide show
  1. package/.turbo/turbo-build.log +20 -20
  2. package/dist/132.js +1 -1
  3. package/dist/197.js +1 -1
  4. package/dist/236.js +1 -1
  5. package/dist/300.js +1 -1
  6. package/dist/335.js +1 -1
  7. package/dist/41.js +1 -1
  8. package/dist/41.js.map +1 -1
  9. package/dist/449.js +1 -0
  10. package/dist/449.js.map +1 -0
  11. package/dist/55.js +1 -1
  12. package/dist/56.js +1 -1
  13. package/dist/56.js.map +1 -1
  14. package/dist/621.js +1 -0
  15. package/dist/621.js.map +1 -0
  16. package/dist/629.js +2 -0
  17. package/dist/629.js.LICENSE.txt +24 -0
  18. package/dist/629.js.map +1 -0
  19. package/dist/652.js +1 -1
  20. package/dist/661.js +1 -1
  21. package/dist/757.js +1 -0
  22. package/dist/757.js.map +1 -0
  23. package/dist/828.js +1 -0
  24. package/dist/828.js.map +1 -0
  25. package/dist/830.js +1 -0
  26. package/dist/830.js.map +1 -0
  27. package/dist/831.js +1 -1
  28. package/dist/831.js.map +1 -1
  29. package/dist/879.js +1 -1
  30. package/dist/913.js +1 -1
  31. package/dist/913.js.LICENSE.txt +3 -3
  32. package/dist/913.js.map +1 -1
  33. package/dist/927.js +1 -0
  34. package/dist/927.js.map +1 -0
  35. package/dist/99.js +1 -1
  36. package/dist/ampath-esm-patient-registration-app.js +1 -1
  37. package/dist/ampath-esm-patient-registration-app.js.buildmanifest.json +183 -111
  38. package/dist/ampath-esm-patient-registration-app.js.map +1 -1
  39. package/dist/main.js +1 -1
  40. package/dist/main.js.LICENSE.txt +0 -32
  41. package/dist/main.js.map +1 -1
  42. package/dist/routes.json +1 -1
  43. package/package.json +7 -10
  44. package/src/config-schema.ts +19 -10
  45. package/src/index.ts +11 -4
  46. package/src/offline.resources.ts +13 -18
  47. package/src/offline.ts +6 -4
  48. package/src/patient-photo.extension.tsx +9 -0
  49. package/src/patient-registration/field/address/custom-address-field.component.tsx +1 -0
  50. package/src/patient-registration/field/custom-field.component.tsx +6 -0
  51. package/src/patient-registration/field/dob/dob.component.tsx +17 -14
  52. package/src/patient-registration/field/field.resource.ts +3 -3
  53. package/src/patient-registration/field/person-attributes/coded-person-attribute-field.component.tsx +4 -0
  54. package/src/patient-registration/field/person-attributes/custom-person-attribute-field.component.tsx +56 -0
  55. package/src/patient-registration/field/person-attributes/person-attribute-field.component.tsx +22 -7
  56. package/src/patient-registration/field/person-attributes/person-attributes.resource.ts +2 -2
  57. package/src/patient-registration/field/phone/phone-field.component.tsx +1 -0
  58. package/src/patient-registration/form-manager.ts +13 -6
  59. package/src/patient-registration/patient-registration-hooks.ts +133 -9
  60. package/src/patient-registration/patient-registration.component.tsx +55 -13
  61. package/src/patient-registration/{patient-registration.resource.test.tsx → patient-registration.resource.testt.tsx} +4 -4
  62. package/src/patient-registration/patient-registration.resource.ts +15 -75
  63. package/src/patient-registration/patient-registration.scss +0 -8
  64. package/src/patient-registration/patient-registration.types.ts +7 -1
  65. package/src/patient-registration/section/patient-relationships/relationships-section.component.tsx +5 -1
  66. package/src/patient-registration/section/patient-relationships/relationships.resource.tsx +2 -2
  67. package/src/patient-verification/assets/counties.json +236 -0
  68. package/src/patient-verification/assets/verification-assets.ts +11 -0
  69. package/src/patient-verification/patient-verification-hook.tsx +176 -0
  70. package/src/patient-verification/patient-verification-utils.ts +179 -0
  71. package/src/patient-verification/patient-verification.component.tsx +124 -0
  72. package/src/patient-verification/patient-verification.scss +25 -0
  73. package/src/patient-verification/verification-modal/confirm-prompt.component.tsx +72 -0
  74. package/src/patient-verification/verification-modal/empty-prompt.component.tsx +35 -0
  75. package/src/patient-verification/verification-types.ts +50 -0
  76. package/src/routes.json +12 -3
  77. package/translations/am.json +26 -12
  78. package/translations/ar.json +26 -12
  79. package/translations/en.json +18 -4
  80. package/translations/es.json +10 -0
  81. package/translations/fr.json +6 -0
  82. package/translations/he.json +18 -0
  83. package/translations/km.json +18 -0
  84. package/translations/zh.json +30 -22
  85. package/translations/zh_CN.json +30 -22
  86. package/dist/229.js +0 -2
  87. package/dist/229.js.LICENSE.txt +0 -56
  88. package/dist/229.js.map +0 -1
  89. package/dist/537.js +0 -1
  90. package/dist/537.js.map +0 -1
  91. package/dist/885.js +0 -1
  92. package/dist/885.js.map +0 -1
  93. package/dist/918.js +0 -1
  94. package/dist/918.js.map +0 -1
  95. package/src/patient-registration/field/address/tests/address-hierarchy.test.tsx +0 -214
  96. package/src/patient-registration/field/address/tests/address-search-component.test.tsx +0 -135
  97. package/src/patient-registration/field/dob/dob.test.tsx +0 -75
  98. package/src/patient-registration/field/field.test.tsx +0 -294
  99. package/src/patient-registration/field/id/id-field.test.tsx +0 -107
  100. package/src/patient-registration/field/person-attributes/coded-attributes.component.tsx +0 -60
  101. package/src/patient-registration/field/person-attributes/coded-person-attribute-field.test.tsx +0 -127
  102. package/src/patient-registration/field/person-attributes/person-attribute-field.test.tsx +0 -187
  103. package/src/patient-registration/field/person-attributes/text-person-attribute-field.test.tsx +0 -88
  104. package/src/patient-registration/form-manager.test.ts +0 -67
  105. package/src/patient-registration/input/basic-input/select/select-input.test.tsx +0 -49
  106. package/src/patient-registration/input/custom-input/autosuggest/autosuggest.test.tsx +0 -132
  107. package/src/patient-registration/input/custom-input/identifier/identifier-input.test.tsx +0 -107
  108. package/src/patient-registration/patient-registration.test.tsx +0 -471
  109. package/src/patient-registration/section/death-info/death-info-section.test.tsx +0 -64
  110. package/src/patient-registration/section/demographics/demographics-section.test.tsx +0 -83
  111. package/src/patient-registration/section/patient-relationships/relationships-section.test.tsx +0 -100
  112. package/src/patient-verification/client-registry-constants.ts +0 -13
  113. package/src/patient-verification/client-registry.component.tsx +0 -66
  114. package/src/patient-verification/client-registry.scss +0 -1
  115. package/src/patient-verification/utils.tsx +0 -56
  116. package/src/patient-verification/verification-modal.scss +0 -20
  117. package/src/patient-verification/verification.component.tsx +0 -48
  118. package/src/root.test.tsx +0 -32
  119. package/src/widgets/cancel-patient-edit.test.tsx +0 -27
  120. package/src/widgets/display-photo.component.tsx +0 -30
  121. package/src/widgets/display-photo.test.tsx +0 -37
  122. package/src/widgets/edit-patient-details-button.test.tsx +0 -41
  123. /package/src/patient-registration/input/custom-input/identifier/{utils.test.ts → utils.testt.ts} +0 -0
  124. /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":"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},{"name":"client-registry-modal","component":"clientRegistryModal"}],"version":"6.0.1-pre.17"}
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.172"}
package/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "@ampath/esm-patient-registration-app",
3
- "version": "6.0.1-pre.17",
3
+ "version": "6.0.1-pre.172",
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/ampath/ampath-esm-3.x#readme",
9
+ "homepage": "https://github.com/openmrs/openmrs-esm-patient-management#readme",
10
10
  "scripts": {
11
- "start": "openmrs develop ",
11
+ "start": "openmrs develop",
12
12
  "serve": "webpack serve --mode=development",
13
13
  "debug": "npm run serve",
14
14
  "build": "webpack --mode production",
@@ -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/ampath/ampath-esm-3.x.git"
34
+ "url": "git+https://github.com/openmrs/openmrs-esm-patient-management.git"
35
35
  },
36
36
  "bugs": {
37
- "url": "https://github.com/ampath/ampath-esm-3.x/issues"
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
  }
@@ -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: '14d4f066-15f5-102d-96e4-000c29c2a5d7',
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/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 VerificationModal from './patient-verification/verification.component';
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 patientPhoto = getSyncLifecycle(patientPhotoComponent, options);
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 clientRegistryModal = getSyncLifecycle(VerificationModal, options);
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
+ );
@@ -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>('/ws/rest/v1/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>('/ws/rest/v1/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('/ws/rest/v1/relationshiptype?v=default');
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 = `/ws/rest/v1/personattributetype/${fieldDefinition.uuid}`;
62
+ apiUrl = `${restBaseUrl}/personattributetype/${fieldDefinition.uuid}`;
63
63
  }
64
64
 
65
65
  if (fieldDefinition.answerConceptSetUuid) {
66
- await cacheAndFetch(`/ws/rest/v1/concept/${fieldDefinition.answerConceptSetUuid}`);
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('/ws/rest/v1/patientidentifiertype?v=custom:(display,uuid,name,format,required,uniquenessBehavior)'),
97
- cacheAndFetch('/ws/rest/v1/metadatamapping/termmapping?v=full&code=emr.primaryIdentifierType'),
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 = primaryIdentifierTypeResponse?.ok
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(`/ws/rest/v1/idgen/identifiersource?v=default&identifierType=${identifierType}`);
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(`/ws/rest/v1/idgen/autogenerationoption?v=full`);
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
- `/ws/fhir2/R4/Patient/${patientUuid}`,
58
- `/ws/rest/v1/relationship?v=${personRelationshipRepresentation}&person=${patientUuid}`,
59
- `/ws/rest/v1/person/${patientUuid}/attribute`,
60
- `/ws/rest/v1/patient/${patientUuid}/identifier?v=custom:(uuid,identifier,identifierType:(uuid,required,name),preferred)`,
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[0]);
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
- <DatePicker dateFormat={dateFormat} datePickerType="single" onChange={onDateChange} maxDate={format(today)}>
105
- <DatePickerInput
106
- id="birthdate"
107
- {...birthdate}
108
- placeholder={placeHolder}
109
- labelText={t('dateOfBirthLabelText', 'Date of Birth')}
110
- invalid={!!(birthdateMeta.touched && birthdateMeta.error)}
111
- invalidText={birthdateMeta.error && t(birthdateMeta.error)}
112
- value={format(birthdate.value)}
113
- />
114
- </DatePicker>
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 ? `/ws/rest/v1/concept/${conceptUuid}` : null,
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 ? `/ws/rest/v1/concept/${conceptUuid}` : null,
24
+ shouldFetch ? `${restBaseUrl}/concept/${conceptUuid}` : null,
25
25
  openmrsFetch,
26
26
  );
27
27
  if (error) {
@@ -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) => (
@@ -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;
@@ -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
- <TextPersonAttributeField
26
- personAttributeType={personAttributeType}
27
- validationRegex={fieldDefinition.validation?.matches ?? ''}
28
- label={fieldDefinition.label}
29
- required={fieldDefinition.validation?.required ?? false}
30
- id={fieldDefinition?.id}
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
- `/ws/rest/v1/personattributetype/${personAttributeTypeUuid}`,
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 { type FetchResponse, openmrsFetch, queueSynchronizationItem, type Session } from '@openmrs/esm-framework';
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
- if (config.concepts.patientPhotoUuid && capturePhotoProps?.imageData) {
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
- '/ws/rest/v1/obs',
139
+ `${restBaseUrl}/obs`,
132
140
  capturePhotoProps.dateTime || new Date().toISOString(),
133
- config.concepts.patientPhotoUuid,
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(`/ws/rest/v1/person/${values.patientUuid}/attribute/${attributeUuid}`, {
364
+ await openmrsFetch(`${restBaseUrl}/person/${values.patientUuid}/attribute/${attributeUuid}`, {
358
365
  method: 'DELETE',
359
366
  }).catch((err) => {
360
367
  console.error(err);