@olaboot/esm-patient-registration-app 9.2.1 → 10.0.2

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 (342) hide show
  1. package/dist/1339.js +1 -0
  2. package/dist/1339.js.map +1 -0
  3. package/dist/1480.js +1 -0
  4. package/dist/1480.js.map +1 -0
  5. package/dist/1646.js +1 -0
  6. package/dist/1646.js.map +1 -0
  7. package/dist/1789.js +1 -0
  8. package/dist/1789.js.map +1 -0
  9. package/dist/1869.js +1 -0
  10. package/dist/1869.js.map +1 -0
  11. package/dist/1877.js +1 -0
  12. package/dist/1877.js.map +1 -0
  13. package/dist/2317.js +1 -0
  14. package/dist/2317.js.map +1 -0
  15. package/dist/2416.js +1 -0
  16. package/dist/2416.js.map +1 -0
  17. package/dist/2747.js +1 -0
  18. package/dist/2747.js.map +1 -0
  19. package/dist/282.js +1 -0
  20. package/dist/282.js.map +1 -0
  21. package/dist/2881.js +1 -0
  22. package/dist/2881.js.map +1 -0
  23. package/dist/3378.js +1 -0
  24. package/dist/3378.js.map +1 -0
  25. package/dist/3720.js +1 -0
  26. package/dist/3720.js.map +1 -0
  27. package/dist/3906.js +1 -0
  28. package/dist/3906.js.map +1 -0
  29. package/dist/3963.js +1 -0
  30. package/dist/3963.js.map +1 -0
  31. package/dist/3989.js +1 -0
  32. package/dist/3989.js.map +1 -0
  33. package/dist/4106.js +1 -0
  34. package/dist/4106.js.map +1 -0
  35. package/dist/4111.js +1 -0
  36. package/dist/4111.js.map +1 -0
  37. package/dist/434.js +1 -0
  38. package/dist/434.js.map +1 -0
  39. package/dist/4348.js +1 -0
  40. package/dist/4348.js.map +1 -0
  41. package/dist/4383.js +1 -0
  42. package/dist/4383.js.map +1 -0
  43. package/dist/4658.js +1 -0
  44. package/dist/4658.js.map +1 -0
  45. package/dist/466.js +1 -0
  46. package/dist/466.js.map +1 -0
  47. package/dist/4928.js +1 -0
  48. package/dist/4928.js.map +1 -0
  49. package/dist/5117.js +1 -0
  50. package/dist/5117.js.map +1 -0
  51. package/dist/5132.js +1 -0
  52. package/dist/5132.js.map +1 -0
  53. package/dist/5145.js +1 -0
  54. package/dist/5145.js.map +1 -0
  55. package/dist/5208.js +43 -0
  56. package/dist/5208.js.map +1 -0
  57. package/dist/527.js +1 -0
  58. package/dist/527.js.map +1 -0
  59. package/dist/5280.js +1 -0
  60. package/dist/5280.js.map +1 -0
  61. package/dist/5338.js +6 -0
  62. package/dist/5338.js.map +1 -0
  63. package/dist/5503.js +1 -0
  64. package/dist/5503.js.map +1 -0
  65. package/dist/555.js +1 -0
  66. package/dist/555.js.map +1 -0
  67. package/dist/556.js +1 -0
  68. package/dist/556.js.map +1 -0
  69. package/dist/5644.js +1 -0
  70. package/dist/5644.js.map +1 -0
  71. package/dist/5697.js +1 -0
  72. package/dist/{4024.js.map → 5697.js.map} +1 -1
  73. package/dist/5940.js +1 -0
  74. package/dist/5940.js.map +1 -0
  75. package/dist/6047.js +1 -0
  76. package/dist/6047.js.map +1 -0
  77. package/dist/6371.js +1 -0
  78. package/dist/6371.js.map +1 -0
  79. package/dist/6377.js +1 -0
  80. package/dist/6377.js.map +1 -0
  81. package/dist/6388.js +1 -0
  82. package/dist/6388.js.map +1 -0
  83. package/dist/6444.js +1 -0
  84. package/dist/6444.js.map +1 -0
  85. package/dist/6508.js +1 -0
  86. package/dist/6508.js.map +1 -0
  87. package/dist/6724.js +1 -0
  88. package/dist/6724.js.map +1 -0
  89. package/dist/689.js +1 -0
  90. package/dist/689.js.map +1 -0
  91. package/dist/6904.js +1 -0
  92. package/dist/6904.js.map +1 -0
  93. package/dist/7045.js +1 -0
  94. package/dist/7045.js.map +1 -0
  95. package/dist/7175.js +1 -0
  96. package/dist/7175.js.map +1 -0
  97. package/dist/7182.js +1 -0
  98. package/dist/7182.js.map +1 -0
  99. package/dist/7649.js +1 -0
  100. package/dist/7649.js.map +1 -0
  101. package/dist/7742.js +1 -0
  102. package/dist/7742.js.map +1 -0
  103. package/dist/7912.js +1 -0
  104. package/dist/7912.js.map +1 -0
  105. package/dist/8358.js +1 -0
  106. package/dist/8358.js.map +1 -0
  107. package/dist/8359.js +1 -0
  108. package/dist/8359.js.map +1 -0
  109. package/dist/8695.js +1 -0
  110. package/dist/8695.js.map +1 -0
  111. package/dist/903.js +1 -0
  112. package/dist/903.js.map +1 -0
  113. package/dist/9061.js +1 -0
  114. package/dist/9061.js.map +1 -0
  115. package/dist/9072.js +1 -0
  116. package/dist/9072.js.map +1 -0
  117. package/dist/9397.js +1 -0
  118. package/dist/9397.js.map +1 -0
  119. package/dist/9712.js +1 -0
  120. package/dist/9712.js.map +1 -0
  121. package/dist/9771.js +1 -0
  122. package/dist/9771.js.map +1 -0
  123. package/dist/9806.js +1 -0
  124. package/dist/9806.js.map +1 -0
  125. package/dist/9816.js +1 -0
  126. package/dist/9816.js.map +1 -0
  127. package/dist/main.js +7 -6
  128. package/dist/main.js.map +1 -1
  129. package/dist/openmrs-esm-patient-registration-app.js +6 -0
  130. package/dist/{olaboot-esm-patient-registration-app.js.buildmanifest.json → openmrs-esm-patient-registration-app.js.buildmanifest.json} +540 -455
  131. package/dist/openmrs-esm-patient-registration-app.js.map +1 -0
  132. package/dist/routes.json +1 -1
  133. package/package.json +8 -9
  134. package/src/add-patient-link.extension.tsx +3 -2
  135. package/src/add-patient-link.test.tsx +2 -1
  136. package/src/config-schema.ts +507 -507
  137. package/src/constants.ts +1 -1
  138. package/src/index.ts +2 -24
  139. package/src/nav-link.test.tsx +1 -0
  140. package/src/offline.resources.ts +97 -31
  141. package/src/patient-registration/before-save-prompt.test.tsx +199 -0
  142. package/src/patient-registration/field/__mocks__/field.resource.ts +8 -7
  143. package/src/patient-registration/field/address/address-field.component.tsx +183 -186
  144. package/src/patient-registration/field/address/address-hierarchy-levels.component.tsx +6 -1
  145. package/src/patient-registration/field/address/address-hierarchy.test.tsx +289 -296
  146. package/src/patient-registration/field/address/address-search.component.tsx +20 -8
  147. package/src/patient-registration/field/address/address-search.scss +19 -2
  148. package/src/patient-registration/field/address/address-search.test.tsx +333 -141
  149. package/src/patient-registration/field/address/custom-address-field.component.tsx +1 -1
  150. package/src/patient-registration/field/cause-of-death/cause-of-death.component.tsx +1 -1
  151. package/src/patient-registration/field/cause-of-death/cause-of-death.test.tsx +251 -0
  152. package/src/patient-registration/field/custom-field.component.tsx +1 -1
  153. package/src/patient-registration/field/date-and-time-of-death/date-and-time-of-death.component.tsx +1 -1
  154. package/src/patient-registration/field/date-and-time-of-death/date-and-time-of-death.test.tsx +144 -0
  155. package/src/patient-registration/field/dob/dob.component.tsx +2 -2
  156. package/src/patient-registration/field/dob/dob.test.tsx +370 -54
  157. package/src/patient-registration/field/field.component.tsx +1 -1
  158. package/src/patient-registration/field/field.resource.ts +2 -2
  159. package/src/patient-registration/field/field.test.tsx +333 -330
  160. package/src/patient-registration/field/gender/gender-field.test.tsx +240 -54
  161. package/src/patient-registration/field/id/id-field.component.tsx +146 -144
  162. package/src/patient-registration/field/id/id-field.test.tsx +177 -121
  163. package/src/patient-registration/field/id/identifier-selection-overlay.component.tsx +200 -200
  164. package/src/patient-registration/field/id/identifier-selection-overlay.test.tsx +346 -0
  165. package/src/patient-registration/field/name/name-field.component.tsx +2 -2
  166. package/src/patient-registration/field/name/name-field.test.tsx +282 -0
  167. package/src/patient-registration/field/obs/obs-field.test.tsx +294 -118
  168. package/src/patient-registration/field/person-attributes/coded-person-attribute-field.test.tsx +172 -108
  169. package/src/patient-registration/field/person-attributes/location-person-attribute-field.component.tsx +3 -3
  170. package/src/patient-registration/field/person-attributes/location-person-attribute-field.resource.tsx +2 -5
  171. package/src/patient-registration/field/person-attributes/person-attribute-field.component.tsx +2 -2
  172. package/src/patient-registration/field/person-attributes/person-attribute-field.test.tsx +249 -131
  173. package/src/patient-registration/field/person-attributes/person-attributes.resource.ts +1 -1
  174. package/src/patient-registration/field/person-attributes/text-person-attribute-field.test.tsx +98 -70
  175. package/src/patient-registration/field/phone/phone-field.test.tsx +100 -0
  176. package/src/patient-registration/form-manager.test.ts +6 -5
  177. package/src/patient-registration/form-manager.ts +5 -2
  178. package/src/patient-registration/input/basic-input/input/input.component.tsx +3 -121
  179. package/src/patient-registration/input/basic-input/input/input.test.tsx +151 -51
  180. package/src/patient-registration/input/basic-input/select/select-input.test.tsx +113 -33
  181. package/src/patient-registration/input/combo-input/combo-input.component.tsx +60 -24
  182. package/src/patient-registration/input/custom-input/autosuggest/autosuggest.component.tsx +10 -101
  183. package/src/patient-registration/input/custom-input/autosuggest/autosuggest.test.tsx +144 -108
  184. package/src/patient-registration/input/custom-input/identifier/identifier-input.test.tsx +241 -177
  185. package/src/patient-registration/input/custom-input/identifier/utils.test.ts +47 -8
  186. package/src/patient-registration/input/dummy-data/dummy-data-input.component.tsx +12 -12
  187. package/src/patient-registration/input/dummy-data/dummy-data-input.test.tsx +52 -20
  188. package/src/patient-registration/input/input.scss +1 -2
  189. package/src/patient-registration/patient-registration-context.ts +5 -3
  190. package/src/patient-registration/patient-registration-hooks.ts +4 -12
  191. package/src/patient-registration/patient-registration-utils.test.ts +2 -1
  192. package/src/patient-registration/patient-registration-utils.ts +2 -98
  193. package/src/patient-registration/patient-registration.component.tsx +50 -46
  194. package/src/patient-registration/patient-registration.resource.test.tsx +4 -7
  195. package/src/patient-registration/patient-registration.resource.ts +1 -4
  196. package/src/patient-registration/patient-registration.scss +16 -3
  197. package/src/patient-registration/patient-registration.test.tsx +614 -580
  198. package/src/patient-registration/patient-registration.types.ts +17 -28
  199. package/src/patient-registration/section/death-info/death-info-section.test.tsx +130 -34
  200. package/src/patient-registration/section/demographics/demographics-section.test.tsx +122 -68
  201. package/src/patient-registration/section/patient-relationships/relationships-section.component.tsx +15 -15
  202. package/src/patient-registration/section/patient-relationships/relationships-section.test.tsx +278 -84
  203. package/src/patient-registration/section/section-wrapper.component.tsx +1 -1
  204. package/src/patient-registration/ui-components/overlay/overlay.test.tsx +104 -0
  205. package/src/patient-registration/validation/patient-registration-validation.test.ts +2 -1
  206. package/src/patient-registration/validation/patient-registration-validation.ts +9 -3
  207. package/src/root.component.tsx +2 -5
  208. package/src/widgets/cancel-patient-edit.test.tsx +48 -11
  209. package/src/widgets/delete-identifier-confirmation.test.tsx +77 -24
  210. package/src/widgets/edit-patient-details-button.component.tsx +14 -18
  211. package/src/widgets/edit-patient-details-button.scss +2 -2
  212. package/src/widgets/edit-patient-details-button.test.tsx +11 -13
  213. package/translations/am.json +9 -4
  214. package/translations/ar.json +9 -4
  215. package/translations/ar_SY.json +9 -4
  216. package/translations/bn.json +9 -4
  217. package/translations/cs.json +9 -4
  218. package/translations/de.json +120 -115
  219. package/translations/en.json +10 -4
  220. package/translations/en_US.json +9 -4
  221. package/translations/es.json +9 -4
  222. package/translations/es_MX.json +9 -4
  223. package/translations/fr.json +9 -4
  224. package/translations/he.json +9 -4
  225. package/translations/hi.json +9 -4
  226. package/translations/hi_IN.json +9 -4
  227. package/translations/id.json +9 -4
  228. package/translations/it.json +9 -4
  229. package/translations/ka.json +9 -4
  230. package/translations/km.json +9 -4
  231. package/translations/ku.json +9 -4
  232. package/translations/ky.json +9 -4
  233. package/translations/lg.json +9 -4
  234. package/translations/ne.json +9 -4
  235. package/translations/pl.json +9 -4
  236. package/translations/pt.json +9 -4
  237. package/translations/pt_BR.json +10 -5
  238. package/translations/qu.json +9 -4
  239. package/translations/ro_RO.json +9 -4
  240. package/translations/ru_RU.json +9 -4
  241. package/translations/si.json +9 -4
  242. package/translations/sq.json +9 -4
  243. package/translations/sw.json +9 -4
  244. package/translations/sw_KE.json +9 -4
  245. package/translations/tr.json +9 -4
  246. package/translations/tr_TR.json +9 -4
  247. package/translations/uk.json +9 -4
  248. package/translations/uz.json +9 -4
  249. package/translations/uz@Latn.json +9 -4
  250. package/translations/uz_UZ.json +9 -4
  251. package/translations/vi.json +9 -4
  252. package/translations/zh.json +50 -45
  253. package/translations/zh_CN.json +9 -4
  254. package/translations/zh_TW.json +9 -4
  255. package/vitest.config.ts +4 -0
  256. package/dist/126.js +0 -1
  257. package/dist/15.js +0 -1
  258. package/dist/1564.js +0 -1
  259. package/dist/1567.js +0 -1
  260. package/dist/1845.js +0 -1
  261. package/dist/1953.js +0 -1
  262. package/dist/200.js +0 -1
  263. package/dist/200.js.map +0 -1
  264. package/dist/215.js +0 -1
  265. package/dist/2178.js +0 -1
  266. package/dist/250.js +0 -1
  267. package/dist/250.js.map +0 -1
  268. package/dist/2523.js +0 -1
  269. package/dist/2523.js.map +0 -1
  270. package/dist/2566.js +0 -1
  271. package/dist/2586.js +0 -1
  272. package/dist/2586.js.map +0 -1
  273. package/dist/2716.js +0 -1
  274. package/dist/2716.js.map +0 -1
  275. package/dist/2759.js +0 -1
  276. package/dist/2821.js +0 -6
  277. package/dist/2821.js.map +0 -1
  278. package/dist/3089.js +0 -1
  279. package/dist/3089.js.map +0 -1
  280. package/dist/3230.js +0 -1
  281. package/dist/3441.js +0 -1
  282. package/dist/3565.js +0 -1
  283. package/dist/3571.js +0 -1
  284. package/dist/3571.js.map +0 -1
  285. package/dist/3746.js +0 -1
  286. package/dist/3925.js +0 -1
  287. package/dist/3946.js +0 -1
  288. package/dist/4024.js +0 -1
  289. package/dist/4744.js +0 -1
  290. package/dist/4744.js.map +0 -1
  291. package/dist/4809.js +0 -1
  292. package/dist/4894.js +0 -1
  293. package/dist/4970.js +0 -1
  294. package/dist/4970.js.map +0 -1
  295. package/dist/5130.js +0 -1
  296. package/dist/5187.js +0 -1
  297. package/dist/5491.js +0 -1
  298. package/dist/5491.js.map +0 -1
  299. package/dist/5595.js +0 -1
  300. package/dist/5961.js +0 -1
  301. package/dist/6133.js +0 -1
  302. package/dist/634.js +0 -1
  303. package/dist/634.js.map +0 -1
  304. package/dist/6456.js +0 -1
  305. package/dist/6466.js +0 -1
  306. package/dist/6613.js +0 -1
  307. package/dist/6783.js +0 -1
  308. package/dist/7073.js +0 -38
  309. package/dist/7073.js.map +0 -1
  310. package/dist/7154.js +0 -1
  311. package/dist/7154.js.map +0 -1
  312. package/dist/7348.js +0 -1
  313. package/dist/7439.js +0 -1
  314. package/dist/7439.js.map +0 -1
  315. package/dist/7543.js +0 -1
  316. package/dist/7607.js +0 -1
  317. package/dist/772.js +0 -1
  318. package/dist/7984.js +0 -1
  319. package/dist/7984.js.map +0 -1
  320. package/dist/8538.js +0 -1
  321. package/dist/8538.js.map +0 -1
  322. package/dist/8599.js +0 -1
  323. package/dist/8727.js +0 -1
  324. package/dist/8847.js +0 -1
  325. package/dist/9015.js +0 -1
  326. package/dist/906.js +0 -1
  327. package/dist/9065.js +0 -1
  328. package/dist/9182.js +0 -1
  329. package/dist/9339.js +0 -1
  330. package/dist/9453.js +0 -1
  331. package/dist/9833.js +0 -1
  332. package/dist/9833.js.map +0 -1
  333. package/dist/9856.js +0 -1
  334. package/dist/9856.js.map +0 -1
  335. package/dist/9920.js +0 -1
  336. package/dist/9938.js +0 -1
  337. package/dist/9943.js +0 -1
  338. package/dist/9943.js.map +0 -1
  339. package/dist/olaboot-esm-patient-registration-app.js +0 -5
  340. package/dist/olaboot-esm-patient-registration-app.js.map +0 -1
  341. package/jest.config.js +0 -3
  342. package/src/resource.ts +0 -12
@@ -1,186 +1,183 @@
1
- import React, { useEffect, useState, useMemo } from 'react';
2
- import { useTranslation } from 'react-i18next';
3
- import { SkeletonText, InlineNotification } from '@carbon/react';
4
- import { type Session, useConfig, useConnectivity } from '@openmrs/esm-framework';
5
- import { useOrderedAddressHierarchyLevels } from './address-hierarchy.resource';
6
- import {
7
- type PatientRegistrationContextProps,
8
- PatientRegistrationContextProvider,
9
- usePatientRegistrationContext,
10
- } from '../../patient-registration-context';
11
- import { ResourcesContextProvider, useResourcesContext } from '../../../resources-context';
12
- import { Input } from '../../input/basic-input/input/input.component';
13
- import AddressHierarchyLevels from './address-hierarchy-levels.component';
14
- import AddressSearchComponent from './address-search.component';
15
- import styles from '../field.scss';
16
- import { type AddressTemplate } from '../../patient-registration.types';
17
-
18
- export const AddressComponent: React.FC = () => {
19
- const config = useConfig();
20
- const { t } = useTranslation();
21
- const { setFieldValue } = usePatientRegistrationContext();
22
- const { orderedFields, isLoadingFieldOrder, errorFetchingFieldOrder } = useOrderedAddressHierarchyLevels();
23
-
24
- const isOnline = useConnectivity();
25
- const {
26
- fieldConfigurations: {
27
- address: {
28
- useAddressHierarchy: { enabled: addressHierarchyEnabled, useQuickSearch, searchAddressByLevel },
29
- requiredAddressFields,
30
- },
31
- },
32
- } = config;
33
-
34
- const { addressTemplate } = useResourcesContext();
35
- const addressLayout = useMemo(() => {
36
- if (!addressTemplate?.lines) {
37
- return [];
38
- }
39
-
40
- const allFields = addressTemplate?.lines?.flat();
41
- const fields = allFields?.filter(({ isToken }) => isToken === 'IS_ADDR_TOKEN');
42
-
43
- // Use config-based required fields if provided, otherwise fall back to backend template
44
- const allRequiredFields = requiredAddressFields?.length
45
- ? Object.fromEntries(requiredAddressFields.map((field) => [field, field]))
46
- : Object.fromEntries(addressTemplate?.requiredElements?.map((curr) => [curr, curr]) || []);
47
-
48
- return fields.map(({ displayText, codeName }) => {
49
- return {
50
- id: codeName,
51
- name: codeName,
52
- label: displayText,
53
- required: Boolean(allRequiredFields[codeName]),
54
- };
55
- });
56
- }, [addressTemplate, requiredAddressFields]);
57
-
58
- const [selected, setSelected] = useState('');
59
-
60
- useEffect(() => {
61
- if (addressTemplate?.elementDefaults) {
62
- Object.entries(addressTemplate.elementDefaults).forEach(([name, defaultValue]) => {
63
- setFieldValue(`address.${name}`, defaultValue);
64
- });
65
- }
66
- }, [addressTemplate, setFieldValue]);
67
-
68
- const orderedAddressFields = useMemo(() => {
69
- if (isLoadingFieldOrder || errorFetchingFieldOrder) {
70
- return [];
71
- }
72
-
73
- const orderMap = Object.fromEntries(orderedFields.map((field, indx) => [field, indx]));
74
-
75
- return [...addressLayout].sort(
76
- (existingField1, existingField2) => orderMap[existingField1.name] - orderMap[existingField2.name],
77
- );
78
- }, [isLoadingFieldOrder, errorFetchingFieldOrder, orderedFields, addressLayout]);
79
-
80
- if (addressTemplate && !Object.keys(addressTemplate)?.length) {
81
- return (
82
- <AddressComponentContainer>
83
- <SkeletonText
84
- // @ts-expect-error
85
- role="progressbar"
86
- />
87
- </AddressComponentContainer>
88
- );
89
- }
90
-
91
- if (!addressHierarchyEnabled || !isOnline) {
92
- return (
93
- <AddressComponentContainer>
94
- {addressLayout.map((attributes, index) => (
95
- <Input
96
- key={`combo_input_${index}`}
97
- name={`address.${attributes.name}`}
98
- labelText={t(attributes.label)}
99
- id={attributes.name}
100
- value={selected}
101
- required={attributes.required}
102
- />
103
- ))}
104
- </AddressComponentContainer>
105
- );
106
- }
107
-
108
- if (isLoadingFieldOrder) {
109
- return (
110
- <AddressComponentContainer>
111
- <SkeletonText
112
- // @ts-expect-error
113
- role="progressbar"
114
- />
115
- </AddressComponentContainer>
116
- );
117
- }
118
-
119
- if (errorFetchingFieldOrder) {
120
- return (
121
- <AddressComponentContainer>
122
- <InlineNotification
123
- style={{ margin: '0', minWidth: '100%' }}
124
- kind="error"
125
- lowContrast={true}
126
- title={t('errorFetchingOrderedFields', 'Error occurred fetching ordered fields for address hierarchy')}
127
- />
128
- </AddressComponentContainer>
129
- );
130
- }
131
-
132
- return (
133
- <AddressComponentContainer>
134
- {useQuickSearch && <AddressSearchComponent addressLayout={orderedAddressFields} />}
135
- {searchAddressByLevel ? (
136
- <AddressHierarchyLevels orderedAddressFields={orderedAddressFields} />
137
- ) : (
138
- orderedAddressFields.map((attributes, index) => (
139
- <Input
140
- key={`combo_input_${index}`}
141
- name={`address.${attributes.name}`}
142
- labelText={t(attributes.label)}
143
- id={attributes.name}
144
- value={selected}
145
- required={attributes.required}
146
- />
147
- ))
148
- )}
149
- </AddressComponentContainer>
150
- );
151
- };
152
-
153
- const AddressComponentContainer = ({ children }) => {
154
- const { t } = useTranslation();
155
- const contextValue = useMemo(
156
- () =>
157
- ({
158
- fieldConfigurations: {},
159
- setFieldValue: () => {},
160
- values: {},
161
- }) as unknown as PatientRegistrationContextProps,
162
- [],
163
- );
164
-
165
- return (
166
- <ResourcesContextProvider
167
- value={{
168
- addressTemplate: {} as AddressTemplate,
169
- currentSession: {} as Session,
170
- identifierTypes: [],
171
- relationshipTypes: [],
172
- }}>
173
- <PatientRegistrationContextProvider value={contextValue}>
174
- <div>
175
- <h4 className={styles.productiveHeading02Light}>{t('addressHeader', 'Address')}</h4>
176
- <div
177
- style={{
178
- paddingBottom: '5%',
179
- }}>
180
- {children}
181
- </div>
182
- </div>
183
- </PatientRegistrationContextProvider>
184
- </ResourcesContextProvider>
185
- );
186
- };
1
+ import React, { useEffect, useState, useMemo } from 'react';
2
+ import { useTranslation } from 'react-i18next';
3
+ import { SkeletonText, InlineNotification } from '@carbon/react';
4
+ import { type Session, useConfig, useConnectivity } from '@openmrs/esm-framework';
5
+ import { useOrderedAddressHierarchyLevels } from './address-hierarchy.resource';
6
+ import {
7
+ type PatientRegistrationContextProps,
8
+ PatientRegistrationContextProvider,
9
+ usePatientRegistrationContext,
10
+ } from '../../patient-registration-context';
11
+ import { ResourcesContextProvider, useResourcesContext } from '../../../resources-context';
12
+ import { type AddressTemplate } from '../../patient-registration.types';
13
+ import { Input } from '../../input/basic-input/input/input.component';
14
+ import AddressHierarchyLevels from './address-hierarchy-levels.component';
15
+ import AddressSearchComponent from './address-search.component';
16
+ import styles from '../field.scss';
17
+
18
+
19
+ export const AddressComponent: React.FC = () => {
20
+ const config = useConfig();
21
+ const { t } = useTranslation();
22
+ const { setFieldValue } = usePatientRegistrationContext();
23
+ const { orderedFields, isLoadingFieldOrder, errorFetchingFieldOrder } = useOrderedAddressHierarchyLevels();
24
+
25
+ const isOnline = useConnectivity();
26
+ const {
27
+ fieldConfigurations: {
28
+ address: {
29
+ useAddressHierarchy: { enabled: addressHierarchyEnabled, useQuickSearch, searchAddressByLevel },
30
+ requiredAddressFields,
31
+ },
32
+ },
33
+ } = config;
34
+
35
+ const { addressTemplate } = useResourcesContext();
36
+ const addressLayout = useMemo(() => {
37
+ if (!addressTemplate?.lines) {
38
+ return [];
39
+ }
40
+
41
+ const allFields = addressTemplate?.lines?.flat();
42
+ const fields = allFields?.filter(({ isToken }) => isToken === 'IS_ADDR_TOKEN');
43
+ const allRequiredFields = requiredAddressFields?.length
44
+ ? Object.fromEntries(requiredAddressFields.map((field) => [field, field]))
45
+ : Object.fromEntries(addressTemplate?.requiredElements?.map((curr) => [curr, curr]) || []);
46
+
47
+ return fields.map(({ displayText, codeName }) => {
48
+ return {
49
+ id: codeName,
50
+ name: codeName,
51
+ label: displayText,
52
+ required: Boolean(allRequiredFields[codeName]),
53
+ };
54
+ });
55
+ }, [addressTemplate, requiredAddressFields]);
56
+
57
+ const [selected, setSelected] = useState('');
58
+
59
+ useEffect(() => {
60
+ if (addressTemplate?.elementDefaults) {
61
+ Object.entries(addressTemplate.elementDefaults).forEach(([name, defaultValue]) => {
62
+ setFieldValue(`address.${name}`, defaultValue);
63
+ });
64
+ }
65
+ }, [addressTemplate, setFieldValue]);
66
+
67
+ const orderedAddressFields = useMemo(() => {
68
+ if (isLoadingFieldOrder || errorFetchingFieldOrder) {
69
+ return [];
70
+ }
71
+
72
+ const orderMap = Object.fromEntries(orderedFields.map((field, indx) => [field, indx]));
73
+
74
+ return [...addressLayout].sort(
75
+ (existingField1, existingField2) => orderMap[existingField1.name] - orderMap[existingField2.name],
76
+ );
77
+ }, [isLoadingFieldOrder, errorFetchingFieldOrder, orderedFields, addressLayout]);
78
+
79
+ if (addressTemplate && !Object.keys(addressTemplate)?.length) {
80
+ return (
81
+ <AddressComponentContainer>
82
+ <div role="progressbar" aria-label={t('loading', 'Loading')}>
83
+ <SkeletonText />
84
+ </div>
85
+ </AddressComponentContainer>
86
+ );
87
+ }
88
+
89
+ if (!addressHierarchyEnabled || !isOnline) {
90
+ return (
91
+ <AddressComponentContainer>
92
+ {addressLayout.map((attributes, index) => (
93
+ <Input
94
+ key={`combo_input_${index}`}
95
+ name={`address.${attributes.name}`}
96
+ labelText={t(attributes.label)}
97
+ id={attributes.name}
98
+ value={selected}
99
+ required={attributes.required}
100
+ />
101
+ ))}
102
+ </AddressComponentContainer>
103
+ );
104
+ }
105
+
106
+ if (isLoadingFieldOrder) {
107
+ return (
108
+ <AddressComponentContainer>
109
+ <div role="progressbar" aria-label={t('loading', 'Loading')}>
110
+ <SkeletonText />
111
+ </div>
112
+ </AddressComponentContainer>
113
+ );
114
+ }
115
+
116
+ if (errorFetchingFieldOrder) {
117
+ return (
118
+ <AddressComponentContainer>
119
+ <InlineNotification
120
+ style={{ margin: '0', minWidth: '100%' }}
121
+ kind="error"
122
+ lowContrast={true}
123
+ title={t('errorFetchingOrderedFields', 'Error occurred fetching ordered fields for address hierarchy')}
124
+ />
125
+ </AddressComponentContainer>
126
+ );
127
+ }
128
+
129
+ return (
130
+ <AddressComponentContainer>
131
+ {useQuickSearch && <AddressSearchComponent addressLayout={orderedAddressFields} />}
132
+ {searchAddressByLevel ? (
133
+ <AddressHierarchyLevels orderedAddressFields={orderedAddressFields} />
134
+ ) : (
135
+ orderedAddressFields.map((attributes, index) => (
136
+ <Input
137
+ key={`combo_input_${index}`}
138
+ name={`address.${attributes.name}`}
139
+ labelText={t(attributes.label)}
140
+ id={attributes.name}
141
+ value={selected}
142
+ required={attributes.required}
143
+ />
144
+ ))
145
+ )}
146
+ </AddressComponentContainer>
147
+ );
148
+ };
149
+
150
+ const AddressComponentContainer = ({ children }) => {
151
+ const { t } = useTranslation();
152
+ const contextValue = useMemo(
153
+ () =>
154
+ ({
155
+ fieldConfigurations: {},
156
+ setFieldValue: async () => {},
157
+ values: {},
158
+ }) as unknown as PatientRegistrationContextProps,
159
+ [],
160
+ );
161
+
162
+ return (
163
+ <ResourcesContextProvider
164
+ value={{
165
+ addressTemplate: {} as AddressTemplate,
166
+ currentSession: {} as Session,
167
+ identifierTypes: [],
168
+ relationshipTypes: { results: [] },
169
+ }}>
170
+ <PatientRegistrationContextProvider value={contextValue}>
171
+ <div>
172
+ <h4 className={styles.productiveHeading02Light}>{t('addressHeader', 'Address')}</h4>
173
+ <div
174
+ style={{
175
+ paddingBottom: '5%',
176
+ }}>
177
+ {children}
178
+ </div>
179
+ </div>
180
+ </PatientRegistrationContextProvider>
181
+ </ResourcesContextProvider>
182
+ );
183
+ };
@@ -22,7 +22,10 @@ const AddressComboBox: React.FC<AddressComboBoxProps> = ({ attribute }) => {
22
22
  const { t } = useTranslation();
23
23
  const [field, meta, { setValue }] = useField(`address.${attribute.name}`);
24
24
  const { fetchEntriesForField, searchString, updateChildElements } = useAddressEntryFetchConfig(attribute.name);
25
- const { entries } = useAddressEntries(fetchEntriesForField, searchString);
25
+ const { entries, isLoadingAddressEntries, errorFetchingAddressEntries } = useAddressEntries(
26
+ fetchEntriesForField,
27
+ searchString,
28
+ );
26
29
  const label = t(attribute.label) + (attribute?.required ? '' : ` (${t('optional', 'optional')})`);
27
30
 
28
31
  const handleInputChange = useCallback(
@@ -45,6 +48,8 @@ const AddressComboBox: React.FC<AddressComboBoxProps> = ({ attribute }) => {
45
48
  return (
46
49
  <ComboInput
47
50
  entries={entries}
51
+ error={errorFetchingAddressEntries}
52
+ isLoading={isLoadingAddressEntries}
48
53
  handleSelection={handleSelection}
49
54
  name={`address.${attribute.name}`}
50
55
  fieldProps={{