mirror of
https://github.com/simstudioai/sim.git
synced 2026-04-06 03:00:16 -04:00
feat(workspace): added option to leave workspace (#2854)
This commit is contained in:
@@ -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({
|
||||
</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}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -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 (
|
||||
<ContextMenu
|
||||
@@ -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}
|
||||
|
||||
@@ -157,6 +157,7 @@ export function Sidebar() {
|
||||
isCreatingWorkspace,
|
||||
updateWorkspaceName,
|
||||
confirmDeleteWorkspace,
|
||||
handleLeaveWorkspace,
|
||||
} = useWorkspaceManagement({
|
||||
workspaceId,
|
||||
sessionUserId: sessionData?.user?.id,
|
||||
@@ -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) => {
|
||||
@@ -509,6 +521,8 @@ export function Sidebar() {
|
||||
onImportWorkspace={handleImportWorkspace}
|
||||
isImportingWorkspace={isImportingWorkspace}
|
||||
showCollapseButton={isOnWorkflowPage}
|
||||
onLeaveWorkspace={handleLeaveWorkspaceWrapper}
|
||||
sessionUserId={sessionData?.user?.id}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
@@ -542,6 +556,8 @@ export function Sidebar() {
|
||||
onImportWorkspace={handleImportWorkspace}
|
||||
isImportingWorkspace={isImportingWorkspace}
|
||||
showCollapseButton={isOnWorkflowPage}
|
||||
onLeaveWorkspace={handleLeaveWorkspaceWrapper}
|
||||
sessionUserId={sessionData?.user?.id}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user