Skip to content

Commit

Permalink
Updated blood pressure range and remove hyphen for infusion "nor-adre…
Browse files Browse the repository at this point in the history
…naline" (#8498)
  • Loading branch information
rithviknishad authored Sep 21, 2024
1 parent 5027d5b commit 7163746
Show file tree
Hide file tree
Showing 18 changed files with 112 additions and 128 deletions.
41 changes: 16 additions & 25 deletions src/Components/Common/BloodPressureFormField.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useTranslation } from "react-i18next";
import { FieldValidator } from "../Form/FieldValidators";
import FormField from "../Form/FormFields/FormField";
import RangeAutocompleteFormField from "../Form/FormFields/RangeAutocompleteFormField";
Expand All @@ -8,42 +9,34 @@ import {
} from "../Form/FormFields/Utils";
import { BloodPressure } from "../Patient/models";

type Props = FormFieldBaseProps<BloodPressure>;
type Props = FormFieldBaseProps<BloodPressure | null>;

export default function BloodPressureFormField(props: Props) {
const { t } = useTranslation();
const field = useFormFieldPropsResolver(props);
const map = meanArterialPressure(props.value)?.toFixed();

const handleChange = (event: FieldChangeEvent<number>) => {
const value: BloodPressure = {
...field.value,
[event.name]: event.value,
};
value.mean = meanArterialPressure(value);
field.onChange({ name: field.name, value });
const bp = field.value ?? {};
bp[event.name as keyof BloodPressure] = event.value;
field.handleChange(Object.values(bp).filter(Boolean).length ? bp : null);
};

const map =
!!props.value?.diastolic &&
!!props.value.systolic &&
meanArterialPressure(props.value);

return (
<FormField
field={{
...field,
labelSuffix: map ? (
<span className="font-medium">MAP: {map.toFixed(1)}</span>
) : undefined,
labelSuffix: map && <span className="font-medium">MAP: {map}</span>,
}}
>
<div className="flex flex-row items-center">
<RangeAutocompleteFormField
name="systolic"
placeholder="Systolic"
placeholder={t("systolic")}
start={0}
end={250}
step={1}
value={field.value?.systolic}
value={field.value?.systolic ?? undefined}
onChange={handleChange}
labelClassName="hidden"
errorClassName="hidden"
Expand All @@ -68,11 +61,11 @@ export default function BloodPressureFormField(props: Props) {
<span className="px-2 text-lg font-medium text-secondary-400">/</span>
<RangeAutocompleteFormField
name="diastolic"
placeholder="Diastolic"
placeholder={t("diastolic")}
start={0}
end={250}
step={1}
value={field.value?.diastolic}
value={field.value?.diastolic ?? undefined}
onChange={handleChange}
labelClassName="hidden"
errorClassName="hidden"
Expand All @@ -99,13 +92,11 @@ export default function BloodPressureFormField(props: Props) {
);
}

export const meanArterialPressure = ({
diastolic,
systolic,
}: BloodPressure) => {
if (diastolic != null && systolic != null) {
return (2 * diastolic + systolic) / 3;
export const meanArterialPressure = (bp?: BloodPressure | null) => {
if (bp?.diastolic == null || bp?.systolic == null) {
return;
}
return (2 * bp.diastolic + bp.systolic) / 3;
};

export const BloodPressureValidator: FieldValidator<BloodPressure> = (bp) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import { useTranslation } from "react-i18next";
import PatientCategoryBadge from "../../../Common/PatientCategoryBadge";
import {
BloodPressure,
DailyRoundsModel,
NameQuantity,
} from "../../../Patient/models";
import { DailyRoundsModel, NameQuantity } from "../../../Patient/models";
import { PatientCategory } from "../../models";

interface Props<T extends keyof DailyRoundsModel> {
Expand Down Expand Up @@ -45,8 +41,8 @@ const LogUpdateCardAttribute = <T extends keyof DailyRoundsModel>({
<div className="flex flex-col items-center gap-2 md:flex-row">
<AttributeLabel attributeKey={attributeKey} />
<span className="text-sm font-semibold text-secondary-700">
{(attributeValue as BloodPressure).systolic}/
{(attributeValue as BloodPressure).diastolic} mmHg
{(attributeValue as DailyRoundsModel["bp"])?.systolic || "--"}/
{(attributeValue as DailyRoundsModel["bp"])?.diastolic || "--"} mmHg
</span>
</div>
);
Expand Down
2 changes: 1 addition & 1 deletion src/Components/Facility/Consultations/Mews.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const getHeartRateScore = (value?: number) => {
return 3;
};

const getSystolicBPScore = (value?: number) => {
const getSystolicBPScore = (value?: number | null) => {
if (typeof value !== "number") return;

if (value <= 70) return 3;
Expand Down
18 changes: 4 additions & 14 deletions src/Components/Facility/Consultations/PrimaryParametersPlot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import CareIcon from "../../../CAREUI/icons/CareIcon";
import { PainDiagrams } from "./PainDiagrams";
import PageTitle from "../../Common/PageTitle";
import dayjs from "../../../Utils/dayjs";
import { meanArterialPressure } from "../../Common/BloodPressureFormField";
import { PrimaryParametersPlotFields } from "../models";

interface PrimaryParametersPlotProps {
Expand All @@ -18,17 +19,6 @@ interface PrimaryParametersPlotProps {
consultationId: string;
}

const sanitizeBPAttribute = (value: number | undefined) => {
// Temp. hack until the cleaning of daily rounds as a db migration is done.
// TODO: remove once migration is merged.

if (value == null || value < 0) {
return;
}

return value;
};

export const PrimaryParametersPlot = ({
consultationId,
}: PrimaryParametersPlotProps) => {
Expand Down Expand Up @@ -77,19 +67,19 @@ export const PrimaryParametersPlot = ({
{
name: "diastolic",
data: Object.values(results)
.map((p: any) => p.bp && sanitizeBPAttribute(p.bp.diastolic))
.map((p: any) => p.bp?.diastolic)
.reverse(),
},
{
name: "systolic",
data: Object.values(results)
.map((p: any) => p.bp && sanitizeBPAttribute(p.bp.systolic))
.map((p: any) => p.bp?.systolic)
.reverse(),
},
{
name: "mean",
data: Object.values(results)
.map((p: any) => p.bp && sanitizeBPAttribute(p.bp.mean))
.map((p: any) => meanArterialPressure(p.bp))
.reverse(),
},
];
Expand Down
7 changes: 2 additions & 5 deletions src/Components/Facility/models.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { ConsultationDiagnosis, CreateDiagnosis } from "../Diagnosis/types";
import { NormalPrescription, PRNPrescription } from "../Medicine/models";
import {
AssignedToObjectModel,
BloodPressure,
DailyRoundsModel,
FileUploadModel,
} from "../Patient/models";
Expand Down Expand Up @@ -427,11 +428,7 @@ export const PrimaryParametersPlotFields = [
] as const satisfies (keyof DailyRoundsModel)[];

export type PrimaryParametersPlotRes = {
bp: {
mean?: number;
systolic?: number;
diastolic?: number;
};
bp: BloodPressure;
pulse: number;
temperature: string;
resp: number;
Expand Down
48 changes: 32 additions & 16 deletions src/Components/Form/FormFields/RangeFormField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@ import { SelectFormField } from "./SelectFormField";
type BaseProps = FormFieldBaseProps<number> & {
min: number;
max: number;
sliderMin?: number;
sliderMax?: number;
step?: number;
valueDescriptions?: ValueDescription[];
hideInput?: boolean;
hideUnitInLabel?: boolean;
};

type PropsWithUnit = BaseProps & {
Expand Down Expand Up @@ -75,18 +78,20 @@ export default function RangeFormField(props: Props) {
? props.valueDescriptions?.find((vd) => (vd.till || props.max) >= value)
: undefined;

const roundedValue =
Math.round(((value || min) + Number.EPSILON) * 100) / 100;

const allValueColors = props.valueDescriptions?.every((vd) => vd.color);

const trailPercent = ((roundedValue - min) / ((max || 0) - (min || 0))) * 100;
const [sliderMin, sliderMax] = [
props.sliderMin ?? props.min,
props.sliderMax ?? props.max,
].map(unit.conversionFn);

const snapStopLength = Math.min(
(props.max - props.min) / (props.step || 1),
props.max - props.min,
20,
);
const sliderDelta = sliderMax - sliderMin;

const trailPercent =
((Math.round(((value || sliderMin) + Number.EPSILON) * 100) / 100 -
sliderMin) /
sliderDelta) *
100;

const handleChange = (v: number) => field.handleChange(unit.inversionFn(v));

Expand All @@ -98,7 +103,10 @@ export default function RangeFormField(props: Props) {
...field,
label: (
<>
{field.label} {unit.label && <span>({unit.label})</span>}
{field.label}{" "}
{!props.hideUnitInLabel && unit.label && (
<span>({unit.label})</span>
)}
</>
),
labelSuffix: (
Expand All @@ -124,6 +132,7 @@ export default function RangeFormField(props: Props) {
max={max}
errorClassName="hidden"
inputClassName="py-1.5 mr-4"
disabled={props.disabled}
/>
{props.units?.length ? (
<SelectFormField
Expand Down Expand Up @@ -166,7 +175,11 @@ export default function RangeFormField(props: Props) {
<input
type="range"
id={field.id}
className={classNames("cui-range-slider", field.className)}
className={classNames(
"cui-range-slider",
field.className,
props.disabled && "opacity-50",
)}
style={
allValueColors
? {
Expand All @@ -179,22 +192,25 @@ export default function RangeFormField(props: Props) {
disabled={field.disabled}
name={field.name}
value={displayValue}
min={min}
max={max}
min={sliderMin}
max={sliderMax}
step={props.step}
onChange={(e) => handleChange(e.target.valueAsNumber)}
/>
</div>

<div className="flex justify-between">
{Array.from({ length: snapStopLength + 1 }).map((_, index) => (
{Array.from({
length:
1 + Math.min(sliderDelta / (props.step || 1), sliderDelta, 20),
}).map((_, index) => (
<div key={index} className="h-1 w-px bg-black/20" />
))}
</div>

<div className="flex justify-between text-xs text-black/30">
<span>{properRoundOf(min)}</span>
<span>{properRoundOf(max)}</span>
<span>{properRoundOf(sliderMin)}</span>
<span>{properRoundOf(sliderMax)}</span>
</div>
</FormField>
);
Expand Down
3 changes: 2 additions & 1 deletion src/Components/LogUpdate/CriticalCarePreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { VentilatorFields } from "./Sections/RespiratorySupport/Ventilator";
import PressureSore from "./Sections/PressureSore/PressureSore";
import { IOBalanceSections } from "./Sections/IOBalance";
import PainChart from "./components/PainChart";
import { meanArterialPressure } from "../Common/BloodPressureFormField";
import { DailyRoundsModel } from "../Patient/models";

type Props = {
Expand Down Expand Up @@ -255,7 +256,7 @@ export default function CriticalCarePreview(props: Props) {
/>
<Detail
label="Mean"
value={data.bp.mean && properRoundOf(data.bp.mean)}
value={meanArterialPressure(data.bp)?.toFixed()}
/>
</div>
)}
Expand Down
2 changes: 1 addition & 1 deletion src/Components/LogUpdate/Sections/IOBalance.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const IOBalanceSections = [
name: "Infusions",
options: [
"Adrenalin",
"Nor-adrenalin",
"Noradrenalin",
"Vasopressin",
"Dopamine",
"Dobutamine",
Expand Down
Loading

0 comments on commit 7163746

Please sign in to comment.