diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel-new/hooks/index.ts b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel-new/hooks/index.ts index 2fa024fd28..e6b8861987 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel-new/hooks/index.ts +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel-new/hooks/index.ts @@ -1,3 +1,2 @@ export { usePanelResize } from './use-panel-resize' -export { useRunWorkflow } from './use-run-workflow' export { type UsageData, useUsageLimits } from './use-usage-limits' diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel-new/hooks/use-run-workflow.ts b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel-new/hooks/use-run-workflow.ts deleted file mode 100644 index e13cc621cf..0000000000 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel-new/hooks/use-run-workflow.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { useCallback } from 'react' -import { createLogger } from '@/lib/logs/console/logger' -import { useWorkflowExecution } from '@/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-workflow-execution' - -const logger = createLogger('useRunWorkflow') - -/** - * Custom hook to handle workflow execution with usage limit checks. - * Provides a unified way to run workflows from anywhere in the codebase. - * - * Features: - * - Automatic usage limit checking - * - Handles execution state - * - * @param options - Configuration options - * @param options.usageExceeded - Whether usage limit is exceeded (required) - * @param options.onBeforeRun - Optional callback before running workflow - * @param options.onAfterRun - Optional callback after running workflow - * @returns Run workflow function and related state - */ -export function useRunWorkflow(options: { - usageExceeded: boolean - onBeforeRun?: () => void | Promise - onAfterRun?: () => void | Promise -}) { - const { usageExceeded, onBeforeRun, onAfterRun } = options - - const { handleRunWorkflow, isExecuting, handleCancelExecution } = useWorkflowExecution() - - /** - * Runs the workflow with automatic checks and UI management - */ - const runWorkflow = useCallback(async () => { - try { - // Execute before run callback - if (onBeforeRun) { - await onBeforeRun() - } - - // Check if usage is exceeded - if (usageExceeded) { - logger.warn('Usage limit exceeded, opening subscription settings') - return - } - - // Run the workflow - await handleRunWorkflow(undefined) - - // Execute after run callback - if (onAfterRun) { - await onAfterRun() - } - } catch (error) { - logger.error('Error running workflow:', { error }) - } - }, [usageExceeded, onBeforeRun, onAfterRun, handleRunWorkflow]) - - /** - * Cancels the currently executing workflow - */ - const cancelWorkflow = useCallback(async () => { - try { - await handleCancelExecution() - logger.info('Workflow execution cancelled') - } catch (error) { - logger.error('Error cancelling workflow:', { error }) - } - }, [handleCancelExecution]) - - return { - runWorkflow, - cancelWorkflow, - isExecuting, - } -} diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel-new/panel-new.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel-new/panel-new.tsx index b6615551b9..b730ee4cde 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel-new/panel-new.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel-new/panel-new.tsx @@ -26,6 +26,7 @@ import { createLogger } from '@/lib/logs/console/logger' import { useRegisterGlobalCommands } from '@/app/workspace/[workspaceId]/providers/global-commands-provider' import { useUserPermissionsContext } from '@/app/workspace/[workspaceId]/providers/workspace-permissions-provider' import { Variables } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/variables/variables' +import { useWorkflowExecution } from '@/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-workflow-execution' import { useDeleteWorkflow } from '@/app/workspace/[workspaceId]/w/hooks' import { useChatStore } from '@/stores/chat/store' import { usePanelStore } from '@/stores/panel-new/store' @@ -35,7 +36,7 @@ import { useWorkflowJsonStore } from '@/stores/workflows/json/store' import { useWorkflowRegistry } from '@/stores/workflows/registry/store' import { useWorkflowStore } from '@/stores/workflows/workflow/store' import { Copilot, Deploy, Editor, Toolbar } from './components' -import { usePanelResize, useRunWorkflow, useUsageLimits } from './hooks' +import { usePanelResize, useUsageLimits } from './hooks' const logger = createLogger('Panel') /** @@ -99,12 +100,43 @@ export function Panel() { autoRefresh: !isRegistryLoading, }) - // Run workflow hook - const { runWorkflow, cancelWorkflow, isExecuting } = useRunWorkflow({ usageExceeded }) + // Workflow execution hook + const { handleRunWorkflow, handleCancelExecution, isExecuting } = useWorkflowExecution() // Panel resize hook const { handleMouseDown } = usePanelResize() + /** + * Opens subscription settings modal + */ + const openSubscriptionSettings = () => { + if (typeof window !== 'undefined') { + window.dispatchEvent( + new CustomEvent('open-settings', { + detail: { tab: 'subscription' }, + }) + ) + } + } + + /** + * Runs the workflow with usage limit check + */ + const runWorkflow = useCallback(async () => { + if (usageExceeded) { + openSubscriptionSettings() + return + } + await handleRunWorkflow() + }, [usageExceeded, handleRunWorkflow]) + + /** + * Cancels the currently executing workflow + */ + const cancelWorkflow = useCallback(async () => { + await handleCancelExecution() + }, [handleCancelExecution]) + // Chat state const { isChatOpen, setIsChatOpen } = useChatStore() const { isOpen: isVariablesOpen, setIsOpen: setVariablesOpen } = useVariablesStore() diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-workflow-execution.ts b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-workflow-execution.ts index ba78faa2d9..b781b081a7 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-workflow-execution.ts +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-workflow-execution.ts @@ -20,6 +20,7 @@ import { type ConsoleEntry, useTerminalConsoleStore } from '@/stores/terminal' import { useWorkflowDiffStore } from '@/stores/workflow-diff' import { useWorkflowRegistry } from '@/stores/workflows/registry/store' import { mergeSubblockState } from '@/stores/workflows/utils' +import { useWorkflowStore } from '@/stores/workflows/workflow/store' import { useCurrentWorkflow } from './use-current-workflow' const logger = createLogger('useWorkflowExecution') @@ -671,10 +672,14 @@ export function useWorkflowExecution() { const executionWorkflowState = hasActiveDiffWorkflow && executionDiffWorkflow ? executionDiffWorkflow : null const usingDiffForExecution = executionWorkflowState !== null + + // Read blocks and edges directly from store to ensure we get the latest state, + // even if React hasn't re-rendered yet after adding blocks/edges + const latestWorkflowState = useWorkflowStore.getState().getWorkflowState() const workflowBlocks = (executionWorkflowState?.blocks ?? - currentWorkflow.blocks) as typeof currentWorkflow.blocks + latestWorkflowState.blocks) as typeof currentWorkflow.blocks const workflowEdges = (executionWorkflowState?.edges ?? - currentWorkflow.edges) as typeof currentWorkflow.edges + latestWorkflowState.edges) as typeof currentWorkflow.edges // Filter out blocks without type (these are layout-only blocks) const validBlocks = Object.entries(workflowBlocks).reduce(