diff --git a/sim/app/w/[id]/components/control-bar/control-bar.tsx b/sim/app/w/[id]/components/control-bar/control-bar.tsx index 0c5bb43aca..72c785b490 100644 --- a/sim/app/w/[id]/components/control-bar/control-bar.tsx +++ b/sim/app/w/[id]/components/control-bar/control-bar.tsx @@ -398,7 +398,6 @@ export function ControlBar() { cancelFlagRef.current = false setShowRunProgress(runCount > 1) - let result = null let workflowError = null let wasCancelled = false @@ -411,34 +410,41 @@ export function ControlBar() { wasCancelled = true break } + + // Run the workflow and immediately increment counter for visual feedback await handleRunWorkflow() setCompletedRuns(i + 1) } - // Set multi-running to false immediately after the loop finishes or breaks - setIsMultiRunning(false) - // Update workflow stats only if the run wasn't cancelled and completed normally if (!wasCancelled && activeWorkflowId) { - const response = await fetch(`/api/workflows/${activeWorkflowId}/stats?runs=${runCount}`, { - method: 'POST', - }) - - if (!response.ok) { - const errorData = await response.json() - logger.error(`Failed to update workflow stats: ${JSON.stringify(errorData)}`) - throw new Error('Failed to update workflow stats') + try { + // Don't block UI on stats update + fetch(`/api/workflows/${activeWorkflowId}/stats?runs=${runCount}`, { + method: 'POST', + }).catch((error) => { + logger.error(`Failed to update workflow stats: ${error.message}`) + }) + } catch (error) { + logger.error('Error updating workflow stats:', { error }) } } } catch (error) { workflowError = error logger.error('Error during multiple workflow runs:', { error }) - setIsMultiRunning(false) } finally { - // Keep progress visible for a moment after completion/cancellation + // Always immediately update UI state + setIsMultiRunning(false) + + // Handle progress bar visibility if (runCount > 1) { - setTimeout(() => setShowRunProgress(false), 2000) + // Keep progress visible briefly after completion + setTimeout(() => setShowRunProgress(false), 1000) + } else { + // Immediately hide progress for single runs + setShowRunProgress(false) } + setIsCancelling(false) cancelFlagRef.current = false @@ -447,6 +453,11 @@ export function ControlBar() { addNotification('info', 'Workflow run cancelled', activeWorkflowId) } else if (workflowError) { addNotification('error', 'Failed to complete all workflow runs', activeWorkflowId) + } else { + // Success notification for batch runs + if (runCount > 1) { + addNotification('console', `Completed ${completedRuns} workflow runs`, activeWorkflowId) + } } } } @@ -787,7 +798,7 @@ export function ControlBar() { */ const renderRunButton = () => (
@@ -836,7 +847,7 @@ export function ControlBar() { {isCancelling ? 'Cancelling...' : isMultiRunning - ? `Running` + ? `Running (${completedRuns}/${runCount})` : isExecuting ? isDebugging ? 'Debugging' diff --git a/sim/app/w/[id]/hooks/use-workflow-execution.ts b/sim/app/w/[id]/hooks/use-workflow-execution.ts index c414c0f880..41dc53c03a 100644 --- a/sim/app/w/[id]/hooks/use-workflow-execution.ts +++ b/sim/app/w/[id]/hooks/use-workflow-execution.ts @@ -74,6 +74,9 @@ export function useWorkflowExecution() { const handleRunWorkflow = useCallback(async () => { if (!activeWorkflowId) return + + // Reset execution result and set execution state + setExecutionResult(null) setIsExecuting(true) // Set debug mode if it's enabled in settings @@ -157,9 +160,15 @@ export function useWorkflowExecution() { setPendingBlocks(result.metadata.pendingBlocks) } } else { - // Normal execution completed + // Normal execution completed - start with UI updates setExecutionResult(result) - setIsExecuting(false) + + // For better UI responsiveness, update state immediately + if (!isDebugModeEnabled) { + // Reset execution states right away for UI to update + setIsExecuting(false) + setIsDebugging(false) + } // Show notification addNotification( @@ -170,9 +179,11 @@ export function useWorkflowExecution() { activeWorkflowId ) - // In non-debug mode, persist logs - await persistLogs(executionId, result) - setIsDebugging(false) + // In non-debug mode, persist logs (no need to wait for this) + // We explicitly don't await this to avoid blocking UI updates + persistLogs(executionId, result).catch((err) => { + logger.error('Error persisting logs:', { error: err }) + }) } } catch (error: any) { logger.error('Workflow Execution Error:', error) @@ -224,8 +235,10 @@ export function useWorkflowExecution() { logs: [], } + // Update UI state immediately for better responsiveness setExecutionResult(errorResult) setIsExecuting(false) + setIsDebugging(false) // Create a more user-friendly notification message let notificationMessage = `Workflow execution failed` @@ -255,9 +268,10 @@ export function useWorkflowExecution() { console.error('Workflow execution failed:', errorMessage) } - // Also send the error result to the API - await persistLogs(executionId, errorResult) - setIsDebugging(false) + // Also send the error result to the API (don't await to keep UI responsive) + persistLogs(executionId, errorResult).catch((err) => { + logger.error('Error persisting logs:', { error: err }) + }) } }, [ activeWorkflowId, @@ -273,6 +287,7 @@ export function useWorkflowExecution() { setIsExecuting, setIsDebugging, isDebugModeEnabled, + isDebugging, ]) /**