From 1d07cad46039c961d7fbe09e856326fceaa73853 Mon Sep 17 00:00:00 2001 From: BigSimmo <87357024+BigSimmo@users.noreply.github.com> Date: Sat, 18 Jul 2026 03:26:17 +0800 Subject: [PATCH 1/5] fix: place cross-mode matches after results --- .../clinical-dashboard/differentials-home.tsx | 3 ++- .../document-search-results.tsx | 5 ++++- .../favourites-command-library-page.tsx | 4 ++-- .../medication-prescribing-workspace.tsx | 3 ++- .../forms/forms-search-results-page.tsx | 2 +- .../formulation/formulation-home-page.tsx | 4 ++-- .../services/services-navigator-page.tsx | 2 +- tests/ui-universal-search.spec.ts | 16 ++++++++++++++++ 8 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/components/clinical-dashboard/differentials-home.tsx b/src/components/clinical-dashboard/differentials-home.tsx index 4c7abba05..209055fe2 100644 --- a/src/components/clinical-dashboard/differentials-home.tsx +++ b/src/components/clinical-dashboard/differentials-home.tsx @@ -883,7 +883,6 @@ function SearchResultsView({ sortValue={sortValue} onSortChange={setSortValue} /> -

) : null} + +

Clinical decision support only. Review before use.

diff --git a/src/components/clinical-dashboard/document-search-results.tsx b/src/components/clinical-dashboard/document-search-results.tsx index dce916dba..325a16833 100644 --- a/src/components/clinical-dashboard/document-search-results.tsx +++ b/src/components/clinical-dashboard/document-search-results.tsx @@ -896,7 +896,6 @@ function DocumentSearchResultsPanelImpl({ onSortChange={setSortValue} /> - ) : null} {recordMatchCount > 0 || @@ -1140,6 +1139,10 @@ function DocumentSearchResultsPanelImpl({ )} + + {trimmedQuery && !shouldShowHome ? ( + + ) : null} ); } diff --git a/src/components/clinical-dashboard/favourites-command-library-page.tsx b/src/components/clinical-dashboard/favourites-command-library-page.tsx index 1499d88f9..674876d90 100644 --- a/src/components/clinical-dashboard/favourites-command-library-page.tsx +++ b/src/components/clinical-dashboard/favourites-command-library-page.tsx @@ -1005,8 +1005,6 @@ export function FavouritesCommandLibraryPage({ query = "" }: { query?: string })
- - )} + + -

Medication search

@@ -693,6 +692,8 @@ function MedicationResults({ })}
+ +
- {query.trim() && displayedMatches.length === 0 ? ( )} + ) : null}
diff --git a/src/components/formulation/formulation-home-page.tsx b/src/components/formulation/formulation-home-page.tsx index 9c41a5cdd..fe7ebc23c 100644 --- a/src/components/formulation/formulation-home-page.tsx +++ b/src/components/formulation/formulation-home-page.tsx @@ -202,8 +202,6 @@ function FormulationResults({ query }: { query: string }) {

- -
)} + + ); diff --git a/src/components/services/services-navigator-page.tsx b/src/components/services/services-navigator-page.tsx index 87b090573..04e1fe09a 100644 --- a/src/components/services/services-navigator-page.tsx +++ b/src/components/services/services-navigator-page.tsx @@ -514,7 +514,6 @@ export function ServicesNavigatorPage() { sortValue={sortValue} onSortChange={setSortValue} /> - } sidebar={ @@ -643,6 +642,7 @@ export function ServicesNavigatorPage() {
)} + ); } diff --git a/tests/ui-universal-search.spec.ts b/tests/ui-universal-search.spec.ts index 478c4e982..5e582d751 100644 --- a/tests/ui-universal-search.spec.ts +++ b/tests/ui-universal-search.spec.ts @@ -228,6 +228,22 @@ test.describe("universal search typeahead", () => { expect(new URL((await universalRequest).url()).searchParams.get("domains")?.split(",")).not.toContain("services"); }); + test("places submitted cross-mode matches after the owning mode results", async ({ page }) => { + await mockUniversalSearch(page); + await page.goto("/services?q=acamprosate&run=1", { waitUntil: "domcontentloaded" }); + + const results = page.getByTestId("service-search-results"); + const alsoMatches = page.getByTestId("universal-also-matches"); + await expect(results).toBeVisible(); + await expect(alsoMatches).toBeVisible(); + expect( + await alsoMatches.evaluate((node) => { + const resultNode = document.querySelector('[data-testid="service-search-results"]'); + return Boolean(resultNode?.compareDocumentPosition(node) & Node.DOCUMENT_POSITION_FOLLOWING); + }), + ).toBe(true); + }); + test("shows submitted cross-mode matches on phones outside hidden desktop headers", async ({ page }) => { await page.setViewportSize({ width: 390, height: 844 }); await mockUniversalSearch(page); From 62c830df0ab42661696fa973faff4bd854e8eeb7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 17 Jul 2026 19:47:54 +0000 Subject: [PATCH 2/5] test: add descriptive failure message to DOM-order assertion --- tests/ui-universal-search.spec.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/ui-universal-search.spec.ts b/tests/ui-universal-search.spec.ts index 5e582d751..f764bc79b 100644 --- a/tests/ui-universal-search.spec.ts +++ b/tests/ui-universal-search.spec.ts @@ -241,6 +241,7 @@ test.describe("universal search typeahead", () => { const resultNode = document.querySelector('[data-testid="service-search-results"]'); return Boolean(resultNode?.compareDocumentPosition(node) & Node.DOCUMENT_POSITION_FOLLOWING); }), + "universal-also-matches panel must appear after primary results in the DOM", ).toBe(true); }); From 1cdf3dfd26e1616ac32f1f290832ab0ced405b28 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 17 Jul 2026 19:53:24 +0000 Subject: [PATCH 3/5] fix: resolve TS2532 null-safety error in DOM-order assertion --- tests/ui-universal-search.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ui-universal-search.spec.ts b/tests/ui-universal-search.spec.ts index f764bc79b..bbd060af8 100644 --- a/tests/ui-universal-search.spec.ts +++ b/tests/ui-universal-search.spec.ts @@ -239,7 +239,7 @@ test.describe("universal search typeahead", () => { expect( await alsoMatches.evaluate((node) => { const resultNode = document.querySelector('[data-testid="service-search-results"]'); - return Boolean(resultNode?.compareDocumentPosition(node) & Node.DOCUMENT_POSITION_FOLLOWING); + return Boolean((resultNode?.compareDocumentPosition(node) ?? 0) & Node.DOCUMENT_POSITION_FOLLOWING); }), "universal-also-matches panel must appear after primary results in the DOM", ).toBe(true); From 35980ccd150527a4daa310d858dc28f3cdb839fc Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Fri, 17 Jul 2026 19:57:20 +0000 Subject: [PATCH 4/5] fix: format document-search-results.tsx (prettier) --- src/components/clinical-dashboard/document-search-results.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/components/clinical-dashboard/document-search-results.tsx b/src/components/clinical-dashboard/document-search-results.tsx index 325a16833..41889eb73 100644 --- a/src/components/clinical-dashboard/document-search-results.tsx +++ b/src/components/clinical-dashboard/document-search-results.tsx @@ -1140,9 +1140,7 @@ function DocumentSearchResultsPanelImpl({ )} - {trimmedQuery && !shouldShowHome ? ( - - ) : null} + {trimmedQuery && !shouldShowHome ? : null} ); } From 7c0952e9a928706ebc16cadd8a8d86adee565a1b Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Fri, 17 Jul 2026 19:57:29 +0000 Subject: [PATCH 5/5] fix(test): use service-matching query in placement test and fix TS2532 The placement test navigated to /services?q=acamprosate&run=1. Since 'acamprosate' matches no service fixtures, displayedMatches is empty and the empty-state renders instead of the service-search-results div, causing expect(results).toBeVisible() to time out. Fix: route the test through an inline mock that echoes the request query back as the universal-search response query (so universal-also-matches renders), and navigate to q=13YARN which matches the demo service fixture records so service-search-results is present. Also fixes pre-existing TS2532: add ?? 0 fallback before the bitwise & to resolve the 'Object is possibly undefined' error from optional chaining. --- tests/ui-universal-search.spec.ts | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/tests/ui-universal-search.spec.ts b/tests/ui-universal-search.spec.ts index bbd060af8..eca054788 100644 --- a/tests/ui-universal-search.spec.ts +++ b/tests/ui-universal-search.spec.ts @@ -229,8 +229,21 @@ test.describe("universal search typeahead", () => { }); test("places submitted cross-mode matches after the owning mode results", async ({ page }) => { - await mockUniversalSearch(page); - await page.goto("/services?q=acamprosate&run=1", { waitUntil: "domcontentloaded" }); + // "13YARN" matches the demo service fixture so service-search-results renders. + // Use an inline mock that echoes back the same query so universal-also-matches renders. + await page.route(/\/api\/search\/universal(?:\?.*)?$/, async (route) => { + const url = new URL(route.request().url()); + const mode = url.searchParams.get("mode") ?? "services"; + const q = url.searchParams.get("q") ?? "13YARN"; + await fulfillUniversalSearch(route, { + ...universalPayload, + query: q, + contextMode: mode, + preferredDomains: [], + domainOrder: universalPayload.groups.map((g) => g.kind), + }); + }); + await page.goto("/services?q=13YARN&run=1", { waitUntil: "domcontentloaded" }); const results = page.getByTestId("service-search-results"); const alsoMatches = page.getByTestId("universal-also-matches");