@digihmis/esm-triage-app 1.0.2 → 1.0.3

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.
package/dist/routes.json CHANGED
@@ -1 +1 @@
1
- {"$schema":"https://json.openmrs.org/routes.schema.json","backendDependencies":{"fhir2":">=1.2","webservices.rest":">=2.24.0"},"extensions":[{"name":"triage-dashboard-header","slot":"triage-sidebar-slot","component":"triageDashboardHeader","order":0,"online":true,"offline":true},{"name":"triage-db-link","slot":"triage-dashboard-slot","component":"leftPanelLink","meta":{"name":"triage","slot":"triage-homepage-dashboard-slot","title":"Triage Queue"},"order":1,"online":true,"offline":true},{"name":"triage-queue-dashboard","slot":"triage-homepage-dashboard-slot","component":"triageQueueDashboard"},{"name":"patient-vitals-link","slot":"triage-dashboard-slot","component":"patientVitalsLink","meta":{"name":"triage/:patientUuid/vitals","slot":"triage-vitals-dashboard-slot","title":"Patient Vitals","showOnlyOnRoute":"/vitals"},"order":2,"online":true,"offline":true},{"name":"patient-vitals-history","slot":"triage-vitals-dashboard-slot","component":"patientVitalsHistory"},{"name":"vitals-header","slot":"patient-vitals-header-slot","component":"vitalsHeader","online":true,"offline":true}],"workspaces":[{"name":"record-vitals-workspace","component":"recordVitalsWorkspace","title":"Record Vitals","type":"other-form","canMaximize":true,"width":"extra-wide"}],"version":"1.0.2"}
1
+ {"$schema":"https://json.openmrs.org/routes.schema.json","backendDependencies":{"fhir2":">=1.2","webservices.rest":">=2.24.0"},"extensions":[{"name":"triage-dashboard-header","slot":"triage-sidebar-slot","component":"triageDashboardHeader","order":0,"online":true,"offline":true},{"name":"triage-db-link","slot":"triage-dashboard-slot","component":"leftPanelLink","meta":{"name":"triage","slot":"triage-homepage-dashboard-slot","title":"Triage Queue"},"order":1,"online":true,"offline":true},{"name":"triage-queue-dashboard","slot":"triage-homepage-dashboard-slot","component":"triageQueueDashboard"},{"name":"patient-vitals-link","slot":"triage-dashboard-slot","component":"patientVitalsLink","meta":{"name":"triage/:patientUuid/vitals","slot":"triage-vitals-dashboard-slot","title":"Patient Vitals","showOnlyOnRoute":"/vitals"},"order":2,"online":true,"offline":true},{"name":"patient-vitals-history","slot":"triage-vitals-dashboard-slot","component":"patientVitalsHistory"},{"name":"vitals-header","slot":"patient-vitals-header-slot","component":"vitalsHeader","online":true,"offline":true}],"workspaces":[{"name":"record-vitals-workspace","component":"recordVitalsWorkspace","title":"Record Vitals","type":"other-form","canMaximize":true,"width":"extra-wide"}],"version":"1.0.3"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@digihmis/esm-triage-app",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "Triage microfrontend for the OpenMRS SPA",
5
5
  "browser": "dist/digihmis-esm-triage-app.js",
6
6
  "main": "src/index.ts",
@@ -11,7 +11,7 @@ interface VitalsAndBiometricsActionMenuProps {
11
11
 
12
12
  export const VitalsAndBiometricsActionMenu = ({ encounterUuid, patient }: VitalsAndBiometricsActionMenuProps) => {
13
13
  const { t } = useTranslation();
14
- const patientUuid = patient.id;
14
+ const patientUuid = patient?.id;
15
15
  const isTablet = useLayoutType() === 'tablet';
16
16
 
17
17
  const handleLaunchVitalsAndBiometricsForm = useCallback(() => {
@@ -1,6 +1,6 @@
1
1
  import React, { useState } from 'react';
2
2
  import { useTranslation } from 'react-i18next';
3
- import { showModal, useConfig, useLayoutType, usePatient } from '@openmrs/esm-framework';
3
+ import { launchWorkspace, showModal, showSnackbar, useConfig, useLayoutType, usePatient } from '@openmrs/esm-framework';
4
4
  import styles from './patient-vitals-history.scss';
5
5
  import { getPatientUuidFromUrl } from './utils';
6
6
  import PatientBanner from './patient-banner/patient-banner.component';
@@ -9,9 +9,12 @@ import { Tab, Button, Tabs, TabList, TabPanels, TabPanel } from '@carbon/react';
9
9
  import VitalsOverview from './triage-vitals/triage-vitals-history.component';
10
10
  import BiometricsBase from './triage-anthropometrics/triage-antropometrics.component';
11
11
  import NotesSummary from './triage-notes/triage-notes.component';
12
- import { AssetMovement } from '@carbon/react/icons';
12
+ import { AssetMovement, CheckmarkFilled } from '@carbon/react/icons';
13
13
  import { useCurrentQueueEntry } from './patient-vitals-history.resource';
14
14
  import { ConfigObject } from '../config-schema';
15
+ import { useQueueActions } from '../queue-room-table/useQueueActions';
16
+ import { QueueEntry } from '../queue-room-table/type';
17
+ import { mutate } from 'swr';
15
18
  const openmrsSpaBase = window['getOpenmrsSpaBase']();
16
19
 
17
20
  const PatientVitalsHistory: React.FC = () => {
@@ -21,6 +24,10 @@ const PatientVitalsHistory: React.FC = () => {
21
24
  const { patient, isLoading, error } = usePatient(patientUuid);
22
25
  const { currentQueueEntry, isLoading: isLoadingQueueEntry } = useCurrentQueueEntry(patientUuid);
23
26
  const [selectedTabIndex, setSelectedTabIndex] = useState(0);
27
+ const [processingUuid, setProcessingUuid] = useState<string | null>(null);
28
+ const { servePatient, completeService } = useQueueActions();
29
+ const isProcessing = processingUuid !== null;
30
+
24
31
  const config = useConfig<ConfigObject>();
25
32
 
26
33
  const handleMovePatientToQueue = (patientUuid: string) => {
@@ -34,6 +41,50 @@ const PatientVitalsHistory: React.FC = () => {
34
41
 
35
42
  const isInServiceStatus = currentQueueEntry?.status?.uuid === config.concepts.inServiceStatusUuid;
36
43
 
44
+ const handleServePatient = async (entry: QueueEntry) => {
45
+ setProcessingUuid(entry.uuid);
46
+
47
+ try {
48
+
49
+ launchWorkspace('record-vitals-workspace', {
50
+ workspaceTitle: t('recordVitals', 'Record Vitals'),
51
+ patientUuid: entry?.patient?.uuid,
52
+ queueEntryUuid: entry.uuid,
53
+ completeServiceCallback: async () => {
54
+ try {
55
+ await completeService(entry.uuid);
56
+
57
+ showSnackbar({
58
+ title: t('serviceCompleted', 'Service Completed'),
59
+ subtitle: t('serviceCompletedMessage', `Service completed for ${entry.patient.display}`),
60
+ kind: 'success',
61
+ timeoutInMs: 3000,
62
+ });
63
+
64
+ mutate((key) => typeof key === 'string' && key.includes('/queue-entry'));
65
+ } catch (error) {
66
+ console.error('Error completing service:', error);
67
+ showSnackbar({
68
+ title: t('error', 'Error'),
69
+ subtitle: t('completeServiceError', 'Failed to complete service'),
70
+ kind: 'error',
71
+ timeoutInMs: 5000,
72
+ });
73
+ }
74
+ },
75
+ });
76
+ } catch (error) {
77
+ showSnackbar({
78
+ title: t('error', 'Error'),
79
+ subtitle: t('servePatientError', 'Failed to serve patient. Please try again.'),
80
+ kind: 'error',
81
+ timeoutInMs: 5000,
82
+ });
83
+ } finally {
84
+ setProcessingUuid(null);
85
+ }
86
+ };
87
+
37
88
  return (
38
89
  <div>
39
90
  <div className={styles.header}>{t('patientVitalsHistory', 'Patient Vitals History')}</div>
@@ -48,6 +99,16 @@ const PatientVitalsHistory: React.FC = () => {
48
99
  <Tab>{t('vitalSigns', 'Vital Signs')}</Tab>
49
100
  <Tab>{t('anthropometrics', 'Anthropometrics')}</Tab>
50
101
  </TabList>
102
+ {!isLoadingQueueEntry && currentQueueEntry && (
103
+ <Button
104
+ kind="secondary"
105
+ size="sm"
106
+ renderIcon={CheckmarkFilled}
107
+ onClick={() => currentQueueEntry && handleServePatient(currentQueueEntry)}
108
+ disabled={isProcessing}>
109
+ {isProcessing ? t('recordVitals', 'Record Vitals...') : t('recordVitals', 'Record Vitals')}
110
+ </Button>
111
+ )}
51
112
  {!isLoadingQueueEntry && isInServiceStatus && (
52
113
  <Button
53
114
  size="sm"
@@ -28,7 +28,7 @@
28
28
  display: flex;
29
29
  align-items: center;
30
30
  justify-content: space-between;
31
- gap: layout.$spacing-05;
31
+ margin-right: 0.51rem;
32
32
 
33
33
  :global(.omrs-breakpoint-lt-desktop) & {
34
34
  gap: layout.$spacing-03;
@@ -40,8 +40,6 @@
40
40
  }
41
41
 
42
42
  .buttonNotesTab {
43
- margin-right: layout.$spacing-03;
44
-
45
43
  :global(.omrs-breakpoint-lt-tablet) & {
46
44
  padding: layout.$spacing-02 layout.$spacing-03;
47
45
  white-space: nowrap;
@@ -84,7 +84,7 @@ export const QueueRoomTable: React.FC<QueueRoomTableProps> = ({ queueRoomUuid, q
84
84
  return 'gray';
85
85
  };
86
86
 
87
- const handleServePatient = async (entry: QueueEntry) => {
87
+ const handleViewPastVitals = async (patientUuid: string, entry: QueueEntry) => {
88
88
  setProcessingUuid(entry.uuid);
89
89
 
90
90
  try {
@@ -96,40 +96,11 @@ export const QueueRoomTable: React.FC<QueueRoomTableProps> = ({ queueRoomUuid, q
96
96
  kind: 'success',
97
97
  timeoutInMs: 3000,
98
98
  });
99
-
100
- mutate();
101
-
102
- launchWorkspace('record-vitals-workspace', {
103
- workspaceTitle: t('recordVitals', 'Record Vitals'),
104
- patientUuid: entry?.patient?.uuid,
105
- queueEntryUuid: entry.uuid,
106
- completeServiceCallback: async () => {
107
- // This callback will be executed after vitals are saved and room transition is complete
108
- try {
109
- await completeService(entry.uuid);
110
-
111
- showSnackbar({
112
- title: t('serviceCompleted', 'Service Completed'),
113
- subtitle: t('serviceCompletedMessage', `Service completed for ${entry.patient.display}`),
114
- kind: 'success',
115
- timeoutInMs: 3000,
116
- });
117
-
118
- mutate();
119
- } catch (error) {
120
- console.error('Error completing service:', error);
121
- showSnackbar({
122
- title: t('error', 'Error'),
123
- subtitle: t('completeServiceError', 'Failed to complete service'),
124
- kind: 'error',
125
- timeoutInMs: 5000,
126
- });
127
- }
128
- },
99
+ navigate({
100
+ to: `${window.spaBase}/home/triage/patient/${patientUuid}/vitals`,
129
101
  });
102
+ mutate();
130
103
  } catch (error) {
131
- console.error('Error serving patient:', error);
132
-
133
104
  showSnackbar({
134
105
  title: t('error', 'Error'),
135
106
  subtitle: t('servePatientError', 'Failed to serve patient. Please try again.'),
@@ -141,39 +112,33 @@ export const QueueRoomTable: React.FC<QueueRoomTableProps> = ({ queueRoomUuid, q
141
112
  }
142
113
  };
143
114
 
144
- const handleViewPastVitals = (patientUuid: string) => {
145
- navigate({
146
- to: `${window.spaBase}/home/triage/patient/${patientUuid}/vitals`,
147
- });
148
- };
149
-
150
- const handleCompleteService = async (entry: QueueEntry) => {
151
- setProcessingUuid(entry.uuid);
152
-
153
- try {
154
- await completeService(entry.uuid);
155
-
156
- showSnackbar({
157
- title: t('serviceCompleted', 'Service Completed'),
158
- subtitle: t('patientServedMessage', `${entry?.patient?.person?.display} is now being served`),
159
- kind: 'success',
160
- timeoutInMs: 3000,
161
- });
162
-
163
- mutate();
164
- } catch (error) {
165
- console.error('Error completing service:', error);
166
-
167
- showSnackbar({
168
- title: t('error', 'Error'),
169
- subtitle: t('completeServiceError', 'Failed to complete service. Please try again.'),
170
- kind: 'error',
171
- timeoutInMs: 5000,
172
- });
173
- } finally {
174
- setProcessingUuid(null);
175
- }
176
- };
115
+ // const handleCompleteService = async (entry: QueueEntry) => {
116
+ // setProcessingUuid(entry.uuid);
117
+
118
+ // try {
119
+ // await completeService(entry.uuid);
120
+
121
+ // showSnackbar({
122
+ // title: t('serviceCompleted', 'Service Completed'),
123
+ // subtitle: t('patientServedMessage', `${entry?.patient?.person?.display} is now being served`),
124
+ // kind: 'success',
125
+ // timeoutInMs: 3000,
126
+ // });
127
+
128
+ // mutate();
129
+ // } catch (error) {
130
+ // console.error('Error completing service:', error);
131
+
132
+ // showSnackbar({
133
+ // title: t('error', 'Error'),
134
+ // subtitle: t('completeServiceError', 'Failed to complete service. Please try again.'),
135
+ // kind: 'error',
136
+ // timeoutInMs: 5000,
137
+ // });
138
+ // } finally {
139
+ // setProcessingUuid(null);
140
+ // }
141
+ // };
177
142
 
178
143
  const headers = [
179
144
  { key: 'position', header: '#' },
@@ -320,35 +285,13 @@ export const QueueRoomTable: React.FC<QueueRoomTableProps> = ({ queueRoomUuid, q
320
285
  return (
321
286
  <TableCell key={cell.id}>
322
287
  <div className={styles.actions}>
323
- {(isWaiting || isInService) && (
324
- <Button
325
- kind="primary"
326
- size="sm"
327
- renderIcon={CheckmarkFilled}
328
- onClick={() => handleServePatient(entry)}
329
- disabled={isProcessing}>
330
- {isProcessing
331
- ? t('recordVitals', 'Record Vitals...')
332
- : t('recordVitals', 'Record Vitals')}
333
- </Button>
334
- )}
335
- {/* {isInService && (
336
- <Button
337
- kind="tertiary"
338
- size="sm"
339
- renderIcon={CheckmarkFilled}
340
- onClick={() => handleCompleteService(entry)}
341
- disabled={isProcessing}>
342
- {isProcessing ? t('completing', 'Completing...') : t('complete', 'Complete')}
343
- </Button>
344
- )} */}
345
288
  <Button
346
289
  kind="secondary"
347
290
  size="sm"
348
- renderIcon={Activity}
349
- onClick={() => handleViewPastVitals(patientUuid)}
291
+ renderIcon={CheckmarkFilled}
292
+ onClick={() => handleViewPastVitals(patientUuid, entry)}
350
293
  disabled={isProcessing}>
351
- {isProcessing ? t('pastVitals', 'Past Vitals...') : t('pastVitals', 'Past Vitals')}
294
+ {isProcessing ? t('serving', 'Serving...') : t('servePatient', 'Serve Patient')}
352
295
  </Button>
353
296
  </div>
354
297
  </TableCell>