Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export { HelpModal } from './help-modal/help-modal'
export { NavItemContextMenu } from './nav-item-context-menu'
export { SearchModal } from './search-modal/search-modal'
export { SettingsModal } from './settings-modal/settings-modal'
export { UsageIndicator } from './usage-indicator/usage-indicator'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { NavItemContextMenu } from './nav-item-context-menu'
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
'use client'

import { Popover, PopoverAnchor, PopoverContent, PopoverItem } from '@/components/emcn'

interface NavItemContextMenuProps {
/**
* Whether the context menu is open
*/
isOpen: boolean
/**
* Position of the context menu
*/
position: { x: number; y: number }
/**
* Ref for the menu element
*/
menuRef: React.RefObject<HTMLDivElement | null>
/**
* Callback when menu should close
*/
onClose: () => void
/**
* Callback when open in new tab is clicked
*/
onOpenInNewTab: () => void
/**
* Callback when copy link is clicked
*/
onCopyLink: () => void
}

/**
* Context menu component for sidebar navigation items.
* Displays navigation-appropriate options (open in new tab, copy link) in a popover at the right-click position.
*/
export function NavItemContextMenu({
isOpen,
position,
menuRef,
onClose,
onOpenInNewTab,
onCopyLink,
}: NavItemContextMenuProps) {
return (
<Popover
open={isOpen}
onOpenChange={onClose}
variant='secondary'
size='sm'
colorScheme='inverted'
>
<PopoverAnchor
style={{
position: 'fixed',
left: `${position.x}px`,
top: `${position.y}px`,
width: '1px',
height: '1px',
}}
/>
<PopoverContent ref={menuRef} align='start' side='bottom' sideOffset={4}>
<PopoverItem
onClick={() => {
onOpenInNewTab()
onClose()
}}
>
Open in new tab
</PopoverItem>
<PopoverItem
onClick={() => {
onCopyLink()
onClose()
}}
>
Copy link
</PopoverItem>
</PopoverContent>
</Popover>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@ import { useUserPermissionsContext } from '@/app/workspace/[workspaceId]/provide
import { createCommands } from '@/app/workspace/[workspaceId]/utils/commands-utils'
import {
HelpModal,
NavItemContextMenu,
SearchModal,
SettingsModal,
UsageIndicator,
WorkflowList,
WorkspaceHeader,
} from '@/app/workspace/[workspaceId]/w/components/sidebar/components'
import {
useContextMenu,
useFolderOperations,
useSidebarResize,
useWorkflowOperations,
Expand Down Expand Up @@ -168,6 +170,37 @@ export function Sidebar() {
workspaceId,
})

/** Context menu state for navigation items */
const [activeNavItemHref, setActiveNavItemHref] = useState<string | null>(null)
const {
isOpen: isNavContextMenuOpen,
position: navContextMenuPosition,
menuRef: navMenuRef,
handleContextMenu: handleNavContextMenuBase,
closeMenu: closeNavContextMenu,
} = useContextMenu()

const handleNavItemContextMenu = useCallback(
(e: React.MouseEvent, href: string) => {
setActiveNavItemHref(href)
handleNavContextMenuBase(e)
},
[handleNavContextMenuBase]
)

const handleNavOpenInNewTab = useCallback(() => {
if (activeNavItemHref) {
window.open(activeNavItemHref, '_blank')
}
}, [activeNavItemHref])

const handleNavCopyLink = useCallback(async () => {
if (activeNavItemHref) {
const fullUrl = `${window.location.origin}${activeNavItemHref}`
await navigator.clipboard.writeText(fullUrl)
}
}, [activeNavItemHref])

const { handleDuplicateWorkspace: duplicateWorkspace } = useDuplicateWorkspace({
getWorkspaceId: () => workspaceId,
})
Expand Down Expand Up @@ -629,12 +662,23 @@ export function Sidebar() {
href={item.href!}
data-item-id={item.id}
className={`${baseClasses} ${activeClasses}`}
onContextMenu={(e) => handleNavItemContextMenu(e, item.href!)}
>
{content}
</Link>
)
})}
</div>

{/* Nav Item Context Menu */}
<NavItemContextMenu
isOpen={isNavContextMenuOpen}
position={navContextMenuPosition}
menuRef={navMenuRef}
onClose={closeNavContextMenu}
onOpenInNewTab={handleNavOpenInNewTab}
onCopyLink={handleNavCopyLink}
/>
</div>
</aside>

Expand Down