@palladium-ethiopia/esm-admin-app 5.4.2-pre.100

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 (149) hide show
  1. package/.turbo/turbo-build.log +15 -0
  2. package/README.md +12 -0
  3. package/dist/117.js +1 -0
  4. package/dist/152.js +1 -0
  5. package/dist/152.js.map +1 -0
  6. package/dist/209.js +1 -0
  7. package/dist/209.js.map +1 -0
  8. package/dist/41.js +1 -0
  9. package/dist/41.js.map +1 -0
  10. package/dist/442.js +1 -0
  11. package/dist/442.js.map +1 -0
  12. package/dist/466.js +1 -0
  13. package/dist/466.js.map +1 -0
  14. package/dist/555.js +1 -0
  15. package/dist/555.js.map +1 -0
  16. package/dist/61.js +1 -0
  17. package/dist/61.js.map +1 -0
  18. package/dist/672.js +15 -0
  19. package/dist/672.js.map +1 -0
  20. package/dist/689.js +1 -0
  21. package/dist/689.js.map +1 -0
  22. package/dist/710.js +1 -0
  23. package/dist/710.js.map +1 -0
  24. package/dist/712.js +1 -0
  25. package/dist/712.js.map +1 -0
  26. package/dist/771.js +1 -0
  27. package/dist/771.js.map +1 -0
  28. package/dist/789.js +1 -0
  29. package/dist/789.js.map +1 -0
  30. package/dist/806.js +1 -0
  31. package/dist/826.js +1 -0
  32. package/dist/826.js.map +1 -0
  33. package/dist/914.js +27 -0
  34. package/dist/914.js.map +1 -0
  35. package/dist/926.js +17 -0
  36. package/dist/926.js.map +1 -0
  37. package/dist/ethiopia-esm-admin-app.js +6 -0
  38. package/dist/ethiopia-esm-admin-app.js.buildmanifest.json +556 -0
  39. package/dist/ethiopia-esm-admin-app.js.map +1 -0
  40. package/dist/main.js +32 -0
  41. package/dist/main.js.map +1 -0
  42. package/dist/routes.json +1 -0
  43. package/jest.config.js +8 -0
  44. package/package.json +52 -0
  45. package/rspack.config.js +1 -0
  46. package/src/components/confirm-modal/confirmation-operation-modal.component.tsx +43 -0
  47. package/src/components/confirm-modal/confirmation-operation.test.tsx +69 -0
  48. package/src/components/dashboard/dashboard.component.tsx +131 -0
  49. package/src/components/dashboard/dashboard.scss +38 -0
  50. package/src/components/dashboard/etl-dashboard.component.tsx +11 -0
  51. package/src/components/empty-state/empty-state-log.components.tsx +20 -0
  52. package/src/components/empty-state/empty-state-log.scss +28 -0
  53. package/src/components/empty-state/empty-state-log.test.tsx +24 -0
  54. package/src/components/facility-setup/card.component.tsx +16 -0
  55. package/src/components/facility-setup/facility-info.component.tsx +142 -0
  56. package/src/components/facility-setup/facility-info.scss +87 -0
  57. package/src/components/facility-setup/facility-setup.component.tsx +21 -0
  58. package/src/components/facility-setup/facility-setup.resource.tsx +7 -0
  59. package/src/components/facility-setup/facility-setup.scss +38 -0
  60. package/src/components/facility-setup/header/header.component.tsx +23 -0
  61. package/src/components/facility-setup/header/header.scss +19 -0
  62. package/src/components/header/header-illustration.component.tsx +13 -0
  63. package/src/components/header/header.component.tsx +28 -0
  64. package/src/components/header/header.scss +19 -0
  65. package/src/components/hook/healthWorkerAdapter.ts +213 -0
  66. package/src/components/hook/useFacilityInfo.tsx +37 -0
  67. package/src/components/hook/useSystemRoleSetting.tsx +33 -0
  68. package/src/components/locations/auto-suggest/autosuggest.component.tsx +149 -0
  69. package/src/components/locations/auto-suggest/autosuggest.scss +61 -0
  70. package/src/components/locations/auto-suggest/location-autosuggest.component.tsx +94 -0
  71. package/src/components/locations/auto-suggest/location-autosuggest.scss +48 -0
  72. package/src/components/locations/common/results-tile.component.tsx +45 -0
  73. package/src/components/locations/common/results-tile.scss +86 -0
  74. package/src/components/locations/forms/add-location/add-location.workspace.scss +34 -0
  75. package/src/components/locations/forms/add-location/add-location.workspace.tsx +200 -0
  76. package/src/components/locations/forms/search-location/search-location.workspace.scss +79 -0
  77. package/src/components/locations/forms/search-location/search-location.workspace.tsx +215 -0
  78. package/src/components/locations/header/header.component.tsx +48 -0
  79. package/src/components/locations/header/header.scss +58 -0
  80. package/src/components/locations/helpers/index.ts +16 -0
  81. package/src/components/locations/home/home-locations.component.tsx +18 -0
  82. package/src/components/locations/home/home-locations.scss +8 -0
  83. package/src/components/locations/hooks/UseFacilityLocations.ts +12 -0
  84. package/src/components/locations/hooks/useLocation.ts +18 -0
  85. package/src/components/locations/hooks/useLocationTags.ts +15 -0
  86. package/src/components/locations/tables/locations-table.component.tsx +243 -0
  87. package/src/components/locations/tables/locations-table.resource.ts +26 -0
  88. package/src/components/locations/tables/locations-table.scss +115 -0
  89. package/src/components/locations/types/index.ts +120 -0
  90. package/src/components/locations/utils/index.ts +5 -0
  91. package/src/components/logs-table/operation-log-resource.ts +41 -0
  92. package/src/components/logs-table/operation-log-table.component.tsx +120 -0
  93. package/src/components/logs-table/operation-log.scss +10 -0
  94. package/src/components/logs-table/operation-log.test.tsx +47 -0
  95. package/src/components/modal/hwr-confirmation.modal.scss +21 -0
  96. package/src/components/modal/hwr-confirmation.modal.tsx +170 -0
  97. package/src/components/modal/hwr-empty.modal.component.tsx +54 -0
  98. package/src/components/modal/hwr-sync.modal.scss +30 -0
  99. package/src/components/modal/hwr-sync.modal.tsx +209 -0
  100. package/src/components/modal/hwr-sync.resource.ts +23 -0
  101. package/src/components/provider-banner/provider-banner.component.tsx +106 -0
  102. package/src/components/provider-banner/provider-banner.module.scss +51 -0
  103. package/src/components/provider-banner/provider-banner.resource.ts +29 -0
  104. package/src/components/side-menu/left-panel.scss +42 -0
  105. package/src/components/side-menu/left-pannel.component.tsx +22 -0
  106. package/src/components/users/header/header.scss +90 -0
  107. package/src/components/users/header/user-management-header.component.tsx +42 -0
  108. package/src/components/users/manage-users/hooks/useProviderAttributeMapping.ts +110 -0
  109. package/src/components/users/manage-users/hooks/useUserFormSteps.ts +119 -0
  110. package/src/components/users/manage-users/hooks/useUserFormSubmission.ts +264 -0
  111. package/src/components/users/manage-users/hooks/useUserManagementForm.ts +122 -0
  112. package/src/components/users/manage-users/manage-user-role-scope/user-role-scope-list/user-role-scope-list.component.tsx +177 -0
  113. package/src/components/users/manage-users/manage-user-role-scope/user-role-scope-workspace/user-role-fields.scss +117 -0
  114. package/src/components/users/manage-users/manage-user-role-scope/user-role-scope-workspace/user-role-scope-fields.component.tsx +290 -0
  115. package/src/components/users/manage-users/manage-user-role-scope/user-role-scope-workspace/user-role-scope.workspace.tsx +316 -0
  116. package/src/components/users/manage-users/manage-user-role-scope/user-role-scope-workspace/userRoleScopeFormSchema.tsx +43 -0
  117. package/src/components/users/manage-users/manage-user.component.tsx +19 -0
  118. package/src/components/users/manage-users/manage-user.scss +31 -0
  119. package/src/components/users/manage-users/provider-autosuggest.component.tsx +117 -0
  120. package/src/components/users/manage-users/provider-search.resource.ts +34 -0
  121. package/src/components/users/manage-users/sections/demographic-section.component.tsx +156 -0
  122. package/src/components/users/manage-users/sections/login-section.component.tsx +88 -0
  123. package/src/components/users/manage-users/sections/provider-section.component.tsx +270 -0
  124. package/src/components/users/manage-users/sections/roles-section.component.tsx +88 -0
  125. package/src/components/users/manage-users/user-details/user-detail.scss +75 -0
  126. package/src/components/users/manage-users/user-details/user-details.component.tsx +182 -0
  127. package/src/components/users/manage-users/user-list/user-list.component.tsx +378 -0
  128. package/src/components/users/manage-users/user-list/user-list.resource.ts +30 -0
  129. package/src/components/users/manage-users/user-list/user-list.scss +37 -0
  130. package/src/components/users/manage-users/user-management.constants.ts +20 -0
  131. package/src/components/users/manage-users/user-management.utils.ts +100 -0
  132. package/src/components/users/manage-users/user-management.workspace.scss +172 -0
  133. package/src/components/users/manage-users/user-management.workspace.tsx +334 -0
  134. package/src/components/users/userManagementFormSchema.tsx +179 -0
  135. package/src/config-schema.ts +142 -0
  136. package/src/constants.ts +50 -0
  137. package/src/declarations.d.ts +2 -0
  138. package/src/index.ts +55 -0
  139. package/src/left-pannel-link.component.tsx +40 -0
  140. package/src/root.component.tsx +39 -0
  141. package/src/root.scss +12 -0
  142. package/src/routes.json +100 -0
  143. package/src/setup-tests.ts +1 -0
  144. package/src/types/index.ts +385 -0
  145. package/src/user-management.resources.ts +232 -0
  146. package/src/utils/utils.ts +20 -0
  147. package/translations/am.json +159 -0
  148. package/translations/en.json +159 -0
  149. package/tsconfig.json +5 -0
@@ -0,0 +1,385 @@
1
+ import { fhirBaseUrl, Type } from '@openmrs/esm-framework';
2
+
3
+ export interface ETLResponse {
4
+ script_name: string;
5
+ start_time: string;
6
+ stop_time: string;
7
+ status: string;
8
+ }
9
+
10
+ export interface DashboardConfig {
11
+ name: string;
12
+ slot: string;
13
+ title: string;
14
+ }
15
+ export interface FrontendModule {
16
+ name: string;
17
+ version?: string;
18
+ }
19
+ export interface SHAFacility {
20
+ operationalStatus: string;
21
+ approved: string;
22
+ kephLevel: string;
23
+ shaFacilityId: string;
24
+ shaFacilityExpiryDate: string;
25
+ registrationNumber: string;
26
+ mflCode: string;
27
+ shaFacilityLicenseNumber: string;
28
+ facilityRegistryCode: string;
29
+ source: string;
30
+ }
31
+
32
+ export interface DefaultFacility {
33
+ locationId: number;
34
+ uuid: string;
35
+ display: string;
36
+ }
37
+
38
+ export interface PractitionerResponse {
39
+ id: string;
40
+ link: Link[];
41
+ meta: Metadata;
42
+ entry: Entry[];
43
+ }
44
+
45
+ interface Metadata {
46
+ lastUpdated: string;
47
+ }
48
+ interface Link {
49
+ relation: string;
50
+ url: string;
51
+ }
52
+ interface Entry {
53
+ resource: {
54
+ id: string;
55
+ identifier: IdentifierType[];
56
+ active: boolean;
57
+ name: Name[];
58
+ telecom: ContactList[];
59
+ extension: Extension[];
60
+ gender: string;
61
+ qualification: Qualification[];
62
+ };
63
+ }
64
+ export interface Extension {
65
+ url: string;
66
+ valueCodeableConcept: ValueCodeableConcept;
67
+ }
68
+
69
+ export interface ValueCodeableConcept {
70
+ coding: Coding[];
71
+ }
72
+
73
+ export interface Coding {
74
+ system: string;
75
+ code: string;
76
+ display: string;
77
+ }
78
+
79
+ interface IdentifierType {
80
+ type: {
81
+ coding: {
82
+ code: string;
83
+ display: string;
84
+ system?: string;
85
+ }[];
86
+ };
87
+ value: string;
88
+ period?: {
89
+ start?: string;
90
+ end?: string;
91
+ };
92
+ }
93
+
94
+ interface ContactList {
95
+ system: string;
96
+ value?: string;
97
+ }
98
+
99
+ interface Name {
100
+ text: string;
101
+ }
102
+
103
+ interface Qualification {
104
+ extension: QualificationExtension[];
105
+ code: {
106
+ coding: {
107
+ system?: string;
108
+ code?: string;
109
+ display: string;
110
+ }[];
111
+ };
112
+ period: {
113
+ start: string;
114
+ end: string;
115
+ };
116
+ }
117
+
118
+ interface QualificationExtension {
119
+ url: string;
120
+ valueCoding?: {
121
+ system?: string;
122
+ code?: string;
123
+ display?: string;
124
+ };
125
+ valueString?: string;
126
+ valueCodeableConcept?: {
127
+ coding: {
128
+ system: string;
129
+ code: string;
130
+ display: string;
131
+ }[];
132
+ };
133
+ }
134
+ export interface Person {
135
+ uuid?: string;
136
+ display?: string;
137
+ gender: string;
138
+ names?: Array<PersonName>;
139
+ attributes?: Array<Attribute>;
140
+ }
141
+
142
+ export interface Role {
143
+ uuid: string;
144
+ description?: string;
145
+ display?: string;
146
+ name?: string;
147
+ }
148
+
149
+ export interface User {
150
+ uuid: string;
151
+ display: string;
152
+ username: string;
153
+ password?: string;
154
+ systemId: string;
155
+ userProperties: UserProperties;
156
+ person: Person;
157
+ privileges?: Array<string>;
158
+ roles: Array<Role>;
159
+ retired: boolean;
160
+ resourceVersion: string;
161
+ }
162
+
163
+ export interface PersonName {
164
+ givenName: string;
165
+ familyName: string;
166
+ middleName: string;
167
+ }
168
+
169
+ export interface Attribute {
170
+ attributeType?: string;
171
+ value?: string;
172
+ }
173
+
174
+ export interface UserProperties {
175
+ loginAttempts: string;
176
+ lastViewedPatientIds: string;
177
+ }
178
+
179
+ export interface UserRoleSchema {
180
+ name: string;
181
+ description: string;
182
+ category: string;
183
+ }
184
+
185
+ export interface Provider {
186
+ uuid?: string;
187
+ identifier?: string;
188
+ retired: boolean;
189
+ attributes?: Array<Attribute>;
190
+ }
191
+
192
+ export interface ProviderAttributes {
193
+ uuid?: string;
194
+ identifier?: string;
195
+ retired: boolean;
196
+ attributes?: Array<AttributeItems>;
197
+ }
198
+
199
+ export interface AttributeItems {
200
+ attributeType?: AttributeType;
201
+ value?: any;
202
+ }
203
+
204
+ export interface AttributeType {
205
+ uuid?: string;
206
+ description?: string;
207
+ display?: string;
208
+ name?: string;
209
+ }
210
+
211
+ export interface AttributeValue {
212
+ name?: string;
213
+ uuid?: string;
214
+ }
215
+
216
+ export interface ProviderLocation {
217
+ uuid: string;
218
+ name?: string;
219
+ description?: string;
220
+ retired: boolean;
221
+ attributes?: Array<AttributeItems>;
222
+ }
223
+
224
+ // Stock roles
225
+ export interface OpenmrsData extends OpenmrsObject {}
226
+ export interface OpenmrsObject {
227
+ uuid?: string;
228
+ }
229
+ export type BaseOpenmrsObject = OpenmrsObject;
230
+ export interface BaseOpenmrsData extends BaseOpenmrsObject, OpenmrsData {}
231
+ export interface StockOperationType extends BaseOpenmrsData {
232
+ uuid: string;
233
+ name: string;
234
+ description: string;
235
+ operationType: string;
236
+ hasSource: boolean;
237
+ hasDestination: boolean;
238
+ stockOperationTypeLocationScopes: Array<StockOperationTypeLocationScope>;
239
+ }
240
+
241
+ export interface StockOperationTypeLocationScope {
242
+ uuid: string;
243
+ locationTag: string;
244
+ isSource: string;
245
+ isDestination: string;
246
+ }
247
+
248
+ // Pagging
249
+ export interface PageableResult<ResultType> {
250
+ results: ResultType[];
251
+ totalCount: number | null;
252
+ }
253
+
254
+ export interface PagingCriteria {
255
+ startIndex?: number | null;
256
+ limit?: number | null;
257
+ }
258
+
259
+ // stock location
260
+
261
+ export interface FHIRResponse {
262
+ entry: Array<{ resource: fhir.Location }>;
263
+ total: number;
264
+ type: string;
265
+ resourceType: string;
266
+ }
267
+
268
+ export interface UserRoleScopeLocation extends BaseOpenmrsData {
269
+ locationUuid?: string;
270
+ locationName?: string;
271
+ enableDescendants?: boolean;
272
+ }
273
+
274
+ export interface UserRoleScopeOperationType extends BaseOpenmrsData {
275
+ operationTypeUuid?: string;
276
+ operationTypeName?: string;
277
+ }
278
+
279
+ export interface UserRoleScope extends BaseOpenmrsData {
280
+ userUuid?: string;
281
+ role?: string;
282
+ userName?: string;
283
+ userGivenName?: string;
284
+ userFamilyName?: string;
285
+ permanent: boolean;
286
+ activeFrom?: Date;
287
+ activeTo?: Date;
288
+ enabled: boolean;
289
+ locations?: Array<UserRoleScopeLocation>;
290
+ operationTypes?: Array<UserRoleScopeOperationType>;
291
+ }
292
+
293
+ export interface ProviderResponse {
294
+ uuid: string;
295
+ display: string;
296
+ person: PersonResponse;
297
+ identifier: string;
298
+ attributes: Array<{
299
+ uuid: string;
300
+ display: string;
301
+ attributeType: {
302
+ uuid: string;
303
+ display: string;
304
+ };
305
+ value: string;
306
+ }>;
307
+ retired: boolean;
308
+ voided: boolean;
309
+ }
310
+ interface PersonResponse {
311
+ uuid: string;
312
+ display: string;
313
+ names: {
314
+ givenName: string;
315
+ familyName: string;
316
+ };
317
+ gender: string;
318
+ birthdate: string;
319
+ attributes: Array<{
320
+ uuid: string;
321
+ display: string;
322
+ }>;
323
+ }
324
+ export interface UserResponse {
325
+ uuid: string;
326
+ display: string;
327
+ username: string;
328
+ systemId: string;
329
+ person: PersonResponse;
330
+ roles: Array<{
331
+ uuid: string;
332
+ display: string;
333
+ description: string;
334
+ }>;
335
+ }
336
+
337
+ export interface CustomHIEPractitionerResponse {
338
+ message: {
339
+ membership: {
340
+ id: string;
341
+ status: string;
342
+ salutation: string;
343
+ full_name: string;
344
+ gender: string;
345
+ first_name: string;
346
+ middle_name: string;
347
+ last_name: string;
348
+ registration_id: string;
349
+ external_reference_id: string;
350
+ licensing_body: string;
351
+ specialty: string;
352
+ is_active: number;
353
+ is_withdrawn: number;
354
+ withdrawal_reason: string;
355
+ withdrawal_date: string;
356
+ };
357
+ licenses: Array<{
358
+ id: string;
359
+ external_reference_id: string;
360
+ license_type: string;
361
+ license_start: string;
362
+ license_end: string;
363
+ }>;
364
+ professional_details: {
365
+ professional_cadre: string;
366
+ practice_type: string;
367
+ specialty: string;
368
+ subspecialty: string;
369
+ discipline_name: string;
370
+ educational_qualifications: string;
371
+ };
372
+ contacts: {
373
+ phone: string;
374
+ email: string;
375
+ postal_address: string;
376
+ };
377
+ identifiers: {
378
+ identification_type: string;
379
+ identification_number: string;
380
+ client_registry_id: string;
381
+ student_id: string;
382
+ };
383
+ };
384
+ fhirFormat: boolean;
385
+ }
@@ -0,0 +1,232 @@
1
+ import { fhirBaseUrl, openmrsFetch, restBaseUrl } from '@openmrs/esm-framework';
2
+ import useSWR, { mutate } from 'swr';
3
+ import {
4
+ AttributeType,
5
+ FHIRResponse,
6
+ PageableResult,
7
+ Provider,
8
+ ProviderAttributes,
9
+ ProviderLocation,
10
+ ProviderResponse,
11
+ Role,
12
+ StockOperationType,
13
+ User,
14
+ UserRoleScope,
15
+ } from './types';
16
+ import uniqBy from 'lodash-es/uniqBy';
17
+ import { useMemo } from 'react';
18
+
19
+ export const useUser = () => {
20
+ const url = `${restBaseUrl}/user?v=custom:(uuid,username,display,systemId,retired,person:(uuid,display,gender,names:(givenName,familyName,middleName),attributes:(uuid,display)),roles:(uuid,description,display,name))`;
21
+ const { data, isLoading, error, mutate } = useSWR<{ data: { results: Array<User> } }>(url, openmrsFetch, {
22
+ errorRetryCount: 2,
23
+ });
24
+ return {
25
+ users: data?.data?.results,
26
+ isLoading,
27
+ mutate,
28
+ error,
29
+ };
30
+ };
31
+
32
+ export const postUser = async (user: Partial<User>, url: string) => {
33
+ const response = await openmrsFetch(url, {
34
+ method: 'POST',
35
+ body: JSON.stringify(user),
36
+ headers: {
37
+ 'Content-Type': 'application/json',
38
+ },
39
+ });
40
+ return response.json();
41
+ };
42
+
43
+ export const createProvider = async (
44
+ uuid: string,
45
+ identifier: string,
46
+ attributes: Partial<Provider>,
47
+ providerUrl?: string,
48
+ ) => {
49
+ const providerBody = {
50
+ person: uuid,
51
+ identifier: identifier,
52
+ ...attributes,
53
+ retired: false,
54
+ };
55
+
56
+ return await openmrsFetch(providerUrl, {
57
+ method: 'POST',
58
+ body: JSON.stringify(providerBody),
59
+ headers: {
60
+ 'Content-Type': 'application/json',
61
+ },
62
+ });
63
+ };
64
+
65
+ export const createUser = async (user: Partial<User>, uuid?: string) => {
66
+ const userUrl = uuid ? `${restBaseUrl}/user/${uuid}` : `${restBaseUrl}/user`;
67
+
68
+ return await postUser(user, userUrl);
69
+ };
70
+
71
+ export const createOrUpdateUserRoleScope = async (
72
+ userRoleScopeUrl?: string,
73
+ userRoleScopePayload?: Partial<UserRoleScope>,
74
+ userUuid?: string,
75
+ ) => {
76
+ const userRoleScopeBody = {
77
+ userUuid: userUuid,
78
+ ...userRoleScopePayload,
79
+ };
80
+
81
+ return await openmrsFetch(userRoleScopeUrl, {
82
+ method: 'POST',
83
+ body: JSON.stringify(userRoleScopeBody),
84
+ headers: {
85
+ 'Content-Type': 'application/json',
86
+ },
87
+ });
88
+ };
89
+
90
+ export const handleMutation = (url: string) => {
91
+ mutate((key) => typeof key === 'string' && key.startsWith(url), undefined, { revalidate: true });
92
+ };
93
+
94
+ export const useRoles = () => {
95
+ const url = `${restBaseUrl}/role?v=custom:(uuid,description,display,name)`;
96
+ const { data, isLoading, error, mutate } = useSWR<{ data: { results: Array<Role> } }>(url, openmrsFetch, {
97
+ errorRetryCount: 2,
98
+ });
99
+ return {
100
+ roles: data?.data?.results,
101
+ isLoading,
102
+ mutate,
103
+ error,
104
+ };
105
+ };
106
+
107
+ export const usePersonAttribute = () => {
108
+ const url = `${restBaseUrl}/personattributetype?v=custom:(name,uuid)`;
109
+ const { data, isLoading, error } = useSWR<{ data: { results: Array<AttributeType> } }>(url, openmrsFetch, {
110
+ errorRetryCount: 2,
111
+ });
112
+ return {
113
+ attributeTypes: data?.data?.results,
114
+ isLoading,
115
+ error,
116
+ };
117
+ };
118
+
119
+ export const useProvider = (searchQuery: string) => {
120
+ const url = `${restBaseUrl}/provider?q=${searchQuery}&v=custom:(uuid,identifier,retired,attributes:(uuid,display,value:(name),attributeType:(uuid,name)))`;
121
+ const { data, isLoading, error } = useSWR<{ data: { results: Array<ProviderResponse> } }>(url, openmrsFetch, {
122
+ errorRetryCount: 2,
123
+ });
124
+ return {
125
+ provider: data?.data?.results,
126
+ loadingProvider: isLoading,
127
+ providerError: error,
128
+ };
129
+ };
130
+
131
+ export interface ProviderWithAttributes {
132
+ uuid: string;
133
+ identifier?: string;
134
+ attributes?: Array<{
135
+ uuid?: string;
136
+ display?: string;
137
+ value?: string | { name?: string };
138
+ attributeType?: { uuid: string; name?: string };
139
+ }>;
140
+ }
141
+
142
+ export const useProviderAttributeType = () => {
143
+ const url = `${restBaseUrl}/providerattributetype?v=custom:(uuid,name,display)`;
144
+ const { data, isLoading, error } = useSWR<{ data: { results: Array<AttributeType> } }>(url, openmrsFetch, {
145
+ errorRetryCount: 2,
146
+ });
147
+ return {
148
+ providerAttributeType: data?.data?.results,
149
+ isLoading,
150
+ error,
151
+ };
152
+ };
153
+
154
+ export const useLocation = () => {
155
+ const url = `${restBaseUrl}/location?v=custom:(uuid,name,description,retired,attributes:(value))`;
156
+ const { data, isLoading, error } = useSWR<{ data: { results: Array<ProviderLocation> } }>(url, openmrsFetch, {
157
+ errorRetryCount: 2,
158
+ });
159
+ return {
160
+ location: data?.data?.results,
161
+ loadingLocation: isLoading,
162
+ locationError: error,
163
+ };
164
+ };
165
+
166
+ export function useStockOperationTypes() {
167
+ const apiUrl = `${restBaseUrl}/stockmanagement/stockoperationtype?v=default`;
168
+ const { data, isLoading, error } = useSWR<
169
+ {
170
+ data: PageableResult<StockOperationType>;
171
+ },
172
+ Error
173
+ >(apiUrl, openmrsFetch);
174
+ return {
175
+ stockOperations: data?.data.results,
176
+ loadingStock: isLoading,
177
+ error,
178
+ };
179
+ }
180
+
181
+ export function useStockTagLocations() {
182
+ const apiUrl = `${fhirBaseUrl}/Location?_summary=data&_tag=main store,main pharmacy,dispensary,sub store `;
183
+ const { data, error, isLoading } = useSWR<{ data: FHIRResponse }>(apiUrl, openmrsFetch);
184
+ const stockLocations = useMemo(
185
+ () => data?.data?.entry?.map((response) => response.resource) ?? [],
186
+ [data?.data?.entry],
187
+ );
188
+ return {
189
+ stockLocations: uniqBy(stockLocations, 'id') ?? [],
190
+ isLoading,
191
+ error,
192
+ };
193
+ }
194
+
195
+ export const useUserRoleScopes = () => {
196
+ const apiUrl = `${restBaseUrl}/stockmanagement/userrolescope?v=full`;
197
+ const { data, error, isLoading, isValidating } = useSWR<{ data: PageableResult<UserRoleScope> }, Error>(
198
+ apiUrl,
199
+ openmrsFetch,
200
+ );
201
+ return {
202
+ items: data?.data,
203
+ loadingRoleScope: isLoading,
204
+ userRoleScopeError: error,
205
+ isValidating,
206
+ };
207
+ };
208
+
209
+ export function deleteUserRoleScopes(roleScopeIds: string[]) {
210
+ let encodedRoleScopeIds = roleScopeIds.reduce((queryString, currentId, index) => {
211
+ if (index === 0) {
212
+ return queryString;
213
+ }
214
+ queryString += (queryString.length > 0 ? ',' : '') + encodeURIComponent(currentId);
215
+ return queryString;
216
+ }, '');
217
+
218
+ if (encodedRoleScopeIds.length > 0) {
219
+ encodedRoleScopeIds = '?ids=' + encodedRoleScopeIds;
220
+ }
221
+
222
+ const apiUrl = `${restBaseUrl}/stockmanagement/userrolescope/${roleScopeIds[0]}${encodedRoleScopeIds}`;
223
+ const abortController = new AbortController();
224
+
225
+ return openmrsFetch(apiUrl, {
226
+ method: 'DELETE',
227
+ headers: {
228
+ 'Content-Type': 'application/json',
229
+ },
230
+ signal: abortController.signal,
231
+ });
232
+ }
@@ -0,0 +1,20 @@
1
+ import dayjs from 'dayjs';
2
+
3
+ /**
4
+ * Formats a given date string into "DD-MMM-YYYY, hh:mm A" format.
5
+ *
6
+ * @param {string | Date | undefined} date - The date to format.
7
+ * @returns {string} - The formatted date or '--' if the date is invalid or missing.
8
+ */
9
+ export const formatDateTime = (date) => {
10
+ if (!date) {
11
+ return '--';
12
+ }
13
+
14
+ const parsedDate = dayjs(date);
15
+ if (!parsedDate.isValid()) {
16
+ return '--';
17
+ }
18
+
19
+ return parsedDate.format('DD-MMM-YYYY, hh:mm A');
20
+ };