mirror of
https://github.com/supabase/supabase.git
synced 2026-10-06 18:05:11 +03:00
### Context Adds context menu to the explorer nav to allow users to delete notebooks or chats from there (instead of having to open the notebook / chat first, then select delete from the header) <img width="304" height="339" alt="image" src="https://github.com/user-attachments/assets/2ad0f21c-0d49-407c-97a2-ef11ae59e280" /> ### Changes involved: - Consolidates the rendering of explorer nav items into a single component that both `ExplorerNavNotebook`, `ExplorerNavHome` and `ExplorerNavChats` use. - We were previously rendering a link for notebook, and a button for chats. But chats' button was just calling `router.push` under the hood. - Opting to use a Context to handle the delete functionality such that we can render the confirmation modal just once at the layout level since there's multiple places that have this delete functionality - notebook tab, chat tab, context menu in each of the explorer navs ### To test - [ ] Verify that navigating around the explorer is status quo - [ ] Verify that you can delete a notebook/chat from within the notebook/chat tab - [ ] Verify that you can delete a notebook/chat from the explorer nav - [ ] Verify that after deleting a notebook/chat from either locations, the tabs should clear <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Unified chat and notebook navigation with direct links and active-item highlighting. - Added context-menu options to delete chats and notebooks with confirmation and status notifications. - Added double-click support for keeping recently viewed chats and notebooks open as tabs. - Deleted items and their related tabs are removed automatically. - **Tests** - Updated Explorer navigation tests for the unified link-based item behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
61 lines
2.2 KiB
TypeScript
61 lines
2.2 KiB
TypeScript
import { useParams } from 'common'
|
|
import { useRouter } from 'next/router'
|
|
import { useState } from 'react'
|
|
|
|
import { ExplorerNavResourceWrapper } from './ExplorerLayout.constants'
|
|
import { ExplorerNavItem } from './ExplorerNavItem'
|
|
import { useExplorerDeleteItem } from './ExplorerProvider'
|
|
import type { ChatSession } from '@/state/ai-assistant-state'
|
|
import { useAiAssistantChatList } from '@/state/ai-assistant-state'
|
|
import { createTabId, useTabsStateSnapshot } from '@/state/tabs'
|
|
|
|
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 = () => {
|
|
const [search, setSearch] = useState('')
|
|
const router = useRouter()
|
|
const { id, ref } = useParams()
|
|
const chatList = useAiAssistantChatList()
|
|
const tabs = useTabsStateSnapshot()
|
|
const { onSelectDelete } = useExplorerDeleteItem()
|
|
|
|
const chats = getVisibleChats(chatList, search)
|
|
|
|
return (
|
|
<ExplorerNavResourceWrapper type="chat" search={search} setSearch={setSearch}>
|
|
<div className="flex flex-1 flex-col gap-px overflow-y-auto p-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 (
|
|
<ExplorerNavItem
|
|
type="chat"
|
|
key={chat.id}
|
|
name={chat.name}
|
|
isActive={isActive}
|
|
href={`/project/${ref}/explorer/chat/${chat.id}`}
|
|
onDoubleClick={() => tabs.makeTabPermanent(createTabId('chat', { id: chat.id }))}
|
|
onSelectDelete={() =>
|
|
onSelectDelete({ id: chat.id, type: 'chat', name: chat.name })
|
|
}
|
|
/>
|
|
)
|
|
})
|
|
)}
|
|
</div>
|
|
</ExplorerNavResourceWrapper>
|
|
)
|
|
}
|