Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
Expand Up @@ -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
}

/**
Expand Down Expand Up @@ -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')

Expand Down Expand Up @@ -412,8 +429,20 @@ export function ContextMenu({
</PopoverItem>
)}

{/* Destructive action */}
{/* Destructive actions */}
{(hasNavigationSection || hasEditSection || hasCopySection) && <PopoverDivider rootOnly />}
{showLeave && onLeave && (
<PopoverItem
rootOnly
disabled={disableLeave}
onClick={() => {
onLeave()
onClose()
}}
>
Leave
</PopoverItem>
)}
<PopoverItem
rootOnly
disabled={disableDelete}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,14 @@ interface WorkspaceHeaderProps {
* Whether to show the collapse button
*/
showCollapseButton?: boolean
/**
* Callback to leave the workspace
*/
onLeaveWorkspace?: (workspaceId: string) => Promise<void>
/**
* Current user's session ID for owner check
*/
sessionUserId?: string
}

/**
Expand All @@ -128,6 +136,8 @@ export function WorkspaceHeader({
onImportWorkspace,
isImportingWorkspace,
showCollapseButton = true,
onLeaveWorkspace,
sessionUserId,
}: WorkspaceHeaderProps) {
const [isInviteModalOpen, setIsInviteModalOpen] = useState(false)
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false)
Expand Down Expand Up @@ -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
*/
Expand Down Expand Up @@ -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 (
<ContextMenu
Expand All @@ -523,10 +545,12 @@ export function WorkspaceHeader({
onDuplicate={handleDuplicateAction}
onExport={handleExportAction}
onDelete={handleDeleteAction}
onLeave={handleLeaveAction}
showRename={true}
showDuplicate={true}
showExport={true}
disableRename={!contextCanEdit}
showLeave={!isOwner && !!onLeaveWorkspace}
disableRename={!contextCanAdmin}
disableDuplicate={!contextCanEdit}
disableExport={!contextCanAdmin}
disableDelete={!contextCanAdmin}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ export function Sidebar() {
isCreatingWorkspace,
updateWorkspaceName,
confirmDeleteWorkspace,
handleLeaveWorkspace,
} = useWorkspaceManagement({
workspaceId,
sessionUserId: sessionData?.user?.id,
Expand Down Expand Up @@ -378,6 +379,17 @@ export function Sidebar() {
[workspaces, confirmDeleteWorkspace]
)

/** Leaves a workspace */
const handleLeaveWorkspaceWrapper = useCallback(
async (workspaceIdToLeave: string) => {
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) => {
Expand Down Expand Up @@ -509,6 +521,8 @@ export function Sidebar() {
onImportWorkspace={handleImportWorkspace}
isImportingWorkspace={isImportingWorkspace}
showCollapseButton={isOnWorkflowPage}
onLeaveWorkspace={handleLeaveWorkspaceWrapper}
sessionUserId={sessionData?.user?.id}
/>
</div>
) : (
Expand Down Expand Up @@ -542,6 +556,8 @@ export function Sidebar() {
onImportWorkspace={handleImportWorkspace}
isImportingWorkspace={isImportingWorkspace}
showCollapseButton={isOnWorkflowPage}
onLeaveWorkspace={handleLeaveWorkspaceWrapper}
sessionUserId={sessionData?.user?.id}
/>
</div>

Expand Down