-
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 6 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,96 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { format } from "date-fns"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import CareIcon from "@/CAREUI/icons/CareIcon"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { LocationList } from "@/types/location/location"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
interface LocationPathProps { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
location: LocationList; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
datetime?: string; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
isLatest?: boolean; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
showTimeline?: boolean; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
function getLocationHierarchy(location: LocationList): LocationList[] { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const hierarchy: LocationList[] = []; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
let current: LocationList | undefined = location; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
while (current?.id) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
hierarchy.unshift(current); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
current = current.parent; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return hierarchy; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
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. Add safety check for circular references in getLocationHierarchy. The while loop could potentially run indefinitely if there's a circular reference in the location hierarchy. function getLocationHierarchy(location: LocationList): LocationList[] {
const hierarchy: LocationList[] = [];
let current: LocationList | undefined = location;
+ const visited = new Set<string>();
while (current?.id) {
+ if (visited.has(current.id)) {
+ console.error('Circular reference detected in location hierarchy');
+ break;
+ }
+ visited.add(current.id);
hierarchy.unshift(current);
current = current.parent;
} 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
export function LocationTree({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
location, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
datetime, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
isLatest, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
showTimeline = false, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}: LocationPathProps) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const hierarchy = getLocationHierarchy(location); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<div | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
className={`relative flex ${showTimeline ? "gap-8 pl-12" : ""} pb-4 pt-0.5`} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{showTimeline && ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<div className="absolute left-0 top-0 bottom-0 flex flex-col items-center"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<div | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
className={`absolute w-[1px] bg-gray-200 h-full ${isLatest ? "top-3" : "-top-3"}`} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
amjithtitus09 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{isLatest ? ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<div className="h-6 w-6 rounded-full bg-green-100 flex items-center justify-center z-10"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<CareIcon | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
icon="l-location-point" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
className="h-4 w-4 text-green-600" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) : ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<div className="h-6 w-6 rounded-full bg-gray-100 flex items-center justify-center z-10"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<CareIcon icon="l-check" className="h-4 w-4 text-gray-600" /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
)} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{!isLatest && <div className="flex-1 w-[1px] bg-gray-200" />} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
amjithtitus09 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
)} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<div className="flex flex-col gap-3"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{hierarchy.map((loc, index) => ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<div key={loc.id}> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<div | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
className="flex items-center text-sm" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
style={{ paddingLeft: `${index * 24}px` }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{index === 0 ? ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<span className="w-2 h-2 rounded-full bg-gray-400 mr-2" /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) : ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<CareIcon | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
icon="l-corner-down-right" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
className="w-4 h-4 mr-2 mb-1 text-gray-400" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
)} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<span | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
className={ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
index === hierarchy.length - 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
? "font-semibold" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
: "text-gray-700 font-medium" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{loc.name} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</span> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{index === hierarchy.length - 1 && datetime && ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<div | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
className="flex items-center text-sm font-normal text-gray-700 italic" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
style={{ paddingLeft: `${index * 24 + 24}px` }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{format(new Date(datetime), "MMM d, yyyy h:mm a")} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
amjithtitus09 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
)} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
rithviknishad marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
))} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</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`} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<PopoverContent align={"start"} className="w-auto p-2"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
amjithtitus09 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<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.