Skip to content

Commit bbbb13a

Browse files
authored
feat(folders): add the ability to create a folder within a folder in popover (#2287)
1 parent 6fd4087 commit bbbb13a

File tree

2 files changed

+52
-4
lines changed

2 files changed

+52
-4
lines changed

apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/workflow-list/components/context-menu/context-menu.tsx

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,13 @@ interface ContextMenuProps {
2828
*/
2929
onRename?: () => void
3030
/**
31-
* Callback when create is clicked (for folders)
31+
* Callback when create workflow is clicked (for folders)
3232
*/
3333
onCreate?: () => void
34+
/**
35+
* Callback when create folder is clicked (for folders)
36+
*/
37+
onCreateFolder?: () => void
3438
/**
3539
* Callback when duplicate is clicked
3640
*/
@@ -54,10 +58,15 @@ interface ContextMenuProps {
5458
*/
5559
showRename?: boolean
5660
/**
57-
* Whether to show the create option (default: false)
61+
* Whether to show the create workflow option (default: false)
5862
* Set to true for folders to create workflows inside
5963
*/
6064
showCreate?: boolean
65+
/**
66+
* Whether to show the create folder option (default: false)
67+
* Set to true for folders to create sub-folders inside
68+
*/
69+
showCreateFolder?: boolean
6170
/**
6271
* Whether to show the duplicate option (default: true)
6372
* Set to false for items that cannot be duplicated
@@ -89,10 +98,15 @@ interface ContextMenuProps {
8998
*/
9099
disableDelete?: boolean
91100
/**
92-
* Whether the create option is disabled (default: false)
101+
* Whether the create workflow option is disabled (default: false)
93102
* Set to true when creation is in progress or user lacks permissions
94103
*/
95104
disableCreate?: boolean
105+
/**
106+
* Whether the create folder option is disabled (default: false)
107+
* Set to true when creation is in progress or user lacks permissions
108+
*/
109+
disableCreateFolder?: boolean
96110
}
97111

98112
/**
@@ -110,19 +124,22 @@ export function ContextMenu({
110124
onOpenInNewTab,
111125
onRename,
112126
onCreate,
127+
onCreateFolder,
113128
onDuplicate,
114129
onExport,
115130
onDelete,
116131
showOpenInNewTab = false,
117132
showRename = true,
118133
showCreate = false,
134+
showCreateFolder = false,
119135
showDuplicate = true,
120136
showExport = false,
121137
disableExport = false,
122138
disableRename = false,
123139
disableDuplicate = false,
124140
disableDelete = false,
125141
disableCreate = false,
142+
disableCreateFolder = false,
126143
}: ContextMenuProps) {
127144
return (
128145
<Popover open={isOpen} onOpenChange={onClose} variant='primary'>
@@ -168,6 +185,17 @@ export function ContextMenu({
168185
Create workflow
169186
</PopoverItem>
170187
)}
188+
{showCreateFolder && onCreateFolder && (
189+
<PopoverItem
190+
disabled={disableCreateFolder}
191+
onClick={() => {
192+
onCreateFolder()
193+
onClose()
194+
}}
195+
>
196+
Create folder
197+
</PopoverItem>
198+
)}
171199
{showDuplicate && onDuplicate && (
172200
<PopoverItem
173201
disabled={disableDuplicate}

apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/workflow-list/components/folder-item/folder-item.tsx

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import {
1515
useItemRename,
1616
} from '@/app/workspace/[workspaceId]/w/components/sidebar/hooks'
1717
import { useDeleteFolder, useDuplicateFolder } from '@/app/workspace/[workspaceId]/w/hooks'
18-
import { useUpdateFolder } from '@/hooks/queries/folders'
18+
import { useCreateFolder, useUpdateFolder } from '@/hooks/queries/folders'
1919
import { useCreateWorkflow } from '@/hooks/queries/workflows'
2020
import type { FolderTreeNode } from '@/stores/folders/store'
2121
import {
@@ -48,6 +48,7 @@ export function FolderItem({ folder, level, hoverHandlers }: FolderItemProps) {
4848
const workspaceId = params.workspaceId as string
4949
const updateFolderMutation = useUpdateFolder()
5050
const createWorkflowMutation = useCreateWorkflow()
51+
const createFolderMutation = useCreateFolder()
5152
const userPermissions = useUserPermissionsContext()
5253

5354
// Delete modal state
@@ -93,6 +94,22 @@ export function FolderItem({ folder, level, hoverHandlers }: FolderItemProps) {
9394
}
9495
}, [createWorkflowMutation, workspaceId, folder.id, router])
9596

97+
/**
98+
* Handle create sub-folder using React Query mutation.
99+
* Creates a new folder inside the current folder.
100+
*/
101+
const handleCreateFolderInFolder = useCallback(async () => {
102+
try {
103+
await createFolderMutation.mutateAsync({
104+
workspaceId,
105+
name: 'New Folder',
106+
parentId: folder.id,
107+
})
108+
} catch (error) {
109+
logger.error('Failed to create folder:', error)
110+
}
111+
}, [createFolderMutation, workspaceId, folder.id])
112+
96113
// Folder expand hook
97114
const {
98115
isExpanded,
@@ -279,11 +296,14 @@ export function FolderItem({ folder, level, hoverHandlers }: FolderItemProps) {
279296
onClose={closeMenu}
280297
onRename={handleStartEdit}
281298
onCreate={handleCreateWorkflowInFolder}
299+
onCreateFolder={handleCreateFolderInFolder}
282300
onDuplicate={handleDuplicateFolder}
283301
onDelete={() => setIsDeleteModalOpen(true)}
284302
showCreate={true}
303+
showCreateFolder={true}
285304
disableRename={!userPermissions.canEdit}
286305
disableCreate={!userPermissions.canEdit || createWorkflowMutation.isPending}
306+
disableCreateFolder={!userPermissions.canEdit || createFolderMutation.isPending}
287307
disableDuplicate={!userPermissions.canEdit}
288308
disableDelete={!userPermissions.canEdit}
289309
/>

0 commit comments

Comments
 (0)