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,24 +46,25 @@ export class WorkflowExecute {
* @returns {(Promise<string>)}
* @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
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
let runNodeFilter: string[] | undefined = undefined;
if (destinationNode) {
// TODO: Combine that later with getStartNodes which does more or less the same tree iteration
runNodeFilter = workflow.getParentNodes(destinationNode);
runNodeFilter.push(destinationNode);
}
// Initialize the data of the start nodes
const nodeExecutionStack: IExecuteData[] = [];
startNodes.forEach((node) => {
nodeExecutionStack.push(
const nodeExecutionStack: IExecuteData[] = [
{
node,
node: startNode,
data: {
main: [
[
@ -73,9 +74,8 @@ export class WorkflowExecute {
],
],
},
},
);
});
}
];
const runExecutionData: IRunExecutionData = {
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]
* @returns {INode[]}
* @param {string} [destinationNode]
* @returns {(INode | undefined)}
* @memberof Workflow
*/
getStartNodes(destinationNode?: string): INode[] {
const returnData: INode[] = [];
getStartNode(destinationNode?: string): INode | undefined {
const startNodeType = 'n8n-nodes-base.start';
if (destinationNode) {
// Find the highest parent nodes of the given one
const nodeNames = this.getHighestNode(destinationNode);
if (nodeNames.length === 0) {
// If no parent nodes have been found then only the destination-node
// is in the tree so add that one
nodeNames.push(destinationNode);
}
nodeNames.forEach((nodeName) => {
returnData.push(this.nodes[nodeName]);
});
// Check which node to return as start node
// Check if there are any trigger nodes and then return the first one
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 find all the nodes which do not have any input
let nodeType: INodeType | undefined;
// No node given so start from "start" node
let node: INode;
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) {
returnData.push(this.nodes[nodeName]);
node = this.nodes[nodeName];
if (node.type === startNodeType) {
return node;
}
}
}
return returnData;
return undefined;
}