diff --git a/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/workflow-list/components/context-menu/context-menu.tsx b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/workflow-list/components/context-menu/context-menu.tsx index e48673db20..1c1984d4a1 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/workflow-list/components/context-menu/context-menu.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/workflow-list/components/context-menu/context-menu.tsx @@ -161,6 +161,20 @@ interface ContextMenuProps { * Set to true when creation is in progress or user lacks permissions */ disableCreateFolder?: boolean + /** + * Callback when leave is clicked (for workspaces) + */ + onLeave?: () => void + /** + * Whether to show the leave option (default: false) + * Set to true for workspaces the user can leave + */ + showLeave?: boolean + /** + * Whether the leave option is disabled (default: false) + * Set to true when user cannot leave (e.g., last admin) + */ + disableLeave?: boolean } /** @@ -198,6 +212,9 @@ export function ContextMenu({ disableDelete = false, disableCreate = false, disableCreateFolder = false, + onLeave, + showLeave = false, + disableLeave = false, }: ContextMenuProps) { const [hexInput, setHexInput] = useState(currentColor || '#ffffff') @@ -412,8 +429,20 @@ export function ContextMenu({ )} - {/* Destructive action */} + {/* Destructive actions */} {(hasNavigationSection || hasEditSection || hasCopySection) && } + {showLeave && onLeave && ( + { + onLeave() + onClose() + }} + > + Leave + + )} Promise + /** + * Current user's session ID for owner check + */ + sessionUserId?: string } /** @@ -128,6 +136,8 @@ export function WorkspaceHeader({ onImportWorkspace, isImportingWorkspace, showCollapseButton = true, + onLeaveWorkspace, + sessionUserId, }: WorkspaceHeaderProps) { const [isInviteModalOpen, setIsInviteModalOpen] = useState(false) const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false) @@ -267,6 +277,16 @@ export function WorkspaceHeader({ } } + /** + * Handles leave action from context menu + */ + const handleLeaveAction = async () => { + if (!capturedWorkspaceRef.current || !onLeaveWorkspace) return + + await onLeaveWorkspace(capturedWorkspaceRef.current.id) + setIsWorkspaceMenuOpen(false) + } + /** * Handle delete workspace */ @@ -512,6 +532,8 @@ export function WorkspaceHeader({ const capturedPermissions = capturedWorkspaceRef.current?.permissions const contextCanEdit = capturedPermissions === 'admin' || capturedPermissions === 'write' const contextCanAdmin = capturedPermissions === 'admin' + const capturedWorkspace = workspaces.find((w) => w.id === capturedWorkspaceRef.current?.id) + const isOwner = capturedWorkspace && sessionUserId === capturedWorkspace.ownerId return ( { + const workspaceToLeave = workspaces.find((w) => w.id === workspaceIdToLeave) + if (workspaceToLeave) { + await handleLeaveWorkspace(workspaceToLeave) + } + }, + [workspaces, handleLeaveWorkspace] + ) + /** Duplicates a workspace */ const handleDuplicateWorkspace = useCallback( async (_workspaceIdToDuplicate: string, workspaceName: string) => { @@ -509,6 +521,8 @@ export function Sidebar() { onImportWorkspace={handleImportWorkspace} isImportingWorkspace={isImportingWorkspace} showCollapseButton={isOnWorkflowPage} + onLeaveWorkspace={handleLeaveWorkspaceWrapper} + sessionUserId={sessionData?.user?.id} /> ) : ( @@ -542,6 +556,8 @@ export function Sidebar() { onImportWorkspace={handleImportWorkspace} isImportingWorkspace={isImportingWorkspace} showCollapseButton={isOnWorkflowPage} + onLeaveWorkspace={handleLeaveWorkspaceWrapper} + sessionUserId={sessionData?.user?.id} />