diff --git a/src/app/globals.css b/src/app/globals.css index 8972d62e2..de9009a47 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -1606,53 +1606,6 @@ summary::-webkit-details-marker { white-space: nowrap; } -/* Quick actions on the answer home — deliberately lighter than the recent / - prompt pills so the two rows read as distinct tiers (content vs. actions). */ -.answer-quick-actions { - display: flex; - min-height: 1.75rem; - align-items: center; - justify-content: center; - gap: 0.875rem; -} - -.answer-quick-action { - display: inline-flex; - align-items: center; - gap: 0.375rem; - border: 0; - background: transparent; - padding: 0.25rem; - color: var(--text-soft); - font-size: 0.75rem; - font-weight: 600; - line-height: 1.25rem; - transition: color 160ms ease; -} - -.answer-quick-action:hover { - color: var(--clinical-accent); -} - -.answer-quick-action:focus-visible { - border-radius: var(--radius-sm); - outline: 2px solid var(--focus); - outline-offset: 2px; -} - -.answer-quick-action-icon { - width: 0.9375rem; - height: 0.9375rem; - flex-shrink: 0; -} - -.answer-quick-action-divider { - width: 1px; - height: 0.75rem; - flex-shrink: 0; - background: var(--border); -} - .answer-footer-search-edge .answer-suggestion-row { padding-inline: 0.25rem; } diff --git a/src/components/ClinicalDashboard.tsx b/src/components/ClinicalDashboard.tsx index 1b2faa658..4e9e6963d 100644 --- a/src/components/ClinicalDashboard.tsx +++ b/src/components/ClinicalDashboard.tsx @@ -3961,8 +3961,6 @@ export function ClinicalDashboard({ ) : null ) : showAnswerHome ? ( setSearchMode("documents")} - onUploadDocument={openUploadDrawer} desktopComposerSlotId={desktopHomeComposerSlotId} recentQueries={recentQueries} onSelectRecent={(recentQuery) => { diff --git a/src/components/clinical-dashboard/answer-status.tsx b/src/components/clinical-dashboard/answer-status.tsx index 88389fd05..bd4097c79 100644 --- a/src/components/clinical-dashboard/answer-status.tsx +++ b/src/components/clinical-dashboard/answer-status.tsx @@ -8,10 +8,8 @@ import { History, Loader2, MessageSquareText, - Search, ShieldCheck, Square, - Upload, } from "lucide-react"; import { useEffect, useState } from "react"; @@ -59,14 +57,10 @@ export function CopyButton({ } export function AnswerEmptyState({ - onSearchDocuments, - onUploadDocument, desktopComposerSlotId, recentQueries = [], onSelectRecent, }: { - onSearchDocuments: () => void; - onUploadDocument: () => void; desktopComposerSlotId?: string; recentQueries?: string[]; onSelectRecent?: (query: string) => void; @@ -104,20 +98,6 @@ export function AnswerEmptyState({ icon={History} /> )} - {/* Quick actions are secondary to the composer above, so they read as - light text links (not pills) with a hairline divider — this also - breaks the visual repetition of stacked equal-weight chip rows. */} -
- -
{/* No privacy link here: the composer's PrivacyInputNotice is the single site-wide notice, so the hero footer must not repeat it. */} {/* Pre-query copy must describe what the search does, not assert that diff --git a/src/lib/ui-copy.ts b/src/lib/ui-copy.ts index c82ee02fb..6a16f1844 100644 --- a/src/lib/ui-copy.ts +++ b/src/lib/ui-copy.ts @@ -16,23 +16,7 @@ export const answerEmptyState = { heading: "How can I help?", subheading: "Ask a clinical question or search your documents.", starterActionsLabel: "Starter actions", - quickActionsLabel: "Quick actions", recentLabel: "Recent searches", - starters: { - ask: { - title: "Ask a question", - description: "Start a source-backed clinical answer.", - samplePrompt: "What monitoring and escalation issues should I consider across these documents?", - }, - searchDocuments: { - title: "Search documents", - description: "Browse matching files and source sections.", - }, - uploadDocument: { - title: "Upload document", - description: "Add a guideline, PDF, or local source.", - }, - }, } as const; // Recovery copy for the answer flow — actions and calm no-results guidance shown diff --git a/tests/answer-preferences.dom.test.tsx b/tests/answer-preferences.dom.test.tsx index 6f13fb75e..2b933093f 100644 --- a/tests/answer-preferences.dom.test.tsx +++ b/tests/answer-preferences.dom.test.tsx @@ -18,12 +18,7 @@ function storePreferences(overrides: Record) { function renderEmptyState() { return render( - {}} - onUploadDocument={() => {}} - recentQueries={["clozapine monitoring", "lithium levels"]} - onSelectRecent={vi.fn()} - />, + , ); } diff --git a/tests/mobile-interaction-regressions.test.ts b/tests/mobile-interaction-regressions.test.ts index affd2c444..1fde939a4 100644 --- a/tests/mobile-interaction-regressions.test.ts +++ b/tests/mobile-interaction-regressions.test.ts @@ -42,11 +42,9 @@ describe("mobile interaction regressions", () => { ); }); - it("keeps phone quick actions and the privacy link at the semantic tap size", () => { - const answerSource = source("src/components/clinical-dashboard/answer-status.tsx"); + it("keeps the privacy link at the semantic tap size", () => { const privacySource = source("src/components/privacy-input-notice.tsx"); - expect(answerSource.match(/answer-quick-action min-h-tap sm:min-h-7/g)).toHaveLength(2); expect(privacySource).toContain("inline-flex min-h-tap items-center"); expect(privacySource).toContain("sm:min-h-0"); }); diff --git a/tests/ui-accessibility.spec.ts b/tests/ui-accessibility.spec.ts index ce308087e..e5243c917 100644 --- a/tests/ui-accessibility.spec.ts +++ b/tests/ui-accessibility.spec.ts @@ -209,7 +209,7 @@ test.describe("Clinical KB accessibility coverage", () => { await expect(modeButton).toHaveAttribute("aria-expanded", "false"); }); - test("phone quick actions meet the tap target and guests do not poll private ingestion routes", async ({ page }) => { + test("phone privacy link meets the tap target and guests do not poll private ingestion routes", async ({ page }) => { const privateIngestionRequests: string[] = []; page.on("request", (request) => { if (/\/api\/ingestion\/(?:jobs|batches|quality)(?:\?|$)/.test(request.url())) { @@ -223,11 +223,7 @@ test.describe("Clinical KB accessibility coverage", () => { await expectDashboardUsable(page); const targetSizes = await Promise.all( - [ - page.getByRole("button", { name: "Search documents", exact: true }), - page.getByRole("button", { name: "Upload document", exact: true }), - page.getByRole("link", { name: "Privacy and data processing", exact: true }), - ].map((target) => + [page.getByRole("link", { name: "Privacy and data processing", exact: true })].map((target) => target.evaluate((element) => { const bounds = element.getBoundingClientRect(); return { width: bounds.width, height: bounds.height }; @@ -365,9 +361,12 @@ test.describe("Clinical KB accessibility coverage", () => { await mockMinimalDashboardApi(page); await gotoApp(page); - const uploadButton = page.getByRole("button", { name: /Upload document/i }); - await expect(uploadButton).toBeVisible(); - await uploadButton.click(); + const menuTrigger = page.getByRole("button", { name: "Open answer options" }); + await expect(menuTrigger).toBeVisible(); + await menuTrigger.click(); + const menu = page.getByTestId("daily-actions-menu"); + await expect(menu).toBeVisible(); + await menu.getByRole("menuitem", { name: "Add document" }).click(); await expect(page.getByRole("dialog", { name: "Upload and indexing" })).toHaveCount(0); await expect(page.getByRole("dialog", { name: "Source library" })).toBeVisible(); await expect(page.getByRole("alert").filter({ hasText: "Upload and indexing tools are admin-only" })).toContainText( diff --git a/tests/ui-smoke.spec.ts b/tests/ui-smoke.spec.ts index 77e153bbd..5125ae293 100644 --- a/tests/ui-smoke.spec.ts +++ b/tests/ui-smoke.spec.ts @@ -844,10 +844,10 @@ async function expectAccountSetupSurface(setup: Locator) { } async function expectAdminOnlyUploadNotice(page: Page) { - const uploadButton = page.getByRole("button", { name: /Upload document/i }); - await expect(uploadButton).toBeVisible(); - await waitForReactEventHandler(uploadButton, "onClick"); - await uploadButton.click(); + const menu = await openDailyActions(page); + const uploadAction = menu.getByRole("menuitem", { name: "Add document" }); + await expect(uploadAction).toBeVisible(); + await uploadAction.click(); await expect(page.getByRole("alert").filter({ hasText: "Upload and indexing tools are admin-only." })).toContainText( "Use the source library to open indexed documents.", ); @@ -893,8 +893,6 @@ test.describe("Clinical KB UI smoke coverage", () => { await expect(page.getByTestId("scope-command-popover")).toBeHidden(); await expect(page.getByTestId("scope-prompts-drawer")).toHaveCount(0); await expect(page.getByTestId("mobile-scope-popover")).toHaveCount(0); - await expect(page.getByRole("button", { name: "Search documents" })).toBeVisible(); - await expect(page.getByRole("button", { name: "Upload document" })).toBeVisible(); await expectDomIntegrity(page, { mobileNav: viewport.width <= 768 }); if (viewport.width <= 768) { await expect(page.getByTestId("mobile-section-fab-button")).toHaveCount(0);