mirror of
https://github.com/supabase/supabase.git
synced 2026-09-07 02:20:52 +08:00
<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>
62 lines
2.2 KiB
TypeScript
62 lines
2.2 KiB
TypeScript
import { useParams } from 'common'
|
|
import { MessageSquare } from 'lucide-react'
|
|
import { useRouter } from 'next/router'
|
|
import { useState } from 'react'
|
|
import { cn } from 'ui'
|
|
|
|
import { ExplorerNavResourceWrapper, rowClassName } from './ExplorerLayout.constants'
|
|
import { useCreateChat } from '@/components/interfaces/Explorer/hooks'
|
|
import type { ChatSession } from '@/state/ai-assistant-state'
|
|
import { useAiAssistantChatList } from '@/state/ai-assistant-state'
|
|
|
|
const getVisibleChats = (chats: ChatSession[], search: string): ChatSession[] => {
|
|
const normalizedSearch = search.trim().toLowerCase()
|
|
|
|
return chats
|
|
.filter((chat) => !chat.supportMetadata?.isSupportChat)
|
|
.filter((chat) => !normalizedSearch || chat.name.toLowerCase().includes(normalizedSearch))
|
|
.sort((a, b) => (b.updatedAt?.getTime() ?? 0) - (a.updatedAt?.getTime() ?? 0))
|
|
}
|
|
|
|
export const ExplorerNavChats = ({ onBack }: { onBack: () => void }) => {
|
|
const [search, setSearch] = useState('')
|
|
const router = useRouter()
|
|
const { id } = useParams()
|
|
const { openChat } = useCreateChat()
|
|
const chatList = useAiAssistantChatList()
|
|
|
|
const chats = getVisibleChats(chatList, search)
|
|
|
|
return (
|
|
<ExplorerNavResourceWrapper type="chat" search={search} setSearch={setSearch} onBack={onBack}>
|
|
<div className="flex flex-1 flex-col gap-px overflow-y-auto px-3 pb-3">
|
|
{chats.length === 0 ? (
|
|
<p className="px-2 py-2 text-xs text-foreground-lighter">
|
|
{search ? 'No chats found' : 'No chats created yet'}
|
|
</p>
|
|
) : (
|
|
chats.map((chat) => {
|
|
const isActive = router.pathname.includes('/explorer/chat/') && id === chat.id
|
|
|
|
return (
|
|
<button
|
|
key={chat.id}
|
|
type="button"
|
|
tabIndex={0}
|
|
className={rowClassName(isActive)}
|
|
onClick={() => openChat(chat.id)}
|
|
>
|
|
<MessageSquare
|
|
size={14}
|
|
className={cn('shrink-0', isActive && 'text-foreground')}
|
|
/>
|
|
<span className="truncate text-left">{chat.name}</span>
|
|
</button>
|
|
)
|
|
})
|
|
)}
|
|
</div>
|
|
</ExplorerNavResourceWrapper>
|
|
)
|
|
}
|