@openmrs/esm-patient-vitals-app 9.2.3-pre.7474 → 9.2.3-pre.7484

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.
@@ -15,14 +15,13 @@ import {
15
15
  } from '@carbon/react';
16
16
  import {
17
17
  age,
18
- createErrorHandler,
18
+ ExtensionSlot,
19
19
  showSnackbar,
20
+ useAbortController,
20
21
  useConfig,
21
22
  useLayoutType,
22
23
  useSession,
23
- ExtensionSlot,
24
24
  useVisit,
25
- useAbortController,
26
25
  } from '@openmrs/esm-framework';
27
26
  import { type DefaultPatientWorkspaceProps } from '@openmrs/esm-patient-common-lib';
28
27
  import { type ConfigObject } from '../config-schema';
@@ -34,14 +33,15 @@ import {
34
33
  } from './vitals-biometrics-form.utils';
35
34
  import {
36
35
  assessValue,
36
+ createOrUpdateVitalsAndBiometrics,
37
37
  getReferenceRangesForConcept,
38
38
  interpretBloodPressure,
39
39
  invalidateCachedVitalsAndBiometrics,
40
- useVitalsConceptMetadata,
41
- createOrUpdateVitalsAndBiometrics,
40
+ useConceptUnits,
42
41
  useEncounterVitalsAndBiometrics,
43
42
  } from '../common';
44
43
  import { prepareObsForSubmission } from '../common/helpers';
44
+ import { useVitalsConceptMetadata } from '../common/data.resource';
45
45
  import { VitalsAndBiometricsFormSchema, type VitalsBiometricsFormData } from './schema';
46
46
  import VitalsAndBiometricsInput from './vitals-biometrics-input.component';
47
47
  import styles from './vitals-biometrics-form.scss';
@@ -68,12 +68,8 @@ const VitalsAndBiometricsForm: React.FC<VitalsAndBiometricsFormProps> = ({
68
68
 
69
69
  const session = useSession();
70
70
  const { currentVisit } = useVisit(patientUuid);
71
- const {
72
- data: conceptUnits,
73
- conceptMetadata,
74
- conceptRanges,
75
- isLoading: isLoadingConceptMetadata,
76
- } = useVitalsConceptMetadata();
71
+ const { conceptUnits, isLoading: isLoadingConceptUnits } = useConceptUnits();
72
+ const { conceptRanges, conceptRangeMap } = useVitalsConceptMetadata(patientUuid);
77
73
  const {
78
74
  getRefinedInitialValues,
79
75
  isLoading: isLoadingEncounter,
@@ -153,28 +149,17 @@ const VitalsAndBiometricsForm: React.FC<VitalsAndBiometricsFormProps> = ({
153
149
 
154
150
  const concepts = useMemo(
155
151
  () => ({
156
- midUpperArmCircumferenceRange: conceptRanges.get(config.concepts.midUpperArmCircumferenceUuid),
157
- diastolicBloodPressureRange: conceptRanges.get(config.concepts.diastolicBloodPressureUuid),
158
- systolicBloodPressureRange: conceptRanges.get(config.concepts.systolicBloodPressureUuid),
159
- oxygenSaturationRange: conceptRanges.get(config.concepts.oxygenSaturationUuid),
160
- respiratoryRateRange: conceptRanges.get(config.concepts.respiratoryRateUuid),
161
- temperatureRange: conceptRanges.get(config.concepts.temperatureUuid),
162
- weightRange: conceptRanges.get(config.concepts.weightUuid),
163
- heightRange: conceptRanges.get(config.concepts.heightUuid),
164
- pulseRange: conceptRanges.get(config.concepts.pulseUuid),
152
+ midUpperArmCircumferenceRange: conceptRangeMap.get(config.concepts.midUpperArmCircumferenceUuid),
153
+ diastolicBloodPressureRange: conceptRangeMap.get(config.concepts.diastolicBloodPressureUuid),
154
+ systolicBloodPressureRange: conceptRangeMap.get(config.concepts.systolicBloodPressureUuid),
155
+ oxygenSaturationRange: conceptRangeMap.get(config.concepts.oxygenSaturationUuid),
156
+ respiratoryRateRange: conceptRangeMap.get(config.concepts.respiratoryRateUuid),
157
+ temperatureRange: conceptRangeMap.get(config.concepts.temperatureUuid),
158
+ weightRange: conceptRangeMap.get(config.concepts.weightUuid),
159
+ heightRange: conceptRangeMap.get(config.concepts.heightUuid),
160
+ pulseRange: conceptRangeMap.get(config.concepts.pulseUuid),
165
161
  }),
166
- [
167
- conceptRanges,
168
- config.concepts.diastolicBloodPressureUuid,
169
- config.concepts.heightUuid,
170
- config.concepts.midUpperArmCircumferenceUuid,
171
- config.concepts.oxygenSaturationUuid,
172
- config.concepts.pulseUuid,
173
- config.concepts.respiratoryRateUuid,
174
- config.concepts.systolicBloodPressureUuid,
175
- config.concepts.temperatureUuid,
176
- config.concepts.weightUuid,
177
- ],
162
+ [conceptRangeMap, config.concepts],
178
163
  );
179
164
 
180
165
  const savePatientVitalsAndBiometrics = useCallback(
@@ -187,7 +172,7 @@ const VitalsAndBiometricsForm: React.FC<VitalsAndBiometricsFormProps> = ({
187
172
 
188
173
  const allFieldsAreValid = Object.entries(formData)
189
174
  .filter(([, value]) => Boolean(value))
190
- .every(([key, value]) => isValueWithinReferenceRange(conceptMetadata, config.concepts[`${key}Uuid`], value));
175
+ .every(([key, value]) => isValueWithinReferenceRange(conceptRanges, config.concepts[`${key}Uuid`], value));
191
176
 
192
177
  if (allFieldsAreValid) {
193
178
  setShowErrorMessage(false);
@@ -224,7 +209,6 @@ const VitalsAndBiometricsForm: React.FC<VitalsAndBiometricsFormProps> = ({
224
209
  });
225
210
  })
226
211
  .catch(() => {
227
- createErrorHandler();
228
212
  showSnackbar({
229
213
  title:
230
214
  formContext === 'creating'
@@ -241,17 +225,17 @@ const VitalsAndBiometricsForm: React.FC<VitalsAndBiometricsFormProps> = ({
241
225
  },
242
226
  [
243
227
  abortController,
244
- conceptMetadata,
228
+ closeWorkspaceWithSavedChanges,
245
229
  config.concepts,
246
230
  config.vitals.encounterTypeUuid,
247
231
  dirtyFields,
248
232
  editEncounterUuid,
233
+ conceptRanges,
249
234
  formContext,
250
235
  initialFieldValuesMap,
236
+ mutateEncounter,
251
237
  patientUuid,
252
238
  session?.sessionLocation?.uuid,
253
- closeWorkspaceWithSavedChanges,
254
- mutateEncounter,
255
239
  t,
256
240
  ],
257
241
  );
@@ -274,7 +258,7 @@ const VitalsAndBiometricsForm: React.FC<VitalsAndBiometricsFormProps> = ({
274
258
  );
275
259
  }
276
260
 
277
- if (isLoadingConceptMetadata || isLoadingInitialValues) {
261
+ if (isLoadingConceptUnits || isLoadingInitialValues) {
278
262
  return (
279
263
  <Form className={styles.form}>
280
264
  <ExtensionSlot name="visit-context-header-slot" state={{ patientUuid }} />
@@ -322,7 +306,7 @@ const VitalsAndBiometricsForm: React.FC<VitalsAndBiometricsFormProps> = ({
322
306
  fieldProperties={[
323
307
  {
324
308
  id: 'temperature',
325
- max: concepts.temperatureRange?.highAbsolute,
309
+ max: concepts.temperatureRange?.hiAbsolute,
326
310
  min: concepts.temperatureRange?.lowAbsolute,
327
311
  name: t('temperature', 'Temperature'),
328
312
  type: 'number',
@@ -330,14 +314,11 @@ const VitalsAndBiometricsForm: React.FC<VitalsAndBiometricsFormProps> = ({
330
314
  ]}
331
315
  interpretation={
332
316
  temperature &&
333
- assessValue(
334
- temperature,
335
- getReferenceRangesForConcept(config.concepts.temperatureUuid, conceptMetadata),
336
- )
317
+ assessValue(temperature, getReferenceRangesForConcept(config.concepts.temperatureUuid, conceptRanges))
337
318
  }
338
319
  isValueWithinReferenceRange={
339
320
  temperature
340
- ? isValueWithinReferenceRange(conceptMetadata, config.concepts['temperatureUuid'], temperature)
321
+ ? isValueWithinReferenceRange(conceptRanges, config.concepts['temperatureUuid'], temperature)
341
322
  : true
342
323
  }
343
324
  showErrorMessage={showErrorMessage}
@@ -354,37 +335,32 @@ const VitalsAndBiometricsForm: React.FC<VitalsAndBiometricsFormProps> = ({
354
335
  separator: '/',
355
336
  type: 'number',
356
337
  min: concepts.systolicBloodPressureRange?.lowAbsolute,
357
- max: concepts.systolicBloodPressureRange?.highAbsolute,
338
+ max: concepts.systolicBloodPressureRange?.hiAbsolute,
358
339
  id: 'systolicBloodPressure',
359
340
  },
360
341
  {
361
342
  name: t('diastolic', 'diastolic'),
362
343
  type: 'number',
363
344
  min: concepts.diastolicBloodPressureRange?.lowAbsolute,
364
- max: concepts.diastolicBloodPressureRange?.highAbsolute,
345
+ max: concepts.diastolicBloodPressureRange?.hiAbsolute,
365
346
  id: 'diastolicBloodPressure',
366
347
  },
367
348
  ]}
368
349
  interpretation={
369
350
  systolicBloodPressure &&
370
351
  diastolicBloodPressure &&
371
- interpretBloodPressure(
372
- systolicBloodPressure,
373
- diastolicBloodPressure,
374
- config.concepts,
375
- conceptMetadata,
376
- )
352
+ interpretBloodPressure(systolicBloodPressure, diastolicBloodPressure, config.concepts, conceptRanges)
377
353
  }
378
354
  isValueWithinReferenceRange={
379
355
  systolicBloodPressure &&
380
356
  diastolicBloodPressure &&
381
357
  isValueWithinReferenceRange(
382
- conceptMetadata,
358
+ conceptRanges,
383
359
  config.concepts.systolicBloodPressureUuid,
384
360
  systolicBloodPressure,
385
361
  ) &&
386
362
  isValueWithinReferenceRange(
387
- conceptMetadata,
363
+ conceptRanges,
388
364
  config.concepts.diastolicBloodPressureUuid,
389
365
  diastolicBloodPressure,
390
366
  )
@@ -402,15 +378,15 @@ const VitalsAndBiometricsForm: React.FC<VitalsAndBiometricsFormProps> = ({
402
378
  name: t('pulse', 'Pulse'),
403
379
  type: 'number',
404
380
  min: concepts.pulseRange?.lowAbsolute,
405
- max: concepts.pulseRange?.highAbsolute,
381
+ max: concepts.pulseRange?.hiAbsolute,
406
382
  id: 'pulse',
407
383
  },
408
384
  ]}
409
385
  interpretation={
410
- pulse && assessValue(pulse, getReferenceRangesForConcept(config.concepts.pulseUuid, conceptMetadata))
386
+ pulse && assessValue(pulse, getReferenceRangesForConcept(config.concepts.pulseUuid, conceptRanges))
411
387
  }
412
388
  isValueWithinReferenceRange={
413
- pulse && isValueWithinReferenceRange(conceptMetadata, config.concepts['pulseUuid'], pulse)
389
+ pulse && isValueWithinReferenceRange(conceptRanges, config.concepts['pulseUuid'], pulse)
414
390
  }
415
391
  label={t('heartRate', 'Heart rate')}
416
392
  showErrorMessage={showErrorMessage}
@@ -425,7 +401,7 @@ const VitalsAndBiometricsForm: React.FC<VitalsAndBiometricsFormProps> = ({
425
401
  name: t('respirationRate', 'Respiration rate'),
426
402
  type: 'number',
427
403
  min: concepts.respiratoryRateRange?.lowAbsolute,
428
- max: concepts.respiratoryRateRange?.highAbsolute,
404
+ max: concepts.respiratoryRateRange?.hiAbsolute,
429
405
  id: 'respiratoryRate',
430
406
  },
431
407
  ]}
@@ -433,12 +409,12 @@ const VitalsAndBiometricsForm: React.FC<VitalsAndBiometricsFormProps> = ({
433
409
  respiratoryRate &&
434
410
  assessValue(
435
411
  respiratoryRate,
436
- getReferenceRangesForConcept(config.concepts.respiratoryRateUuid, conceptMetadata),
412
+ getReferenceRangesForConcept(config.concepts.respiratoryRateUuid, conceptRanges),
437
413
  )
438
414
  }
439
415
  isValueWithinReferenceRange={
440
416
  respiratoryRate &&
441
- isValueWithinReferenceRange(conceptMetadata, config.concepts['respiratoryRateUuid'], respiratoryRate)
417
+ isValueWithinReferenceRange(conceptRanges, config.concepts['respiratoryRateUuid'], respiratoryRate)
442
418
  }
443
419
  showErrorMessage={showErrorMessage}
444
420
  label={t('respirationRate', 'Respiration rate')}
@@ -453,7 +429,7 @@ const VitalsAndBiometricsForm: React.FC<VitalsAndBiometricsFormProps> = ({
453
429
  name: t('oxygenSaturation', 'Oxygen saturation'),
454
430
  type: 'number',
455
431
  min: concepts.oxygenSaturationRange?.lowAbsolute,
456
- max: concepts.oxygenSaturationRange?.highAbsolute,
432
+ max: concepts.oxygenSaturationRange?.hiAbsolute,
457
433
  id: 'oxygenSaturation',
458
434
  },
459
435
  ]}
@@ -461,16 +437,12 @@ const VitalsAndBiometricsForm: React.FC<VitalsAndBiometricsFormProps> = ({
461
437
  oxygenSaturation &&
462
438
  assessValue(
463
439
  oxygenSaturation,
464
- getReferenceRangesForConcept(config.concepts.oxygenSaturationUuid, conceptMetadata),
440
+ getReferenceRangesForConcept(config.concepts.oxygenSaturationUuid, conceptRanges),
465
441
  )
466
442
  }
467
443
  isValueWithinReferenceRange={
468
444
  oxygenSaturation &&
469
- isValueWithinReferenceRange(
470
- conceptMetadata,
471
- config.concepts['oxygenSaturationUuid'],
472
- oxygenSaturation,
473
- )
445
+ isValueWithinReferenceRange(conceptRanges, config.concepts['oxygenSaturationUuid'], oxygenSaturation)
474
446
  }
475
447
  showErrorMessage={showErrorMessage}
476
448
  label={t('spo2', 'SpO2')}
@@ -510,16 +482,15 @@ const VitalsAndBiometricsForm: React.FC<VitalsAndBiometricsFormProps> = ({
510
482
  name: t('weight', 'Weight'),
511
483
  type: 'number',
512
484
  min: concepts.weightRange?.lowAbsolute,
513
- max: concepts.weightRange?.highAbsolute,
485
+ max: concepts.weightRange?.hiAbsolute,
514
486
  id: 'weight',
515
487
  },
516
488
  ]}
517
489
  interpretation={
518
- weight &&
519
- assessValue(weight, getReferenceRangesForConcept(config.concepts.weightUuid, conceptMetadata))
490
+ weight && assessValue(weight, getReferenceRangesForConcept(config.concepts.weightUuid, conceptRanges))
520
491
  }
521
492
  isValueWithinReferenceRange={
522
- height && isValueWithinReferenceRange(conceptMetadata, config.concepts['weightUuid'], weight)
493
+ height && isValueWithinReferenceRange(conceptRanges, config.concepts['weightUuid'], weight)
523
494
  }
524
495
  showErrorMessage={showErrorMessage}
525
496
  label={t('weight', 'Weight')}
@@ -534,16 +505,15 @@ const VitalsAndBiometricsForm: React.FC<VitalsAndBiometricsFormProps> = ({
534
505
  name: t('height', 'Height'),
535
506
  type: 'number',
536
507
  min: concepts.heightRange?.lowAbsolute,
537
- max: concepts.heightRange?.highAbsolute,
508
+ max: concepts.heightRange?.hiAbsolute,
538
509
  id: 'height',
539
510
  },
540
511
  ]}
541
512
  interpretation={
542
- height &&
543
- assessValue(height, getReferenceRangesForConcept(config.concepts.heightUuid, conceptMetadata))
513
+ height && assessValue(height, getReferenceRangesForConcept(config.concepts.heightUuid, conceptRanges))
544
514
  }
545
515
  isValueWithinReferenceRange={
546
- weight && isValueWithinReferenceRange(conceptMetadata, config.concepts['heightUuid'], height)
516
+ weight && isValueWithinReferenceRange(conceptRanges, config.concepts['heightUuid'], height)
547
517
  }
548
518
  showErrorMessage={showErrorMessage}
549
519
  label={t('height', 'Height')}
@@ -573,7 +543,7 @@ const VitalsAndBiometricsForm: React.FC<VitalsAndBiometricsFormProps> = ({
573
543
  name: t('muac', 'MUAC'),
574
544
  type: 'number',
575
545
  min: concepts.midUpperArmCircumferenceRange?.lowAbsolute,
576
- max: concepts.midUpperArmCircumferenceRange?.highAbsolute,
546
+ max: concepts.midUpperArmCircumferenceRange?.hiAbsolute,
577
547
  id: 'midUpperArmCircumference',
578
548
  },
579
549
  ]}
@@ -582,7 +552,7 @@ const VitalsAndBiometricsForm: React.FC<VitalsAndBiometricsFormProps> = ({
582
552
  height &&
583
553
  weight &&
584
554
  isValueWithinReferenceRange(
585
- conceptMetadata,
555
+ conceptRanges,
586
556
  config.concepts['midUpperArmCircumferenceUuid'],
587
557
  midUpperArmCircumference,
588
558
  )
@@ -91,7 +91,7 @@ jest.mock('../common', () => {
91
91
  return {
92
92
  ...originalModule,
93
93
  launchPatientWorkspace: jest.fn(),
94
- useVitalsConceptMetadata: jest.fn().mockImplementation(() => ({
94
+ useConceptUnits: jest.fn().mockImplementation(() => ({
95
95
  data: mockConceptUnits,
96
96
  conceptMetadata: { ...overridenMetadata },
97
97
  isLoading: false,