@kenyaemr/esm-ward-app 8.0.1-pre.99 → 8.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 (196) hide show
  1. package/.turbo/turbo-build.log +20 -24
  2. package/dist/109.js +1 -0
  3. package/dist/109.js.map +1 -0
  4. package/dist/124.js +1 -0
  5. package/dist/124.js.map +1 -0
  6. package/dist/125.js +1 -0
  7. package/dist/125.js.map +1 -0
  8. package/dist/130.js +1 -1
  9. package/dist/130.js.LICENSE.txt +2 -0
  10. package/dist/130.js.map +1 -1
  11. package/dist/146.js +1 -0
  12. package/dist/146.js.map +1 -0
  13. package/dist/15.js +1 -0
  14. package/dist/15.js.map +1 -0
  15. package/dist/153.js +1 -0
  16. package/dist/153.js.map +1 -0
  17. package/dist/303.js +2 -1
  18. package/dist/303.js.map +1 -1
  19. package/dist/325.js +1 -0
  20. package/dist/325.js.map +1 -0
  21. package/dist/372.js +2 -0
  22. package/dist/372.js.map +1 -0
  23. package/dist/471.js +1 -0
  24. package/dist/471.js.map +1 -0
  25. package/dist/481.js +1 -0
  26. package/dist/481.js.map +1 -0
  27. package/dist/53.js +1 -0
  28. package/dist/53.js.map +1 -0
  29. package/dist/{960.js → 559.js} +1 -1
  30. package/dist/559.js.map +1 -0
  31. package/dist/574.js +1 -1
  32. package/dist/576.js +1 -0
  33. package/dist/576.js.map +1 -0
  34. package/dist/577.js +1 -1
  35. package/dist/577.js.map +1 -1
  36. package/dist/{255.js → 649.js} +2 -2
  37. package/dist/649.js.LICENSE.txt +9 -0
  38. package/dist/649.js.map +1 -0
  39. package/dist/{659.js → 662.js} +1 -1
  40. package/dist/662.js.map +1 -0
  41. package/dist/920.js +1 -0
  42. package/dist/920.js.map +1 -0
  43. package/dist/921.js +1 -0
  44. package/dist/921.js.map +1 -0
  45. package/dist/922.js +1 -0
  46. package/dist/922.js.map +1 -0
  47. package/dist/969.js +1 -0
  48. package/dist/969.js.map +1 -0
  49. package/dist/kenyaemr-esm-ward-app.js +1 -1
  50. package/dist/kenyaemr-esm-ward-app.js.buildmanifest.json +304 -128
  51. package/dist/kenyaemr-esm-ward-app.js.map +1 -1
  52. package/dist/main.js +1 -1
  53. package/dist/main.js.LICENSE.txt +0 -10
  54. package/dist/main.js.map +1 -1
  55. package/dist/routes.json +1 -1
  56. package/mock.tsx +62 -0
  57. package/package-lock.json +5001 -0
  58. package/package.json +2 -3
  59. package/src/action-menu-buttons/clinical-forms-workspace-siderail.component.tsx +37 -0
  60. package/src/action-menu-buttons/discharge-workspace-siderail.component.tsx +20 -0
  61. package/src/beds/empty-bed-skeleton.tsx +4 -3
  62. package/src/beds/empty-bed.component.tsx +3 -3
  63. package/src/beds/ward-bed.component.tsx +41 -0
  64. package/src/beds/ward-bed.scss +45 -0
  65. package/src/beds/{occupied-bed.test.tsx → ward-bed.test.tsx} +42 -20
  66. package/src/config-schema.ts +203 -84
  67. package/src/constant.ts +1 -1
  68. package/src/hooks/useAdmissionLocation.ts +22 -4
  69. package/src/hooks/useAssignedBedByPatient.ts +9 -0
  70. package/src/hooks/useBeds.ts +3 -4
  71. package/src/hooks/useConcept.ts +3 -4
  72. package/src/hooks/useEmrConfiguration.ts +5 -0
  73. package/src/hooks/useInpatientAdmission.ts +9 -14
  74. package/src/hooks/useInpatientRequest.ts +4 -15
  75. package/src/hooks/useLocations.ts +8 -51
  76. package/src/hooks/useMotherAndChildren.ts +46 -0
  77. package/src/hooks/useObs.ts +3 -7
  78. package/src/hooks/usePatientPendingOrders.ts +16 -0
  79. package/src/hooks/useWardPatientGrouping.ts +32 -0
  80. package/src/index.ts +45 -17
  81. package/src/location-selector/location-selector.component.tsx +18 -21
  82. package/src/root.component.tsx +3 -0
  83. package/src/routes.json +41 -3
  84. package/src/types/index.ts +50 -1
  85. package/src/ward-patient-card/card-rows/admission-request-note-row.component.tsx +38 -0
  86. package/src/ward-patient-card/card-rows/coded-obs-tags-row.component.tsx +108 -0
  87. package/src/ward-patient-card/card-rows/mother-child-row.component.tsx +84 -0
  88. package/src/ward-patient-card/card-rows/mother-child-row.scss +22 -0
  89. package/src/ward-patient-card/card-rows/pending-items-row.component.tsx +54 -0
  90. package/src/ward-patient-card/row-elements/ward-patient-age.tsx +1 -1
  91. package/src/ward-patient-card/row-elements/ward-patient-coded-obs-tags.tsx +62 -39
  92. package/src/ward-patient-card/row-elements/ward-patient-header-address.tsx +5 -5
  93. package/src/ward-patient-card/row-elements/ward-patient-identifier.tsx +18 -41
  94. package/src/ward-patient-card/row-elements/ward-patient-location.tsx +19 -0
  95. package/src/ward-patient-card/row-elements/ward-patient-obs.resource.ts +38 -34
  96. package/src/ward-patient-card/row-elements/ward-patient-obs.tsx +26 -13
  97. package/src/ward-patient-card/row-elements/ward-patient-pending-order.component.tsx +45 -0
  98. package/src/ward-patient-card/row-elements/ward-patient-pending-transfer.tsx +38 -0
  99. package/src/ward-patient-card/row-elements/ward-patient-responsive-tooltip.tsx +32 -0
  100. package/src/ward-patient-card/row-elements/ward-patient-skeleton-text.tsx +9 -0
  101. package/src/ward-patient-card/ward-patient-card.component.tsx +14 -45
  102. package/src/ward-patient-card/ward-patient-card.scss +68 -9
  103. package/src/ward-view/default-ward/default-ward-beds.component.tsx +42 -0
  104. package/src/ward-view/default-ward/default-ward-patient-card-header.component.tsx +32 -0
  105. package/src/ward-view/default-ward/default-ward-patient-card.component.tsx +31 -0
  106. package/src/ward-view/default-ward/default-ward-pending-patients.component.tsx +52 -0
  107. package/src/ward-view/default-ward/default-ward-unassigned-patients.component.tsx +32 -0
  108. package/src/ward-view/default-ward/default-ward-view.component.tsx +31 -0
  109. package/src/ward-view/materal-ward/maternal-ward-beds.component.tsx +65 -0
  110. package/src/ward-view/materal-ward/maternal-ward-patient-card-header.component.tsx +30 -0
  111. package/src/ward-view/materal-ward/maternal-ward-patient-card.component.tsx +93 -0
  112. package/src/{beds/occupied-bed.scss → ward-view/materal-ward/maternal-ward-patient-card.scss} +4 -9
  113. package/src/ward-view/materal-ward/maternal-ward-patient-card.test.tsx +58 -0
  114. package/src/ward-view/materal-ward/maternal-ward-pending-patients.component.tsx +48 -0
  115. package/src/ward-view/materal-ward/maternal-ward-unassigned-patients.component.tsx +33 -0
  116. package/src/ward-view/materal-ward/maternal-ward-view.component.tsx +38 -0
  117. package/src/ward-view/materal-ward/maternal-ward-view.resource.ts +89 -0
  118. package/src/ward-view/ward-view.component.tsx +15 -163
  119. package/src/ward-view/ward-view.resource.ts +193 -1
  120. package/src/ward-view/ward-view.scss +17 -6
  121. package/src/ward-view/ward-view.test.tsx +43 -48
  122. package/src/ward-view/ward.component.tsx +106 -0
  123. package/src/ward-view-header/admission-requests-bar.component.tsx +14 -9
  124. package/src/ward-view-header/admission-requests-bar.test.tsx +11 -23
  125. package/src/ward-view-header/admission-requests.scss +1 -1
  126. package/src/ward-view-header/ward-metric.component.tsx +24 -0
  127. package/src/ward-view-header/ward-metric.scss +25 -0
  128. package/src/ward-view-header/ward-metrics.component.tsx +78 -0
  129. package/src/ward-view-header/ward-metrics.scss +7 -0
  130. package/src/ward-view-header/ward-metrics.test.tsx +37 -0
  131. package/src/ward-view-header/ward-view-header.component.tsx +9 -4
  132. package/src/ward-view-header/ward-view-header.scss +0 -1
  133. package/src/ward-workspace/admission-request-card/admission-request-card-actions.component.tsx +70 -6
  134. package/src/ward-workspace/admission-request-card/admission-request-card-header.component.tsx +10 -23
  135. package/src/ward-workspace/admission-request-card/admission-request-card.component.tsx +9 -3
  136. package/src/ward-workspace/admission-request-card/admission-request-card.scss +13 -4
  137. package/src/ward-workspace/admission-request-workspace/admission-requests-workspace.test.tsx +55 -33
  138. package/src/ward-workspace/admission-request-workspace/admission-requests.workspace.tsx +30 -37
  139. package/src/ward-workspace/admit-patient-form-workspace/admit-patient-form.test.tsx +98 -203
  140. package/src/ward-workspace/admit-patient-form-workspace/admit-patient-form.workspace.tsx +116 -180
  141. package/src/ward-workspace/bed-selector.component.tsx +119 -0
  142. package/src/ward-workspace/bed-selector.scss +15 -0
  143. package/src/ward-workspace/patient-banner/patient-banner.component.tsx +7 -14
  144. package/src/ward-workspace/patient-clinical-forms-workspace/patient-clinical-forms.workspace.tsx +23 -0
  145. package/src/{ward-patient-workspace → ward-workspace/patient-details}/ward-patient-action-button.extension.tsx +2 -1
  146. package/src/{ward-patient-workspace → ward-workspace/patient-details}/ward-patient.workspace.tsx +18 -9
  147. package/src/ward-workspace/patient-discharge/patient-discharge.scss +41 -0
  148. package/src/ward-workspace/patient-discharge/patient-discharge.workspace.tsx +113 -0
  149. package/src/ward-workspace/patient-transfer-bed-swap/patient-bed-swap-form.component.tsx +68 -79
  150. package/src/ward-workspace/patient-transfer-bed-swap/patient-transfer-request-form.component.tsx +24 -24
  151. package/src/ward-workspace/patient-transfer-bed-swap/patient-transfer-swap.scss +12 -2
  152. package/src/ward-workspace/patient-transfer-bed-swap/patient-transfer-swap.workspace.tsx +12 -8
  153. package/src/ward-workspace/patient-transfer-request-workspace/patient-transfer-request.workspace.tsx +11 -0
  154. package/src/ward-workspace/ward-patient-notes/form/notes-form.component.tsx +1 -1
  155. package/src/ward-workspace/ward-patient-notes/form/notes-form.test.tsx +1 -1
  156. package/src/ward-workspace/ward-patient-notes/history/notes-container.component.tsx +2 -2
  157. package/src/ward-workspace/ward-patient-notes/notes.resource.ts +5 -7
  158. package/src/ward-workspace/ward-patient-notes/notes.workspace.tsx +1 -1
  159. package/src/ward-workspace/ward-patient-notes/types.ts +0 -4
  160. package/src/ward.resource.ts +38 -2
  161. package/translations/en.json +31 -7
  162. package/dist/152.js +0 -1
  163. package/dist/152.js.map +0 -1
  164. package/dist/255.js.map +0 -1
  165. package/dist/269.js +0 -1
  166. package/dist/269.js.map +0 -1
  167. package/dist/346.js +0 -1
  168. package/dist/346.js.map +0 -1
  169. package/dist/466.js +0 -1
  170. package/dist/466.js.map +0 -1
  171. package/dist/659.js.map +0 -1
  172. package/dist/729.js +0 -1
  173. package/dist/729.js.map +0 -1
  174. package/dist/749.js +0 -1
  175. package/dist/749.js.map +0 -1
  176. package/dist/76.js +0 -1
  177. package/dist/76.js.map +0 -1
  178. package/dist/793.js +0 -2
  179. package/dist/793.js.map +0 -1
  180. package/dist/803.js +0 -1
  181. package/dist/803.js.map +0 -1
  182. package/dist/960.js.map +0 -1
  183. package/src/beds/empty-bed.scss +0 -28
  184. package/src/beds/occupied-bed.component.tsx +0 -35
  185. package/src/beds/unassigned-patient.component.tsx +0 -20
  186. package/src/beds/unassigned-patient.scss +0 -6
  187. package/src/config-schema-admission-request-note.ts +0 -9
  188. package/src/config-schema-extension-colored-obs-tags.ts +0 -91
  189. package/src/hooks/useCurrentWardCardConfig.ts +0 -32
  190. package/src/ward-patient-card/card-rows/admission-request-note.extension.tsx +0 -27
  191. package/src/ward-patient-card/card-rows/colored-obs-tags-card-row.extension.tsx +0 -13
  192. package/src/ward-patient-card/ward-patient-card-element.component.tsx +0 -65
  193. package/src/ward-view/ward-bed.component.tsx +0 -14
  194. /package/dist/{793.js.LICENSE.txt → 303.js.LICENSE.txt} +0 -0
  195. /package/dist/{255.js.LICENSE.txt → 372.js.LICENSE.txt} +0 -0
  196. /package/src/{ward-patient-workspace → ward-workspace/patient-details}/ward-patient.style.scss +0 -0
@@ -1,14 +1,5 @@
1
1
  import { type ConfigSchema, Type, validators } from '@openmrs/esm-framework';
2
2
 
3
- export const defaultWardPatientCard: WardPatientCardDefinition = {
4
- id: 'default',
5
- headerRowElements: ['patient-age', 'patient-address', 'patient-identifier'],
6
- footerRowElements: [],
7
- appliedTo: null,
8
- };
9
-
10
- export const builtInPatientCardElements = ['patient-age', 'time-on-ward', 'time-since-admission'];
11
-
12
3
  export const addressFields = [
13
4
  'cityVillage',
14
5
  'stateProvince',
@@ -37,11 +28,12 @@ export const addressFields = [
37
28
  type AddressField = keyof typeof addressFields;
38
29
 
39
30
  export const configSchema: ConfigSchema = {
40
- wardPatientCards: {
41
- _description: 'Configure the display of ward patient cards',
42
- obsElementDefinitions: {
31
+ patientCardElements: {
32
+ _description:
33
+ 'Configuration of various patient card elements. Each configured element must have a unique id, defined in the ward React component being used.',
34
+ obs: {
43
35
  _type: Type.Array,
44
- _description: 'Defines obs display elements that can be included in the card header or footer.',
36
+ _description: 'Configures obs values to display.',
45
37
  _default: [],
46
38
  _elements: {
47
39
  id: {
@@ -58,12 +50,6 @@ export const configSchema: ConfigSchema = {
58
50
  "Optional. The custom label or i18n key to the translated label to display. If not provided, defaults to the concept's name. (Note that this can be set to an empty string to not show a label)",
59
51
  _default: null,
60
52
  },
61
- labelI18nModule: {
62
- _type: Type.String,
63
- _description:
64
- 'Optional. The custom module to use for translation of the label. If not provided, the label will not be translated.',
65
- _default: null,
66
- },
67
53
  orderBy: {
68
54
  _type: Type.String,
69
55
  _description:
@@ -85,12 +71,16 @@ export const configSchema: ConfigSchema = {
85
71
  },
86
72
  },
87
73
  },
88
- identifierElementDefinitions: {
74
+ pendingItems: {
89
75
  _type: Type.Array,
90
- _description: `Defines patient identifier elements that can be included in the card header or footer. The default element 'patient-identifier' displays the preferred identifier.`,
76
+ _description: 'Configures pending orders and transfers to display.',
91
77
  _default: [
92
78
  {
93
- id: 'patient-identifier',
79
+ id: 'pending-items',
80
+ orders: {
81
+ orderTypes: [{ label: 'Labs', uuid: '52a447d3-a64a-11e3-9aeb-50e549534c5e' }],
82
+ },
83
+ showPendingItems: true,
94
84
  },
95
85
  ],
96
86
  _elements: {
@@ -98,28 +88,55 @@ export const configSchema: ConfigSchema = {
98
88
  _type: Type.String,
99
89
  _description: 'The unique identifier for this patient card element',
100
90
  },
101
- identifierTypeUuid: {
102
- _type: Type.UUID,
103
- _description:
104
- 'The UUID of the identifier type to display. If not provided, defaults to the preferred identifier.',
105
- _default: null,
91
+ orders: {
92
+ orderTypes: {
93
+ _type: Type.Array,
94
+ _description: 'Configures pending orders and transfers to display.',
95
+ _elements: {
96
+ uuid: {
97
+ _type: Type.UUID,
98
+ _description: 'Identifies the order type.',
99
+ },
100
+ label: {
101
+ _type: Type.String,
102
+ _description:
103
+ "The label or i18n key to the translated label to display. If not provided, defaults to 'Orders'",
104
+ _default: null,
105
+ },
106
+ },
107
+ },
106
108
  },
107
- label: {
108
- _type: Type.String,
109
+ showPendingItems: {
110
+ _type: Type.Boolean,
109
111
  _description:
110
- 'the custom label or i18n key to the translated label to display for patient identifier. If not provided, defaults to the patient-identifier name.',
111
- _default: null,
112
+ 'Optional. If true, pending items (e.g., number of pending orders) will be displayed on the patient card.',
113
+ },
114
+ },
115
+ },
116
+ patientIdentifier: {
117
+ _type: Type.Array,
118
+ _description: `Configures patient identifier to display. An unconfigured element displays the preferred identifier.`,
119
+ _default: [
120
+ {
121
+ id: 'patient-identifier',
122
+ showIdentifierLabel: false,
112
123
  },
113
- labelI18nModule: {
124
+ ],
125
+ _elements: {
126
+ id: {
114
127
  _type: Type.String,
115
- _description: 'Optional. The custom module to use for translation of the label',
116
- _default: null,
128
+ _description: 'The unique identifier for this patient card element',
129
+ },
130
+ showIdentifierLabel: {
131
+ _type: Type.Boolean,
132
+ _description:
133
+ 'If true, the identifier type (eg: "OpenMRS ID") is shown along with the identifier itself. Defaults to false',
117
134
  },
118
135
  },
119
136
  },
120
- addressElementDefinitions: {
137
+ patientAddress: {
121
138
  _type: Type.Array,
122
- _description: 'Defines patient address elements that can be included in the card header or footer.',
139
+ _description: 'Configures patient address elements.',
123
140
  _default: [
124
141
  {
125
142
  id: 'patient-address',
@@ -143,90 +160,151 @@ export const configSchema: ConfigSchema = {
143
160
  },
144
161
  },
145
162
  },
146
- cardDefinitions: {
163
+ admissionRequestNote: {
147
164
  _type: Type.Array,
148
- _default: [defaultWardPatientCard],
149
- _description: `An array of card configuration. A card configuration can be applied to different ward locations.
150
- If multiple card configurations apply to a location, only the first one is chosen.`,
165
+ _description: 'Configures admission request notes to display.',
166
+ _default: [
167
+ {
168
+ id: 'admission-request-note',
169
+ conceptUuid: '161011AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
170
+ },
171
+ ],
151
172
  _elements: {
152
- id: {
153
- _type: Type.String,
154
- _description:
155
- 'The unique identifier for this card definition. This is used to set the name of the extension slot the card has, where the rows go. The slot name is "ward-patient-card-<id>", unless the id is "default", in which case the slot name is "ward-patient-card".',
156
- _default: 'default',
157
- },
158
- headerRowElements: {
159
- _type: Type.Array,
160
- _description: `IDs of patient card elements to appear in the header row. These can be built-in, or custom ones can be defined in patientCardElementDefinitions. Built-in elements are: '${builtInPatientCardElements.join(
161
- "', '",
162
- )}'.`,
163
- _elements: {
173
+ fields: {
174
+ id: {
164
175
  _type: Type.String,
176
+ _description: 'The unique identifier for this patient card element',
177
+ },
178
+ conceptUuid: {
179
+ _type: Type.UUID,
180
+ _description: 'Required. Identifies the concept for the admission request note.',
165
181
  },
166
182
  },
167
- footerRowElements: {
168
- _type: Type.Array,
169
- _description: `IDs of patient card elements to appear in the footer row. These can be built-in, or custom ones can be defined in patientCardElementDefinitions. Built-in elements are: '${builtInPatientCardElements.join(
170
- "', '",
171
- )}'.`,
172
- _elements: {
183
+ },
184
+ coloredObsTags: {
185
+ _type: Type.Array,
186
+ _description: 'Configures observation values to display as Carbon tags.',
187
+ _elements: {
188
+ conceptUuid: {
189
+ _type: Type.UUID,
190
+ _description: 'Required. Identifies the concept to use to identify the desired observations.',
191
+ // Problem list
192
+ _default: '1284AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
193
+ },
194
+ summaryLabel: {
173
195
  _type: Type.String,
196
+ _description: `Optional. The custom label or i18n key to the translated label to display for the summary tag. The summary tag shows the count of the number of answers that are present but not configured to show as their own tags. If not provided, defaults to the name of the concept.`,
197
+ _default: null,
174
198
  },
175
- },
176
- appliedTo: {
177
- _type: Type.Array,
178
- _description:
179
- 'Conditions under which this card definition should be used. If not provided, the configuration is applied to all wards.',
180
- _elements: {
181
- location: {
182
- _type: Type.UUID,
183
- _description: 'The UUID of the location. If not provided, applies to all wards.',
184
- _default: null,
199
+ summaryLabelI18nModule: {
200
+ _type: Type.String,
201
+ _description: 'Optional. The custom module to use for translation of the summary label',
202
+ _default: null,
203
+ },
204
+ summaryLabelColor: {
205
+ _type: Type.String,
206
+ _description:
207
+ 'The color of the summary tag. See https://react.carbondesignsystem.com/?path=/docs/components-tag--overview for a list of supported colors',
208
+ _default: null,
209
+ },
210
+ tags: {
211
+ _type: Type.Array,
212
+ _description: `An array specifying concept sets and color. Observations with coded values that are members of the specified concept sets will be displayed as their own tags with the specified color. Any observation with coded values not belonging to any concept sets specified will be summarized as a count in the summary tag. If a concept set is listed multiple times, the first matching applied-to rule takes precedence.`,
213
+ _default: [],
214
+ _elements: {
215
+ color: {
216
+ _type: Type.String,
217
+ _description:
218
+ 'Color of the tag. See https://react.carbondesignsystem.com/?path=/docs/components-tag--overview for a list of supported colors.',
219
+ },
220
+ appliedToConceptSets: {
221
+ _type: Type.Array,
222
+ _description: `The concept sets which the color applies to. Observations with coded values that are members of the specified concept sets will be displayed as their own tag with the specified color. If an observation's coded value belongs to multiple concept sets, the first matching applied-to rule takes precedence.`,
223
+ _elements: {
224
+ _type: Type.UUID,
225
+ },
226
+ },
185
227
  },
186
228
  },
187
229
  },
188
230
  },
189
231
  },
190
232
  },
233
+ wards: {
234
+ _description: 'Configuration of what type of ward to use at different ward locations.',
235
+ _type: Type.Array,
236
+ _default: [{ id: 'default-ward' }],
237
+ _elements: {
238
+ id: {
239
+ _type: Type.String,
240
+ _description:
241
+ 'The ward type to use. Currently, "default-ward" and "maternal-ward" are supported. This string also serves as the extension slot name for the ward view.',
242
+ },
243
+ appliedTo: {
244
+ _type: Type.Array,
245
+ _description:
246
+ 'Optional. Conditions under which this card definition should be used. If not provided, the configuration is applied to all wards.',
247
+ _elements: {
248
+ location: {
249
+ _type: Type.UUID,
250
+ _description: 'The UUID of the location. If not provided, applies to all wards.',
251
+ _default: null,
252
+ },
253
+ },
254
+ },
255
+ },
256
+ },
191
257
  };
192
258
 
193
259
  export interface WardConfigObject {
194
- wardPatientCards: WardPatientCardsConfig;
260
+ patientCardElements: {
261
+ obs: Array<ObsElementConfig>;
262
+ pendingItems: Array<PendingItemsElementConfig>;
263
+ patientIdentifier: Array<IdentifierElementConfig>;
264
+ patientAddress: Array<PatientAddressElementConfig>;
265
+ coloredObsTags: Array<ColoredObsTagsElementConfig>;
266
+ admissionRequestNote: Array<AdmissionRequestNoteElementConfig>;
267
+ };
268
+ wards: Array<WardDefinition>;
195
269
  }
196
270
 
197
- export interface WardPatientCardsConfig {
198
- obsElementDefinitions: Array<ObsElementDefinition>;
199
- identifierElementDefinitions: Array<IdentifierElementDefinition>;
200
- addressElementDefinitions: Array<AddressElementDefinition>;
201
- cardDefinitions: Array<WardPatientCardDefinition>;
271
+ export interface PendingItemsElementConfig {
272
+ id: string;
273
+ showPendingItems: boolean;
274
+ orders: {
275
+ orderTypes: Array<{
276
+ label?: string;
277
+ uuid: string;
278
+ }>;
279
+ };
202
280
  }
203
281
 
204
- export interface ObsElementDefinition {
282
+ export interface ObsElementConfig {
205
283
  id: string;
206
284
  conceptUuid: string;
207
285
  onlyWithinCurrentVisit: boolean;
208
286
  orderBy: 'ascending' | 'descending';
209
287
  limit: number;
210
288
  label?: string;
211
- labelI18nModule?: string;
212
289
  }
213
290
 
214
- export interface IdentifierElementDefinition {
291
+ export interface IdentifierElementConfig {
215
292
  id: string;
216
- identifierTypeUuid: string;
217
- label?: string;
218
- labelI18nModule?: string;
293
+ showIdentifierLabel: boolean;
219
294
  }
220
295
 
221
- export interface AddressElementDefinition {
296
+ export interface PatientAddressElementConfig {
222
297
  id: string;
223
298
  fields: Array<AddressField>;
224
299
  }
225
300
 
226
- export interface WardPatientCardDefinition {
301
+ export interface AdmissionRequestNoteElementConfig {
302
+ id: string;
303
+ conceptUuid: string;
304
+ }
305
+
306
+ export interface WardDefinition {
227
307
  id: string;
228
- headerRowElements: Array<string>;
229
- footerRowElements: Array<string>;
230
308
  appliedTo?: Array<{
231
309
  /**
232
310
  * locationUuid. If given, only applies to patients at the specified ward locations. (If not provided, applies to all locations)
@@ -234,3 +312,44 @@ export interface WardPatientCardDefinition {
234
312
  location: string;
235
313
  }>;
236
314
  }
315
+ export interface ColoredObsTagsElementConfig {
316
+ /**
317
+ * Required. Identifies the concept to use to identify the desired observations.
318
+ */
319
+ conceptUuid: string;
320
+
321
+ /**
322
+ * Optional. The custom label or i18n key to the translated label to display for the summary tag. The summary tag
323
+ * shows the count of the number of answers that are present but not configured to show as their own tags. If not
324
+ * provided, defaults to the name of the concept.
325
+ */
326
+ summaryLabel?: string;
327
+
328
+ /**
329
+ * The color of the summary tag.
330
+ * See https://react.carbondesignsystem.com/?path=/docs/components-tag--overview for a list of supported colors
331
+ */
332
+ summaryLabelColor?: string;
333
+
334
+ /**
335
+ * An array specifying concept sets and color. Observations with coded values that are members of the specified concept sets
336
+ * will be displayed as their own tags with the specified color. Any observation with coded values not belonging to
337
+ * any concept sets specified will be summarized as a count in the summary tag. If a concept set is listed multiple times,
338
+ * the first matching applied-to rule takes precedence.
339
+ */
340
+ tags: Array<ColoredObsTagConfig>;
341
+ }
342
+
343
+ export interface ColoredObsTagConfig {
344
+ /**
345
+ * Color of the tag. See https://react.carbondesignsystem.com/?path=/docs/components-tag--overview for a list of supported colors.
346
+ */
347
+ color: string;
348
+
349
+ /**
350
+ * The concept sets which the color applies to. Observations with coded values that are members of the specified concept sets
351
+ * will be displayed as their own tag with the specified color.
352
+ * If an observation's coded value belongs to multiple concept sets, the first matching applied-to rule takes precedence.
353
+ */
354
+ appliedToConceptSets: Array<string>;
355
+ }
package/src/constant.ts CHANGED
@@ -1 +1 @@
1
- export const moduleName = '@openmrs/esm-ward-app';
1
+ export const moduleName = '@kenyaemr/esm-ward-app';
@@ -1,16 +1,34 @@
1
- import { type FetchResponse, openmrsFetch, restBaseUrl } from '@openmrs/esm-framework';
1
+ import { type FetchResponse, openmrsFetch, restBaseUrl, useFeatureFlag } from '@openmrs/esm-framework';
2
+ import useSWR from 'swr';
2
3
  import { type AdmissionLocationFetchResponse } from '../types/index';
3
- import useSWRImmutable from 'swr/immutable';
4
4
  import useWardLocation from './useWardLocation';
5
5
 
6
6
  const requestRep =
7
7
  'custom:(ward,totalBeds,occupiedBeds,bedLayouts:(rowNumber,columnNumber,bedNumber,bedId,bedUuid,status,location,patients:(person:full,identifiers,uuid)))';
8
8
 
9
- // note "admissionLocation" sn't the clearest name, but it matches the endpoint; endpoint fetches bed information (including info about patients in those beds) for a location (as provided by the bed management module)
9
+ /**
10
+ *
11
+ * Fetches bed information (including info about patients in those beds) for a location,
12
+ * as provided by the bed management module. If the bed management module is not installed,
13
+ * then no request will be made, the return object's
14
+ * `isLoading` field will be false, and the `admissionLocation` field will be undefined.
15
+ *
16
+ * Note that "admissionLocation" isn't the clearest name, but it matches the endpoint name
17
+ *
18
+ * @param rep the "v=" representation parameter
19
+ * @returns
20
+ */
10
21
  export function useAdmissionLocation(rep: string = requestRep) {
11
22
  const { location } = useWardLocation();
23
+
24
+ const isBedManagementModuleInstalled = useFeatureFlag('bedmanagement-module');
25
+
12
26
  const apiUrl = location?.uuid ? `${restBaseUrl}/admissionLocation/${location?.uuid}?v=${rep}` : null;
13
- const { data, ...rest } = useSWRImmutable<FetchResponse<AdmissionLocationFetchResponse>, Error>(apiUrl, openmrsFetch);
27
+ const { data, ...rest } = useSWR<FetchResponse<AdmissionLocationFetchResponse>, Error>(
28
+ isBedManagementModuleInstalled ? apiUrl : null,
29
+ openmrsFetch,
30
+ );
31
+
14
32
  return {
15
33
  admissionLocation: data?.data,
16
34
  ...rest,
@@ -0,0 +1,9 @@
1
+ import { openmrsFetch, restBaseUrl } from '@openmrs/esm-framework';
2
+ import { type BedDetail } from '../types';
3
+ import useSWR from 'swr';
4
+
5
+ export function useAssignedBedByPatient(patientUuid: string) {
6
+ const url = `${restBaseUrl}/beds?patientUuid=${patientUuid}`;
7
+
8
+ return useSWR<{ data: { results: Array<BedDetail> } }, Error>(url, openmrsFetch);
9
+ }
@@ -1,5 +1,4 @@
1
- import { openmrsFetch, restBaseUrl } from '@openmrs/esm-framework';
2
- import useSWR from 'swr';
1
+ import { restBaseUrl, useOpenmrsFetchAll } from '@openmrs/esm-framework';
3
2
  import { type Bed, type BedStatus } from '../types/index';
4
3
 
5
4
  interface BedSearchCriteria {
@@ -17,10 +16,10 @@ export function useBeds(searchCriteria?: BedSearchCriteria) {
17
16
  }
18
17
 
19
18
  const apiUrl = `${restBaseUrl}/bed?${searchParam}`;
20
- const { data, ...rest } = useSWR<{ data: { results: Array<Bed> } }, Error>(apiUrl, openmrsFetch);
19
+ const { data, ...rest } = useOpenmrsFetchAll<Bed>(apiUrl);
21
20
 
22
21
  return {
23
- beds: data?.data?.results ?? [],
22
+ beds: data,
24
23
  ...rest,
25
24
  };
26
25
  }
@@ -1,11 +1,10 @@
1
- import { type Concept, openmrsFetch, restBaseUrl } from '@openmrs/esm-framework';
2
- import useSWRImmutable from 'swr/immutable';
1
+ import { type Concept, restBaseUrl, useOpenmrsFetchAll } from '@openmrs/esm-framework';
3
2
 
4
3
  export function useConcepts(uuids: string[], rep = 'default') {
5
4
  const apiUrl = `${restBaseUrl}/concept?references=${uuids.join()}&v=${rep}`;
6
- const { data, ...rest } = useSWRImmutable<{ data: { results: Array<Concept> } }, Error>(apiUrl, openmrsFetch);
5
+ const { data, ...rest } = useOpenmrsFetchAll<Concept>(apiUrl, { immutable: true });
7
6
  return {
8
- concepts: data?.data?.results,
7
+ concepts: data,
9
8
  ...rest,
10
9
  };
11
10
  }
@@ -12,7 +12,10 @@ interface EmrApiConfigurationResponse {
12
12
  clinicianEncounterRole: OpenmrsResource;
13
13
  consultFreeTextCommentsConcept: OpenmrsResource;
14
14
  visitNoteEncounterType: OpenmrsResource;
15
+ inpatientNoteEncounterType: OpenmrsResource;
16
+ transferRequestEncounterType: OpenmrsResource;
15
17
  transferWithinHospitalEncounterType: OpenmrsResource;
18
+ exitFromInpatientEncounterType: OpenmrsResource;
16
19
  supportsTransferLocationTag: LocationTag;
17
20
  supportsAdmissionLocationTag: LocationTag;
18
21
  supportsLoginLocationTag: LocationTag;
@@ -64,6 +67,8 @@ const customRepProps = [
64
67
  ['diagnosisSets', 'ref'],
65
68
  ['personImageDirectory', 'ref'],
66
69
  ['visitNoteEncounterType', 'ref'],
70
+ ['inpatientNoteEncounterType', 'ref'],
71
+ ['transferRequestEncounterType', 'ref'],
67
72
  ['consultEncounterType', 'ref'],
68
73
  ['diagnosisMetadata', 'ref'],
69
74
  ['narrowerThanConceptMapType', 'ref'],
@@ -1,6 +1,5 @@
1
- import useSWR from 'swr';
2
- import { type FetchResponse, openmrsFetch, restBaseUrl } from '@openmrs/esm-framework';
3
- import { type InpatientAdmissionFetchResponse } from '../types';
1
+ import { restBaseUrl, useOpenmrsFetchAll } from '@openmrs/esm-framework';
2
+ import { type InpatientAdmission } from '../types';
4
3
  import useWardLocation from './useWardLocation';
5
4
 
6
5
  export function useInpatientAdmission() {
@@ -9,20 +8,16 @@ export function useInpatientAdmission() {
9
8
  // prettier-ignore
10
9
  const customRepresentation =
11
10
  'custom:(visit,' +
12
- 'patient:(uuid,identifiers,voided,' +
13
- 'person:(uuid,display,gender,age,birthdate,birthtime,preferredName,preferredAddress,dead,deathDate)),' +
14
- 'encounterAssigningToCurrentInpatientLocation:(encounterDatetime),' +
15
- 'firstAdmissionOrTransferEncounter:(encounterDatetime),' +
11
+ 'patient:(uuid,identifiers:(uuid,display,identifier,identifierType),voided,' +
12
+ 'person:(uuid,display,gender,age,birthdate,birthtime,preferredName,preferredAddress,dead,deathDate)),' +
13
+ 'encounterAssigningToCurrentInpatientLocation:(encounterDatetime),' +
14
+ 'currentInpatientRequest:(dispositionLocation,dispositionType,disposition:(uuid,display),dispositionEncounter:(uuid,display),dispositionObsGroup:(uuid,display),visit:(uuid),patient:(uuid)),' +
15
+ 'firstAdmissionOrTransferEncounter:(encounterDatetime),' +
16
16
  ')';
17
- const { data, ...rest } = useSWR<FetchResponse<InpatientAdmissionFetchResponse>, Error>(
17
+
18
+ return useOpenmrsFetchAll<InpatientAdmission>(
18
19
  location
19
20
  ? `${restBaseUrl}/emrapi/inpatient/admission?currentInpatientLocation=${location.uuid}&v=${customRepresentation}`
20
21
  : null,
21
- openmrsFetch,
22
22
  );
23
-
24
- return {
25
- inpatientAdmissions: data?.data?.results,
26
- ...rest,
27
- };
28
23
  }
@@ -1,8 +1,6 @@
1
- import { type FetchResponse, openmrsFetch, restBaseUrl } from '@openmrs/esm-framework';
2
- import type { DispositionType, InpatientRequestFetchResponse } from '../types';
3
- import useSWR from 'swr';
1
+ import { restBaseUrl, useOpenmrsFetchAll } from '@openmrs/esm-framework';
2
+ import type { DispositionType, InpatientRequest } from '../types';
4
3
  import useWardLocation from './useWardLocation';
5
- import { useMemo } from 'react';
6
4
 
7
5
  // prettier-ignore
8
6
  const defaultRep =
@@ -26,18 +24,9 @@ export function useInpatientRequest(
26
24
  searchParams.set('dispositionLocation', location?.uuid);
27
25
  searchParams.set('v', rep);
28
26
 
29
- const { data, ...rest } = useSWR<FetchResponse<InpatientRequestFetchResponse>, Error>(
27
+ const { data, ...rest } = useOpenmrsFetchAll<InpatientRequest>(
30
28
  location?.uuid ? `${restBaseUrl}/emrapi/inpatient/request?${searchParams.toString()}` : null,
31
- openmrsFetch,
32
29
  );
33
30
 
34
- const results = useMemo(
35
- () => ({
36
- inpatientRequests: data?.data?.results,
37
- ...rest,
38
- }),
39
- [data, rest],
40
- );
41
-
42
- return results;
31
+ return { inpatientRequests: data, ...rest };
43
32
  }
@@ -1,54 +1,11 @@
1
- import { type FetchResponse, fhirBaseUrl, openmrsFetch } from '@openmrs/esm-framework';
2
- import { useEffect, useMemo, useState } from 'react';
3
- import useSWRImmutable from 'swr/immutable';
1
+ import { fhirBaseUrl, useFhirPagination } from '@openmrs/esm-framework';
4
2
 
5
- interface FhirLocation {
6
- fullUrl: string;
7
- resource: {
8
- resourceType: 'Location';
9
- id: string;
10
- name: string;
11
- description: string;
12
- };
13
- }
14
-
15
- interface FhirResponse {
16
- resourceType: 'Bundle';
17
- id: '6a107c31-d760-4df0-bb70-89ad742225ca';
18
- meta: {
19
- lastUpdated: '2024-08-08T06:28:01.495+00:00';
20
- };
21
- type: 'searchset';
22
- total: number;
23
- link: Array<{
24
- relation: 'self' | 'prev' | 'next';
25
- url: string;
26
- }>;
27
- entry: Array<FhirLocation>;
28
- }
29
-
30
- export default function useLocations(filterCriteria: Array<Array<string>> = [], skip: boolean = false) {
31
- const [totalLocations, setTotalLocations] = useState(0);
32
- const [url, setUrl] = useState(`${fhirBaseUrl}/Location`);
3
+ export default function useLocations(
4
+ filterCriteria: Array<Array<string>> = [],
5
+ pageSize: number,
6
+ skip: boolean = false,
7
+ ) {
33
8
  const searchParams = new URLSearchParams(filterCriteria);
34
- const urlWithSearchParams = `${url}?${searchParams.toString()}`;
35
- const { data, ...rest } = useSWRImmutable<FetchResponse<FhirResponse>>(
36
- !skip ? urlWithSearchParams : null,
37
- openmrsFetch,
38
- );
39
-
40
- useEffect(() => {
41
- if (data?.data) {
42
- setTotalLocations(data.data.total);
43
- }
44
- }, [data]);
45
-
46
- const results = useMemo(() => {
47
- return {
48
- locations: data?.data?.entry?.map((entry) => entry.resource),
49
- totalLocations,
50
- ...rest,
51
- };
52
- }, [data, rest, totalLocations]);
53
- return results;
9
+ const urlWithSearchParams = `${fhirBaseUrl}/Location?${searchParams.toString()}`;
10
+ return useFhirPagination<fhir.Location>(skip ? null : urlWithSearchParams, pageSize, { immutable: true });
54
11
  }
@@ -0,0 +1,46 @@
1
+ import { makeUrl, restBaseUrl, useOpenmrsFetchAll } from '@openmrs/esm-framework';
2
+ import { type MotherAndChild } from '../types';
3
+
4
+ export interface MothersAndChildrenSearchCriteria {
5
+ mothers?: Array<string>;
6
+ children?: Array<string>;
7
+ requireMotherHasActiveVisit?: boolean;
8
+ requireChildHasActiveVisit?: boolean;
9
+ requireChildBornDuringMothersActiveVisit?: boolean;
10
+ }
11
+
12
+ export function useMotherAndChildren(
13
+ criteria: MothersAndChildrenSearchCriteria,
14
+ fetch: boolean = true,
15
+ rep: string = null,
16
+ ) {
17
+ const url = makeUrlUrl(`${restBaseUrl}/emrapi/maternal/mothersAndChildren`);
18
+ const {
19
+ mothers,
20
+ children,
21
+ requireChildBornDuringMothersActiveVisit,
22
+ requireChildHasActiveVisit,
23
+ requireMotherHasActiveVisit,
24
+ } = criteria;
25
+
26
+ for (const m of mothers ?? []) {
27
+ url.searchParams.append('mother', m);
28
+ }
29
+
30
+ for (const c of children ?? []) {
31
+ url.searchParams.append('child', c);
32
+ }
33
+
34
+ url.searchParams.append('requireMotherHasActiveVisit', requireMotherHasActiveVisit?.toString() ?? 'false');
35
+ url.searchParams.append('requireChildHasActiveVisit', requireChildHasActiveVisit?.toString() ?? 'false');
36
+ url.searchParams.append(
37
+ 'requireChildBornDuringMothersActiveVisit',
38
+ requireChildBornDuringMothersActiveVisit?.toString() ?? 'false',
39
+ );
40
+ rep && url.searchParams.append('v', rep);
41
+ return useOpenmrsFetchAll<MotherAndChild>(fetch ? url : null);
42
+ }
43
+
44
+ function makeUrlUrl(path: string) {
45
+ return new URL(makeUrl(path), window.location.toString());
46
+ }