Files
supabase/apps/studio/components/ui/AIAssistantPanel/AIAssistantHeader.test.tsx
Saxon FletcherandClaude Opus 5 fd8d213135 feat: add Explorer chat discovery and controls (#49032)
<img width="1693" height="1038" alt="image"
src="https://github.com/user-attachments/assets/9ef52446-c517-4ea9-ada6-ac6dc57c8af4"
/>


## Summary

- add an Explorer-specific chat toolbar with rename, chat ID,
permission, and branching controls
- list searchable non-support chats in Explorer with reactive updates
and safe rehydrated-date sorting
- add chat creation entry points to Explorer home and navigation menus
- route chat recent items correctly and show chat icons across shared
tab surfaces
- make the assistant sidebar expand action open the active chat in
Explorer

This is PR 3 of 3 and is stacked on #49031. Review #48973 first, then
#49031, then this PR. Compared with its base, this PR contains only
discovery, toolbar, and cross-surface integration work.

## To Test
- visit /explorer
- Create a new chat either via home tab chat input OR the chats sidebar
- Validate chats show up in sidebar
- Validate chat conversation works
- Close the chat tab and open a chat via sidebar
- Change permission settings via the chat tab toolbar and verify it
persists


## Test plan

- `mise exec node@22 -- pnpm --dir apps/studio exec tsc --noEmit`
- focused Vitest suite: 4 files / 5 tests covering reactive chat lists,
navigation filtering and sorting, recent-item routing, and sidebar
handoff
- ESLint on changed TypeScript files
- Prettier check on changed source files


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Added chat creation from the Explorer home, navigation, and new-tab
menu.
- Added an Explorer chat toolbar with editable names, ID copying,
permissions, shortcuts, and metadata warnings.
- Added searchable chat history with sorting, active-chat highlighting,
and clear empty states.
  - Chats can now open directly in Explorer from the AI Assistant panel.
  - Recent items now link correctly to chats and notebooks.

- **Bug Fixes**
- Improved chat list updates after creation, deletion, and restored
sessions.
  - Added safer handling for chats without update timestamps.

- **Tests**
- Expanded coverage for chat navigation, creation, metadata warnings,
shortcuts, and recent-item links.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-14 11:19:43 +10:00

57 lines
1.6 KiB
TypeScript

import { fireEvent, screen } from '@testing-library/react'
import { describe, expect, it, vi } from 'vitest'
import { AIAssistantHeader } from './AIAssistantHeader'
import { customRender } from '@/tests/lib/custom-render'
const { openChat } = vi.hoisted(() => ({ openChat: vi.fn() }))
vi.mock('@/state/ai-assistant-state', () => ({
useAiAssistantStateSnapshot: () => ({
activeChatId: 'chat-1',
activeChat: { name: 'Investigate errors' },
renameChat: vi.fn(),
}),
}))
vi.mock('@/components/interfaces/Explorer/hooks', () => ({
useCreateChat: () => ({ openChat }),
}))
vi.mock('@/state/shortcuts/useShortcut', () => ({ useShortcut: vi.fn() }))
vi.mock('./AIAssistantChatSelector', () => ({
AIAssistantChatSelector: () => (
<button type="button" tabIndex={0}>
History
</button>
),
}))
vi.mock('./AIAssistantMetadataWarning', () => ({
AIAssistantMetadataWarning: () => null,
}))
const defaultProps = {
isChatLoading: false,
onNewChat: vi.fn(),
onCloseAssistant: vi.fn(),
showMetadataWarning: false,
updatedOptInSinceMCP: true,
isHipaaProjectDisallowed: false,
aiOptInLevel: 'full',
}
describe('AIAssistantHeader', () => {
it('opens the active chat in Explorer and closes the sidebar', () => {
const onCloseAssistant = vi.fn()
customRender(<AIAssistantHeader {...defaultProps} onCloseAssistant={onCloseAssistant} />)
fireEvent.click(screen.getByRole('button', { name: 'Open in Explorer' }))
expect(openChat).toHaveBeenCalledWith('chat-1')
expect(onCloseAssistant).toHaveBeenCalledOnce()
expect(screen.queryByRole('button', { name: 'Minimize' })).not.toBeInTheDocument()
})
})