From 5baf75eb5c5ce642ba5eba66523c4dbd5024166d Mon Sep 17 00:00:00 2001 From: BigSimmo <87357024+BigSimmo@users.noreply.github.com> Date: Sat, 25 Jul 2026 04:46:58 +0800 Subject: [PATCH 1/4] feat(search): unify result filters and source browsing --- .../(search-app)/documents/search/page.tsx | 6 +- src/components/ClinicalDashboard.tsx | 34 +-- src/components/applications-launcher-page.tsx | 45 ++-- .../clinical-dashboard/dashboard-shell.tsx | 13 +- .../clinical-dashboard/differentials-home.tsx | 17 +- .../clinical-dashboard/document-admin.tsx | 21 +- .../document-search-results.tsx | 220 +++++++----------- .../favourites-command-library-page.tsx | 39 ++-- .../medication-prescribing-workspace.tsx | 11 +- .../clinical-dashboard/mode-action-popup.tsx | 6 +- .../search-results-header-band.tsx | 43 +++- src/components/dsm/dsm-search-page.tsx | 61 ++--- .../factsheets/factsheets-search-page.tsx | 127 +++++----- .../forms/forms-search-results-page.tsx | 29 +-- .../formulation/formulation-home-page.tsx | 89 ++++--- .../services/services-navigator-page.tsx | 93 ++++---- .../specifiers/specifiers-home-page.tsx | 33 ++- .../therapy-compass/screens/search-screen.tsx | 86 +++---- tests/search-results-header-band.dom.test.tsx | 45 +++- tests/ui-accessibility.spec.ts | 11 +- tests/ui-formulation.spec.ts | 8 +- tests/ui-smoke.spec.ts | 94 ++++++-- tests/ui-specifiers.spec.ts | 8 +- tests/ui-stress.spec.ts | 2 +- tests/ui-tools.spec.ts | 12 +- 25 files changed, 630 insertions(+), 523 deletions(-) diff --git a/src/app/(search-app)/documents/search/page.tsx b/src/app/(search-app)/documents/search/page.tsx index 378cd483b..204caee4c 100644 --- a/src/app/(search-app)/documents/search/page.tsx +++ b/src/app/(search-app)/documents/search/page.tsx @@ -9,12 +9,12 @@ export default function DocumentsSearchRoute() { return (

- Indexed library + Indexed sources

Search clinical documents

- Enter a query in the Documents composer to search the live indexed library. Results open the source document at - the matching page and passage. + Enter a query in the Documents composer to search the indexed sources. Results open the source document at the + matching page and passage.

); diff --git a/src/components/ClinicalDashboard.tsx b/src/components/ClinicalDashboard.tsx index b8bb4a620..8bc203ff6 100644 --- a/src/components/ClinicalDashboard.tsx +++ b/src/components/ClinicalDashboard.tsx @@ -508,6 +508,7 @@ export function ClinicalDashboard({ const [mobileSidebarOpen, setMobileSidebarOpen] = useState(false); const [sidebarCollapsed, setSidebarCollapsed] = useSidebarCollapsed(); const [documentsDrawerOpen, setDocumentsDrawerOpen] = useState(false); + const documentsDrawerReturnFocusRef = useRef(null); const [documentScopeOpen, setDocumentScopeOpen] = useState(false); const [documentsDrawerMode, setDocumentsDrawerMode] = useState("library"); const [uploadDrawerOpen, setUploadDrawerOpen] = useState(false); @@ -2659,18 +2660,13 @@ export function ClinicalDashboard({ } function openDocumentsDrawer(mode: DocumentDrawerMode) { + documentsDrawerReturnFocusRef.current = + document.activeElement instanceof HTMLElement ? document.activeElement : null; closeDashboardTransientSurfaces("documents"); setSearchMode("documents"); setDocumentDrawerStatusFilter("indexed"); setDocumentsDrawerMode(mode); setDocumentsDrawerOpen(true); - if (window.matchMedia("(min-width: 1024px)").matches) { - window.requestAnimationFrame(() => { - document - .getElementById("dashboard-documents-drawer") - ?.scrollIntoView({ block: "start", behavior: resolveScrollBehavior() }); - }); - } } function openRecentDocuments() { @@ -2690,7 +2686,7 @@ export function ClinicalDashboard({ openDocumentsDrawer("library"); setActionNotice({ tone: "warning", - message: "Upload and indexing tools are admin-only. Use the source library to open indexed documents.", + message: "Upload and indexing tools are admin-only. Use Sources to open indexed documents.", }); return; } @@ -3193,7 +3189,7 @@ export function ClinicalDashboard({ ? "Source PDFs" : documentsDrawerIsAdmin ? "Document admin" - : "Source library"; + : "Sources"; const documentsDrawerSummary = dashboardDataLoading ? "Loading indexed document status." : documentsDrawerMode === "recent" @@ -3204,14 +3200,14 @@ export function ClinicalDashboard({ ? `${indexedDocumentTotal.toLocaleString()} indexed documents available.` : "Search and open indexed clinical sources."; const documentsDrawerMobileSummary = dashboardDataLoading - ? "Loading library" + ? "Loading sources" : documentsDrawerMode === "recent" ? "Recent sources" : documentsDrawerMode === "source" ? "PDF sources" : documentsDrawerIsAdmin ? "Admin" - : "Library"; + : "Sources"; const DocumentsDrawerIcon = documentsDrawerMode === "recent" ? Clock3 @@ -3220,7 +3216,7 @@ export function ClinicalDashboard({ : documentsDrawerIsAdmin ? UploadCloud : FolderOpen; - const drawerGroupTitle = uploadDrawerOpen || documentsDrawerIsAdmin ? "Library and admin" : "Sources"; + const drawerGroupTitle = uploadDrawerOpen || documentsDrawerIsAdmin ? "Sources and admin" : "Sources"; // Stable-identity handlers for the React.memo children (StagedAnswerResultSurface, // DocumentSearchResultsPanel). These close over the draft `query` or call the @@ -3236,6 +3232,15 @@ export function ClinicalDashboard({ const handleDocumentTagSearch = useEventCallback(handleTagSearch); const handleOpenRecentDocuments = useEventCallback(openRecentDocuments); const handleOpenSourceLibrary = useEventCallback(openSourceLibrary); + const handleDocumentsDrawerOpenChange = useEventCallback((nextOpen: boolean) => { + setDocumentsDrawerOpen(nextOpen); + if (nextOpen) return; + + const returnTarget = documentsDrawerReturnFocusRef.current; + window.requestAnimationFrame(() => { + if (returnTarget?.isConnected) returnTarget.focus({ preventScroll: true }); + }); + }); const handleOpenSourcePdfBrowser = useEventCallback(openSourcePdfBrowser); const handleCopyAnswer = useEventCallback(() => { copyText("answer", answerRenderModel?.copyText || safeAnswerText || answer?.answer || ""); @@ -3828,8 +3833,9 @@ export function ClinicalDashboard({ summary={documentsDrawerSummary} mobileSummary={documentsDrawerMobileSummary} open={documentsDrawerOpen} - onOpenChange={setDocumentsDrawerOpen} - sheetBreakpoint="lg" + onOpenChange={handleDocumentsDrawerOpenChange} + sheetBreakpoint={documentsDrawerIsAdmin ? "lg" : "all"} + sheetReturnFocusRef={documentsDrawerReturnFocusRef} sheetHeaderLeading={