Improve selection of start node for manual execution

This commit is contained in:
Jan Oberhauser 2019-08-02 12:26:51 +02:00
parent b38623fa92
commit f568122e3a
2 changed files with 56 additions and 34 deletions

View file

@ -46,36 +46,36 @@ export class WorkflowExecute {
* @returns {(Promise<string>)} * @returns {(Promise<string>)}
* @memberof WorkflowExecute * @memberof WorkflowExecute
*/ */
async run(workflow: Workflow, startNodes?: INode[], destinationNode?: string): Promise<string> { async run(workflow: Workflow, startNode?: INode, destinationNode?: string): Promise<string> {
// Get the nodes to start workflow execution from // Get the nodes to start workflow execution from
startNodes = startNodes || workflow.getStartNodes(destinationNode); startNode = startNode || workflow.getStartNode(destinationNode);
if (startNode === undefined) {
throw new Error('No node to start the workflow from could be found!');
}
// If a destination node is given we only run the direct parent nodes and no others // If a destination node is given we only run the direct parent nodes and no others
let runNodeFilter: string[] | undefined = undefined; let runNodeFilter: string[] | undefined = undefined;
if (destinationNode) { if (destinationNode) {
// TODO: Combine that later with getStartNodes which does more or less the same tree iteration
runNodeFilter = workflow.getParentNodes(destinationNode); runNodeFilter = workflow.getParentNodes(destinationNode);
runNodeFilter.push(destinationNode); runNodeFilter.push(destinationNode);
} }
// Initialize the data of the start nodes // Initialize the data of the start nodes
const nodeExecutionStack: IExecuteData[] = []; const nodeExecutionStack: IExecuteData[] = [
startNodes.forEach((node) => { {
nodeExecutionStack.push( node: startNode,
{ data: {
node, main: [
data: { [
main: [ {
[ json: {},
{ },
json: {},
},
],
], ],
}, ],
}, },
); }
}); ];
const runExecutionData: IRunExecutionData = { const runExecutionData: IRunExecutionData = {
startData: { startData: {

View file

@ -707,40 +707,62 @@ export class Workflow {
/** /**
* Return all the start nodes which can be found in the workflow. * Returns the start node to start the worfklow from
* *
* @param {(string | undefined)} [destinationNode] * @param {string} [destinationNode]
* @returns {INode[]} * @returns {(INode | undefined)}
* @memberof Workflow * @memberof Workflow
*/ */
getStartNodes(destinationNode?: string): INode[] { getStartNode(destinationNode?: string): INode | undefined {
const returnData: INode[] = []; const startNodeType = 'n8n-nodes-base.start';
if (destinationNode) { if (destinationNode) {
// Find the highest parent nodes of the given one // Find the highest parent nodes of the given one
const nodeNames = this.getHighestNode(destinationNode); const nodeNames = this.getHighestNode(destinationNode);
if (nodeNames.length === 0) { if (nodeNames.length === 0) {
// If no parent nodes have been found then only the destination-node // If no parent nodes have been found then only the destination-node
// is in the tree so add that one // is in the tree so add that one
nodeNames.push(destinationNode); nodeNames.push(destinationNode);
} }
nodeNames.forEach((nodeName) => { // Check which node to return as start node
returnData.push(this.nodes[nodeName]);
});
} else {
// No node given so find all the nodes which do not have any input
let nodeType: INodeType | undefined;
for (const nodeName of Object.keys(this.nodes)) {
nodeType = this.nodeTypes.getByName(this.nodes[nodeName].type);
if (nodeType !== undefined && nodeType.description.inputs.length === 0 && this.nodes[nodeName].disabled !== true) { // Check if there are any trigger nodes and then return the first one
returnData.push(this.nodes[nodeName]); let node: INode;
let nodeType: INodeType;
for (const nodeName of nodeNames) {
node = this.nodes[nodeName];
nodeType = this.nodeTypes.getByName(node.type) as INodeType;
if (nodeType.trigger !== undefined) {
return node;
}
}
// Check if there is the actual "start" node
for (const nodeName of nodeNames) {
node = this.nodes[nodeName];
if (node.type === startNodeType) {
return node;
}
}
// If none of the above did find anything simply return the
// first parent node in the list
return this.nodes[nodeNames[0]];
} else {
// No node given so start from "start" node
let node: INode;
for (const nodeName of Object.keys(this.nodes)) {
node = this.nodes[nodeName];
if (node.type === startNodeType) {
return node;
} }
} }
} }
return returnData; return undefined;
} }