Skip to content

Commit

Permalink
fixes #6544; Principal Diagnosis as Dropdown
Browse files Browse the repository at this point in the history
  • Loading branch information
rithviknishad committed Nov 6, 2023
1 parent 8b48e9b commit a1e8493
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 108 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import ConsultationDiagnosisEntry from "./ConsultationDiagnosisEntry";
import request from "../../../Utils/request/request";
import DiagnosesRoutes from "../routes";
import * as Notification from "../../../Utils/Notifications";
import PrincipalDiagnosisCard from "./PrincipalDiagnosisCard";
import PrincipalDiagnosisSelect from "./PrincipalDiagnosisSelect";

interface CreateDiagnosesProps {
className?: string;
Expand All @@ -19,7 +19,6 @@ interface CreateDiagnosesProps {
}

export const CreateDiagnosesBuilder = (props: CreateDiagnosesProps) => {
const principalDiagnosis = props.value.find((d) => d.is_principal);
return (
<div className={props.className}>
<div className="flex w-full flex-col items-start rounded-lg border border-gray-400">
Expand All @@ -30,18 +29,11 @@ export const CreateDiagnosesBuilder = (props: CreateDiagnosesProps) => {
value={diagnosis}
onChange={(action) => {
if (action.type === "remove") {
const diagnoses = [...props.value];
diagnoses.splice(index, 1);
props.onChange(diagnoses);
props.onChange(props.value.toSpliced(index, 1));
}

if (action.type === "edit") {
const diagnoses = action.value.is_principal
? props.value.map((d) => {
d.is_principal = false;
return d;
})
: [...props.value];
const diagnoses = [...props.value];
diagnoses[index] = action.value as CreateDiagnosis;
props.onChange(diagnoses);
}
Expand All @@ -65,12 +57,15 @@ export const CreateDiagnosesBuilder = (props: CreateDiagnosesProps) => {
</div>
</div>

{principalDiagnosis?.diagnosis_object && (
<PrincipalDiagnosisCard
className="my-2"
diagnosis={principalDiagnosis.diagnosis_object}
/>
)}
<PrincipalDiagnosisSelect
className="my-2"
diagnoses={props.value}
onChange={async (value) => {
props.onChange(
props.value.map((d) => ({ ...d, is_principal: d === value }))
);
}}
/>
</div>
);
};
Expand All @@ -83,9 +78,6 @@ interface EditDiagnosesProps {
export const EditDiagnosesBuilder = (props: EditDiagnosesProps) => {
const consultation = useSlug("consultation");
const [diagnoses, setDiagnoses] = useState(props.value);

const principalDiagnosis = diagnoses.find((d) => d.is_principal);

return (
<div className={props.className}>
<div className="flex w-full flex-col items-start rounded-lg border border-gray-400">
Expand Down Expand Up @@ -139,12 +131,51 @@ export const EditDiagnosesBuilder = (props: EditDiagnosesProps) => {
</div>
</div>

{principalDiagnosis?.diagnosis_object && (
<PrincipalDiagnosisCard
className="my-2"
diagnosis={principalDiagnosis?.diagnosis_object}
/>
)}
<PrincipalDiagnosisSelect
className="my-2"
diagnoses={diagnoses}
onChange={async (value) => {
// Unset existing principal diagnoses
await Promise.all(
diagnoses
.filter((d) => d.is_principal)
.map((d) => {
return request(DiagnosesRoutes.updateConsultationDiagnosis, {
pathParams: { consultation, id: d.id },
body: { ...d, is_principal: false },
});
})
);

if (!value) {
setDiagnoses((diagnoses) =>
diagnoses.map((d) => ({ ...d, is_principal: false }))
);
return;
}

// Set new principal diagnosis
const { res, data, error } = await request(
DiagnosesRoutes.updateConsultationDiagnosis,
{
pathParams: { consultation, id: value.id },
body: { ...value, is_principal: true },
}
);

if (res?.ok && data) {
setDiagnoses((diagnoses) =>
diagnoses.map((d) =>
d.id === data.id ? data : { ...d, is_principal: false }
)
);
}

if (error) {
Notification.Error({ msg: error });
}
}}
/>
</div>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
import { useTranslation } from "react-i18next";
import CareIcon from "../../../CAREUI/icons/CareIcon";
import ButtonV2 from "../../Common/components/ButtonV2";
import ConditionVerificationStatusMenu from "../ConditionVerificationStatusMenu";
import {
ActiveConditionVerificationStatuses,
Expand Down Expand Up @@ -41,8 +38,6 @@ interface ConsultationEditProps extends BaseProps {
type Props = ConsultationCreateProps | ConsultationEditProps;

export default function ConsultationDiagnosisEntry(props: Props) {
const { t } = useTranslation();
const [data, setData] = useState<ConsultationDiagnosis>();
const [disabled, setDisabled] = useState(false);

const handleUpdate = async (value: ConsultationDiagnosis) => {
Expand All @@ -60,12 +55,11 @@ export default function ConsultationDiagnosisEntry(props: Props) {
setDisabled(false);

if (res?.ok && data) {
setData(data);
props.onChange({ type: "edit", value: data });
}
};

const object = data ?? props.value;

const object = props.value;
const isActive = ActiveConditionVerificationStatuses.includes(
object.verification_status as (typeof ActiveConditionVerificationStatuses)[number]
);
Expand All @@ -90,43 +84,7 @@ export default function ConsultationDiagnosisEntry(props: Props) {
>
{object.diagnosis_object?.label}
</span>

<div className="flex items-center justify-end gap-2 sm:flex-row md:absolute md:inset-y-0 md:right-2 md:justify-normal">
{isActive && (
<ButtonV2
type="button"
size="small"
variant={object.is_principal ? "primary" : "secondary"}
disabled={disabled}
ghost
border
onClick={async () => {
const value = { ...object, is_principal: !object.is_principal };
if (props.consultationId) {
await handleUpdate(value as ConsultationDiagnosis);
}
props.onChange({ type: "edit", value });
}}
tooltip={object.is_principal ? t("unmark_as_principal") : ""}
tooltipClassName="tooltip-bottom -translate-x-1/2 translate-y-1 text-xs"
>
{object.is_principal && (
<CareIcon icon="l-check" className="text-lg" />
)}
<span className="py-0.5">
{object.is_principal ? (
<>
<span className="hidden md:block">
{t("principal_diagnosis")}
</span>
<span className="block md:hidden">{t("principal")}</span>
</>
) : (
t("mark_as_principal")
)}
</span>
</ButtonV2>
)}
<div className="w-32">
<ConditionVerificationStatusMenu
className="w-full"
Expand All @@ -141,11 +99,12 @@ export default function ConsultationDiagnosisEntry(props: Props) {
const value = { ...object, verification_status };
if (props.consultationId) {
await handleUpdate(value as ConsultationDiagnosis);
} else {
props.onChange({
type: "edit",
value: value as CreateDiagnosis | ConsultationDiagnosis,
});
}
props.onChange({
type: "edit",
value: value as CreateDiagnosis | ConsultationDiagnosis,
});
}}
onRemove={
props.consultationId === undefined
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { useState } from "react";
import {
ActiveConditionVerificationStatuses,
ConsultationDiagnosis,
CreateDiagnosis,
} from "../types";
import { SelectFormField } from "../../Form/FormFields/SelectFormField";

type Option = CreateDiagnosis | ConsultationDiagnosis;

interface Props<T extends Option> {
className?: string;
diagnoses: T[];
onChange: (value?: T) => Promise<void>;
}

const PrincipalDiagnosisSelect = <T extends Option>(props: Props<T>) => {
const [disabled, setDisabled] = useState(false);
const value = props.diagnoses.find((d) => d.is_principal);
const diagnosis = value?.diagnosis_object;

const options = props.diagnoses.some(isConfirmed)
? props.diagnoses.filter(isConfirmedOrPrincipal)
: props.diagnoses.filter(isActive);

return (
<div className={props.className}>
<div className="rounded-lg border border-gray-400 bg-gray-200 p-4">
<SelectFormField
name="principal_diagnosis"
label="Principal Diagnosis"
value={JSON.stringify(value)}
disabled={disabled}
options={options}
optionLabel={(d) => d.diagnosis_object?.label}
optionDescription={(d) => (
<p>
Categorised under:{" "}
<span className="font-bold">{d.diagnosis_object?.chapter}</span>
</p>
)}
optionValue={(d) => JSON.stringify(d)} // TODO: momentary hack, figure out a better way to do this
onChange={async ({ value }) => {
setDisabled(true);
await props.onChange(value ? (JSON.parse(value) as T) : undefined);
setDisabled(false);
}}
errorClassName="hidden"
/>
{diagnosis && (
<span className="mt-3 flex w-full flex-wrap justify-center gap-x-1 px-2 text-center text-gray-900">
<p>This encounter will be categorised under:</p>
<p className="font-bold">{diagnosis.chapter}</p>
</span>
)}
</div>
</div>
);
};

export default PrincipalDiagnosisSelect;

const isConfirmed = (d: Option) => d.verification_status === "confirmed";
const isConfirmedOrPrincipal = (d: Option) => isConfirmed(d) || d.is_principal;
const isActive = (d: Option) =>
ActiveConditionVerificationStatuses.includes(d.verification_status as any);
15 changes: 8 additions & 7 deletions src/Components/Diagnosis/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,20 @@ export type ConditionVerificationStatus =
(typeof ConditionVerificationStatuses)[number];

export interface ConsultationDiagnosis {
id: string;
diagnosis_object: ICD11DiagnosisModel;
readonly id: string;
diagnosis?: ICD11DiagnosisModel["id"];
readonly diagnosis_object: ICD11DiagnosisModel;
verification_status: ConditionVerificationStatus;
is_principal: boolean;
is_migrated: boolean;
created_by: PerformedByModel;
created_date: string;
modified_date: string;
readonly is_migrated: boolean;
readonly created_by: PerformedByModel;
readonly created_date: string;
readonly modified_date: string;
}

export interface CreateDiagnosis {
diagnosis: ICD11DiagnosisModel["id"];
diagnosis_object?: ICD11DiagnosisModel;
readonly diagnosis_object?: ICD11DiagnosisModel;
verification_status: (typeof ActiveConditionVerificationStatuses)[number];
is_principal: boolean;
}
2 changes: 0 additions & 2 deletions src/Locale/en/Diagnosis.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
"diagnosis_already_added": "This diagnosis was already added",
"principal": "Principal",
"principal_diagnosis": "Principal diagnosis",
"mark_as_principal": "Mark as principal",
"unmark_as_principal": "Unmark as principal",
"unconfirmed": "Unconfirmed",
"provisional": "Provisional",
"differential": "Differential",
Expand Down

0 comments on commit a1e8493

Please sign in to comment.