@@ -58,6 +58,7 @@ import {
5858 getDescendantBlockIds ,
5959 getEdgeSelectionContextId ,
6060 getNodeSelectionContextId ,
61+ getRunFromBlockDependencyState ,
6162 getWorkflowLockToggleIds ,
6263 isBlockProtected ,
6364 isEdgeProtected ,
@@ -93,7 +94,11 @@ import { useCollaborativeWorkflow } from '@/hooks/use-collaborative-workflow'
9394import { useOAuthReturnForWorkflow } from '@/hooks/use-oauth-return'
9495import { useCanvasModeStore } from '@/stores/canvas-mode'
9596import { useChatStore } from '@/stores/chat/store'
96- import { defaultWorkflowExecutionState , useExecutionStore } from '@/stores/execution'
97+ import {
98+ defaultWorkflowExecutionState ,
99+ useExecutionStore ,
100+ useLastExecutionSnapshot ,
101+ } from '@/stores/execution'
97102import { useSearchModalStore } from '@/stores/modals/search/store'
98103import type { PendingConnect } from '@/stores/modals/search/types'
99104import { usePanelEditorStore } from '@/stores/panel'
@@ -839,7 +844,7 @@ const WorkflowContent = React.memo(
839844 }
840845 } )
841846 )
842- const getLastExecutionSnapshot = useExecutionStore ( ( s ) => s . getLastExecutionSnapshot )
847+ const lastExecutionSnapshot = useLastExecutionSnapshot ( workflowIdParam )
843848
844849 const [ dragStartParentId , setDragStartParentId ] = useState < string | null > ( null )
845850
@@ -1386,22 +1391,11 @@ const WorkflowContent = React.memo(
13861391 return { canRun : false , reason : undefined }
13871392 }
13881393 const block = contextMenuBlocks [ 0 ]
1389- const snapshot = getLastExecutionSnapshot ( workflowIdParam )
1390- const incomingEdges = edges . filter ( ( edge ) => edge . target === block . id )
1391- const isTriggerBlock = incomingEdges . length === 0
1392-
1393- // Check if each source block is either executed OR is a trigger block (triggers don't need prior execution)
1394- const isSourceSatisfied = ( sourceId : string ) => {
1395- if ( snapshot ?. executedBlocks . includes ( sourceId ) ) return true
1396- // Check if source is a trigger (has no incoming edges itself)
1397- const sourceIncomingEdges = edges . filter ( ( edge ) => edge . target === sourceId )
1398- return sourceIncomingEdges . length === 0
1399- }
1400-
1401- // Non-trigger blocks need a snapshot to exist (so upstream outputs are available)
1402- const dependenciesSatisfied =
1403- isTriggerBlock ||
1404- ( snapshot && incomingEdges . every ( ( edge ) => isSourceSatisfied ( edge . source ) ) )
1394+ const { dependenciesSatisfied } = getRunFromBlockDependencyState (
1395+ block . id ,
1396+ edges ,
1397+ lastExecutionSnapshot
1398+ )
14051399 const isNoteBlock = block . type === 'note'
14061400 const isInsideSubflow =
14071401 block . parentId && ( block . parentType === 'loop' || block . parentType === 'parallel' )
@@ -1412,7 +1406,7 @@ const WorkflowContent = React.memo(
14121406 if ( isExecuting ) return { canRun : false , reason : undefined }
14131407
14141408 return { canRun : true , reason : undefined }
1415- } , [ contextMenuBlocks , edges , workflowIdParam , getLastExecutionSnapshot , isExecuting ] )
1409+ } , [ contextMenuBlocks , edges , lastExecutionSnapshot , isExecuting ] )
14161410
14171411 const handleContextAddBlock = useCallback ( ( ) => {
14181412 useSearchModalStore . getState ( ) . open ( )
0 commit comments