-
Notifications
You must be signed in to change notification settings - Fork 649
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Location Popover & History Sheet #10540
Changes from 15 commits
322cf9d
c783ce1
340a975
b25e067
980aed1
7af96b2
37f0c32
4a424ff
aba11be
b199625
85c838e
3346a49
39ef239
c6fa906
5819c06
aba997f
ecaa675
32d5f72
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import { useTranslation } from "react-i18next"; | ||
|
||
import { ScrollArea } from "@/components/ui/scroll-area"; | ||
import { | ||
Sheet, | ||
SheetContent, | ||
SheetHeader, | ||
SheetTitle, | ||
SheetTrigger, | ||
} from "@/components/ui/sheet"; | ||
|
||
import { LocationHistory } from "@/types/emr/encounter"; | ||
|
||
import { LocationTree } from "./LocationTree"; | ||
|
||
interface LocationHistorySheetProps { | ||
trigger: React.ReactNode; | ||
history: LocationHistory[]; | ||
} | ||
|
||
export function LocationHistorySheet({ | ||
trigger, | ||
history, | ||
}: LocationHistorySheetProps) { | ||
const { t } = useTranslation(); | ||
|
||
return ( | ||
<Sheet> | ||
<SheetTrigger asChild>{trigger}</SheetTrigger> | ||
<SheetContent className="w-full sm:max-w-xl"> | ||
<SheetHeader className="px-1"> | ||
<SheetTitle>{t("location_history")}</SheetTitle> | ||
</SheetHeader> | ||
<ScrollArea className="h-[calc(100vh-8rem)] mt-6"> | ||
{history.map((item, index) => ( | ||
<div key={index}> | ||
<LocationTree | ||
location={item.location} | ||
datetime={item.start_datetime} | ||
isLatest={index === 0} | ||
showTimeline | ||
/> | ||
</div> | ||
))} | ||
</ScrollArea> | ||
</SheetContent> | ||
</Sheet> | ||
); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
import { format } from "date-fns"; | ||
import React from "react"; | ||
|
||
import CareIcon from "@/CAREUI/icons/CareIcon"; | ||
|
||
import { LocationList } from "@/types/location/location"; | ||
|
||
interface LocationPathProps { | ||
location: LocationList; | ||
datetime?: string; | ||
isLatest?: boolean; | ||
showTimeline?: boolean; | ||
} | ||
|
||
interface LocationNodeProps { | ||
location: LocationList; | ||
isLast: boolean; | ||
datetime?: string; | ||
children?: React.ReactNode; | ||
} | ||
|
||
function LocationNode({ | ||
location, | ||
isLast, | ||
datetime, | ||
children, | ||
}: LocationNodeProps) { | ||
if (!location.parent?.id) { | ||
return ( | ||
<div className="flex flex-col gap-2"> | ||
<div className="flex items-center text-sm"> | ||
<span className="w-2 h-2 rounded-full bg-gray-400 mr-2" /> | ||
<span | ||
className={isLast ? "font-semibold" : "text-gray-700 font-medium"} | ||
> | ||
{location.name} | ||
</span> | ||
</div> | ||
{children} | ||
{isLast && datetime && ( | ||
<div className="pl-6 flex items-center text-sm font-normal text-gray-700 italic"> | ||
{format(new Date(datetime), "MMM d, yyyy h:mm a")} | ||
</div> | ||
)} | ||
</div> | ||
); | ||
} | ||
|
||
return ( | ||
<LocationNode location={location.parent} isLast={false} datetime={datetime}> | ||
<div className="flex flex-col gap-2 ml-6"> | ||
<div className="flex items-center text-sm"> | ||
<CareIcon | ||
icon="l-corner-down-right" | ||
className="w-4 h-4 mr-2 mb-1 text-gray-400" | ||
/> | ||
<span | ||
className={isLast ? "font-semibold" : "text-gray-700 font-medium"} | ||
> | ||
{location.name} | ||
</span> | ||
</div> | ||
{children} | ||
{isLast && datetime && ( | ||
<div className="pl-6 flex items-center text-sm font-normal text-gray-700 italic"> | ||
{format(new Date(datetime), "MMM d, yyyy h:mm a")} | ||
</div> | ||
)} | ||
</div> | ||
</LocationNode> | ||
); | ||
} | ||
|
||
export function LocationTree({ | ||
location, | ||
datetime, | ||
isLatest, | ||
showTimeline = false, | ||
}: LocationPathProps) { | ||
return ( | ||
<div | ||
className={`relative flex ${showTimeline ? "gap-8 pl-12" : ""} pt-0.5`} | ||
> | ||
{showTimeline && ( | ||
<div className="absolute left-0 top-0 bottom-0 flex flex-col items-center"> | ||
<div | ||
className={`absolute w-px bg-gray-200 h-full ${isLatest ? "top-3" : "-top-3"}`} | ||
/> | ||
<div | ||
className={`h-6 w-6 rounded-full ${isLatest ? "bg-green-100" : "bg-gray-100"} flex items-center justify-center z-10`} | ||
> | ||
<CareIcon | ||
icon={isLatest ? "l-location-point" : "l-check"} | ||
className={`h-4 w-4 ${isLatest ? "text-green-600" : "text-gray-600"}`} | ||
/> | ||
</div> | ||
{!isLatest && <div className="flex-1 w-px bg-gray-200" />} | ||
</div> | ||
)} | ||
<div className="flex flex-col gap-2"> | ||
<LocationNode location={location} isLast={true} datetime={datetime} /> | ||
</div> | ||
</div> | ||
); | ||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -21,6 +21,7 @@ import { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
DropdownMenuContent, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
DropdownMenuItem, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
DropdownMenuLabel, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
DropdownMenuSeparator, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
DropdownMenuTrigger, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} from "@/components/ui/dropdown-menu"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -30,6 +31,10 @@ import { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} from "@/components/ui/popover"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { Avatar } from "@/components/Common/Avatar"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { LocationHistorySheet } from "@/components/Location/LocationHistorySheet"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { LocationTree } from "@/components/Location/LocationTree"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import useQuestionnaireOptions from "@/hooks/useQuestionnaireOptions"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { PLUGIN_Component } from "@/PluginEngine"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import routes from "@/Utils/request/api"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -50,6 +55,7 @@ export default function PatientInfoCard(props: PatientInfoCardProps) { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const { patient, encounter } = props; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const { t } = useTranslation(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const queryClient = useQueryClient(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const questionnaireOptions = useQuestionnaireOptions("encounter_actions"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const { mutate: updateEncounter } = useMutation({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
mutationFn: mutate(routes.encounter.update, { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -97,7 +103,18 @@ export default function PatientInfoCard(props: PatientInfoCardProps) { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
className="mb-2 flex flex-col text-xl font-semibold capitalize lg:hidden" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
id="patient-name-consultation" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{patient.name} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<Link | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
href={`/facility/${encounter.facility.id}/patient/${encounter.patient.id}`} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
className="text-gray-950 font-semibold flex items-start gap-0.5" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
id="patient-details" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
data-cy="patient-details-button" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{patient.name} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<CareIcon | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
icon="l-external-link-alt" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
className="w-3 h-3 opacity-50 mt-1" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</Link> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<div className="mt-[6px] text-sm font-semibold text-secondary-600"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{formatPatientAge(patient, true)} •{" "} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{t(`GENDER__${patient.gender}`)} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -111,7 +128,18 @@ export default function PatientInfoCard(props: PatientInfoCardProps) { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
className="hidden flex-row text-xl font-semibold capitalize lg:flex" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
id="patient-name-consultation" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{patient.name} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<Link | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
href={`/facility/${encounter.facility.id}/patient/${encounter.patient.id}`} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
className="text-gray-950 font-semibold flex items-start gap-0.5" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
id="patient-details" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
data-cy="patient-details-button" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{patient.name} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<CareIcon | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
icon="l-external-link-alt" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
className="w-3 h-3 opacity-50 mt-1" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
rithviknishad marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</Link> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<div className="ml-3 mr-2 mt-[6px] text-sm font-semibold text-secondary-600"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{formatPatientAge(patient, true)} •{" "} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{t(`GENDER__${patient.gender}`)} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -208,31 +236,57 @@ export default function PatientInfoCard(props: PatientInfoCardProps) { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
variant="outline" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
title={`Current Location: ${props.encounter.current_location.name}`} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<Building className="w-4 h-4 text-blue-400" /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<CareIcon | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
icon="l-location-point" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
className="h-4 w-4 text-green-600" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{props.encounter.current_location.name} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<ChevronDown className="h-3 w-3 opacity-50" /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</Badge> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</PopoverTrigger> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<PopoverContent align={"start"} className="w-auto p-2"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<div className="space-y-2"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<h4 className="font-medium text-sm"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Current Location | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</h4> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<p className="text-sm text-gray-700"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{props.encounter.current_location.name} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</p> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<p className="text-sm text-gray-500"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{props.encounter.current_location.description} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</p> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<Button variant="outline"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<Link | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
href={`/facility/${props.encounter.facility.id}/patient/${props.patient.id}/encounter/${props.encounter.id}/questionnaire/location_association`} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<div className="space-y-2 p-2 items-center"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<div className="flex items-center gap-8 justify-between"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<h4 className="font-medium text-sm"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{t("location")} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</h4> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<LocationHistorySheet | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
history={encounter.location_history} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
trigger={ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<CareIcon | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
icon="l-history" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
className="w-4 h-4 text-gray-700" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<Button | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
variant="link" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
className="text-gray-950 underline pl-1 pr-0 font-semibold" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{t("history")} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</Button> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<div className="border-b border-gray-200 my-2" /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<LocationTree | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
location={props.encounter.current_location} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<div className="border-b border-dashed border-gray-200 my-2" /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<Button | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
variant="outline" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
className="border-gray-400 w-full" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Move Patient | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</Link> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</Button> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<Link | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
href={`/facility/${props.encounter.facility.id}/patient/${props.patient.id}/encounter/${props.encounter.id}/questionnaire/location_association`} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
className="text-sm text-gray-950 font-semibold" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{t("update_location")} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</Link> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</Button> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</PopoverContent> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</Popover> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
)} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -372,6 +426,18 @@ export default function PatientInfoCard(props: PatientInfoCardProps) { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</Button> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</DropdownMenuTrigger> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<DropdownMenuContent align="end"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{questionnaireOptions.map((option) => ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<DropdownMenuItem key={option.slug} asChild> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<Link | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
href={`/facility/${encounter.facility.id}/patient/${patient.id}/encounter/${encounter.id}/questionnaire/${option.slug}`} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
className="cursor-pointer text-gray-800" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
data-cy="update-encounter-option" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{t(option.title)} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</Link> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</DropdownMenuItem> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
))} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<DropdownMenuSeparator /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Add loading state for questionnaire options. The dropdown menu should handle the loading state of questionnaire options to prevent potential UI flickers. +const questionnaireOptions = useQuestionnaireOptions("encounter_actions");
+const isLoading = !questionnaireOptions?.length;
<DropdownMenuContent align="end">
+ {isLoading ? (
+ <DropdownMenuItem disabled>
+ {t("loading_options")}
+ </DropdownMenuItem>
+ ) : (
{questionnaireOptions.map((option) => (
<DropdownMenuItem key={option.slug} asChild>
<Link
href={`/facility/${encounter.facility.id}/patient/${patient.id}/encounter/${encounter.id}/questionnaire/${option.slug}`}
className="cursor-pointer text-gray-800"
data-cy="update-encounter-option"
>
{t(option.title)}
</Link>
</DropdownMenuItem>
))}
+ )}
<DropdownMenuSeparator /> 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<DropdownMenuLabel>{t("actions")}</DropdownMenuLabel> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<DropdownMenuItem onClick={handleMarkAsComplete}> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{t("mark_as_complete")} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Use stable keys for list items instead of array indices.
Using array indices as keys can lead to performance issues and bugs when items are reordered or removed.