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}
/>