feat(FN-3331): add New Chat button to thread header on desktop

Adds a New Chat button to the ChatView thread header on desktop with accompanying CSS styling and tests. The feature is scoped to the dashboard's chat interface with 62 lines of additions across the component, its stylesheet, and test file.

Fusion-Task-Id: FN-3331
This commit is contained in:
Fusion
2026-05-03 15:04:47 -07:00
committed by gsxdsm
parent 4d6c0a463c
commit 1e841df3c7
3 changed files with 62 additions and 0 deletions

View File

@@ -214,6 +214,11 @@
font-size: 15px;
}
.chat-thread-header-new-chat {
margin-left: auto;
flex-shrink: 0;
}
/* Messages */
.chat-messages {
flex: 1;
@@ -1026,6 +1031,10 @@
flex-wrap: wrap;
}
.chat-thread-header-new-chat {
display: none;
}
.chat-session-delete-btn {
opacity: 1;
}

View File

@@ -1686,6 +1686,16 @@ export function ChatView({ projectId, addToast }: ChatViewProps) {
<Bot size={16} />
<span className="chat-thread-header-title">{threadHeaderTitle}</span>
{showThreadHeaderModelTag && <span className="chat-model-tag">{activeModelTag}</span>}
{!isMobile && (
<button
className="btn btn-sm btn-primary chat-thread-header-new-chat"
onClick={() => setShowNewDialog(true)}
data-testid="chat-thread-new-chat-btn"
>
<Plus size={14} />
New Chat
</button>
)}
</div>
)}

View File

@@ -2348,6 +2348,49 @@ describe("resizable sidebar", () => {
});
});
describe("thread header New Chat button", () => {
const activeSession = { id: "session-001", agentId: "agent-001", status: "active", title: "Test Chat", createdAt: "2026-04-08T00:00:00.000Z", updatedAt: "2026-04-08T00:00:00.000Z" };
it("renders New Chat button in thread header on desktop when session is active", () => {
const viewportSpy = mockViewportMode("desktop");
setupMockChat({ activeSession });
render(<ChatView projectId="proj-123" addToast={vi.fn()} />);
const btn = screen.getByTestId("chat-thread-new-chat-btn");
expect(btn).toBeInTheDocument();
expect(btn).toHaveTextContent("New Chat");
expect(btn).toHaveClass("btn", "btn-sm", "btn-primary");
viewportSpy.mockRestore();
});
it("clicking thread header New Chat button opens the NewChatDialog", () => {
const viewportSpy = mockViewportMode("desktop");
setupMockChat({ activeSession });
render(<ChatView projectId="proj-123" addToast={vi.fn()} />);
const btn = screen.getByTestId("chat-thread-new-chat-btn");
fireEvent.click(btn);
expect(screen.getByTestId("chat-new-dialog-mode-toggle")).toBeInTheDocument();
viewportSpy.mockRestore();
});
it("does not render New Chat button in thread header on mobile", () => {
const viewportSpy = mockViewportMode("mobile");
setupMockChat({ activeSession });
render(<ChatView projectId="proj-123" addToast={vi.fn()} />);
expect(screen.queryByTestId("chat-thread-new-chat-btn")).toBeNull();
viewportSpy.mockRestore();
});
});
describe("ChatView mobile behavior", () => {
let savedVisualViewport: typeof window.visualViewport;
let savedInnerHeight: number;