diff --git a/src/components/clinical-dashboard/differentials-home.tsx b/src/components/clinical-dashboard/differentials-home.tsx index dcc9caa09..3042f07ba 100644 --- a/src/components/clinical-dashboard/differentials-home.tsx +++ b/src/components/clinical-dashboard/differentials-home.tsx @@ -30,6 +30,7 @@ import { useDifferentialSearch } from "@/components/clinical-dashboard/use-diffe import { useResultSort } from "@/components/use-result-sort"; import { cn } from "@/components/ui-primitives"; import { appModeHomeHref } from "@/lib/app-modes"; +import { differentialRouteWithQuery, differentialSelectedCompareHref } from "@/lib/differentials-navigation"; import { differentialsMobileCompareAddonSlotId } from "@/lib/mode-home-composer"; import { composeDifferentialSearchResults, @@ -111,17 +112,6 @@ const candidateIconBySlug: Array<[string, LucideIcon]> = [ ["delirium", BrainCircuit], ]; -function routeWithQuery(path: string, query: string, selectedIds?: Set) { - const params = new URLSearchParams(); - const trimmedQuery = query.trim(); - if (trimmedQuery) params.set("q", trimmedQuery); - if (selectedIds && selectedIds.size > 0) { - params.set("ids", Array.from(selectedIds).join(",")); - } - const suffix = params.toString(); - return suffix ? `${path}?${suffix}` : path; -} - /** * Mobile/tablet floating compare action. Portals into the search composer's * addon slot so it stays anchored beside the active result controls, but @@ -162,7 +152,7 @@ function DifferentialsMobileCompareBar({
{hasSelection ? ( @@ -599,7 +589,7 @@ function SafetyCard({ safety, query }: { safety: string; query: string }) {

{safety}

View presentation guide @@ -929,14 +919,14 @@ function SearchResultsView({

Browse presentations Browse diagnoses @@ -1097,7 +1087,7 @@ function SearchResultsView({
View all catalogue matches ({results.length}) @@ -1106,7 +1096,7 @@ function SearchResultsView({ {selectedCount > 0 ? ( @@ -1205,12 +1195,12 @@ export function DifferentialsHome({ function handleAction(action: DifferentialAction) { if (action.target === "presentations") { if (onOpenPresentations) onOpenPresentations(action.query); - else router.push(routeWithQuery("/differentials/presentations", action.query)); + else router.push(differentialRouteWithQuery("/differentials/presentations", action.query)); return; } if (action.target === "diagnoses") { if (onOpenDiagnoses) onOpenDiagnoses(action.query); - else router.push(routeWithQuery("/differentials/diagnoses", action.query)); + else router.push(differentialRouteWithQuery("/differentials/diagnoses", action.query)); return; } runSearch(action.query); diff --git a/src/lib/differentials-navigation.ts b/src/lib/differentials-navigation.ts new file mode 100644 index 000000000..cbd465a18 --- /dev/null +++ b/src/lib/differentials-navigation.ts @@ -0,0 +1,20 @@ +import { getPresentationWorkflowSelectionForDiagnosisIds } from "@/lib/differentials"; + +export function differentialRouteWithQuery(path: string, query: string, selectedIds?: Iterable) { + const params = new URLSearchParams(); + const trimmedQuery = query.trim(); + if (trimmedQuery) params.set("q", trimmedQuery); + const ids = selectedIds ? Array.from(selectedIds, (id) => id.trim()).filter(Boolean) : []; + if (ids.length > 0) params.set("ids", ids.join(",")); + const suffix = params.toString(); + return suffix ? `${path}?${suffix}` : path; +} + +export function differentialSelectedCompareHref(query: string, selectedIds: Iterable) { + const selection = getPresentationWorkflowSelectionForDiagnosisIds(selectedIds); + return differentialRouteWithQuery( + `/differentials/presentations/${selection?.workflow.id ?? "acute-confusion-encephalopathy"}`, + query, + selection?.diagnosisIds, + ); +} diff --git a/tests/differentials-navigation.test.ts b/tests/differentials-navigation.test.ts new file mode 100644 index 000000000..42e2dee0f --- /dev/null +++ b/tests/differentials-navigation.test.ts @@ -0,0 +1,20 @@ +import { describe, expect, it } from "vitest"; + +import { differentialRouteWithQuery, differentialSelectedCompareHref } from "@/lib/differentials-navigation"; + +describe("differentials navigation", () => { + it("builds same-origin relative query routes", () => { + expect(differentialRouteWithQuery("/differentials/diagnoses", " acute confusion ")).toBe( + "/differentials/diagnoses?q=acute+confusion", + ); + }); + + it("wires selected comparison directly to a presentation page instead of the redirect endpoint", () => { + const href = differentialSelectedCompareHref("Pain", new Set(["anorexia-nervosa", "bulimia-nervosa-binge-purge-pattern"])); + + expect(href).toMatch(/^\/differentials\/presentations\/[^?]+\?/); + expect(href).toContain("q=Pain"); + expect(href).toContain("ids=anorexia-nervosa%2Cbulimia-nervosa-binge-purge-pattern"); + expect(href).not.toContain("0.0.0.0"); + }); +});