mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 17:35:10 +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 -->
58 lines
1.6 KiB
TypeScript
58 lines
1.6 KiB
TypeScript
import { MessageSquare, NotebookText, Trash } from 'lucide-react'
|
|
import Link from 'next/link'
|
|
import { type CSSProperties } from 'react'
|
|
import { cn, ContextMenu, ContextMenuContent, ContextMenuItem, ContextMenuTrigger } from 'ui'
|
|
|
|
import { rowClassName } from './ExplorerLayout.constants'
|
|
|
|
interface ExplorerNavItemProps {
|
|
href: string
|
|
type: 'notebook' | 'chat'
|
|
name: string
|
|
description?: string
|
|
isActive?: boolean
|
|
style?: CSSProperties
|
|
onDoubleClick: () => void
|
|
onSelectDelete: () => void
|
|
}
|
|
|
|
export const ExplorerNavItem = ({
|
|
href,
|
|
type,
|
|
name,
|
|
description,
|
|
isActive = false,
|
|
style,
|
|
onDoubleClick,
|
|
onSelectDelete,
|
|
}: ExplorerNavItemProps) => {
|
|
return (
|
|
<ContextMenu modal={false}>
|
|
<ContextMenuTrigger asChild>
|
|
<Link
|
|
href={href}
|
|
className={rowClassName(isActive)}
|
|
style={style}
|
|
onDoubleClick={onDoubleClick}
|
|
>
|
|
{type === 'notebook' ? (
|
|
<NotebookText size={14} className={cn('shrink-0', isActive && 'text-foreground')} />
|
|
) : (
|
|
<MessageSquare size={14} className={cn('shrink-0', isActive && 'text-foreground')} />
|
|
)}
|
|
<span className="flex-1 truncate text-left">{name}</span>
|
|
{!!description && (
|
|
<span className="shrink-0 text-xs text-foreground-lighter">{description}</span>
|
|
)}
|
|
</Link>
|
|
</ContextMenuTrigger>
|
|
<ContextMenuContent>
|
|
<ContextMenuItem className="gap-x-2" onSelect={onSelectDelete}>
|
|
<Trash size={14} />
|
|
<span>Delete {type}</span>
|
|
</ContextMenuItem>
|
|
</ContextMenuContent>
|
|
</ContextMenu>
|
|
)
|
|
}
|