@digihmis/esm-outpatient-app 1.0.0

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 (116) hide show
  1. package/README.md +4 -0
  2. package/dist/117.js +1 -0
  3. package/dist/117.js.map +1 -0
  4. package/dist/132.js +1 -0
  5. package/dist/132.js.map +1 -0
  6. package/dist/152.js +1 -0
  7. package/dist/152.js.map +1 -0
  8. package/dist/209.js +1 -0
  9. package/dist/209.js.map +1 -0
  10. package/dist/317.js +1 -0
  11. package/dist/317.js.map +1 -0
  12. package/dist/349.js +1 -0
  13. package/dist/349.js.map +1 -0
  14. package/dist/371.js +1 -0
  15. package/dist/371.js.map +1 -0
  16. package/dist/378.js +1 -0
  17. package/dist/378.js.map +1 -0
  18. package/dist/395.js +12 -0
  19. package/dist/395.js.map +1 -0
  20. package/dist/442.js +1 -0
  21. package/dist/442.js.map +1 -0
  22. package/dist/45.js +1 -0
  23. package/dist/45.js.map +1 -0
  24. package/dist/466.js +1 -0
  25. package/dist/466.js.map +1 -0
  26. package/dist/508.js +1 -0
  27. package/dist/508.js.map +1 -0
  28. package/dist/564.js +1 -0
  29. package/dist/564.js.map +1 -0
  30. package/dist/61.js +1 -0
  31. package/dist/61.js.map +1 -0
  32. package/dist/640.js +1 -0
  33. package/dist/640.js.map +1 -0
  34. package/dist/689.js +1 -0
  35. package/dist/689.js.map +1 -0
  36. package/dist/709.js +1 -0
  37. package/dist/709.js.map +1 -0
  38. package/dist/712.js +1 -0
  39. package/dist/712.js.map +1 -0
  40. package/dist/720.js +1 -0
  41. package/dist/720.js.map +1 -0
  42. package/dist/742.js +1 -0
  43. package/dist/742.js.map +1 -0
  44. package/dist/759.js +15 -0
  45. package/dist/759.js.map +1 -0
  46. package/dist/771.js +1 -0
  47. package/dist/771.js.map +1 -0
  48. package/dist/797.js +1 -0
  49. package/dist/797.js.map +1 -0
  50. package/dist/806.js +1 -0
  51. package/dist/806.js.map +1 -0
  52. package/dist/912.js +1 -0
  53. package/dist/912.js.map +1 -0
  54. package/dist/913.js +1 -0
  55. package/dist/913.js.map +1 -0
  56. package/dist/940.js +1 -0
  57. package/dist/940.js.map +1 -0
  58. package/dist/974.js +1 -0
  59. package/dist/974.js.map +1 -0
  60. package/dist/digihmis-esm-outpatient-app.js +6 -0
  61. package/dist/digihmis-esm-outpatient-app.js.buildmanifest.json +827 -0
  62. package/dist/digihmis-esm-outpatient-app.js.map +1 -0
  63. package/dist/main.js +17 -0
  64. package/dist/main.js.map +1 -0
  65. package/dist/routes.json +1 -0
  66. package/jest.config.js +26 -0
  67. package/package.json +51 -0
  68. package/rspack.config.js +1 -0
  69. package/src/config-schema.ts +347 -0
  70. package/src/dashboard.meta.ts +16 -0
  71. package/src/declarations.d.ts +6 -0
  72. package/src/icon-wrapper/icon-wrapper.extension.tsx +17 -0
  73. package/src/index.ts +27 -0
  74. package/src/left-panel/left-panel.component.tsx +100 -0
  75. package/src/left-panel/left-panel.scss +13 -0
  76. package/src/main-dashboard/outpatient-dashboard.component.tsx +264 -0
  77. package/src/main-dashboard/outpatient-dashboard.resource.ts +71 -0
  78. package/src/main-dashboard/outpatient-dashboard.scss +166 -0
  79. package/src/main-dashboard/type/index.ts +162 -0
  80. package/src/page-header/page-header.component.tsx +35 -0
  81. package/src/page-header/page-header.scss +76 -0
  82. package/src/patient-management/components/auto-suggest/autosuggest.component.tsx +149 -0
  83. package/src/patient-management/components/auto-suggest/autosuggest.scss +61 -0
  84. package/src/patient-management/components/auto-suggest/diagnosis-autosuggest.component.tsx +131 -0
  85. package/src/patient-management/components/auto-suggest/diagnosis-autosuggest.scss +42 -0
  86. package/src/patient-management/patient-banner/patient-banner.component.tsx +60 -0
  87. package/src/patient-management/patient-banner/patient-banner.scss +72 -0
  88. package/src/patient-management/patient-management-workspace/billable-services-selector.component.tsx +150 -0
  89. package/src/patient-management/patient-management-workspace/patient-management-schema/index.ts +261 -0
  90. package/src/patient-management/patient-management-workspace/patient-management-workspace.scss +304 -0
  91. package/src/patient-management/patient-management-workspace/patient-management-workspace.tsx +1581 -0
  92. package/src/patient-management/patient-management-workspace/patient-management.resource.ts +182 -0
  93. package/src/patient-management/patient-management-workspace/type/index.ts +193 -0
  94. package/src/patient-management/patient-management-workspace/utils/index.ts +172 -0
  95. package/src/patient-management/patient-management.component.tsx +97 -0
  96. package/src/patient-management/patient-management.scss +30 -0
  97. package/src/patient-management/utils/index.ts +5 -0
  98. package/src/queue-room-table/queue-room-table.component.tsx +313 -0
  99. package/src/queue-room-table/queue-room-table.resource.ts +73 -0
  100. package/src/queue-room-table/queue-room-table.scss +193 -0
  101. package/src/queue-room-table/type/index.ts +34 -0
  102. package/src/queue-room-table/useQueueActions.ts +24 -0
  103. package/src/routes.json +55 -0
  104. package/src/setup-tests.ts +1 -0
  105. package/translations/am.json +57 -0
  106. package/translations/ar.json +57 -0
  107. package/translations/en.json +57 -0
  108. package/translations/es.json +57 -0
  109. package/translations/fr.json +57 -0
  110. package/translations/he.json +57 -0
  111. package/translations/km.json +57 -0
  112. package/translations/pt.json +57 -0
  113. package/translations/sw.json +57 -0
  114. package/translations/vi.json +57 -0
  115. package/translations/zh.json +57 -0
  116. package/tsconfig.json +5 -0
@@ -0,0 +1 @@
1
+ {"$schema":"https://json.openmrs.org/routes.schema.json","backendDependencies":{"fhir2":">=1.2","webservices.rest":"^2.24.0"},"extensions":[{"name":"outpatient-dashboard-header","slot":"outpatient-sidebar-slot","component":"outpatientDashboardHeader","order":0,"online":true,"offline":true},{"name":"outpatient-db-link","slot":"outpatient-dashboard-slot","component":"leftPanelLink","meta":{"name":"outpatient","slot":"outpatient-homepage-dashboard-slot","title":"Outpatient queue"},"order":1,"online":true,"offline":true},{"name":"outpatient-queue-dashboard","slot":"outpatient-homepage-dashboard-slot","component":"outpatientQueueDashboard"},{"name":"care-panel-link","slot":"outpatient-dashboard-slot","component":"carePanelLink","meta":{"name":"outpatient/patient/:patientUuid/file","slot":"outpatient-file-dashboard-slot","title":"Care panel","showOnlyOnRoute":"/file"},"order":2,"online":true,"offline":true},{"name":"care-panel-history","slot":"outpatient-file-dashboard-slot","component":"carePanel"}],"workspaces":[],"version":"1.0.0"}
package/jest.config.js ADDED
@@ -0,0 +1,26 @@
1
+ /** @type {import('jest').Config} */
2
+ module.exports = {
3
+ clearMocks: true,
4
+ transform: {
5
+ '^.+\\.[jt]sx?$': ['@swc/jest'],
6
+ },
7
+ transformIgnorePatterns: ['/node_modules/(?!@openmrs|.+\\.pnp\\.[^\\/]+$)'],
8
+ moduleNameMapper: {
9
+ '\\.(s?css)$': 'identity-obj-proxy',
10
+ '@openmrs/esm-framework': '@openmrs/esm-framework/mock',
11
+ 'lodash-es': 'lodash',
12
+ '^dexie$': require.resolve('dexie'),
13
+ },
14
+ collectCoverageFrom: [
15
+ '**/src/**/*.tsx',
16
+ '!**/node_modules/**',
17
+ '!**/vendor/**',
18
+ '!**/src/**/*.test.*',
19
+ '!**/src/declarations.d.ts',
20
+ ],
21
+ setupFilesAfterEnv: ['<rootDir>/setupTests.ts'],
22
+ testEnvironment: 'jsdom',
23
+ testEnvironmentOptions: {
24
+ url: 'http://localhost/',
25
+ },
26
+ };
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@digihmis/esm-outpatient-app",
3
+ "version": "1.0.0",
4
+ "description": "Outpatient microfrontend for the OpenMRS SPA",
5
+ "browser": "dist/digihmis-esm-outpatient-app.js",
6
+ "main": "src/index.ts",
7
+ "source": true,
8
+ "license": "MPL-2.0",
9
+ "homepage": "https://github.com/its-kios09/DigiHMIS-apps#readme",
10
+ "scripts": {
11
+ "analyze": "rspack --mode=production --env analyze=true",
12
+ "build": "rspack --mode=production",
13
+ "coverage": "yarn test --coverage",
14
+ "debug": "npm run serve",
15
+ "extract-translations": "i18next 'src/**/*.component.tsx' 'src/index.ts' --config ../../tools/i18next-parser.config.js",
16
+ "lint": "eslint src --ext ts,tsx",
17
+ "serve": "rspack serve --mode=development",
18
+ "start": "openmrs develop",
19
+ "test": "cross-env TZ=UTC jest --config jest.config.js --verbose false --passWithNoTests",
20
+ "test:watch": "cross-env TZ=UTC jest --watch --config jest.config.js",
21
+ "typescript": "tsc"
22
+ },
23
+ "browserslist": [
24
+ "extends browserslist-config-openmrs"
25
+ ],
26
+ "keywords": [
27
+ "openmrs"
28
+ ],
29
+ "publishConfig": {
30
+ "access": "public"
31
+ },
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "git+https://github.com/its-kios09/DigiHMIS-apps.git#readme"
35
+ },
36
+ "bugs": {
37
+ "url": "https://github.com/its-kios09/DigiHMIS-apps/issues"
38
+ },
39
+ "dependencies": {
40
+ "lodash-es": "^4.17.15",
41
+ "react-to-print": "2.14.13"
42
+ },
43
+ "peerDependencies": {
44
+ "@carbon/react": "1.x",
45
+ "@openmrs/esm-framework": "8.x",
46
+ "react": "^18.1.0",
47
+ "react-i18next": "16.x",
48
+ "react-router-dom": "6.x",
49
+ "swr": "2.x"
50
+ }
51
+ }
@@ -0,0 +1 @@
1
+ module.exports = require('../../tools/rs-pack-code-spliting');
@@ -0,0 +1,347 @@
1
+ import { ConfigSchema, Type, validators } from '@openmrs/esm-framework';
2
+
3
+ export const configSchema: ConfigSchema = {
4
+ outpatientIcon: {
5
+ src: {
6
+ _type: Type.String,
7
+ _default: '/openmrs/spa/outpatient.svg',
8
+ _description:
9
+ 'The path or URL to the logo image. If set to an empty string, the default OpenMRS SVG sprite will be used.',
10
+ _validators: [validators.isUrl],
11
+ },
12
+ },
13
+ outpatientQueueUuid: {
14
+ _type: Type.String,
15
+ _description: 'The UUID of the queue room to be used for outpatient.',
16
+ _default: '13b5ce7a-cc47-434f-94d7-c7533f1d4b58',
17
+ },
18
+ concepts: {
19
+ waitingStatusUuid: {
20
+ _type: Type.UUID,
21
+ _default: '167407AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
22
+ _description: 'UUID for waiting status concept',
23
+ },
24
+ inServiceStatusUuid: {
25
+ _type: Type.UUID,
26
+ _default: '167408AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
27
+ _description: 'UUID for in-service status concept',
28
+ },
29
+ completedStatusUuid: {
30
+ _type: Type.UUID,
31
+ _default: '167409AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
32
+ _description: 'UUID for completed status concept',
33
+ },
34
+ },
35
+ OpenmrsIdentifierTypeUuid: {
36
+ _type: Type.UUID,
37
+ _default: 'dfacd928-0370-4315-99d7-6ec1c9f7ae76',
38
+ _description: 'UUID for OpenMRS Identifier Type',
39
+ },
40
+ symptomsConceptAnswers: {
41
+ _type: Type.Array,
42
+ _description: 'Array of symptom concept objects with concept UUID and label',
43
+ _default: [],
44
+ },
45
+ tuberculosisContactQuestionConceptUuid: {
46
+ _type: Type.UUID,
47
+ _description: 'UUID for tuberculosis contact question concept',
48
+ _default: '124068AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
49
+ },
50
+ QuestionObservationConceptAnswers: {
51
+ _type: Type.Array,
52
+ _description: 'Array of question observation concept answer objects',
53
+ _default: [],
54
+ },
55
+ coughConceptUuid: {
56
+ _type: Type.UUID,
57
+ _description: 'UUID for cough concept',
58
+ _default: '143264AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
59
+ },
60
+ onsetStatusAnswers: {
61
+ _type: Type.Array,
62
+ _description: 'Array of onset status answer objects with label and concept UUID',
63
+ _default: [],
64
+ },
65
+ pastIllnessConceptUuid: {
66
+ _type: Type.UUID,
67
+ _description: 'UUID for past illness concept',
68
+ _default: '159520AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
69
+ },
70
+ pastIllnessAnswers: {
71
+ _type: Type.Array,
72
+ _description: 'Array of past illness concept answer objects with concept UUID and label',
73
+ _default: [],
74
+ },
75
+ generalExaminationConceptUuid: {
76
+ _type: Type.UUID,
77
+ _description: 'UUID for general examination concept',
78
+ _default: '162737AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
79
+ },
80
+ generalExaminationConceptAnswers: {
81
+ _type: Type.Array,
82
+ _description: 'Array of general examination concept answer objects with concept UUID and label',
83
+ _default: [],
84
+ },
85
+ gaitFindingConceptUuid: {
86
+ _type: Type.UUID,
87
+ _description: 'UUID for gait finding concept',
88
+ _default: '5108AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
89
+ },
90
+ gaitFindingConceptAnswers: {
91
+ _type: Type.Array,
92
+ _description: 'Array of gait finding concept answer objects with concept UUID and label',
93
+ _default: [],
94
+ },
95
+ jaundiceGradingConceptUuid: {
96
+ _type: Type.UUID,
97
+ _description: 'UUID for jaundice grading concept',
98
+ _default: '164448AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
99
+ },
100
+ jaundiceGradingAnswers: {
101
+ _type: Type.Array,
102
+ _description: 'Array of jaundice grading answer objects with concept UUID and label',
103
+ _default: [],
104
+ },
105
+ cyanosisTypeConceptUuid: {
106
+ _type: Type.UUID,
107
+ _description: 'UUID for cyanosis type concept',
108
+ _default: '136443AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
109
+ },
110
+ cyanosisTypeAnswers: {
111
+ _type: Type.Array,
112
+ _description: 'Array of cyanosis type answer objects with concept UUID and label',
113
+ _default: [],
114
+ },
115
+ dehydrationTypeConceptUuid: {
116
+ _type: Type.UUID,
117
+ _description: 'UUID for dehydration type concept',
118
+ _default: '142630AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
119
+ },
120
+ dehydrationTypeAnswers: {
121
+ _type: Type.Array,
122
+ _description: 'Array of dehydration type answer objects with concept UUID and label',
123
+ _default: [],
124
+ },
125
+ fingerclubGradingConceptUuid: {
126
+ _type: Type.UUID,
127
+ _description: 'UUID for fingerclub grading concept',
128
+ _default: '140125AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
129
+ },
130
+ fingerclubGradingAnswers: {
131
+ _type: Type.Array,
132
+ _description: 'Array of fingerclub grading answer objects with concept UUID and label',
133
+ _default: [],
134
+ },
135
+ oedemaLocationConceptUuid: {
136
+ _type: Type.UUID,
137
+ _description: 'UUID for oedema location concept',
138
+ _default: '460AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
139
+ },
140
+ oedemaLocationAnswers: {
141
+ _type: Type.Array,
142
+ _description: 'Array of oedema location answer objects with concept UUID and label',
143
+ _default: [],
144
+ },
145
+ oedemaTypeConceptUuid: {
146
+ _type: Type.UUID,
147
+ _description: 'UUID for oedema type concept',
148
+ _default: '166852AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
149
+ },
150
+ oedemaTypeAnswers: {
151
+ _type: Type.Array,
152
+ _description: 'Array of oedema type answer objects with concept UUID and label',
153
+ _default: [],
154
+ },
155
+ oedemaGradingConceptUuid: {
156
+ _type: Type.UUID,
157
+ _description: 'UUID for oedema grading concept',
158
+ _default: '166852AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
159
+ },
160
+ oedemaGradingAnswers: {
161
+ _type: Type.Array,
162
+ _description: 'Array of oedema grading answer objects with concept UUID and label',
163
+ _default: [],
164
+ },
165
+ pallorLocationConceptUuid: {
166
+ _type: Type.UUID,
167
+ _description: 'UUID for pallor location concept',
168
+ _default: '5245AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
169
+ },
170
+ pallorLocationAnswers: {
171
+ _type: Type.Array,
172
+ _description: 'Array of pallor location answer objects with concept UUID and label',
173
+ _default: [],
174
+ },
175
+ pallorGradingConceptUuid: {
176
+ _type: Type.UUID,
177
+ _description: 'UUID for pallor grading concept',
178
+ _default: '5245AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
179
+ },
180
+ pallorGradingAnswers: {
181
+ _type: Type.Array,
182
+ _description: 'Array of pallor grading answer objects with concept UUID and label',
183
+ _default: [],
184
+ },
185
+ siteLymphadenopathyConceptUuid: {
186
+ _type: Type.UUID,
187
+ _description: 'UUID for site lymphadenopathy concept',
188
+ _default: '5245AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
189
+ },
190
+ siteLymphadenopathyAnswers: {
191
+ _type: Type.Array,
192
+ _description: 'Array of site lymphadenopathy answer objects with concept UUID and label',
193
+ _default: [],
194
+ },
195
+ orders: {
196
+ _type: Type.Object,
197
+ _description: 'List of lab orderable concepts',
198
+ _default: {
199
+ labOrderableConcepts: [],
200
+ labOrderTypeUuid: '',
201
+ },
202
+ },
203
+ procedureOrderTypeUuid: {
204
+ _type: Type.String,
205
+ _description: 'Procedure Order type UUID',
206
+ _default: 'b4a7c280-369e-4d12-9ce8-18e36783fed6',
207
+ },
208
+ procedureConceptSetUuid: {
209
+ _type: Type.String,
210
+ _description: 'Procedure Concept SET UUID',
211
+ _default: '165418AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
212
+ },
213
+ visitAttributeTypes: {
214
+ paymentMethods: {
215
+ _type: Type.String,
216
+ _description: 'The payment methods visit attribute uuid',
217
+ _default: 'e6cb0c3b-04b0-4117-9bc6-ce24adbda802',
218
+ },
219
+ insuranceScheme: {
220
+ _type: Type.String,
221
+ _description: 'The insurance scheme visit attribute uuid',
222
+ _default: '2d0fa959-6780-41f1-85b1-402045935068',
223
+ },
224
+ policyNumber: {
225
+ _type: Type.String,
226
+ _description: 'The policy number visit attribute uuid',
227
+ _default: '0f4f3306-f01b-43c6-af5b-fdb60015cb02',
228
+ },
229
+ },
230
+ insurancePaymentMethod: {
231
+ _type: Type.String,
232
+ _description: 'Insurance Payment method UUID',
233
+ _default: 'beac329b-f1dc-4a33-9e7c-d95821a137a6',
234
+ },
235
+ patientOutcomeConceptUuid: {
236
+ _type: Type.UUID,
237
+ _description: 'UUID for patient outcome concept',
238
+ _default: '160433AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
239
+ },
240
+ patientOutcomeAnswers: {
241
+ _type: Type.Array,
242
+ _description: 'Array of patient outcome answer objects with concept UUID and label',
243
+ _default: [
244
+ { concept: '160035AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', label: 'Review' },
245
+ { concept: '1654AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', label: 'Admit' },
246
+ { concept: '9008cf1c-8631-440b-8fde-061ff273c04c', label: 'Internal Referral' },
247
+ ],
248
+ },
249
+ SurgicalOutpatientDepartmentServiceConceptUuid: {
250
+ _type: Type.String,
251
+ _description: 'Configuration for the surgical outpatient department',
252
+ _default: '164164AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
253
+ },
254
+ LaboratoryServiceConceptUuid: {
255
+ _type: Type.String,
256
+ _description: 'Configuration for the laboratory services',
257
+ _default: 'c9604249-db0a-4d03-b074-fc6bc2fa13e6',
258
+ },
259
+ ImagingServiceConceptUuid: {
260
+ _type: Type.String,
261
+ _description: 'Configuration for the imaging services',
262
+ _default: '160463AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
263
+ },
264
+ localeCurrencyMapping: {
265
+ _type: Type.Object,
266
+ _description: 'Mapping of locale codes to currency codes for internationalization',
267
+ _default: {
268
+ en: 'KES',
269
+ sw: 'KES',
270
+ am: 'ETB',
271
+ ar: 'SAR',
272
+ es: 'EUR',
273
+ fr: 'EUR',
274
+ he: 'ILS',
275
+ km: 'KHR',
276
+ pt: 'EUR',
277
+ vi: 'VND',
278
+ zh: 'CNY',
279
+ 'en-KE': 'KES',
280
+ 'sw-KE': 'KES',
281
+ 'am-ET': 'ETB',
282
+ },
283
+ },
284
+ };
285
+
286
+ export type ConfigObject = {
287
+ outpatientIcon: { src: string; alt: string };
288
+ outpatientQueueUuid: string;
289
+ concepts: {
290
+ waitingStatusUuid: string;
291
+ inServiceStatusUuid: string;
292
+ completedStatusUuid: string;
293
+ };
294
+ OpenmrsIdentifierTypeUuid: string;
295
+ symptomsConceptAnswers: Array<{ concept: string; label: string }>;
296
+ tuberculosisContactQuestionConceptUuid: string;
297
+ QuestionObservationConceptAnswers: Array<{ concept: string; label: string }>;
298
+ coughConceptUuid: string;
299
+ onsetStatusAnswers: Array<{ label: string; concept: string }>;
300
+ pastIllnessConceptUuid: string;
301
+ pastIllnessAnswers: Array<{ concept: string; label: string }>;
302
+ surgicalHistoryConceptUuid: string;
303
+ admissionHistoryConceptUuid: string;
304
+ otherPastIllnessConceptUuid: string;
305
+ generalExaminationConceptUuid: string;
306
+ generalExaminationConceptAnswers: Array<{ concept: string; label: string }>;
307
+ gaitFindingConceptUuid: string;
308
+ gaitFindingConceptAnswers: Array<{ concept: string; label: string }>;
309
+ jaundiceGradingConceptUuid: string;
310
+ jaundiceGradingAnswers: Array<{ concept: string; label: string }>;
311
+ cyanosisTypeConceptUuid: string;
312
+ cyanosisTypeAnswers: Array<{ concept: string; label: string }>;
313
+ dehydrationTypeConceptUuid: string;
314
+ dehydrationTypeAnswers: Array<{ concept: string; label: string }>;
315
+ fingerclubGradingConceptUuid: string;
316
+ fingerclubGradingAnswers: Array<{ concept: string; label: string }>;
317
+ oedemaLocationConceptUuid: string;
318
+ oedemaLocationAnswers: Array<{ concept: string; label: string }>;
319
+ oedemaTypeConceptUuid: string;
320
+ oedemaTypeAnswers: Array<{ concept: string; label: string }>;
321
+ oedemaGradingConceptUuid: string;
322
+ oedemaGradingAnswers: Array<{ concept: string; label: string }>;
323
+ pallorLocationConceptUuid: string;
324
+ pallorLocationAnswers: Array<{ concept: string; label: string }>;
325
+ pallorGradingConceptUuid: string;
326
+ pallorGradingAnswers: Array<{ concept: string; label: string }>;
327
+ siteLymphadenopathyConceptUuid: string;
328
+ siteLymphadenopathyAnswers: Array<{ concept: string; label: string }>;
329
+ orders: {
330
+ labOrderTypeUuid: string;
331
+ labOrderableConcepts: Array<string>;
332
+ };
333
+ procedureOrderTypeUuid: string;
334
+ procedureConceptSetUuid: string;
335
+ visitAttributeTypes: {
336
+ paymentMethods: string;
337
+ insuranceScheme: string;
338
+ policyNumber: string;
339
+ };
340
+ insurancePaymentMethod: string;
341
+ patientOutcomeConceptUuid: string;
342
+ patientOutcomeAnswers: Array<{ concept: string; label: string }>;
343
+ SurgicalOutpatientDepartmentServiceConceptUuid: string;
344
+ LaboratoryServiceConceptUuid: string;
345
+ ImagingServiceConceptUuid: string;
346
+ localeCurrencyMapping: Record<string, string>;
347
+ };
@@ -0,0 +1,16 @@
1
+ import { HealthCross, UserIdentification } from '@carbon/react/icons';
2
+
3
+ export const dashboardMeta = {
4
+ name: 'outpatient',
5
+ slot: 'outpatient-dashboard-slot',
6
+ title: 'Outpatient queue',
7
+ icon: HealthCross,
8
+ };
9
+
10
+ export const carePanelMeta = {
11
+ name: 'outpatient/patient/:patientUuid/file',
12
+ slot: 'outpatient-file-dashboard-slot',
13
+ title: 'Care panel',
14
+ icon: UserIdentification,
15
+ showOnlyOnRoute: '/file',
16
+ };
@@ -0,0 +1,6 @@
1
+ declare module '@carbon/react';
2
+ declare module '*.css';
3
+ declare module '*.scss';
4
+ declare module '*.png';
5
+
6
+ declare type SideNavProps = object;
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+
3
+ interface IconWrapperProps {
4
+ src: string;
5
+ alt?: string;
6
+ className?: string;
7
+ style?: React.CSSProperties;
8
+ }
9
+
10
+ export const IconWrapper: React.FC<IconWrapperProps> = ({
11
+ src,
12
+ alt = 'Icon',
13
+ className,
14
+ style = { width: '100px', height: '148px' },
15
+ }) => {
16
+ return <img src={src} alt={alt} className={className} style={style} />;
17
+ };
package/src/index.ts ADDED
@@ -0,0 +1,27 @@
1
+ import { getAsyncLifecycle, defineConfigSchema, getSyncLifecycle } from '@openmrs/esm-framework';
2
+ import { configSchema } from './config-schema';
3
+ import { carePanelMeta, dashboardMeta } from './dashboard.meta';
4
+ import { createDashboardLink } from './left-panel/left-panel.component';
5
+ import { OutpatientQueueDashboard } from './main-dashboard/outpatient-dashboard.component';
6
+ import CarePanel from './patient-management/patient-management.component';
7
+ const moduleName = '@digihmis/esm-outpatient-app';
8
+ const pageName = 'outpatient';
9
+
10
+ const options = {
11
+ featureName: pageName,
12
+ moduleName,
13
+ };
14
+
15
+ export const importTranslation = require.context('../translations', false, /.json$/, 'lazy');
16
+
17
+ // t('outpatientQueue', 'Outpatient queue')
18
+ export const leftPanelLink = getSyncLifecycle(createDashboardLink(dashboardMeta), options);
19
+ // t('carePanel', 'Care panel')
20
+ export const carePanelLink = getSyncLifecycle(createDashboardLink(carePanelMeta), options);
21
+
22
+ export const outpatientQueueDashboard = getSyncLifecycle(OutpatientQueueDashboard, options);
23
+ export const carePanel = getSyncLifecycle(CarePanel, options);
24
+
25
+ export function startupApp() {
26
+ defineConfigSchema(moduleName, configSchema);
27
+ }
@@ -0,0 +1,100 @@
1
+ import React, { useMemo } from 'react';
2
+ import { ConfigurableLink, MaybeIcon } from '@openmrs/esm-framework';
3
+ import { useTranslation } from 'react-i18next';
4
+ import { BrowserRouter, useLocation, useParams } from 'react-router-dom';
5
+ import { type CarbonIconType } from '@carbon/react/icons';
6
+ import last from 'lodash-es/last';
7
+ import styles from './left-panel.scss';
8
+
9
+ export interface DashboardLinkConfig {
10
+ name: string;
11
+ title: string;
12
+ icon?: string | CarbonIconType;
13
+ showOnlyOnRoute?: string;
14
+ }
15
+
16
+ const DashboardLink = ({ dashboardLinkConfig }: { dashboardLinkConfig: DashboardLinkConfig }) => {
17
+ const { t } = useTranslation();
18
+ const { name, title, icon, showOnlyOnRoute } = dashboardLinkConfig;
19
+ const location = useLocation();
20
+ const params = useParams();
21
+ const spaBasePath = window.getOpenmrsSpaBase() + 'home';
22
+
23
+ // Extract patientUuid from the current URL path if params.patientUuid is not available
24
+ const patientUuid = useMemo(() => {
25
+ if (params.patientUuid) {
26
+ return params.patientUuid;
27
+ }
28
+ // Extract UUID from path like /outpatient/UUID/file or /outpatient/patient/UUID/file
29
+ const pathParts = location.pathname.split('/');
30
+ const outpatientIndex = pathParts.indexOf('outpatient');
31
+ if (outpatientIndex !== -1 && pathParts.length > outpatientIndex + 1) {
32
+ const nextPart = pathParts[outpatientIndex + 1];
33
+ // Check if it's a UUID pattern (basic check)
34
+ if (nextPart && nextPart.length > 20 && nextPart.includes('-')) {
35
+ return nextPart;
36
+ }
37
+ // Check if path is /outpatient/patient/UUID/file
38
+ if (nextPart === 'patient' && pathParts.length > outpatientIndex + 2) {
39
+ const uuidPart = pathParts[outpatientIndex + 2];
40
+ if (uuidPart && uuidPart.length > 20 && uuidPart.includes('-')) {
41
+ return uuidPart;
42
+ }
43
+ }
44
+ }
45
+ return null;
46
+ }, [params.patientUuid, location.pathname]);
47
+
48
+ const shouldShow = useMemo(() => {
49
+ if (!showOnlyOnRoute) {
50
+ return true;
51
+ }
52
+ return location.pathname.includes(showOnlyOnRoute);
53
+ }, [showOnlyOnRoute, location.pathname]);
54
+
55
+ const linkPath = useMemo(() => {
56
+ let path = name;
57
+ if (name.includes(':patientUuid') && patientUuid) {
58
+ path = name.replace(':patientUuid', patientUuid);
59
+ }
60
+ return path;
61
+ }, [name, patientUuid]);
62
+
63
+ const isActive = useMemo(() => {
64
+ if (name.includes(':patientUuid')) {
65
+ return location.pathname.includes('/file');
66
+ }
67
+ const urlSegment = decodeURIComponent(last(location.pathname.split('/')));
68
+ const nameSegment = name.split('/').at(-1);
69
+ return nameSegment === urlSegment;
70
+ }, [location.pathname, name]);
71
+
72
+ if (!shouldShow) {
73
+ return null;
74
+ }
75
+
76
+ const IconComp = typeof icon !== 'string' ? (icon as CarbonIconType) : null;
77
+
78
+ return (
79
+ <ConfigurableLink
80
+ to={`${spaBasePath}/${linkPath}`}
81
+ className={`cds--side-nav__link ${isActive && 'active-left-nav-link'}`}>
82
+ {typeof icon === 'string' ? (
83
+ <MaybeIcon icon={icon} className={styles.icon} size={16} />
84
+ ) : (
85
+ IconComp && <IconComp className={styles.icon} />
86
+ )}
87
+ {t(title)}
88
+ </ConfigurableLink>
89
+ );
90
+ };
91
+
92
+ export const createDashboardLink = (dashboardLinkConfig: DashboardLinkConfig) => () => {
93
+ return (
94
+ <BrowserRouter>
95
+ <DashboardLink dashboardLinkConfig={dashboardLinkConfig} />
96
+ </BrowserRouter>
97
+ );
98
+ };
99
+
100
+ export default DashboardLink;
@@ -0,0 +1,13 @@
1
+ @use '@carbon/colors';
2
+ @use '@carbon/layout';
3
+
4
+ .menu {
5
+ display: flex;
6
+ align-items: center;
7
+ justify-content: center;
8
+ }
9
+
10
+ .icon {
11
+ margin-right: layout.$spacing-05;
12
+ fill: colors.$gray-70;
13
+ }