-
- Differential matches
-
-
- {sortValue === "alpha"
- ? "Sorted A–Z; the best relevance match remains marked."
- : hasSourceEvidence
- ? `${reviewedSourceCount.toLocaleString()} indexed source ${reviewedSourceCount === 1 ? "match" : "matches"}. Review before use.`
- : sourcesChecked
- ? "No indexed source matches. Catalogue order is unchanged."
- : "Ranked from the imported catalogue; indexed sources are not checked yet."}
-
-
- {!hasSourceEvidence && !sourcesChecked ? (
-
- ) : sourcesChecked && !hasSourceEvidence ? (
-
-
- No indexed source matches
+
+ {safetyLead?.safety ? (
+
+
+
+ Safety first:
+ {safetyLead.safety}
+
+
+ ) : null}
+
+
+
+
+
+ Differential matches
+
+
+ {sortValue === "alpha"
+ ? "Sorted A–Z; the best relevance match remains marked."
+ : hasSourceEvidence
+ ? `${reviewedSourceCount.toLocaleString()} indexed source ${reviewedSourceCount === 1 ? "match" : "matches"}. Review before use.`
+ : sourcesChecked
+ ? "No indexed source matches. Catalogue order is unchanged."
+ : "Ranked from the imported catalogue; indexed sources are not checked yet."}
- ) : null}
+
+
+ {!hasSourceEvidence && !sourcesChecked ? (
+
+ ) : sourcesChecked && !hasSourceEvidence ? (
+
+
+ No indexed source matches
+
+ ) : null}
+
-
-
-
toggleSelected(best.id) : undefined}
- />
- {safetyLead?.safety ? (
-
-
-
- Safety first:
- {safetyLead.safety}
-
-
- ) : null}
- {hasSourceEvidence ? (
-
-
-
- {reviewedSourceCount.toLocaleString()} indexed source{" "}
- {reviewedSourceCount === 1 ? "match" : "matches"}
-
-
- ) : loading ? (
-
-
-
- Checking indexed sources…
-
-
- ) : !sourcesChecked ? (
-
-
-
+
+
toggleSelected(best.id) : undefined}
+ />
+ {hasSourceEvidence ? (
+
+
- Sources not checked
+ {reviewedSourceCount.toLocaleString()} indexed source{" "}
+ {reviewedSourceCount === 1 ? "match" : "matches"}
-
-
-
- ) : (
-
-
-
- No indexed source matches
-
-
- )}
-
-
-
- {visibleResults.map((result, displayIndex) => {
- // Best-match styling remains tied to relevance while the row
- // number follows the user's chosen presentation order.
- const isBest = result.kind === best.kind && result.id === best.id;
- // The featured card owns rank 1 on phones. Continue the
- // remaining visible sequence at 2 without leaving a gap when
- // the best match moves under A-Z presentation order.
- const precedingNonBestResults = visibleResults
- .slice(0, displayIndex)
- .filter((candidate) => candidate.kind !== best.kind || candidate.id !== best.id);
- const mobileIndex = precedingNonBestResults.length + 1;
- return (
- // The best answer is already featured above the phone list,
- // so its ranked duplicate only renders from the desktop
- // breakpoint (hiding the wrapper keeps the grid gap clean).
-
-
- {isBest ? (
-
toggleSelected(result.id) : undefined}
- />
- ) : (
- toggleSelected(result.id) : undefined}
- />
- )}
+
+
+ Checking indexed sources…
+
+
+ ) : !sourcesChecked ? (
+
+
+
+
+ Sources not checked
+
- {!isBest ? (
-
- toggleSelected(result.id) : undefined}
- />
-
- ) : null}
-
- );
- })}
-
+
+
+ ) : (
+
+
+
+ No indexed source matches
+
+
+ )}
+
-
- View all catalogue matches ({results.length})
-
-
+
+ {visibleResults.map((result, displayIndex) => {
+ // Best-match styling remains tied to relevance while the row
+ // number follows the user's chosen presentation order.
+ const isBest = result.kind === best.kind && result.id === best.id;
+ // The featured card owns rank 1 on phones. Continue the
+ // remaining visible sequence at 2 without leaving a gap when
+ // the best match moves under A-Z presentation order.
+ const precedingNonBestResults = visibleResults
+ .slice(0, displayIndex)
+ .filter((candidate) => candidate.kind !== best.kind || candidate.id !== best.id);
+ const mobileIndex = precedingNonBestResults.length + 1;
+ return (
+ // The best answer is already featured above the phone list,
+ // so its ranked duplicate only renders from the desktop
+ // breakpoint (hiding the wrapper keeps the grid gap clean).
+
+
+ {isBest ? (
+ toggleSelected(result.id) : undefined}
+ />
+ ) : (
+ toggleSelected(result.id) : undefined}
+ />
+ )}
+
+ {!isBest ? (
+
+ toggleSelected(result.id) : undefined}
+ />
+
+ ) : null}
+
+ );
+ })}
+
- {selectedCount > 0 ? (
-
- Compare selected
-
- {selectedCount}
-
-
+ View all catalogue matches ({results.length})
+
- ) : (
-
-
- Tick results to compare them side by side
-
- )}
-
-
+ {selectedCount > 0 ? (
+
+
+ Compare selected
+
+ {selectedCount}
+
+
+
+ ) : (
+
+
+ Tick results to compare them side by side
+
+ )}
+
+
+
+
)}
diff --git a/tests/differentials-compare-selection.dom.test.tsx b/tests/differentials-compare-selection.dom.test.tsx
index 75ea0f2dc..b8d295a27 100644
--- a/tests/differentials-compare-selection.dom.test.tsx
+++ b/tests/differentials-compare-selection.dom.test.tsx
@@ -165,6 +165,65 @@ describe("DifferentialsHome compare selection URL handoff", () => {
expect(screen.getAllByText("Anorexia nervosa").length).toBeGreaterThan(0);
});
+ it("narrows by clinical urgency independently of result type, and clears both together", async () => {
+ const emergent = getDifferentialRecord("medical-gi-endocrine-painful-organic-cause");
+ const urgent = getDifferentialRecord("acute-dystonia");
+ expect(emergent?.status).toBe("emergent");
+ expect(urgent?.status).toBe("urgent");
+ catalogState.status = "ready";
+ catalogState.matches = {
+ diagnoses: [
+ { record: emergent!, score: 20, reasons: ["title"] },
+ { record: urgent!, score: 12, reasons: ["title"] },
+ ],
+ presentations: [],
+ };
+
+ render(
);
+
+ await waitFor(() => {
+ expect(screen.getAllByText(emergent!.title).length).toBeGreaterThan(0);
+ expect(screen.getAllByText(urgent!.title).length).toBeGreaterThan(0);
+ });
+
+ await act(async () => {
+ screen.getByTestId("differential-filter-trigger-phone").click();
+ });
+ expect(screen.getByRole("heading", { name: "Clinical urgency" })).toBeVisible();
+ await act(async () => {
+ screen.getByRole("radio", { name: "Emergent (1)" }).click();
+ });
+ await act(async () => {
+ screen.getByTestId("differential-filter-panel-done").click();
+ });
+
+ expect(screen.getAllByText(emergent!.title).length).toBeGreaterThan(0);
+ expect(screen.queryByText(urgent!.title)).not.toBeInTheDocument();
+
+ // A no-longer-active urgency filter narrowing the result type to zero
+ // reports the combined reason, not just the result-type half of it.
+ await act(async () => {
+ screen.getByTestId("differential-filter-trigger-phone").click();
+ });
+ await act(async () => {
+ screen.getByRole("radio", { name: "Presentations (0)" }).click();
+ });
+ await act(async () => {
+ screen.getByTestId("differential-filter-panel-done").click();
+ });
+ expect(
+ screen.getByRole("heading", { name: "No presentations at Emergent priority in this result set" }),
+ ).toBeVisible();
+
+ await act(async () => {
+ screen.getByRole("button", { name: "Show all results" }).click();
+ });
+
+ expect(screen.queryByTestId("differentials-filter-empty-results")).not.toBeInTheDocument();
+ expect(screen.getAllByText(emergent!.title).length).toBeGreaterThan(0);
+ expect(screen.getAllByText(urgent!.title).length).toBeGreaterThan(0);
+ });
+
it("keeps the submitted query when opening a presentation comparison", async () => {
const presentation = getPresentationWorkflow("acute-confusion-encephalopathy");
expect(presentation).toBeTruthy();