@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
@@ -16,10 +16,11 @@ interface BiometricsBaseProps {
16
16
  pageSize: number;
17
17
  pageUrl: string;
18
18
  patientUuid: string;
19
+ patient: fhir.Patient;
19
20
  urlLabel: string;
20
21
  }
21
22
 
22
- const BiometricsBase: React.FC<BiometricsBaseProps> = ({ patientUuid, pageSize, urlLabel, pageUrl }) => {
23
+ const BiometricsBase: React.FC<BiometricsBaseProps> = ({ patientUuid, patient, pageSize, urlLabel, pageUrl }) => {
23
24
  const { t } = useTranslation();
24
25
  const displayText = t('biometrics_lower', 'biometrics');
25
26
  const headerTitle = t('biometrics', 'Biometrics');
@@ -30,7 +31,7 @@ const BiometricsBase: React.FC<BiometricsBaseProps> = ({ patientUuid, pageSize,
30
31
  const { bmiUnit } = config.biometrics;
31
32
  const { data: biometrics, isLoading, error, isValidating } = useVitalsAndBiometrics(patientUuid, 'biometrics');
32
33
  const { conceptUnits } = useConceptUnits();
33
- const launchBiometricsForm = useLaunchVitalsAndBiometricsForm();
34
+ const launchBiometricsForm = useLaunchVitalsAndBiometricsForm(patientUuid);
34
35
 
35
36
  const tableHeaders: Array<BiometricsTableHeader> = [
36
37
  {
@@ -130,6 +131,7 @@ const BiometricsBase: React.FC<BiometricsBaseProps> = ({ patientUuid, pageSize,
130
131
  urlLabel={urlLabel}
131
132
  pageUrl={pageUrl}
132
133
  tableHeaders={tableHeaders}
134
+ patient={patient}
133
135
  />
134
136
  )}
135
137
  </div>
@@ -4,15 +4,24 @@ import BiometricsBase from './biometrics-base.component';
4
4
 
5
5
  interface BiometricsProps {
6
6
  patientUuid: string;
7
+ patient: fhir.Patient;
7
8
  }
8
9
 
9
- const BiometricsMain: React.FC<BiometricsProps> = ({ patientUuid }) => {
10
+ const BiometricsMain: React.FC<BiometricsProps> = ({ patientUuid, patient }) => {
10
11
  const pageSize = 10;
11
12
  const { t } = useTranslation();
12
13
  const pageUrl: string = `$\{openmrsSpaBase}/patient/${patientUuid}/chart`;
13
14
  const urlLabel = t('goToSummary', 'Go to Summary');
14
15
 
15
- return <BiometricsBase patientUuid={patientUuid} pageSize={pageSize} urlLabel={urlLabel} pageUrl={pageUrl} />;
16
+ return (
17
+ <BiometricsBase
18
+ patientUuid={patientUuid}
19
+ patient={patient}
20
+ pageSize={pageSize}
21
+ urlLabel={urlLabel}
22
+ pageUrl={pageUrl}
23
+ />
24
+ );
16
25
  };
17
26
 
18
27
  export default BiometricsMain;
@@ -5,15 +5,24 @@ import BiometricsBase from './biometrics-base.component';
5
5
  interface BiometricsProps {
6
6
  patientUuid: string;
7
7
  basePath: string;
8
+ patient: fhir.Patient;
8
9
  }
9
10
 
10
- const BiometricsOverview: React.FC<BiometricsProps> = ({ patientUuid, basePath }) => {
11
+ const BiometricsOverview: React.FC<BiometricsProps> = ({ patientUuid, patient, basePath }) => {
11
12
  const { t } = useTranslation();
12
13
  const pageSize = 5;
13
14
  const pageUrl = `\${openmrsSpaBase}/patient/${patientUuid}/chart/Vitals & Biometrics`;
14
15
  const urlLabel = t('seeAll', 'See all');
15
16
 
16
- return <BiometricsBase patientUuid={patientUuid} pageSize={pageSize} urlLabel={urlLabel} pageUrl={pageUrl} />;
17
+ return (
18
+ <BiometricsBase
19
+ patientUuid={patientUuid}
20
+ patient={patient}
21
+ pageSize={pageSize}
22
+ urlLabel={urlLabel}
23
+ pageUrl={pageUrl}
24
+ />
25
+ );
17
26
  };
18
27
 
19
28
  export default BiometricsOverview;
@@ -12,6 +12,9 @@ import BiometricsOverview from './biometrics-overview.component';
12
12
  const testProps = {
13
13
  basePath: patientChartBasePath,
14
14
  patientUuid: mockPatient.id,
15
+ patient: mockPatient,
16
+ visitContext: null,
17
+ mutateVisitContext: null,
15
18
  };
16
19
 
17
20
  const mockUseConfig = jest.mocked(useConfig<ConfigObject>);
@@ -23,6 +23,7 @@ interface PaginatedBiometricsProps {
23
23
  pageUrl: string;
24
24
  urlLabel: string;
25
25
  tableHeaders: Array<BiometricsTableHeader>;
26
+ patient: fhir.Patient;
26
27
  }
27
28
 
28
29
  const PaginatedBiometrics: React.FC<PaginatedBiometricsProps> = ({
@@ -31,6 +32,7 @@ const PaginatedBiometrics: React.FC<PaginatedBiometricsProps> = ({
31
32
  pageUrl,
32
33
  urlLabel,
33
34
  tableHeaders,
35
+ patient,
34
36
  }) => {
35
37
  const isTablet = useLayoutType() === 'tablet';
36
38
 
@@ -110,7 +112,7 @@ const PaginatedBiometrics: React.FC<PaginatedBiometricsProps> = ({
110
112
  <TableCell key={cell.id}>{cell.value?.content ?? cell.value}</TableCell>
111
113
  ))}
112
114
  <TableCell className="cds--table-column-menu" id="actions">
113
- <VitalsAndBiometricsActionMenu encounterUuid={row.id} />
115
+ <VitalsAndBiometricsActionMenu patient={patient} encounterUuid={row.id} />
114
116
  </TableCell>
115
117
  </TableRow>
116
118
  ))}
@@ -11,7 +11,12 @@ import {
11
11
  import useSWRImmutable from 'swr/immutable';
12
12
  import useSWRInfinite from 'swr/infinite';
13
13
  import { type ConfigObject } from '../config-schema';
14
- import { assessValue, calculateBodyMassIndex, getReferenceRangesForConcept, interpretBloodPressure } from './helpers';
14
+ import {
15
+ assessValue,
16
+ calculateBodyMassIndex,
17
+ interpretBloodPressure,
18
+ mapFhirInterpretationToObservationInterpretation,
19
+ } from './helpers';
15
20
  import type {
16
21
  FHIRObservationResource,
17
22
  FHIRSearchBundleResponse,
@@ -323,23 +328,13 @@ export function useVitalsAndBiometrics(patientUuid: string, mode: VitalsAndBiome
323
328
  vitalSigns.diastolic,
324
329
  concepts,
325
330
  conceptRanges,
331
+ vitalSigns.systolicRenderInterpretation,
332
+ vitalSigns.diastolicRenderInterpretation,
326
333
  );
327
- result.pulseRenderInterpretation = assessValue(
328
- vitalSigns.pulse,
329
- getReferenceRangesForConcept(concepts.pulseUuid, conceptRanges),
330
- );
331
- result.temperatureRenderInterpretation = assessValue(
332
- vitalSigns.temperature,
333
- getReferenceRangesForConcept(concepts.temperatureUuid, conceptRanges),
334
- );
335
- result.spo2RenderInterpretation = assessValue(
336
- vitalSigns.spo2,
337
- getReferenceRangesForConcept(concepts.oxygenSaturationUuid, conceptRanges),
338
- );
339
- result.respiratoryRateRenderInterpretation = assessValue(
340
- vitalSigns.respiratoryRate,
341
- getReferenceRangesForConcept(concepts.respiratoryRateUuid, conceptRanges),
342
- );
334
+ result.pulseRenderInterpretation = vitalSigns.pulseRenderInterpretation;
335
+ result.temperatureRenderInterpretation = vitalSigns.temperatureRenderInterpretation;
336
+ result.spo2RenderInterpretation = vitalSigns.spo2RenderInterpretation;
337
+ result.respiratoryRateRenderInterpretation = vitalSigns.respiratoryRateRenderInterpretation;
343
338
  }
344
339
 
345
340
  return result;
@@ -472,7 +467,14 @@ function mapVitalsAndBiometrics(resource: FHIRObservationResource): MappedVitals
472
467
  return {
473
468
  code: resource?.code?.coding?.[0]?.code,
474
469
  encounterId: extractEncounterUuid(resource.encounter),
475
- interpretation: assessValue(resource?.valueQuantity?.value, referenceRanges),
470
+ // Use Observation.interpretation from FHIR when available (preferred).
471
+ // Fallback to calculation for backward compatibility: existing observations may not have
472
+ // interpretation set if they were created before interpretation was added, or if reference
473
+ // ranges weren't available at creation time (OpenMRS core only sets interpretation when
474
+ // ObsReferenceRange is present).
475
+ interpretation: resource.interpretation?.[0]?.coding?.[0]?.display
476
+ ? mapFhirInterpretationToObservationInterpretation(resource.interpretation?.[0]?.coding?.[0]?.display)
477
+ : assessValue(resource?.valueQuantity?.value, referenceRanges),
476
478
  recordedDate: resource?.effectiveDateTime,
477
479
  value: resource?.valueQuantity?.value,
478
480
  };
@@ -1,6 +1,6 @@
1
1
  import { type OpenmrsResource } from '@openmrs/esm-framework';
2
2
  import { type ConceptMetadata } from '../common';
3
- import type { ObsReferenceRanges, ObservationInterpretation } from './types';
3
+ import type { FHIRInterpretation, ObsReferenceRanges, ObservationInterpretation } from './types';
4
4
  import { type VitalsBiometricsFormData } from '../vitals-biometrics-form/schema';
5
5
  import { type VitalsAndBiometricsFieldValuesMap } from './data.resource';
6
6
 
@@ -33,24 +33,53 @@ export function assessValue(value: number | undefined, range?: ObsReferenceRange
33
33
  return 'normal';
34
34
  }
35
35
 
36
+ export function mapFhirInterpretationToObservationInterpretation(
37
+ interpretation: FHIRInterpretation,
38
+ ): ObservationInterpretation {
39
+ const normalized = interpretation?.trim();
40
+ switch (normalized) {
41
+ case 'Critically Low':
42
+ return 'critically_low';
43
+ case 'Critically High':
44
+ return 'critically_high';
45
+ case 'High':
46
+ return 'high';
47
+ case 'Low':
48
+ return 'low';
49
+ case 'Normal':
50
+ return 'normal';
51
+ default:
52
+ return 'normal';
53
+ }
54
+ }
55
+
36
56
  export function interpretBloodPressure(
37
57
  systolic: number | undefined,
38
58
  diastolic: number | undefined,
39
59
  concepts: { systolicBloodPressureUuid?: string; diastolicBloodPressureUuid?: string } | undefined,
40
60
  conceptMetadata: Array<ConceptMetadata> | undefined,
61
+ systolicInterpretation?: ObservationInterpretation,
62
+ diastolicInterpretation?: ObservationInterpretation,
41
63
  ): ObservationInterpretation {
42
64
  if (!conceptMetadata) {
43
65
  return 'normal';
44
66
  }
45
67
 
46
- const systolicAssessment = assessValue(
47
- systolic,
48
- getReferenceRangesForConcept(concepts?.systolicBloodPressureUuid, conceptMetadata),
49
- );
50
-
51
- const diastolicAssessment = concepts?.diastolicBloodPressureUuid
52
- ? assessValue(diastolic, getReferenceRangesForConcept(concepts.diastolicBloodPressureUuid, conceptMetadata))
53
- : 'normal';
68
+ // Use interpretation from FHIR Observation when available (preferred).
69
+ // Fallback to calculation for backward compatibility: existing observations may not have
70
+ // interpretation set if they were created before interpretation was added, or if reference
71
+ // ranges weren't available at creation time.
72
+ const systolicAssessment =
73
+ systolicInterpretation ??
74
+ (concepts?.systolicBloodPressureUuid
75
+ ? assessValue(systolic, getReferenceRangesForConcept(concepts.systolicBloodPressureUuid, conceptMetadata))
76
+ : 'normal');
77
+
78
+ const diastolicAssessment =
79
+ diastolicInterpretation ??
80
+ (concepts?.diastolicBloodPressureUuid
81
+ ? assessValue(diastolic, getReferenceRangesForConcept(concepts.diastolicBloodPressureUuid, conceptMetadata))
82
+ : 'normal');
54
83
 
55
84
  if (systolicAssessment === 'critically_high' || diastolicAssessment === 'critically_high') {
56
85
  return 'critically_high';
@@ -20,12 +20,14 @@ export type ObservationInterpretation = 'critically_low' | 'critically_high' | '
20
20
 
21
21
  export type MappedVitals = {
22
22
  code: string;
23
- interpretation: string;
23
+ interpretation: ObservationInterpretation;
24
24
  recordedDate: string | Date;
25
25
  value: number;
26
26
  encounterId: string;
27
27
  };
28
28
 
29
+ export type FHIRInterpretation = 'Critically Low' | 'Critically High' | 'High' | 'Low' | 'Normal';
30
+
29
31
  export interface FHIRObservationResource {
30
32
  resourceType: string;
31
33
  id: string;
@@ -82,13 +84,23 @@ export interface FHIRObservationResource {
82
84
  hasMember?: Array<{
83
85
  reference: string;
84
86
  }>;
87
+ interpretation?: Array<{
88
+ coding: Array<{
89
+ code: string;
90
+ display: FHIRInterpretation;
91
+ system: string;
92
+ }>;
93
+ text: string;
94
+ }>;
85
95
  }
86
96
 
87
97
  export interface PatientVitalsAndBiometrics {
88
98
  id: string;
89
99
  date: string;
90
100
  systolic?: number;
101
+ systolicRenderInterpretation?: ObservationInterpretation;
91
102
  diastolic?: number;
103
+ diastolicRenderInterpretation?: ObservationInterpretation;
92
104
  bloodPressureRenderInterpretation?: ObservationInterpretation;
93
105
  pulse?: number;
94
106
  pulseRenderInterpretation?: ObservationInterpretation;
@@ -1,22 +1,22 @@
1
1
  import React, { useCallback } from 'react';
2
2
  import { useTranslation } from 'react-i18next';
3
3
  import { Layer, OverflowMenu, OverflowMenuItem } from '@carbon/react';
4
- import { getPatientUuidFromStore } from '@openmrs/esm-patient-common-lib';
5
- import { launchWorkspace, showModal, useLayoutType } from '@openmrs/esm-framework';
4
+ import { launchWorkspace2, showModal, useLayoutType } from '@openmrs/esm-framework';
6
5
  import { patientVitalsBiometricsFormWorkspace } from '../../constants';
7
6
  import styles from './vitals-biometrics-action-menu.scss';
8
7
 
9
8
  interface VitalsAndBiometricsActionMenuProps {
9
+ patient: fhir.Patient;
10
10
  encounterUuid: string;
11
11
  }
12
12
 
13
- export const VitalsAndBiometricsActionMenu = ({ encounterUuid }: VitalsAndBiometricsActionMenuProps) => {
13
+ export const VitalsAndBiometricsActionMenu = ({ encounterUuid, patient }: VitalsAndBiometricsActionMenuProps) => {
14
14
  const { t } = useTranslation();
15
- const patientUuid = getPatientUuidFromStore();
15
+ const patientUuid = patient.id;
16
16
  const isTablet = useLayoutType() === 'tablet';
17
17
 
18
18
  const handleLaunchVitalsAndBiometricsForm = useCallback(() => {
19
- launchWorkspace(patientVitalsBiometricsFormWorkspace, {
19
+ launchWorkspace2(patientVitalsBiometricsFormWorkspace, {
20
20
  workspaceTitle: t('editVitalsAndBiometrics', 'Edit Vitals and Biometrics'),
21
21
  editEncounterUuid: encounterUuid,
22
22
  formContext: 'editing',
package/src/index.ts CHANGED
@@ -11,7 +11,7 @@ import { configSchema } from './config-schema';
11
11
  import biometricsDetailedSummaryComponent from './biometrics/biometrics-main.component';
12
12
  import biometricsOverviewComponent from './biometrics/biometrics-overview.component';
13
13
  import { dashboardMeta } from './dashboard.meta';
14
- import vitalsHeaderComponent from './vitals-and-biometrics-header/vitals-header.component';
14
+ import vitalsHeaderComponent from './vitals-and-biometrics-header/vitals-header.extension';
15
15
  import vitalsMainComponent from './vitals/vitals-main.component';
16
16
  import vitalsSummaryComponent from './vitals/vitals-summary.component';
17
17
 
@@ -59,12 +59,16 @@ export const vitalsAndBiometricsDashboardLink =
59
59
 
60
60
  export const weightTile = getAsyncLifecycle(() => import('./components/weight-tile/weight-tile.component'), options);
61
61
 
62
- // t('recordVitalsAndBiometrics', 'Record Vitals and Biometrics')
63
62
  export const vitalsBiometricsFormWorkspace = getAsyncLifecycle(
64
63
  () => import('./vitals-biometrics-form/vitals-biometrics-form.workspace'),
65
64
  options,
66
65
  );
67
66
 
67
+ export const exportedVitalsBiometricsFormWorkspace = getAsyncLifecycle(
68
+ () => import('./vitals-biometrics-form/exported-vitals-biometrics-form.workspace'),
69
+ options,
70
+ );
71
+
68
72
  export const vitalsAndBiometricsDeleteConfirmationModal = getAsyncLifecycle(
69
73
  () => import('./components/delete-vitals-biometrics-modal/delete-vitals-biometrics.modal'),
70
74
  options,
package/src/routes.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json.openmrs.org/routes.schema.json",
3
3
  "backendDependencies": {
4
4
  "fhir2": ">=1.2",
5
- "webservices.rest": "^2.2.0"
5
+ "webservices.rest": ">=2.2.0"
6
6
  },
7
7
  "extensions": [
8
8
  {
@@ -67,11 +67,17 @@
67
67
  }
68
68
  ],
69
69
  "pages": [],
70
- "workspaces": [
70
+ "workspaces2": [
71
71
  {
72
72
  "name": "patient-vitals-biometrics-form-workspace",
73
- "title": "recordVitalsAndBiometrics",
74
- "component": "vitalsBiometricsFormWorkspace"
73
+ "component": "vitalsBiometricsFormWorkspace",
74
+ "window": "patient-vitals-biometrics-form-workspace"
75
+ }
76
+ ],
77
+ "workspaceWindows2": [
78
+ {
79
+ "name": "patient-vitals-biometrics-form-workspace",
80
+ "group": "patient-chart"
75
81
  }
76
82
  ],
77
83
  "modals": [
package/src/utils.ts CHANGED
@@ -10,10 +10,11 @@ import { invalidateCachedVitalsAndBiometrics } from './common';
10
10
  * @param currentVisit - The current visit.
11
11
  * @param config - The configuration object.
12
12
  */
13
- export function useLaunchVitalsAndBiometricsForm() {
13
+ export function useLaunchVitalsAndBiometricsForm(patientUuid: string) {
14
14
  const config = useConfig<ConfigObject>();
15
15
  const { useFormEngine, formName, formUuid } = config.vitals;
16
16
  const launchVitalsAndBiometricsForm = useLaunchWorkspaceRequiringVisit(
17
+ patientUuid,
17
18
  useFormEngine ? 'patient-form-entry-workspace' : patientVitalsBiometricsFormWorkspace,
18
19
  );
19
20
 
@@ -24,6 +24,7 @@ interface PaginatedVitalsProps {
24
24
  tableHeaders: Array<VitalsTableHeader>;
25
25
  tableRows: Array<VitalsTableRow>;
26
26
  urlLabel: string;
27
+ patient: fhir.Patient;
27
28
  }
28
29
 
29
30
  const PaginatedVitals: React.FC<PaginatedVitalsProps> = ({
@@ -33,6 +34,7 @@ const PaginatedVitals: React.FC<PaginatedVitalsProps> = ({
33
34
  tableHeaders,
34
35
  tableRows,
35
36
  urlLabel,
37
+ patient,
36
38
  }) => {
37
39
  const { t } = useTranslation();
38
40
  const isTablet = useLayoutType() === 'tablet';
@@ -132,7 +134,7 @@ const PaginatedVitals: React.FC<PaginatedVitalsProps> = ({
132
134
  );
133
135
  })}
134
136
  <TableCell className="cds--table-column-menu" id="actions">
135
- <VitalsAndBiometricsActionMenu encounterUuid={row.id} />
137
+ <VitalsAndBiometricsActionMenu patient={patient} encounterUuid={row.id} />
136
138
  </TableCell>
137
139
  </TableRow>
138
140
  ))}
@@ -40,7 +40,7 @@ const VitalsOverview: React.FC<VitalsOverviewProps> = ({ patientUuid, patient, p
40
40
  const isTablet = useLayoutType() === 'tablet';
41
41
  const [isPrinting, setIsPrinting] = useState(false);
42
42
  const contentToPrintRef = useRef(null);
43
- const launchVitalsBiometricsForm = useLaunchVitalsAndBiometricsForm();
43
+ const launchVitalsBiometricsForm = useLaunchVitalsAndBiometricsForm(patientUuid);
44
44
 
45
45
  const { excludePatientIdentifierCodeTypes } = useConfig();
46
46
  const { data: vitals, error, isLoading, isValidating } = useVitalsAndBiometrics(patientUuid);
@@ -243,6 +243,7 @@ const VitalsOverview: React.FC<VitalsOverviewProps> = ({ patientUuid, patient, p
243
243
  tableHeaders={tableHeaders}
244
244
  tableRows={tableRows}
245
245
  urlLabel={urlLabel}
246
+ patient={patient}
246
247
  />
247
248
  </div>
248
249
  )}
@@ -8,8 +8,7 @@ dayjs.extend(duration);
8
8
  import { Trans, useTranslation } from 'react-i18next';
9
9
  import { Button, InlineLoading, Tag } from '@carbon/react';
10
10
  import { ArrowRight } from '@carbon/react/icons';
11
- import { ConfigurableLink, formatDate, parseDate, useConfig, useWorkspaces } from '@openmrs/esm-framework';
12
- import { useVisitOrOfflineVisit } from '@openmrs/esm-patient-common-lib';
11
+ import { ConfigurableLink, formatDate, parseDate, useConfig, useVisit, useWorkspaces } from '@openmrs/esm-framework';
13
12
  import {
14
13
  assessValue,
15
14
  getReferenceRangesForConcept,
@@ -41,11 +40,11 @@ const VitalsHeader: React.FC<VitalsHeaderProps> = ({ patientUuid, hideLinks = fa
41
40
  const latestVitals = vitals?.[0];
42
41
  const [showDetailsPanel, setShowDetailsPanel] = useState(false);
43
42
  const toggleDetailsPanel = () => setShowDetailsPanel(!showDetailsPanel);
44
- const { currentVisit } = useVisitOrOfflineVisit(patientUuid);
43
+ const { activeVisit } = useVisit(patientUuid);
45
44
  const { workspaces } = useWorkspaces();
46
45
 
47
46
  const isWorkspaceOpen = useCallback(() => Boolean(workspaces?.length), [workspaces]);
48
- const launchForm = useLaunchVitalsAndBiometricsForm();
47
+ const launchForm = useLaunchVitalsAndBiometricsForm(patientUuid);
49
48
 
50
49
  const launchVitalsAndBiometricsForm = useCallback(
51
50
  (event: React.MouseEvent<HTMLButtonElement>) => {
@@ -62,7 +61,7 @@ const VitalsHeader: React.FC<VitalsHeaderProps> = ({ patientUuid, hideLinks = fa
62
61
  }
63
62
 
64
63
  if (latestVitals && Object.keys(latestVitals)?.length && conceptRanges?.length) {
65
- const hasActiveVisit = Boolean(currentVisit?.uuid);
64
+ const hasActiveVisit = Boolean(activeVisit?.uuid);
66
65
  const now = dayjs();
67
66
  const vitalsTakenTimeAgo = dayjs.duration(now.diff(latestVitals?.date));
68
67
  const vitalsOverdueThresholdHours = config.vitals.vitalsOverdueThresholdHours;
@@ -161,25 +160,30 @@ const VitalsHeader: React.FC<VitalsHeaderProps> = ({ patientUuid, hideLinks = fa
161
160
  latestVitals?.diastolic,
162
161
  config?.concepts,
163
162
  conceptRanges,
163
+ latestVitals?.systolicRenderInterpretation,
164
+ latestVitals?.diastolicRenderInterpretation,
164
165
  )}
165
166
  unitName={t('bp', 'BP')}
166
167
  unitSymbol={(latestVitals?.systolic && conceptUnits.get(config.concepts.systolicBloodPressureUuid)) ?? ''}
167
168
  value={`${latestVitals?.systolic ?? '--'} / ${latestVitals?.diastolic ?? '--'}`}
168
169
  />
169
170
  <VitalsHeaderItem
170
- interpretation={assessValue(
171
- latestVitals?.pulse,
172
- getReferenceRangesForConcept(config.concepts.pulseUuid, conceptRanges),
173
- )}
171
+ interpretation={
172
+ latestVitals?.pulseRenderInterpretation ??
173
+ assessValue(latestVitals?.pulse, getReferenceRangesForConcept(config.concepts.pulseUuid, conceptRanges))
174
+ }
174
175
  unitName={t('heartRate', 'Heart rate')}
175
176
  unitSymbol={(latestVitals?.pulse && conceptUnits.get(config.concepts.pulseUuid)) ?? ''}
176
177
  value={latestVitals?.pulse ?? '--'}
177
178
  />
178
179
  <VitalsHeaderItem
179
- interpretation={assessValue(
180
- latestVitals?.respiratoryRate,
181
- getReferenceRangesForConcept(config.concepts.respiratoryRateUuid, conceptRanges),
182
- )}
180
+ interpretation={
181
+ latestVitals?.respiratoryRateRenderInterpretation ??
182
+ assessValue(
183
+ latestVitals?.respiratoryRate,
184
+ getReferenceRangesForConcept(config.concepts.respiratoryRateUuid, conceptRanges),
185
+ )
186
+ }
183
187
  unitName={t('respiratoryRate', 'R. rate')}
184
188
  unitSymbol={
185
189
  (latestVitals?.respiratoryRate && conceptUnits.get(config.concepts.respiratoryRateUuid)) ?? ''
@@ -187,19 +191,25 @@ const VitalsHeader: React.FC<VitalsHeaderProps> = ({ patientUuid, hideLinks = fa
187
191
  value={latestVitals?.respiratoryRate ?? '--'}
188
192
  />
189
193
  <VitalsHeaderItem
190
- interpretation={assessValue(
191
- latestVitals?.spo2,
192
- getReferenceRangesForConcept(config.concepts.oxygenSaturationUuid, conceptRanges),
193
- )}
194
+ interpretation={
195
+ latestVitals?.spo2RenderInterpretation ??
196
+ assessValue(
197
+ latestVitals?.spo2,
198
+ getReferenceRangesForConcept(config.concepts.oxygenSaturationUuid, conceptRanges),
199
+ )
200
+ }
194
201
  unitName={t('spo2', 'SpO2')}
195
202
  unitSymbol={(latestVitals?.spo2 && conceptUnits.get(config.concepts.oxygenSaturationUuid)) ?? ''}
196
203
  value={latestVitals?.spo2 ?? '--'}
197
204
  />
198
205
  <VitalsHeaderItem
199
- interpretation={assessValue(
200
- latestVitals?.temperature,
201
- getReferenceRangesForConcept(config.concepts.temperatureUuid, conceptRanges),
202
- )}
206
+ interpretation={
207
+ latestVitals?.temperatureRenderInterpretation ??
208
+ assessValue(
209
+ latestVitals?.temperature,
210
+ getReferenceRangesForConcept(config.concepts.temperatureUuid, conceptRanges),
211
+ )
212
+ }
203
213
  unitName={t('temperatureAbbreviated', 'Temp')}
204
214
  unitSymbol={(latestVitals?.temperature && conceptUnits.get(config.concepts.temperatureUuid)) ?? ''}
205
215
  value={latestVitals?.temperature ?? '--'}