diff --git a/ui/src/pages/apps/chat/ChatEndpointSetup.routing.test.tsx b/ui/src/pages/apps/chat/ChatEndpointSetup.routing.test.tsx index f2b93640ed..516603a1a7 100644 --- a/ui/src/pages/apps/chat/ChatEndpointSetup.routing.test.tsx +++ b/ui/src/pages/apps/chat/ChatEndpointSetup.routing.test.tsx @@ -3,7 +3,7 @@ import { flushSync } from "react-dom"; import { createRoot, type Root } from "react-dom/client"; import { MemoryRouter, Route, Routes, useLocation } from "react-router-dom"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; -import { ChatEndpointSetup } from "./ChatEndpointSetup"; +import { ChatConnectionPurpose, ChatEndpointSetup } from "./ChatEndpointSetup"; vi.mock("@/lib/router", async () => import("react-router-dom")); vi.mock("./GitHubChatSetup", () => ({ @@ -26,7 +26,7 @@ function Location() { ); } -describe("GitHub code review bot routing", () => { +describe("Chat connector setup routing", () => { let root: Root; let container: HTMLDivElement; beforeEach(() => { @@ -51,6 +51,31 @@ describe("GitHub code review bot routing", () => { ), ); } + it("keeps both chooser actions usable with decorative identity icons", () => { + const onChat = vi.fn(); + const onTools = vi.fn(); + flushSync(() => root.render( + , + )); + const buttons = Array.from(container.querySelectorAll("button")); + const chat = buttons.find(button => button.textContent?.includes("Chat with an agent"))!; + const tools = buttons.find(button => button.textContent?.includes("Use this connection as an agent tool"))!; + expect(chat.querySelector('[data-slot="agent-avatar"][aria-hidden="true"]')).not.toBeNull(); + expect(chat.querySelector("img")?.getAttribute("alt")).toBe(""); + expect(tools.querySelector('[aria-hidden="true"] svg')).not.toBeNull(); + expect(chat.getAttribute("type")).toBe("button"); + expect(tools.getAttribute("type")).toBe("button"); + chat.focus(); + expect(document.activeElement).toBe(chat); + flushSync(() => chat.click()); + expect(onChat).toHaveBeenCalledOnce(); + expect(onTools).not.toHaveBeenCalled(); + tools.focus(); + expect(document.activeElement).toBe(tools); + flushSync(() => tools.click()); + expect(onTools).toHaveBeenCalledOnce(); + expect(onChat).toHaveBeenCalledOnce(); + }); it.each([ "", "agentId=agent-a", diff --git a/ui/src/pages/apps/chat/ChatEndpointSetup.tsx b/ui/src/pages/apps/chat/ChatEndpointSetup.tsx index a7ae74c7c1..54c4a4fe4a 100644 --- a/ui/src/pages/apps/chat/ChatEndpointSetup.tsx +++ b/ui/src/pages/apps/chat/ChatEndpointSetup.tsx @@ -19,7 +19,8 @@ import { type SetStateAction, } from "react"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; -import { AlertTriangle, CheckCircle2, Copy, CircleHelp, ExternalLink, Eye, EyeOff, Loader2 } from "lucide-react"; +import { AlertTriangle, CheckCircle2, Copy, CircleHelp, ExternalLink, Eye, EyeOff, Hammer, Loader2 } from "lucide-react"; +import { AgentAvatar } from "@/components/AgentAvatar"; import { AgentCharacter } from "@/components/AgentCharacter"; import { AgentSelect } from "@/components/AgentMultiSelect"; import { Button } from "@/components/ui/button"; @@ -103,7 +104,7 @@ export function isChatEndpointRepairing( ); } -function ChatConnectionPurpose({ provider, onChat, onTools }: { +export function ChatConnectionPurpose({ provider, onChat, onTools }: { provider: ChatProvider; onChat: () => void; onTools: () => void; @@ -125,28 +126,36 @@ function ChatConnectionPurpose({ provider, onChat, onTools }: {
diff --git a/ui/storybook/stories/slack-automatic-setup.stories.tsx b/ui/storybook/stories/slack-automatic-setup.stories.tsx index fe8aac2c17..4ed65ff603 100644 --- a/ui/storybook/stories/slack-automatic-setup.stories.tsx +++ b/ui/storybook/stories/slack-automatic-setup.stories.tsx @@ -12,6 +12,10 @@ const meta = { } satisfies Meta; export default meta; type Story = StoryObj; +export const ChooseConnection: Story = { + name: "00 · Choose connection", args: { scenario: "choose" }, + parameters: { initialEntries: ["/PAP/apps/chat/connect?provider=slack"] }, +}; export const ChooseAgent: Story = { name: "01 · Choose agent", args: { scenario: "choose" }, parameters: { initialEntries: [start] }, }; @@ -49,3 +53,8 @@ export const WelcomeFailed: Story = { name: "Recovery · Welcome DM failed", arg export const Mobile: Story = { name: "Mobile · App configuration access token", args: { scenario: "create" }, globals: { viewport: { value: "mobile1", isRotated: false } } }; export const SuccessMobile: Story = { name: "Mobile · Success", args: { scenario: "success" }, globals: { viewport: { value: "mobile1", isRotated: false } } }; + +export const ChooseConnectionMobile: Story = { + ...ChooseConnection, name: "Mobile · Choose connection", + globals: { viewport: { value: "mobile1", isRotated: false } }, +};