import { IExecutionPushResponse , IExecutionResponse , IStartRunData , } from '@/Interface' ; import { IRunData , IRunExecutionData , NodeHelpers , } from 'n8n-workflow' ; import { externalHooks } from '@/components/mixins/externalHooks' ; import { restApi } from '@/components/mixins/restApi' ; import { workflowHelpers } from '@/components/mixins/workflowHelpers' ; import { showMessage } from '@/components/mixins/showMessage' ; import mixins from 'vue-typed-mixins' ; import { titleChange } from './titleChange' ; export const workflowRun = mixins ( externalHooks , restApi , workflowHelpers , showMessage , titleChange ) . extend ( { methods : { async runWorkflowApi ( runData ) { if ( this . $store . getters . pushConnectionActive === false ) { throw new Error ( this . $locale . baseText ( 'workflowRun.noActiveConnectionToTheServer' ) ) ; } this . $store . commit ( 'addActiveAction' , 'workflowRunning' ) ; let response ; try { response = await this . restApi ( ) . runWorkflow ( runData ) ; } catch ( error ) { this . $store . commit ( 'removeActiveAction' , 'workflowRunning' ) ; throw error ; } if ( response . executionId !== undefined ) { this . $store . commit ( 'setActiveExecutionId' , response . executionId ) ; } if ( response . waitingForWebhook === true ) { this . $store . commit ( 'setExecutionWaitingForWebhook' , true ) ; } return response ; } , async runWorkflow ( nodeName ? , source ? ) { const workflow = this . getWorkflow ( ) ; if ( nodeName ) { this . $telemetry . track ( 'User clicked execute node button' , { node_type : nodeName , workflow_id : this . $store . getters . workflowId } ) ; } else { this . $telemetry . track ( 'User clicked execute workflow button' , { workflow_id : this . $store . getters . workflowId } ) ; } if ( this . $store . getters . isActionActive ( 'workflowRunning' ) === true ) { return ; } this . $titleSet ( workflow . name as string , 'EXECUTING' ) ; this . clearAllStickyNotifications ( ) ; try { const issuesExist = this . $store . getters . nodesIssuesExist ; if ( issuesExist === true ) { const workflowIssues = this . checkReadyForExecution ( workflow , nodeName ) ; if ( workflowIssues !== null ) { const errorMessages = [ ] ; let nodeIssues ; for ( const nodeName of Object . keys ( workflowIssues ) ) { nodeIssues = NodeHelpers . nodeIssuesToString ( workflowIssues [ nodeName ] ) ; for ( const nodeIssue of nodeIssues ) { errorMessages . push ( `${ nodeName }: ${ nodeIssue }` ) ; } } this . $showMessage ( { title : this . $locale . baseText ( 'workflowRun.showMessage.title' ) , message : this . $locale . baseText ( 'workflowRun.showMessage.message' ) + ':<br />&nbsp;&nbsp;- ' + errorMessages . join ( '<br />&nbsp;&nbsp;- ' ) , type : 'error' , duration : 0 , } ) ; this . $titleSet ( workflow . name as string , 'ERROR' ) ; this . $externalHooks ( ) . run ( 'workflowRun.runError' , { errorMessages , nodeName } ) ; return ; } } let directParentNodes = [ ] ; if ( nodeName !== undefined ) { directParentNodes = workflow . getParentNodes ( nodeName , 'main' , 1 ) ; } const runData = this . $store . getters . getWorkflowRunData ; let newRunData ; const startNodes = [ ] ; if ( runData !== null && Object . keys ( runData ) . length !== 0 ) { newRunData = { } ; for ( const directParentNode of directParentNodes ) { const parentNodes = workflow . getParentNodes ( directParentNode , 'main' ) ; parentNodes . push ( directParentNode ) ; for ( const parentNode of parentNodes ) { if ( runData [ parentNode ] === undefined || runData [ parentNode ] . length === 0 ) { startNodes . push ( parentNode ) ; break ; } newRunData [ parentNode ] = runData [ parentNode ] . slice ( 0 , 1 ) ; } } if ( Object . keys ( newRunData ) . length === 0 ) { newRunData = undefined ; } } if ( startNodes . length === 0 && nodeName !== undefined ) { startNodes . push ( nodeName ) ; } const isNewWorkflow = this . $store . getters . isNewWorkflow ; const hasWebhookNode = this . $store . getters . currentWorkflowHasWebhookNode ; if ( isNewWorkflow && hasWebhookNode ) { await this . saveCurrentWorkflow ( ) ; } const workflowData = await this . getWorkflowDataToSave ( ) ; const startRunData = { workflowData , runData : newRunData , startNodes , } ; if ( nodeName ) { startRunData . destinationNode = nodeName ; } const executionData = { id : '__IN_PROGRESS__' , finished : false , mode : 'manual' , startedAt : new Date ( ) , stoppedAt : undefined , workflowId : workflow . id , data : { resultData : { runData : newRunData || { } , startNodes , workflowData , } , } as IRunExecutionData , workflowData : { id : this . $store . getters . workflowId , name : workflowData . name ! , active : workflowData . active ! , createdAt : 0 , updatedAt : 0 , ... workflowData , } , } ; this . $store . commit ( 'setWorkflowExecutionData' , executionData ) ; this . updateNodesExecutionIssues ( ) ; const runWorkflowApiResponse = await this . runWorkflowApi ( startRunData ) ; this . $externalHooks ( ) . run ( 'workflowRun.runWorkflow' , { nodeName , source } ) ; return runWorkflowApiResponse ; } catch ( error ) { this . $titleSet ( workflow . name as string , 'ERROR' ) ; this . $showError ( error , this . $locale . baseText ( 'workflowRun.showError.title' ) , this . $locale . baseText ( 'workflowRun.showError.message' ) ) ; return undefined ; } } , } , } ) ;