@ampath/esm-patient-registration-app 6.0.1-pre.98 → 9.2.0-next.14

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 (285) hide show
  1. package/dist/1119.js +1 -0
  2. package/dist/1197.js +1 -0
  3. package/dist/1909.js +2 -0
  4. package/dist/{629.js.LICENSE.txt → 1909.js.LICENSE.txt} +9 -3
  5. package/dist/1909.js.map +1 -0
  6. package/dist/2146.js +1 -0
  7. package/dist/2372.js +1 -0
  8. package/dist/2372.js.map +1 -0
  9. package/dist/2470.js +1 -0
  10. package/dist/2470.js.map +1 -0
  11. package/dist/2690.js +1 -0
  12. package/dist/2913.js +2 -0
  13. package/dist/{913.js.LICENSE.txt → 2913.js.LICENSE.txt} +3 -23
  14. package/dist/2913.js.map +1 -0
  15. package/dist/3093.js +1 -0
  16. package/dist/3093.js.map +1 -0
  17. package/dist/3099.js +1 -0
  18. package/dist/3144.js +2 -0
  19. package/dist/3144.js.LICENSE.txt +19 -0
  20. package/dist/3144.js.map +1 -0
  21. package/dist/320.js +2 -0
  22. package/dist/{876.js.LICENSE.txt → 320.js.LICENSE.txt} +2 -3
  23. package/dist/320.js.map +1 -0
  24. package/dist/3464.js +1 -0
  25. package/dist/3464.js.map +1 -0
  26. package/dist/3474.js +2 -0
  27. package/dist/3474.js.LICENSE.txt +8 -0
  28. package/dist/3474.js.map +1 -0
  29. package/dist/3584.js +1 -0
  30. package/dist/4041.js +2 -0
  31. package/dist/4041.js.map +1 -0
  32. package/dist/4055.js +1 -0
  33. package/dist/4132.js +1 -0
  34. package/dist/4300.js +1 -0
  35. package/dist/4335.js +1 -0
  36. package/dist/4463.js +1 -0
  37. package/dist/4463.js.map +1 -0
  38. package/dist/4618.js +1 -0
  39. package/dist/4652.js +1 -0
  40. package/dist/4944.js +1 -0
  41. package/dist/5173.js +1 -0
  42. package/dist/5239.js +2 -0
  43. package/dist/5239.js.LICENSE.txt +29 -0
  44. package/dist/5239.js.map +1 -0
  45. package/dist/5241.js +1 -0
  46. package/dist/5442.js +1 -0
  47. package/dist/5661.js +1 -0
  48. package/dist/6022.js +1 -0
  49. package/dist/627.js +1 -0
  50. package/dist/627.js.map +1 -0
  51. package/dist/6276.js +1 -0
  52. package/dist/6276.js.map +1 -0
  53. package/dist/6336.js +1 -0
  54. package/dist/6336.js.map +1 -0
  55. package/dist/6468.js +1 -0
  56. package/dist/6679.js +1 -0
  57. package/dist/6840.js +1 -0
  58. package/dist/6859.js +1 -0
  59. package/dist/7071.js +1 -0
  60. package/dist/7071.js.map +1 -0
  61. package/dist/7097.js +1 -0
  62. package/dist/7159.js +1 -0
  63. package/dist/723.js +1 -0
  64. package/dist/729.js +2 -0
  65. package/dist/729.js.LICENSE.txt +9 -0
  66. package/dist/729.js.map +1 -0
  67. package/dist/7495.js +2 -0
  68. package/dist/7495.js.LICENSE.txt +9 -0
  69. package/dist/7495.js.map +1 -0
  70. package/dist/7617.js +1 -0
  71. package/dist/795.js +1 -0
  72. package/dist/8163.js +1 -0
  73. package/dist/8349.js +1 -0
  74. package/dist/8434.js +1 -0
  75. package/dist/8434.js.map +1 -0
  76. package/dist/8618.js +1 -0
  77. package/dist/89.js +2 -0
  78. package/dist/89.js.LICENSE.txt +9 -0
  79. package/dist/89.js.map +1 -0
  80. package/dist/890.js +1 -0
  81. package/dist/9214.js +1 -0
  82. package/dist/9538.js +1 -0
  83. package/dist/9569.js +1 -0
  84. package/dist/986.js +1 -0
  85. package/dist/9876.js +1 -0
  86. package/dist/9876.js.map +1 -0
  87. package/dist/9879.js +1 -0
  88. package/dist/9895.js +1 -0
  89. package/dist/9900.js +1 -0
  90. package/dist/9913.js +1 -0
  91. package/dist/main.js +1 -1
  92. package/dist/main.js.LICENSE.txt +36 -1
  93. package/dist/main.js.map +1 -1
  94. package/dist/openmrs-esm-patient-registration-app.js +1 -0
  95. package/dist/openmrs-esm-patient-registration-app.js.buildmanifest.json +1549 -0
  96. package/dist/openmrs-esm-patient-registration-app.js.map +1 -0
  97. package/dist/routes.json +1 -1
  98. package/package.json +15 -13
  99. package/src/{add-patient-link.tsx → add-patient-link.extension.tsx} +4 -2
  100. package/src/add-patient-link.test.tsx +6 -10
  101. package/src/config-schema.ts +109 -55
  102. package/src/constants.ts +1 -1
  103. package/src/declarations.d.ts +5 -4
  104. package/src/index.ts +10 -29
  105. package/src/nav-link.test.tsx +3 -3
  106. package/src/offline.resources.ts +26 -18
  107. package/src/patient-photo.extension.tsx +3 -1
  108. package/src/patient-registration/field/address/address-field.component.tsx +58 -37
  109. package/src/patient-registration/field/address/address-hierarchy-levels.component.tsx +16 -18
  110. package/src/patient-registration/field/address/address-hierarchy.resource.tsx +3 -3
  111. package/src/patient-registration/field/address/address-hierarchy.test.tsx +290 -0
  112. package/src/patient-registration/field/address/address-search.component.tsx +7 -5
  113. package/src/patient-registration/field/address/address-search.scss +5 -5
  114. package/src/patient-registration/field/address/address-search.test.tsx +140 -0
  115. package/src/patient-registration/field/cause-of-death/cause-of-death.component.tsx +98 -0
  116. package/src/patient-registration/field/custom-field.component.tsx +3 -9
  117. package/src/patient-registration/field/date-and-time-of-death/date-and-time-of-death.component.tsx +84 -0
  118. package/src/patient-registration/field/dob/dob.component.tsx +55 -50
  119. package/src/patient-registration/field/dob/dob.test.tsx +90 -0
  120. package/src/patient-registration/field/field.component.tsx +12 -6
  121. package/src/patient-registration/field/field.resource.ts +11 -4
  122. package/src/patient-registration/field/field.scss +69 -25
  123. package/src/patient-registration/field/field.test.tsx +329 -0
  124. package/src/patient-registration/field/gender/gender-field.component.tsx +14 -9
  125. package/src/patient-registration/field/gender/gender-field.test.tsx +73 -33
  126. package/src/patient-registration/field/id/id-field.component.tsx +24 -23
  127. package/src/patient-registration/field/id/id-field.test.tsx +147 -0
  128. package/src/patient-registration/field/id/identifier-selection-overlay.component.tsx +12 -10
  129. package/src/patient-registration/field/id/identifier-selection.scss +12 -8
  130. package/src/patient-registration/field/name/name-field.component.tsx +10 -5
  131. package/src/patient-registration/field/obs/obs-field.component.tsx +59 -2
  132. package/src/patient-registration/field/obs/obs-field.test.tsx +133 -39
  133. package/src/patient-registration/field/person-attributes/coded-person-attribute-field.component.tsx +3 -3
  134. package/src/patient-registration/field/person-attributes/coded-person-attribute-field.test.tsx +141 -0
  135. package/src/patient-registration/field/person-attributes/location-person-attribute-field.component.tsx +105 -0
  136. package/src/patient-registration/field/person-attributes/location-person-attribute-field.resource.tsx +48 -0
  137. package/src/patient-registration/field/person-attributes/person-attribute-field.component.tsx +19 -22
  138. package/src/patient-registration/field/person-attributes/person-attribute-field.test.tsx +193 -0
  139. package/src/patient-registration/field/person-attributes/text-person-attribute-field.test.tsx +90 -0
  140. package/src/patient-registration/form-manager.test.ts +91 -0
  141. package/src/patient-registration/form-manager.ts +49 -23
  142. package/src/patient-registration/input/basic-input/input/input.component.tsx +6 -2
  143. package/src/patient-registration/input/basic-input/select/select-input.test.tsx +49 -0
  144. package/src/patient-registration/input/custom-input/autosuggest/autosuggest.scss +5 -5
  145. package/src/patient-registration/input/custom-input/autosuggest/autosuggest.test.tsx +164 -0
  146. package/src/patient-registration/input/custom-input/identifier/identifier-input.component.tsx +73 -36
  147. package/src/patient-registration/input/custom-input/identifier/identifier-input.test.tsx +335 -0
  148. package/src/patient-registration/input/dummy-data/dummy-data-input.component.tsx +3 -0
  149. package/src/patient-registration/input/dummy-data/dummy-data-input.test.tsx +2 -11
  150. package/src/patient-registration/input/input.scss +17 -13
  151. package/src/patient-registration/patient-registration-context.ts +22 -11
  152. package/src/patient-registration/patient-registration-hooks.ts +158 -193
  153. package/src/patient-registration/patient-registration-utils.test.ts +33 -0
  154. package/src/patient-registration/patient-registration-utils.ts +11 -13
  155. package/src/patient-registration/patient-registration.component.tsx +87 -103
  156. package/src/patient-registration/{patient-registration.resource.testt.tsx → patient-registration.resource.test.tsx} +0 -4
  157. package/src/patient-registration/patient-registration.resource.ts +27 -3
  158. package/src/patient-registration/patient-registration.scss +27 -38
  159. package/src/patient-registration/patient-registration.test.tsx +579 -0
  160. package/src/patient-registration/patient-registration.types.ts +23 -25
  161. package/src/patient-registration/section/death-info/death-info-section.component.tsx +22 -17
  162. package/src/patient-registration/section/death-info/death-info-section.test.tsx +47 -0
  163. package/src/patient-registration/section/demographics/demographics-section.component.tsx +5 -5
  164. package/src/patient-registration/section/demographics/demographics-section.test.tsx +98 -0
  165. package/src/patient-registration/section/patient-relationships/relationships-section.component.tsx +8 -7
  166. package/src/patient-registration/section/patient-relationships/relationships-section.test.tsx +113 -0
  167. package/src/patient-registration/section/patient-relationships/relationships.resource.tsx +28 -28
  168. package/src/patient-registration/section/patient-relationships/relationships.scss +4 -4
  169. package/src/patient-registration/section/section-wrapper.component.tsx +1 -1
  170. package/src/patient-registration/section/section.component.tsx +1 -1
  171. package/src/patient-registration/section/section.scss +21 -1
  172. package/src/patient-registration/ui-components/overlay/overlay.scss +8 -8
  173. package/src/patient-registration/validation/{patient-registration-validation.test.tsx → patient-registration-validation.test.ts} +71 -23
  174. package/src/patient-registration/validation/patient-registration-validation.ts +123 -0
  175. package/src/resources-context.ts +14 -0
  176. package/src/root.component.tsx +3 -3
  177. package/src/routes.json +10 -24
  178. package/src/widgets/cancel-patient-edit.modal.tsx +33 -0
  179. package/src/widgets/cancel-patient-edit.test.tsx +22 -0
  180. package/src/widgets/delete-identifier-confirmation.modal.tsx +48 -0
  181. package/src/widgets/{delete-identifier-confirmation-modal.testt.tsx → delete-identifier-confirmation.test.tsx} +5 -7
  182. package/src/widgets/edit-patient-details-button.component.tsx +0 -1
  183. package/src/widgets/edit-patient-details-button.test.tsx +35 -0
  184. package/translations/am.json +43 -35
  185. package/translations/ar.json +41 -33
  186. package/translations/ar_SY.json +119 -0
  187. package/translations/bn.json +119 -0
  188. package/translations/de.json +119 -0
  189. package/translations/en.json +44 -42
  190. package/translations/en_US.json +119 -0
  191. package/translations/es.json +69 -57
  192. package/translations/es_MX.json +119 -0
  193. package/translations/fr.json +74 -58
  194. package/translations/he.json +44 -40
  195. package/translations/hi.json +119 -0
  196. package/translations/hi_IN.json +119 -0
  197. package/translations/id.json +119 -0
  198. package/translations/it.json +119 -0
  199. package/translations/ka.json +119 -0
  200. package/translations/km.json +44 -40
  201. package/translations/ku.json +119 -0
  202. package/translations/ky.json +119 -0
  203. package/translations/lg.json +119 -0
  204. package/translations/ne.json +119 -0
  205. package/translations/pl.json +119 -0
  206. package/translations/pt.json +119 -0
  207. package/translations/pt_BR.json +119 -0
  208. package/translations/qu.json +119 -0
  209. package/translations/ro_RO.json +119 -0
  210. package/translations/ru_RU.json +119 -0
  211. package/translations/si.json +119 -0
  212. package/translations/sw.json +119 -0
  213. package/translations/sw_KE.json +119 -0
  214. package/translations/tr.json +119 -0
  215. package/translations/tr_TR.json +119 -0
  216. package/translations/uk.json +119 -0
  217. package/translations/uz.json +119 -0
  218. package/translations/uz@Latn.json +119 -0
  219. package/translations/uz_UZ.json +119 -0
  220. package/translations/vi.json +119 -0
  221. package/translations/zh.json +45 -23
  222. package/translations/zh_CN.json +39 -17
  223. package/.turbo/turbo-build.log +0 -40
  224. package/dist/132.js +0 -1
  225. package/dist/197.js +0 -1
  226. package/dist/236.js +0 -1
  227. package/dist/236.js.map +0 -1
  228. package/dist/300.js +0 -1
  229. package/dist/335.js +0 -1
  230. package/dist/372.js +0 -1
  231. package/dist/372.js.map +0 -1
  232. package/dist/41.js +0 -2
  233. package/dist/41.js.map +0 -1
  234. package/dist/449.js +0 -1
  235. package/dist/449.js.map +0 -1
  236. package/dist/464.js +0 -1
  237. package/dist/464.js.map +0 -1
  238. package/dist/495.js +0 -1
  239. package/dist/495.js.map +0 -1
  240. package/dist/55.js +0 -1
  241. package/dist/56.js +0 -1
  242. package/dist/56.js.map +0 -1
  243. package/dist/621.js +0 -1
  244. package/dist/621.js.map +0 -1
  245. package/dist/629.js +0 -2
  246. package/dist/629.js.map +0 -1
  247. package/dist/652.js +0 -1
  248. package/dist/661.js +0 -1
  249. package/dist/757.js +0 -1
  250. package/dist/757.js.map +0 -1
  251. package/dist/828.js +0 -1
  252. package/dist/828.js.map +0 -1
  253. package/dist/830.js +0 -1
  254. package/dist/830.js.map +0 -1
  255. package/dist/831.js +0 -2
  256. package/dist/831.js.LICENSE.txt +0 -3
  257. package/dist/831.js.map +0 -1
  258. package/dist/876.js +0 -2
  259. package/dist/876.js.map +0 -1
  260. package/dist/879.js +0 -1
  261. package/dist/913.js +0 -2
  262. package/dist/913.js.map +0 -1
  263. package/dist/927.js +0 -1
  264. package/dist/927.js.map +0 -1
  265. package/dist/99.js +0 -1
  266. package/dist/ampath-esm-patient-registration-app.js +0 -1
  267. package/dist/ampath-esm-patient-registration-app.js.buildmanifest.json +0 -694
  268. package/dist/ampath-esm-patient-registration-app.js.map +0 -1
  269. package/src/patient-registration/date-util.ts +0 -52
  270. package/src/patient-registration/field/person-attributes/custom-person-attribute-field.component.tsx +0 -56
  271. package/src/patient-registration/validation/patient-registration-validation.tsx +0 -60
  272. package/src/patient-verification/assets/counties.json +0 -236
  273. package/src/patient-verification/assets/verification-assets.ts +0 -11
  274. package/src/patient-verification/patient-verification-hook.tsx +0 -176
  275. package/src/patient-verification/patient-verification-utils.ts +0 -179
  276. package/src/patient-verification/patient-verification.component.tsx +0 -124
  277. package/src/patient-verification/patient-verification.scss +0 -25
  278. package/src/patient-verification/verification-modal/confirm-prompt.component.tsx +0 -72
  279. package/src/patient-verification/verification-modal/empty-prompt.component.tsx +0 -35
  280. package/src/patient-verification/verification-types.ts +0 -50
  281. package/src/widgets/cancel-patient-edit.component.tsx +0 -37
  282. package/src/widgets/delete-identifier-confirmation-modal.tsx +0 -41
  283. package/src/widgets/delete-identifier-modal.scss +0 -34
  284. /package/dist/{41.js.LICENSE.txt → 4041.js.LICENSE.txt} +0 -0
  285. /package/src/patient-registration/input/custom-input/identifier/{utils.testt.ts → utils.test.ts} +0 -0
@@ -1,6 +1,7 @@
1
- import { type FetchResponse, openmrsFetch, showSnackbar, restBaseUrl } from '@openmrs/esm-framework';
1
+ import { type FetchResponse, openmrsFetch, restBaseUrl, showSnackbar } from '@openmrs/esm-framework';
2
2
  import useSWRImmutable from 'swr/immutable';
3
3
  import { type ConceptAnswers, type ConceptResponse } from '../patient-registration.types';
4
+ import { useMemo } from 'react';
4
5
 
5
6
  export function useConcept(conceptUuid: string): { data: ConceptResponse; isLoading: boolean } {
6
7
  const shouldFetch = typeof conceptUuid === 'string' && conceptUuid !== '';
@@ -15,10 +16,15 @@ export function useConcept(conceptUuid: string): { data: ConceptResponse; isLoad
15
16
  kind: 'error',
16
17
  });
17
18
  }
18
- return { data: data?.data, isLoading };
19
+ const results = useMemo(() => ({ data: data?.data, isLoading }), [data, isLoading]);
20
+ return results;
19
21
  }
20
22
 
21
- export function useConceptAnswers(conceptUuid: string): { data: Array<ConceptAnswers>; isLoading: boolean } {
23
+ export function useConceptAnswers(conceptUuid: string): {
24
+ data: Array<ConceptAnswers>;
25
+ isLoading: boolean;
26
+ error: Error;
27
+ } {
22
28
  const shouldFetch = typeof conceptUuid === 'string' && conceptUuid !== '';
23
29
  const { data, error, isLoading } = useSWRImmutable<FetchResponse<ConceptResponse>, Error>(
24
30
  shouldFetch ? `${restBaseUrl}/concept/${conceptUuid}` : null,
@@ -31,5 +37,6 @@ export function useConceptAnswers(conceptUuid: string): { data: Array<ConceptAns
31
37
  kind: 'error',
32
38
  });
33
39
  }
34
- return { data: data?.data?.answers, isLoading };
40
+ const results = useMemo(() => ({ data: data?.data?.answers, isLoading, error }), [isLoading, error, data]);
41
+ return results;
35
42
  }
@@ -1,16 +1,17 @@
1
- @use '@carbon/styles/scss/spacing';
2
- @use '@carbon/styles/scss/type';
3
- @import '~@openmrs/esm-styleguide/src/vars';
1
+ @use '@carbon/colors';
2
+ @use '@carbon/layout';
3
+ @use '@carbon/type';
4
+ @use '@openmrs/esm-styleguide/src/vars' as *;
4
5
 
5
6
  .productiveHeading02 {
6
7
  @include type.type-style('heading-compact-02');
7
- margin-bottom: 1rem;
8
+ margin-bottom: layout.$spacing-05;
8
9
  }
9
10
 
10
11
  .productiveHeading02Light {
11
12
  @include type.type-style('heading-compact-02');
12
- margin-bottom: 1rem;
13
- color: #525252;
13
+ margin-bottom: layout.$spacing-05;
14
+ color: colors.$gray-70;
14
15
  }
15
16
 
16
17
  .label01 {
@@ -20,11 +21,11 @@
20
21
  .grid {
21
22
  display: grid;
22
23
  grid-template-columns: 1fr 1fr;
23
- column-gap: spacing.$spacing-05;
24
+ column-gap: layout.$spacing-05;
24
25
  }
25
26
 
26
27
  .halfWidthInDesktopView {
27
- width: calc(50% - spacing.$spacing-05);
28
+ width: calc(50% - layout.$spacing-05);
28
29
  }
29
30
 
30
31
  .patientPhoto {
@@ -45,7 +46,7 @@
45
46
  }
46
47
 
47
48
  .contentSwitcher {
48
- margin-bottom: 1rem;
49
+ margin-bottom: layout.$spacing-05;
49
50
  }
50
51
 
51
52
  .dobField > :global(.cds--content-switcher) {
@@ -56,19 +57,41 @@
56
57
  }
57
58
 
58
59
  .photoExtension {
59
- margin-bottom: 1rem;
60
+ margin-bottom: layout.$spacing-05;
60
61
  grid-row: 1;
61
62
  grid-column: 2;
62
63
  justify-self: center;
63
64
  }
64
65
 
65
66
  .sexField,
66
- .dobField {
67
- margin-bottom: spacing.$spacing-05;
67
+ .dobField,
68
+ .dodField {
69
+ margin-bottom: layout.$spacing-05;
70
+
71
+ span {
72
+ display: flex;
73
+ flex-flow: row nowrap;
74
+ justify-content: space-between;
75
+ align-items: start;
76
+ }
77
+ }
78
+
79
+ .nonCodedCauseOfDeath {
80
+ margin-top: layout.$spacing-04;
81
+ }
82
+
83
+ .timeOfDeathContainer {
84
+ display: flex;
85
+ align-items: center;
86
+ }
87
+
88
+ .timeOfDeathField {
89
+ flex: none;
90
+ margin-left: layout.$spacing-02;
68
91
  }
69
92
 
70
93
  .dobContentSwitcherLabel {
71
- margin-bottom: spacing.$spacing-03;
94
+ margin-bottom: layout.$spacing-03;
72
95
  }
73
96
 
74
97
  .identifierLabelText {
@@ -76,20 +99,37 @@
76
99
  align-items: center;
77
100
  }
78
101
 
79
- .setIDNumberButton {
80
- margin-bottom: spacing.$spacing-05;
102
+ .arrowRightIcon {
103
+ fill: currentColor !important;
81
104
  }
82
105
 
83
- .setIDNumberButton > svg {
84
- margin-left: spacing.$spacing-03;
85
- }
106
+ .configureIdentifiersButton {
107
+ display: flex;
108
+ align-items: center;
109
+ margin: 0 0 layout.$spacing-05 layout.$spacing-05;
86
110
 
87
- .customField {
88
- margin-bottom: spacing.$spacing-05;
111
+ svg {
112
+ margin-left: layout.$spacing-03;
113
+ }
114
+
115
+ .customField {
116
+ margin-bottom: layout.$spacing-05;
117
+ }
89
118
  }
90
119
 
91
120
  .attributeField {
92
- margin-bottom: spacing.$spacing-05;
121
+ margin-bottom: layout.$spacing-05;
122
+ }
123
+
124
+ .locationAttributeFieldContainer {
125
+ position: relative;
126
+
127
+ .loadingContainer {
128
+ background-color: colors.$white;
129
+ position: absolute;
130
+ right: layout.$spacing-07;
131
+ bottom: layout.$spacing-02;
132
+ }
93
133
  }
94
134
 
95
135
  :global(.omrs-breakpoint-lt-desktop) {
@@ -97,31 +137,35 @@
97
137
  grid-template-columns: 1fr;
98
138
  grid-template-rows: auto auto;
99
139
  }
140
+
100
141
  .nameField {
101
142
  grid-row: 2;
102
143
  grid-column: 1;
103
144
  }
145
+
104
146
  .photoExtension {
105
147
  grid-column: 1;
106
148
  grid-row: 1;
107
149
  justify-self: start;
108
150
  }
151
+
109
152
  .radioButton label {
110
- height: spacing.$spacing-09 !important;
153
+ height: layout.$spacing-09 !important;
111
154
  }
155
+
112
156
  .halfWidthInDesktopView {
113
157
  width: 100%;
114
158
  }
115
159
  }
116
160
 
117
161
  .radioFieldError {
118
- color: #da1e28;
162
+ color: colors.$red-60;
119
163
  display: block;
120
164
  font-weight: 400;
121
165
  max-height: 12.5rem;
122
166
  overflow: visible;
123
- font-size: 0.75rem;
167
+ font-size: layout.$spacing-04;
124
168
  letter-spacing: 0.32px;
125
169
  line-height: 1.34;
126
- margin: 0.25rem 0 0;
170
+ margin: layout.$spacing-02 0 0;
127
171
  }
@@ -0,0 +1,329 @@
1
+ import React from 'react';
2
+ import { Form, Formik } from 'formik';
3
+ import { render, screen } from '@testing-library/react';
4
+ import { getDefaultsFromConfigSchema, useConfig } from '@openmrs/esm-framework';
5
+ import { Field } from './field.component';
6
+ import { esmPatientRegistrationSchema, type RegistrationConfig } from '../../config-schema';
7
+ import { type Resources } from '../../offline.resources';
8
+ import type { AddressTemplate, FormValues } from '../patient-registration.types';
9
+ import { PatientRegistrationContextProvider } from '../patient-registration-context';
10
+ import { ResourcesContextProvider } from '../../resources-context';
11
+ import { renderWithContext } from 'tools';
12
+
13
+ const mockUseConfig = jest.mocked(useConfig<RegistrationConfig>);
14
+
15
+ const predefinedAddressTemplate = {
16
+ uuid: 'test-address-template-uuid',
17
+ property: 'layout.address.format',
18
+ description: 'Test Address Template',
19
+ display:
20
+ 'Layout - Address Format = <org.openmrs.layout.address.AddressTemplate>\n <nameMappings class="properties">\n <property name="postalCode" value="Location.postalCode"/>\n <property name="address2" value="Location.address2"/>\n <property name="address1" value="Location.address1"/>\n <property name="country" value="Location.country"/>\n <property name="stateProvince" value="Location.stateProvince"/>\n <property name="cityVillage" value="Location.cityVillage"/>\n </nameMappings>\n <sizeMappings class="properties">\n <property name="postalCode" value="10"/>\n <property name="address2" value="40"/>\n <property name="address1" value="40"/>\n <property name="country" value="10"/>\n <property name="stateProvince" value="10"/>\n <property name="cityVillage" value="10"/>\n </sizeMappings>\n <lineByLineFormat>\n <string>address1</string>\n <string>address2</string>\n <string>cityVillage stateProvince country postalCode</string>\n </lineByLineFormat>\n </org.openmrs.layout.address.AddressTemplate>',
21
+ value:
22
+ '<org.openmrs.layout.address.AddressTemplate>\r\n <nameMappings class="properties">\r\n <property name="postalCode" value="Location.postalCode"/>\r\n <property name="address2" value="Location.address2"/>\r\n <property name="address1" value="Location.address1"/>\r\n <property name="country" value="Location.country"/>\r\n <property name="stateProvince" value="Location.stateProvince"/>\r\n <property name="cityVillage" value="Location.cityVillage"/>\r\n </nameMappings>\r\n <sizeMappings class="properties">\r\n <property name="postalCode" value="4"/>\r\n <property name="address1" value="40"/>\r\n <property name="address2" value="40"/>\r\n <property name="country" value="10"/>\r\n <property name="stateProvince" value="10"/>\r\n <property name="cityVillage" value="10"/>\r\n <asset name="cityVillage" value="10"/>\r\n </sizeMappings>\r\n <lineByLineFormat>\r\n <string>address1 address2</string>\r\n <string>cityVillage stateProvince postalCode</string>\r\n <string>country</string>\r\n </lineByLineFormat>\r\n <elementDefaults class="properties">\r\n <property name="country" value=""/>\r\n </elementDefaults>\r\n <elementRegex class="properties">\r\n <property name="address1" value="[a-zA-Z]+$"/>\r\n </elementRegex>\r\n <elementRegexFormats class="properties">\r\n <property name="address1" value="Countries can only be letters"/>\r\n </elementRegexFormats>\r\n </org.openmrs.layout.address.AddressTemplate>',
23
+ };
24
+
25
+ const mockIdentifierTypes = [
26
+ {
27
+ fieldName: 'openMrsId',
28
+ format: '',
29
+ identifierSources: [
30
+ {
31
+ uuid: '8549f706-7e85-4c1d-9424-217d50a2988b',
32
+ name: 'Generator for OpenMRS ID',
33
+ description: 'Generator for OpenMRS ID',
34
+ baseCharacterSet: '0123456789ACDEFGHJKLMNPRTUVWXY',
35
+ prefix: '',
36
+ },
37
+ ],
38
+ isPrimary: true,
39
+ name: 'OpenMRS ID',
40
+ required: true,
41
+ uniquenessBehavior: 'UNIQUE' as const,
42
+ uuid: '05a29f94-c0ed-11e2-94be-8c13b969e334',
43
+ },
44
+ {
45
+ fieldName: 'idCard',
46
+ format: '',
47
+ identifierSources: [],
48
+ isPrimary: false,
49
+ name: 'ID Card',
50
+ required: false,
51
+ uniquenessBehavior: 'UNIQUE' as const,
52
+ uuid: 'b4143563-16cd-4439-b288-f83d61670fc8',
53
+ },
54
+ {
55
+ fieldName: 'legacyId',
56
+ format: '',
57
+ identifierSources: [],
58
+ isPrimary: false,
59
+ name: 'Legacy ID',
60
+ required: false,
61
+ uniquenessBehavior: null,
62
+ uuid: '22348099-3873-459e-a32e-d93b17eda533',
63
+ },
64
+ {
65
+ fieldName: 'oldIdentificationNumber',
66
+ format: '',
67
+ identifierSources: [],
68
+ isPrimary: false,
69
+ name: 'Old Identification Number',
70
+ required: false,
71
+ uniquenessBehavior: null,
72
+ uuid: '8d79403a-c2cc-11de-8d13-0010c6dffd0f',
73
+ },
74
+ {
75
+ fieldName: 'openMrsIdentificationNumber',
76
+ format: '',
77
+ identifierSources: [],
78
+ isPrimary: false,
79
+ name: 'OpenMRS Identification Number',
80
+ required: false,
81
+ uniquenessBehavior: null,
82
+ uuid: '8d793bee-c2cc-11de-8d13-0010c6dffd0f',
83
+ },
84
+ ];
85
+
86
+ const mockResourcesContextValue: Resources = {
87
+ addressTemplate: predefinedAddressTemplate as unknown as AddressTemplate,
88
+ currentSession: {
89
+ authenticated: true,
90
+ sessionId: 'JSESSION',
91
+ currentProvider: { uuid: 'provider-uuid', identifier: 'PRO-123' },
92
+ },
93
+ relationshipTypes: [],
94
+ identifierTypes: [...mockIdentifierTypes],
95
+ };
96
+
97
+ const initialContextValues = {
98
+ currentPhoto: 'data:image/png;base64,1234567890',
99
+ identifierTypes: [],
100
+ inEditMode: false,
101
+ initialFormValues: {} as FormValues,
102
+ isOffline: false,
103
+ setCapturePhotoProps: jest.fn(),
104
+ setFieldValue: jest.fn(),
105
+ setFieldTouched: jest.fn(),
106
+ setInitialFormValues: jest.fn(),
107
+ validationSchema: null,
108
+ values: {} as FormValues,
109
+ };
110
+
111
+ describe('Field', () => {
112
+ beforeEach(() => {
113
+ mockUseConfig.mockReturnValue({
114
+ ...getDefaultsFromConfigSchema(esmPatientRegistrationSchema),
115
+ });
116
+ });
117
+
118
+ it('should render NameField component when name prop is "name"', () => {
119
+ mockUseConfig.mockReturnValue({
120
+ ...getDefaultsFromConfigSchema(esmPatientRegistrationSchema),
121
+ fieldConfigurations: {
122
+ name: {
123
+ allowUnidentifiedPatients: true,
124
+ displayMiddleName: true,
125
+ defaultUnknownGivenName: 'UNKNOWN',
126
+ defaultUnknownFamilyName: 'UNKNOWN',
127
+ },
128
+ } as RegistrationConfig['fieldConfigurations'],
129
+ });
130
+
131
+ renderWithContext(
132
+ <Formik initialValues={{}} onSubmit={jest.fn()}>
133
+ <Form>
134
+ <PatientRegistrationContextProvider value={initialContextValues}>
135
+ <Field name="name" />
136
+ </PatientRegistrationContextProvider>
137
+ </Form>
138
+ </Formik>,
139
+ ResourcesContextProvider,
140
+ mockResourcesContextValue,
141
+ );
142
+
143
+ expect(screen.getByText('Full Name')).toBeInTheDocument();
144
+ });
145
+
146
+ it('should render GenderField component when name prop is "gender"', () => {
147
+ mockUseConfig.mockReturnValue({
148
+ ...getDefaultsFromConfigSchema(esmPatientRegistrationSchema),
149
+ fieldConfigurations: {
150
+ gender: [
151
+ {
152
+ value: 'Male',
153
+ label: 'Male',
154
+ id: 'male',
155
+ },
156
+ ],
157
+ } as unknown as RegistrationConfig['fieldConfigurations'],
158
+ });
159
+
160
+ renderWithContext(
161
+ <Formik initialValues={{}} onSubmit={jest.fn()}>
162
+ <Form>
163
+ <PatientRegistrationContextProvider value={initialContextValues}>
164
+ <Field name="gender" />
165
+ </PatientRegistrationContextProvider>
166
+ </Form>
167
+ </Formik>,
168
+ ResourcesContextProvider,
169
+ mockResourcesContextValue,
170
+ );
171
+ expect(screen.getByLabelText('Male')).toBeInTheDocument();
172
+ });
173
+
174
+ it('should render DobField component when name prop is "dob"', () => {
175
+ renderWithContext(
176
+ <Formik initialValues={{}} onSubmit={jest.fn()}>
177
+ <Form>
178
+ <PatientRegistrationContextProvider value={initialContextValues}>
179
+ <Field name="dob" />
180
+ </PatientRegistrationContextProvider>
181
+ </Form>
182
+ </Formik>,
183
+ ResourcesContextProvider,
184
+ mockResourcesContextValue,
185
+ );
186
+
187
+ expect(screen.getByText('Birth')).toBeInTheDocument();
188
+ });
189
+
190
+ it('should render AddressComponent component when name prop is "address"', () => {
191
+ jest.mock('./address/address-hierarchy.resource', () => ({
192
+ ...jest.requireActual('../address-hierarchy.resource'),
193
+ useOrderedAddressHierarchyLevels: jest.fn(),
194
+ }));
195
+
196
+ mockUseConfig.mockReturnValue({
197
+ ...getDefaultsFromConfigSchema(esmPatientRegistrationSchema),
198
+ fieldConfigurations: {
199
+ address: {
200
+ useAddressHierarchy: {
201
+ enabled: false,
202
+ useQuickSearch: false,
203
+ searchAddressByLevel: false,
204
+ },
205
+ },
206
+ } as RegistrationConfig['fieldConfigurations'],
207
+ });
208
+
209
+ renderWithContext(
210
+ <Formik initialValues={{}} onSubmit={jest.fn()}>
211
+ <Form>
212
+ <PatientRegistrationContextProvider value={initialContextValues}>
213
+ <Field name="address" />
214
+ </PatientRegistrationContextProvider>
215
+ </Form>
216
+ </Formik>,
217
+ ResourcesContextProvider,
218
+ mockResourcesContextValue,
219
+ );
220
+
221
+ expect(screen.getByText('Address')).toBeInTheDocument();
222
+ });
223
+
224
+ it('should render Identifiers component when name prop is "id"', () => {
225
+ mockUseConfig.mockReturnValue({
226
+ ...getDefaultsFromConfigSchema(esmPatientRegistrationSchema),
227
+ defaultPatientIdentifierTypes: ['OpenMRS ID'],
228
+ });
229
+
230
+ const openmrsID = {
231
+ name: 'OpenMRS ID',
232
+ fieldName: 'openMrsId',
233
+ required: true,
234
+ uuid: '05a29f94-c0ed-11e2-94be-8c13b969e334',
235
+ format: null,
236
+ isPrimary: true,
237
+ identifierSources: [
238
+ {
239
+ uuid: '691eed12-c0f1-11e2-94be-8c13b969e334',
240
+ name: 'Generator 1 for OpenMRS ID',
241
+ autoGenerationOption: {
242
+ manualEntryEnabled: false,
243
+ automaticGenerationEnabled: true,
244
+ },
245
+ },
246
+ {
247
+ uuid: '01af8526-cea4-4175-aa90-340acb411771',
248
+ name: 'Generator 2 for OpenMRS ID',
249
+ autoGenerationOption: {
250
+ manualEntryEnabled: true,
251
+ automaticGenerationEnabled: true,
252
+ },
253
+ },
254
+ ],
255
+ identifierUuid: 'openmrs-identifier-uuid',
256
+ identifierTypeUuid: 'openmrs-id-identifier-type-uuid',
257
+ initialValue: '12345',
258
+ identifierValue: '12345',
259
+ identifierName: 'OpenMRS ID',
260
+ preferred: true,
261
+ selectedSource: {
262
+ uuid: 'openmrs-id-selected-source-uuid',
263
+ name: 'Generator 1 for OpenMRS ID',
264
+ autoGenerationOption: {
265
+ manualEntryEnabled: false,
266
+ automaticGenerationEnabled: true,
267
+ },
268
+ },
269
+ autoGenerationSource: null,
270
+ };
271
+
272
+ const updatedContextValues = {
273
+ currentPhoto: 'data:image/png;base64,1234567890',
274
+ identifierTypes: [],
275
+ inEditMode: false,
276
+ initialFormValues: { identifiers: { openmrsID } } as unknown as FormValues,
277
+ isOffline: false,
278
+ setCapturePhotoProps: jest.fn(),
279
+ setFieldValue: jest.fn(),
280
+ setInitialFormValues: jest.fn(),
281
+ validationSchema: null,
282
+ values: { identifiers: { openmrsID } } as unknown as FormValues,
283
+ setFieldTouched: jest.fn(),
284
+ };
285
+
286
+ renderWithContext(
287
+ <Formik initialValues={{}} onSubmit={jest.fn()}>
288
+ <Form>
289
+ <PatientRegistrationContextProvider value={updatedContextValues}>
290
+ <Field name="id" />
291
+ </PatientRegistrationContextProvider>
292
+ </Form>
293
+ </Formik>,
294
+ ResourcesContextProvider,
295
+ mockResourcesContextValue,
296
+ );
297
+ expect(screen.getByText('Identifiers')).toBeInTheDocument();
298
+ });
299
+
300
+ it('should return null and report an error for an invalid field name', () => {
301
+ const consoleError = jest.spyOn(console, 'error').mockImplementation(() => {});
302
+
303
+ mockUseConfig.mockReturnValue({
304
+ ...getDefaultsFromConfigSchema(esmPatientRegistrationSchema),
305
+ fieldDefinitions: [{ id: 'weight' }] as RegistrationConfig['fieldDefinitions'],
306
+ });
307
+
308
+ let error = null;
309
+
310
+ try {
311
+ renderWithContext(
312
+ <Formik initialValues={{}} onSubmit={jest.fn()}>
313
+ <Form>
314
+ <Field name="invalidField" />
315
+ </Form>
316
+ </Formik>,
317
+ ResourcesContextProvider,
318
+ mockResourcesContextValue,
319
+ );
320
+ } catch (err) {
321
+ error = err;
322
+ }
323
+
324
+ expect(error).toMatch(/Invalid field name 'invalidField'. Valid options are /);
325
+ expect(screen.queryByTestId('invalid-field')).not.toBeInTheDocument();
326
+
327
+ consoleError.mockRestore();
328
+ });
329
+ });
@@ -1,21 +1,22 @@
1
- import React, { useContext } from 'react';
1
+ import React from 'react';
2
2
  import { RadioButton, RadioButtonGroup } from '@carbon/react';
3
- import styles from '../field.scss';
4
3
  import { useTranslation } from 'react-i18next';
5
- import { PatientRegistrationContext } from '../../patient-registration-context';
6
4
  import { useField } from 'formik';
7
5
  import { type RegistrationConfig } from '../../../config-schema';
6
+ import { usePatientRegistrationContext } from '../../patient-registration-context';
8
7
  import { useConfig } from '@openmrs/esm-framework';
8
+ import styles from '../field.scss';
9
9
 
10
10
  export const GenderField: React.FC = () => {
11
- const { fieldConfigurations } = useConfig() as RegistrationConfig;
12
11
  const { t } = useTranslation();
12
+ const { fieldConfigurations } = useConfig<RegistrationConfig>();
13
+ const { setFieldValue, setFieldTouched } = usePatientRegistrationContext();
13
14
  const [field, meta] = useField('gender');
14
- const { setFieldValue } = useContext(PatientRegistrationContext);
15
15
  const fieldConfigs = fieldConfigurations?.gender;
16
16
 
17
17
  const setGender = (gender: string) => {
18
18
  setFieldValue('gender', gender);
19
+ setFieldTouched('gender', true, false);
19
20
  };
20
21
  /**
21
22
  * DO NOT REMOVE THIS COMMENT HERE, ADDS TRANSLATION FOR SEX OPTIONS
@@ -29,14 +30,18 @@ export const GenderField: React.FC = () => {
29
30
  <div className={styles.halfWidthInDesktopView}>
30
31
  <h4 className={styles.productiveHeading02Light}>{t('sexFieldLabelText', 'Sex')}</h4>
31
32
  <div className={styles.sexField}>
32
- <p className="cds--label">{t('genderLabelText', 'Sex')}</p>
33
- <RadioButtonGroup name="gender" orientation="vertical" onChange={setGender} valueSelected={field.value}>
33
+ <RadioButtonGroup
34
+ name="gender"
35
+ legendText={t('genderLabelText', 'Sex')}
36
+ orientation="vertical"
37
+ onChange={setGender}
38
+ valueSelected={field.value}>
34
39
  {fieldConfigs.map((option) => (
35
40
  <RadioButton
36
- key={option.label ?? option.value}
37
41
  id={`gender-option-${option.value}`}
38
- value={option.value}
42
+ key={option.label ?? option.value}
39
43
  labelText={t(option.label ?? option.value, option.label ?? option.value)}
44
+ value={option.value}
40
45
  />
41
46
  ))}
42
47
  </RadioButtonGroup>