Skip to content

Commit 29031f6

Browse files
committed
standardized import/export hooks
1 parent 56616ef commit 29031f6

File tree

14 files changed

+87
-250
lines changed

14 files changed

+87
-250
lines changed

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/panel.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ export function Panel() {
108108
// Delete workflow hook
109109
const { isDeleting, handleDeleteWorkflow } = useDeleteWorkflow({
110110
workspaceId,
111-
getWorkflowIds: () => activeWorkflowId || '',
111+
workflowIds: activeWorkflowId || '',
112112
isActive: true,
113113
onSuccess: () => setIsDeleteModalOpen(false),
114114
})

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

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -58,29 +58,24 @@ export function FolderItem({ folder, level, hoverHandlers }: FolderItemProps) {
5858
const { canDeleteFolder } = useCanDelete({ workspaceId })
5959
const canDelete = useMemo(() => canDeleteFolder(folder.id), [canDeleteFolder, folder.id])
6060

61-
// Delete modal state
6261
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false)
6362

64-
// Delete folder hook
6563
const { isDeleting, handleDeleteFolder } = useDeleteFolder({
6664
workspaceId,
67-
getFolderIds: () => folder.id,
65+
folderIds: folder.id,
6866
onSuccess: () => setIsDeleteModalOpen(false),
6967
})
7068

71-
// Duplicate folder hook
7269
const { handleDuplicateFolder } = useDuplicateFolder({
7370
workspaceId,
74-
getFolderIds: () => folder.id,
71+
folderIds: folder.id,
7572
})
7673

77-
// Export folder hook
7874
const { isExporting, hasWorkflows, handleExportFolder } = useExportFolder({
7975
workspaceId,
80-
getFolderId: () => folder.id,
76+
folderId: folder.id,
8177
})
8278

83-
// Folder expand hook - must be declared before callbacks that use expandFolder
8479
const {
8580
isExpanded,
8681
handleToggleExpanded,
@@ -97,7 +92,6 @@ export function FolderItem({ folder, level, hoverHandlers }: FolderItemProps) {
9792
*/
9893
const handleCreateWorkflowInFolder = useCallback(async () => {
9994
try {
100-
// Generate name and color upfront for optimistic updates
10195
const name = generateCreativeWorkflowName()
10296
const color = getNextWorkflowColor()
10397

@@ -110,15 +104,12 @@ export function FolderItem({ folder, level, hoverHandlers }: FolderItemProps) {
110104

111105
if (result.id) {
112106
router.push(`/workspace/${workspaceId}/w/${result.id}`)
113-
// Expand the parent folder so the new workflow is visible
114107
expandFolder()
115-
// Scroll to the newly created workflow
116108
window.dispatchEvent(
117109
new CustomEvent(SIDEBAR_SCROLL_EVENT, { detail: { itemId: result.id } })
118110
)
119111
}
120112
} catch (error) {
121-
// Error already handled by mutation's onError callback
122113
logger.error('Failed to create workflow in folder:', error)
123114
}
124115
}, [createWorkflowMutation, workspaceId, folder.id, router, expandFolder])
@@ -135,9 +126,7 @@ export function FolderItem({ folder, level, hoverHandlers }: FolderItemProps) {
135126
parentId: folder.id,
136127
})
137128
if (result.id) {
138-
// Expand the parent folder so the new folder is visible
139129
expandFolder()
140-
// Scroll to the newly created folder
141130
window.dispatchEvent(
142131
new CustomEvent(SIDEBAR_SCROLL_EVENT, { detail: { itemId: result.id } })
143132
)
@@ -154,7 +143,6 @@ export function FolderItem({ folder, level, hoverHandlers }: FolderItemProps) {
154143
*/
155144
const onDragStart = useCallback(
156145
(e: React.DragEvent) => {
157-
// Don't start drag if editing
158146
if (isEditing) {
159147
e.preventDefault()
160148
return
@@ -166,12 +154,10 @@ export function FolderItem({ folder, level, hoverHandlers }: FolderItemProps) {
166154
[folder.id]
167155
)
168156

169-
// Item drag hook
170157
const { isDragging, shouldPreventClickRef, handleDragStart, handleDragEnd } = useItemDrag({
171158
onDragStart,
172159
})
173160

174-
// Context menu hook
175161
const {
176162
isOpen: isContextMenuOpen,
177163
position,
@@ -181,7 +167,6 @@ export function FolderItem({ folder, level, hoverHandlers }: FolderItemProps) {
181167
preventDismiss,
182168
} = useContextMenu()
183169

184-
// Rename hook
185170
const {
186171
isEditing,
187172
editValue,
@@ -265,7 +250,6 @@ export function FolderItem({ folder, level, hoverHandlers }: FolderItemProps) {
265250
e.preventDefault()
266251
e.stopPropagation()
267252

268-
// Toggle: close if open, open if closed
269253
if (isContextMenuOpen) {
270254
closeMenu()
271255
return

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

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -79,27 +79,21 @@ export function WorkflowItem({ workflow, active, level, onWorkflowClick }: Workf
7979
// Delete workflow hook
8080
const { isDeleting, handleDeleteWorkflow } = useDeleteWorkflow({
8181
workspaceId,
82-
getWorkflowIds: () => workflowIdsToDelete,
82+
workflowIds: workflowIdsToDelete,
8383
isActive: (workflowIds) => workflowIds.includes(params.workflowId as string),
8484
onSuccess: () => setIsDeleteModalOpen(false),
8585
})
8686

87-
// Duplicate workflow hook
87+
// Duplicate workflow hook (uses captured selection from right-click)
8888
const { handleDuplicateWorkflow } = useDuplicateWorkflow({
8989
workspaceId,
90-
getWorkflowIds: () => {
91-
// Use the selection captured at right-click time
92-
return capturedSelectionRef.current?.workflowIds || []
93-
},
90+
workflowIds: capturedSelectionRef.current?.workflowIds || [],
9491
})
9592

96-
// Export workflow hook
93+
// Export workflow hook (uses captured selection from right-click)
9794
const { handleExportWorkflow } = useExportWorkflow({
9895
workspaceId,
99-
getWorkflowIds: () => {
100-
// Use the selection captured at right-click time
101-
return capturedSelectionRef.current?.workflowIds || []
102-
},
96+
workflowIds: capturedSelectionRef.current?.workflowIds || [],
10397
})
10498

10599
/**

apps/sim/app/workspace/[workspaceId]/w/components/sidebar/sidebar.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ export function Sidebar() {
216216
}, [activeNavItemHref])
217217

218218
const { handleDuplicateWorkspace: duplicateWorkspace } = useDuplicateWorkspace({
219-
getWorkspaceId: () => workspaceId,
219+
workspaceId,
220220
})
221221

222222
const searchModalWorkflows = useMemo(

apps/sim/app/workspace/[workspaceId]/w/hooks/use-delete-folder.ts

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,9 @@ interface UseDeleteFolderProps {
1111
*/
1212
workspaceId: string
1313
/**
14-
* Function that returns the folder ID(s) to delete
15-
* This function is called when deletion occurs to get fresh selection state
14+
* The folder ID(s) to delete
1615
*/
17-
getFolderIds: () => string | string[]
16+
folderIds: string | string[]
1817
/**
1918
* Optional callback after successful deletion
2019
*/
@@ -24,17 +23,10 @@ interface UseDeleteFolderProps {
2423
/**
2524
* Hook for managing folder deletion.
2625
*
27-
* Handles:
28-
* - Single or bulk folder deletion
29-
* - Calling delete API for each folder
30-
* - Loading state management
31-
* - Error handling and logging
32-
* - Clearing selection after deletion
33-
*
3426
* @param props - Hook configuration
3527
* @returns Delete folder handlers and state
3628
*/
37-
export function useDeleteFolder({ workspaceId, getFolderIds, onSuccess }: UseDeleteFolderProps) {
29+
export function useDeleteFolder({ workspaceId, folderIds, onSuccess }: UseDeleteFolderProps) {
3830
const deleteFolderMutation = useDeleteFolderMutation()
3931
const [isDeleting, setIsDeleting] = useState(false)
4032

@@ -46,23 +38,18 @@ export function useDeleteFolder({ workspaceId, getFolderIds, onSuccess }: UseDel
4638
return
4739
}
4840

41+
if (!folderIds) {
42+
return
43+
}
44+
4945
setIsDeleting(true)
5046
try {
51-
// Get fresh folder IDs at deletion time
52-
const folderIdsOrId = getFolderIds()
53-
if (!folderIdsOrId) {
54-
return
55-
}
56-
57-
// Normalize to array for consistent handling
58-
const folderIdsToDelete = Array.isArray(folderIdsOrId) ? folderIdsOrId : [folderIdsOrId]
47+
const folderIdsToDelete = Array.isArray(folderIds) ? folderIds : [folderIds]
5948

60-
// Delete each folder sequentially
6149
for (const folderId of folderIdsToDelete) {
6250
await deleteFolderMutation.mutateAsync({ id: folderId, workspaceId })
6351
}
6452

65-
// Clear selection after successful deletion
6653
const { clearSelection } = useFolderStore.getState()
6754
clearSelection()
6855

@@ -74,7 +61,7 @@ export function useDeleteFolder({ workspaceId, getFolderIds, onSuccess }: UseDel
7461
} finally {
7562
setIsDeleting(false)
7663
}
77-
}, [getFolderIds, isDeleting, deleteFolderMutation, workspaceId, onSuccess])
64+
}, [folderIds, isDeleting, deleteFolderMutation, workspaceId, onSuccess])
7865

7966
return {
8067
isDeleting,

apps/sim/app/workspace/[workspaceId]/w/hooks/use-delete-workflow.ts

Lines changed: 9 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,9 @@ interface UseDeleteWorkflowProps {
1212
*/
1313
workspaceId: string
1414
/**
15-
* Function that returns the workflow ID(s) to delete
16-
* This function is called when deletion occurs to get fresh selection state
15+
* Workflow ID(s) to delete
1716
*/
18-
getWorkflowIds: () => string | string[]
17+
workflowIds: string | string[]
1918
/**
2019
* Whether the active workflow is being deleted
2120
* Can be a boolean or a function that receives the workflow IDs
@@ -30,20 +29,12 @@ interface UseDeleteWorkflowProps {
3029
/**
3130
* Hook for managing workflow deletion with navigation logic.
3231
*
33-
* Handles:
34-
* - Single or bulk workflow deletion
35-
* - Finding next workflow to navigate to
36-
* - Navigating before deletion (if active workflow)
37-
* - Removing workflow(s) from registry
38-
* - Loading state management
39-
* - Error handling and logging
40-
*
4132
* @param props - Hook configuration
4233
* @returns Delete workflow handlers and state
4334
*/
4435
export function useDeleteWorkflow({
4536
workspaceId,
46-
getWorkflowIds,
37+
workflowIds,
4738
isActive = false,
4839
onSuccess,
4940
}: UseDeleteWorkflowProps) {
@@ -59,30 +50,21 @@ export function useDeleteWorkflow({
5950
return
6051
}
6152

53+
if (!workflowIds) {
54+
return
55+
}
56+
6257
setIsDeleting(true)
6358
try {
64-
// Get fresh workflow IDs at deletion time
65-
const workflowIdsOrId = getWorkflowIds()
66-
if (!workflowIdsOrId) {
67-
return
68-
}
69-
70-
// Normalize to array for consistent handling
71-
const workflowIdsToDelete = Array.isArray(workflowIdsOrId)
72-
? workflowIdsOrId
73-
: [workflowIdsOrId]
59+
const workflowIdsToDelete = Array.isArray(workflowIds) ? workflowIds : [workflowIds]
7460

75-
// Determine if active workflow is being deleted
7661
const isActiveWorkflowBeingDeleted =
7762
typeof isActive === 'function' ? isActive(workflowIdsToDelete) : isActive
7863

79-
// Find next workflow to navigate to (if active workflow is being deleted)
8064
const sidebarWorkflows = Object.values(workflows).filter((w) => w.workspaceId === workspaceId)
8165

82-
// Find which specific workflow is the active one (if any in the deletion list)
8366
let activeWorkflowId: string | null = null
8467
if (isActiveWorkflowBeingDeleted && typeof isActive === 'function') {
85-
// Check each workflow being deleted to find which one is active
8668
activeWorkflowId =
8769
workflowIdsToDelete.find((id) => isActive([id])) || workflowIdsToDelete[0]
8870
} else {
@@ -93,13 +75,11 @@ export function useDeleteWorkflow({
9375

9476
let nextWorkflowId: string | null = null
9577
if (isActiveWorkflowBeingDeleted && sidebarWorkflows.length > workflowIdsToDelete.length) {
96-
// Find the first workflow that's not being deleted
9778
const remainingWorkflows = sidebarWorkflows.filter(
9879
(w) => !workflowIdsToDelete.includes(w.id)
9980
)
10081

10182
if (remainingWorkflows.length > 0) {
102-
// Try to find the next workflow after the current one
10383
const workflowsAfterCurrent = remainingWorkflows.filter((w) => {
10484
const idx = sidebarWorkflows.findIndex((sw) => sw.id === w.id)
10585
return idx > currentIndex
@@ -108,13 +88,11 @@ export function useDeleteWorkflow({
10888
if (workflowsAfterCurrent.length > 0) {
10989
nextWorkflowId = workflowsAfterCurrent[0].id
11090
} else {
111-
// Otherwise, use the first remaining workflow
11291
nextWorkflowId = remainingWorkflows[0].id
11392
}
11493
}
11594
}
11695

117-
// Navigate first if this is the active workflow
11896
if (isActiveWorkflowBeingDeleted) {
11997
if (nextWorkflowId) {
12098
router.push(`/workspace/${workspaceId}/w/${nextWorkflowId}`)
@@ -123,10 +101,8 @@ export function useDeleteWorkflow({
123101
}
124102
}
125103

126-
// Delete all workflows
127104
await Promise.all(workflowIdsToDelete.map((id) => removeWorkflow(id)))
128105

129-
// Clear selection after successful deletion
130106
const { clearSelection } = useFolderStore.getState()
131107
clearSelection()
132108

@@ -138,16 +114,7 @@ export function useDeleteWorkflow({
138114
} finally {
139115
setIsDeleting(false)
140116
}
141-
}, [
142-
getWorkflowIds,
143-
isDeleting,
144-
workflows,
145-
workspaceId,
146-
isActive,
147-
router,
148-
removeWorkflow,
149-
onSuccess,
150-
])
117+
}, [workflowIds, isDeleting, workflows, workspaceId, isActive, router, removeWorkflow, onSuccess])
151118

152119
return {
153120
isDeleting,

0 commit comments

Comments
 (0)