@openmrs/esm-patient-vitals-app 11.3.1-patch.9064 → 11.3.1-patch.9310

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 (55) hide show
  1. package/.turbo/turbo-build.log +21 -18
  2. package/dist/3174.js +2 -0
  3. package/dist/3174.js.map +1 -0
  4. package/dist/4341.js +1 -0
  5. package/dist/4341.js.map +1 -0
  6. package/dist/5652.js +1 -0
  7. package/dist/5652.js.map +1 -0
  8. package/dist/5670.js +1 -1
  9. package/dist/5670.js.map +1 -1
  10. package/dist/6336.js +1 -0
  11. package/dist/6336.js.map +1 -0
  12. package/dist/7299.js +1 -1
  13. package/dist/7437.js +1 -0
  14. package/dist/7437.js.map +1 -0
  15. package/dist/8953.js +1 -1
  16. package/dist/9228.js +1 -0
  17. package/dist/9228.js.map +1 -0
  18. package/dist/main.js +1 -1
  19. package/dist/main.js.map +1 -1
  20. package/dist/openmrs-esm-patient-vitals-app.js +1 -1
  21. package/dist/openmrs-esm-patient-vitals-app.js.buildmanifest.json +155 -130
  22. package/dist/openmrs-esm-patient-vitals-app.js.map +1 -1
  23. package/dist/routes.json +1 -1
  24. package/package.json +4 -3
  25. package/src/biometrics/biometrics-base.component.tsx +4 -2
  26. package/src/biometrics/biometrics-main.component.tsx +11 -2
  27. package/src/biometrics/biometrics-overview.component.tsx +11 -2
  28. package/src/biometrics/biometrics-overview.test.tsx +3 -0
  29. package/src/biometrics/paginated-biometrics.component.tsx +3 -1
  30. package/src/common/data.resource.ts +20 -18
  31. package/src/common/helpers.ts +38 -9
  32. package/src/common/types.ts +13 -1
  33. package/src/components/action-menu/vitals-biometrics-action-menu.component.tsx +5 -5
  34. package/src/index.ts +6 -2
  35. package/src/routes.json +10 -4
  36. package/src/utils.ts +2 -1
  37. package/src/vitals/paginated-vitals.component.tsx +3 -1
  38. package/src/vitals/vitals-overview.component.tsx +2 -1
  39. package/src/vitals-and-biometrics-header/{vitals-header.component.tsx → vitals-header.extension.tsx} +31 -21
  40. package/src/vitals-and-biometrics-header/vitals-header.test.tsx +107 -11
  41. package/src/vitals-biometrics-form/exported-vitals-biometrics-form.workspace.tsx +640 -0
  42. package/src/vitals-biometrics-form/vitals-biometrics-form.test.tsx +38 -17
  43. package/src/vitals-biometrics-form/vitals-biometrics-form.workspace.tsx +19 -604
  44. package/src/vitals-biometrics-form/vitals-biometrics-input.component.tsx +4 -1
  45. package/dist/5415.js +0 -1
  46. package/dist/5415.js.map +0 -1
  47. package/dist/5639.js +0 -1
  48. package/dist/5639.js.map +0 -1
  49. package/dist/5810.js +0 -1
  50. package/dist/5810.js.map +0 -1
  51. package/dist/6712.js +0 -2
  52. package/dist/6712.js.map +0 -1
  53. package/dist/8803.js +0 -1
  54. package/dist/8803.js.map +0 -1
  55. /package/dist/{6712.js.LICENSE.txt → 3174.js.LICENSE.txt} +0 -0
@@ -2,18 +2,18 @@ import React from 'react';
2
2
  import dayjs from 'dayjs';
3
3
  import { screen } from '@testing-library/react';
4
4
  import userEvent from '@testing-library/user-event';
5
- import { type WorkspacesInfo, getDefaultsFromConfigSchema, useConfig, useWorkspaces } from '@openmrs/esm-framework';
6
- import { mockPatient, getByTextWithMarkup, renderWithSwr, waitForLoadingToFinish } from 'tools';
7
5
  import {
8
- formattedVitals,
9
- mockConceptUnits,
10
- mockCurrentVisit,
11
- mockVitalsConceptMetadata,
12
- mockVitalsConfig,
13
- } from '__mocks__';
6
+ type WorkspacesInfo,
7
+ getDefaultsFromConfigSchema,
8
+ useConfig,
9
+ useVisit,
10
+ useWorkspaces,
11
+ } from '@openmrs/esm-framework';
12
+ import { mockPatient, getByTextWithMarkup, renderWithSwr, waitForLoadingToFinish } from 'tools';
13
+ import { formattedVitals, mockConceptUnits, mockVisit, mockVitalsConceptMetadata, mockVitalsConfig } from '__mocks__';
14
14
  import { configSchema, type ConfigObject } from '../config-schema';
15
- import { useVitalsAndBiometrics } from '../common';
16
- import VitalsHeader from './vitals-header.component';
15
+ import { type PatientVitalsAndBiometrics, useVitalsAndBiometrics } from '../common';
16
+ import VitalsHeader from './vitals-header.extension';
17
17
 
18
18
  const testProps = {
19
19
  patientUuid: mockPatient.id,
@@ -23,6 +23,7 @@ const testProps = {
23
23
  const mockUseConfig = jest.mocked(useConfig<ConfigObject>);
24
24
  const mockUseVitalsAndBiometrics = jest.mocked(useVitalsAndBiometrics);
25
25
  const mockUseWorkspaces = jest.mocked(useWorkspaces);
26
+ const mockUseVisit = jest.mocked(useVisit);
26
27
 
27
28
  mockUseWorkspaces.mockReturnValue({ workspaces: [] } as WorkspacesInfo);
28
29
  const mockLaunchWorkspaceRequiringVisit = jest.fn();
@@ -35,7 +36,6 @@ jest.mock('@openmrs/esm-patient-common-lib', () => {
35
36
 
36
37
  return {
37
38
  ...originalModule,
38
- useVisitOrOfflineVisit: jest.fn().mockImplementation(() => ({ currentVisit: mockCurrentVisit })),
39
39
  useLaunchWorkspaceRequiringVisit: jest.fn().mockImplementation(() => mockUseLaunchWorkspaceRequiringVisit),
40
40
  };
41
41
  });
@@ -76,6 +76,7 @@ describe('VitalsHeader', () => {
76
76
  });
77
77
 
78
78
  it('renders the most recently recorded values in the vitals header', async () => {
79
+ mockUseVisit.mockReturnValueOnce({ activeVisit: mockVisit } as ReturnType<typeof useVisit>);
79
80
  mockUseVitalsAndBiometrics.mockReturnValue({
80
81
  data: [
81
82
  {
@@ -129,6 +130,7 @@ describe('VitalsHeader', () => {
129
130
  });
130
131
 
131
132
  it('displays correct overdue tag for vitals 5 days old', async () => {
133
+ mockUseVisit.mockReturnValueOnce({ activeVisit: mockVisit } as ReturnType<typeof useVisit>);
132
134
  const fiveDaysAgo = dayjs().subtract(5, 'days').toISOString();
133
135
  const vitalsData = [
134
136
  {
@@ -260,4 +262,98 @@ describe('VitalsHeader', () => {
260
262
  expect(screen.queryByRole('link', { name: /vitals history/i })).not.toBeInTheDocument();
261
263
  expect(screen.queryByRole('button', { name: /record vitals/i })).not.toBeInTheDocument();
262
264
  });
265
+
266
+ it('uses backend interpretation without recalculating', async () => {
267
+ // Pulse 240 would normally be calculated as "critically_high" (>= 230)
268
+ // Temperature 41 would normally be calculated as "high" (> 37.5 but < 43)
269
+ // SpO2 70 would normally be calculated as "critically_low" (< 95)
270
+ // Respiratory Rate 5 would normally be calculated as "critically_low" (< 12)
271
+ // Backend sends the interpretation for all vitals as "normal", except for Respiratory Rate which is "critically_low" (< 12)
272
+ // It should use backend's interpretation and NOT recalculate
273
+ const vitalsWithConflictingInterpretation: PatientVitalsAndBiometrics[] = [
274
+ {
275
+ id: '0',
276
+ date: '2021-05-19T04:26:51.000Z',
277
+ pulse: 240,
278
+ temperature: 41,
279
+ respiratoryRate: 5,
280
+ diastolic: 145,
281
+ systolic: 240,
282
+ spo2: 70,
283
+ diastolicRenderInterpretation: 'normal',
284
+ systolicRenderInterpretation: 'normal',
285
+ bloodPressureRenderInterpretation: 'normal',
286
+ pulseRenderInterpretation: 'normal',
287
+ temperatureRenderInterpretation: 'normal',
288
+ respiratoryRateRenderInterpretation: 'critically_low',
289
+ spo2RenderInterpretation: 'normal',
290
+ },
291
+ ];
292
+
293
+ mockUseVitalsAndBiometrics.mockReturnValue({
294
+ data: vitalsWithConflictingInterpretation,
295
+ } as ReturnType<typeof useVitalsAndBiometrics>);
296
+
297
+ renderWithSwr(<VitalsHeader {...testProps} />);
298
+
299
+ await waitForLoadingToFinish();
300
+
301
+ expect(getByTextWithMarkup(/BP\s*240 \/ 145\s*mmHg/i)).toBeInTheDocument();
302
+ expect(getByTextWithMarkup(/Heart rate\s*240\s*beats\/min/i)).toBeInTheDocument();
303
+ expect(getByTextWithMarkup(/Temp\s*41\s*DEG C/i)).toBeInTheDocument();
304
+ expect(getByTextWithMarkup(/R\. Rate\s*5\s*breaths\/min/i)).toBeInTheDocument();
305
+ expect(getByTextWithMarkup(/SpO2\s*70\s*/i)).toBeInTheDocument();
306
+
307
+ expect(screen.getAllByTitle(/abnormal value/i)).toHaveLength(1);
308
+ expect(screen.getByTitle(/abnormal value/i)).toHaveClass('critically-low');
309
+ });
310
+
311
+ it('recalculates interpretation when backend does not provide interpretation', async () => {
312
+ // All vitals are abnormal, and backend does not provide interpretation for any of them.
313
+ // It should fallback to recalculating and mark them as abnormal.
314
+ const vitalsWithoutInterpretation: PatientVitalsAndBiometrics[] = [
315
+ {
316
+ id: '0',
317
+ date: '2021-05-19T04:26:51.000Z',
318
+ pulse: 240, // should be marked as "critically_high"
319
+ temperature: 41, // should be marked as "high"
320
+ respiratoryRate: 5, // should be marked as "low"
321
+ diastolic: 145,
322
+ systolic: 240, // blood pressure should be marked as "high"
323
+ spo2: 70, // should be marked as "low"
324
+ },
325
+ ];
326
+
327
+ mockUseVitalsAndBiometrics.mockReturnValue({
328
+ data: vitalsWithoutInterpretation,
329
+ } as ReturnType<typeof useVitalsAndBiometrics>);
330
+
331
+ renderWithSwr(<VitalsHeader {...testProps} />);
332
+
333
+ await waitForLoadingToFinish();
334
+
335
+ expect(getByTextWithMarkup(/BP\s*240 \/ 145\s*mmHg/i)).toBeInTheDocument();
336
+ expect(getByTextWithMarkup(/Heart rate\s*240\s*beats\/min/i)).toBeInTheDocument();
337
+ expect(getByTextWithMarkup(/Temp\s*41\s*DEG C/i)).toBeInTheDocument();
338
+ expect(getByTextWithMarkup(/R\. Rate\s*5\s*breaths\/min/i)).toBeInTheDocument();
339
+ expect(getByTextWithMarkup(/SpO2\s*70\s*/i)).toBeInTheDocument();
340
+
341
+ const abnormalValueElements = screen.getAllByTitle(/abnormal value/i);
342
+ expect(abnormalValueElements).toHaveLength(5);
343
+
344
+ const lowElements = abnormalValueElements.filter((element) => {
345
+ return element.className === 'low';
346
+ });
347
+ expect(lowElements).toHaveLength(2);
348
+
349
+ const highElements = abnormalValueElements.filter((element) => {
350
+ return element.className === 'high';
351
+ });
352
+ expect(highElements).toHaveLength(2);
353
+
354
+ const criticallyHighElements = abnormalValueElements.filter((element) => {
355
+ return element.className === 'critically-high';
356
+ });
357
+ expect(criticallyHighElements).toHaveLength(1);
358
+ });
263
359
  });