mirror of
https://github.com/ansible/awx.git
synced 2024-11-01 16:51:11 +03:00
First pass at implementing better node placement in the workflow graph
This commit is contained in:
parent
7b95d2114d
commit
61fb3eb390
@ -5,7 +5,9 @@
|
||||
*************************************************/
|
||||
|
||||
import workflowChart from './workflow-chart.directive';
|
||||
import workflowChartService from './workflow-chart.service';
|
||||
|
||||
export default
|
||||
angular.module('workflowChart', [])
|
||||
.directive('workflowChart', workflowChart);
|
||||
.directive('workflowChart', workflowChart)
|
||||
.service('WorkflowChartService', workflowChartService);
|
||||
|
@ -56,7 +56,7 @@ export default ['$state','moment', '$timeout', '$window', '$filter', 'Rest', 'Ge
|
||||
function init() {
|
||||
force = d3.layout.force()
|
||||
.gravity(0)
|
||||
.charge(-60)
|
||||
.charge(-300)
|
||||
.linkDistance(300)
|
||||
.size([windowHeight, windowWidth]);
|
||||
|
||||
@ -1003,6 +1003,7 @@ export default ['$state','moment', '$timeout', '$window', '$filter', 'Rest', 'Ge
|
||||
}
|
||||
});
|
||||
|
||||
// TODO: this
|
||||
// if(scope.treeState.arrayOfNodesForChart && scope.treeState.arrayOfNodesForChart > 1 && !graphLoaded) {
|
||||
// zoomToFitChart();
|
||||
// }
|
||||
@ -1010,14 +1011,14 @@ export default ['$state','moment', '$timeout', '$window', '$filter', 'Rest', 'Ge
|
||||
graphLoaded = true;
|
||||
|
||||
// This will make sure that all the link elements appear before the nodes in the dom
|
||||
// TODO: i don't think this is working...
|
||||
svgGroup.selectAll(".WorkflowChart-node").order();
|
||||
|
||||
let tick = (e) => {
|
||||
var k = 6 * e.alpha;
|
||||
|
||||
// TODO: replace hard-coded 60 here
|
||||
let tick = () => {
|
||||
linkLines
|
||||
.each(function(d) { d.source.y -= k; d.target.y += k; })
|
||||
.each(function(d) {
|
||||
d.target.y = scope.treeState.depthMap[d.target.id] * 300;
|
||||
})
|
||||
.attr("x1", function(d) { return d.target.y; })
|
||||
.attr("y1", function(d) { return d.target.x + (nodeH/2); })
|
||||
.attr("x2", function(d) { return d.source.index === 0 ? (scope.mode === 'details' ? d.source.y + 25 : d.source.y + 60) : (d.source.y + nodeW); })
|
||||
|
@ -0,0 +1,144 @@
|
||||
export default [function(){
|
||||
return {
|
||||
generateDepthMap: (arrayOfLinks) => {
|
||||
let depthMap = {};
|
||||
let nodesWithChildren = {};
|
||||
|
||||
let walkBranch = (nodeId, depth) => {
|
||||
depthMap[nodeId] = depthMap[nodeId] ? (depth > depthMap[nodeId] ? depth : depthMap[nodeId]) : depth;
|
||||
if (nodesWithChildren[nodeId]) {
|
||||
_.forEach(nodesWithChildren[nodeId].children, (childNodeId) => {
|
||||
walkBranch(childNodeId, depth+1);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
let rootNodeIds = [];
|
||||
arrayOfLinks.forEach(link => {
|
||||
// link.source.index of 0 is our artificial start node
|
||||
if (link.source.index !== 0) {
|
||||
if (!nodesWithChildren[link.source.id]) {
|
||||
nodesWithChildren[link.source.id] = {
|
||||
children: []
|
||||
};
|
||||
}
|
||||
|
||||
nodesWithChildren[link.source.id].children.push(link.target.id);
|
||||
} else {
|
||||
// Store the fact that might be a root node
|
||||
rootNodeIds.push(link.target.id);
|
||||
}
|
||||
});
|
||||
|
||||
_.forEach(rootNodeIds, function(rootNodeId) {
|
||||
walkBranch(rootNodeId, 1);
|
||||
depthMap[rootNodeId] = 1;
|
||||
});
|
||||
|
||||
return depthMap;
|
||||
},
|
||||
generateArraysOfNodesAndLinks: function(allNodes) {
|
||||
let nonRootNodeIds = [];
|
||||
let allNodeIds = [];
|
||||
let arrayOfLinksForChart = [];
|
||||
let nodeIdToChartNodeIdMapping = {};
|
||||
let chartNodeIdToIndexMapping = {};
|
||||
let nodeRef = {};
|
||||
let nodeIdCounter = 1;
|
||||
let arrayOfNodesForChart = [
|
||||
{
|
||||
index: 0,
|
||||
id: nodeIdCounter,
|
||||
isStartNode: true,
|
||||
unifiedJobTemplate: {
|
||||
name: "START"
|
||||
},
|
||||
fixed: true,
|
||||
x: 0,
|
||||
y: 0
|
||||
}
|
||||
];
|
||||
nodeIdCounter++;
|
||||
// Assign each node an ID - 0 is reserved for the start node. We need to
|
||||
// make sure that we have an ID on every node including new nodes so the
|
||||
// ID returned by the api won't do
|
||||
allNodes.forEach((node) => {
|
||||
node.workflowMakerNodeId = nodeIdCounter;
|
||||
nodeRef[nodeIdCounter] = {
|
||||
originalNodeObject: node
|
||||
};
|
||||
|
||||
const nodeObj = {
|
||||
index: nodeIdCounter-1,
|
||||
id: nodeIdCounter
|
||||
};
|
||||
|
||||
if(node.summary_fields.job) {
|
||||
nodeObj.job = node.summary_fields.job;
|
||||
}
|
||||
if(node.summary_fields.unified_job_template) {
|
||||
nodeObj.unifiedJobTemplate = node.summary_fields.unified_job_template;
|
||||
}
|
||||
|
||||
arrayOfNodesForChart.push(nodeObj);
|
||||
allNodeIds.push(node.id);
|
||||
nodeIdToChartNodeIdMapping[node.id] = node.workflowMakerNodeId;
|
||||
chartNodeIdToIndexMapping[nodeIdCounter] = nodeIdCounter-1;
|
||||
nodeIdCounter++;
|
||||
});
|
||||
|
||||
allNodes.forEach((node) => {
|
||||
const sourceIndex = chartNodeIdToIndexMapping[node.workflowMakerNodeId];
|
||||
node.success_nodes.forEach((nodeId) => {
|
||||
const targetIndex = chartNodeIdToIndexMapping[nodeIdToChartNodeIdMapping[nodeId]];
|
||||
arrayOfLinksForChart.push({
|
||||
source: arrayOfNodesForChart[sourceIndex],
|
||||
target: arrayOfNodesForChart[targetIndex],
|
||||
edgeType: "success"
|
||||
});
|
||||
nonRootNodeIds.push(nodeId);
|
||||
});
|
||||
node.failure_nodes.forEach((nodeId) => {
|
||||
const targetIndex = chartNodeIdToIndexMapping[nodeIdToChartNodeIdMapping[nodeId]];
|
||||
arrayOfLinksForChart.push({
|
||||
source: arrayOfNodesForChart[sourceIndex],
|
||||
target: arrayOfNodesForChart[targetIndex],
|
||||
edgeType: "failure"
|
||||
});
|
||||
nonRootNodeIds.push(nodeId);
|
||||
});
|
||||
node.always_nodes.forEach((nodeId) => {
|
||||
const targetIndex = chartNodeIdToIndexMapping[nodeIdToChartNodeIdMapping[nodeId]];
|
||||
arrayOfLinksForChart.push({
|
||||
source: arrayOfNodesForChart[sourceIndex],
|
||||
target: arrayOfNodesForChart[targetIndex],
|
||||
edgeType: "always"
|
||||
});
|
||||
nonRootNodeIds.push(nodeId);
|
||||
});
|
||||
});
|
||||
|
||||
let uniqueNonRootNodeIds = Array.from(new Set(nonRootNodeIds));
|
||||
|
||||
let rootNodes = _.difference(allNodeIds, uniqueNonRootNodeIds);
|
||||
|
||||
rootNodes.forEach((rootNodeId) => {
|
||||
const targetIndex = chartNodeIdToIndexMapping[nodeIdToChartNodeIdMapping[rootNodeId]];
|
||||
arrayOfLinksForChart.push({
|
||||
source: arrayOfNodesForChart[0],
|
||||
target: arrayOfNodesForChart[targetIndex],
|
||||
edgeType: "always"
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
arrayOfNodesForChart,
|
||||
arrayOfLinksForChart,
|
||||
chartNodeIdToIndexMapping,
|
||||
nodeIdToChartNodeIdMapping,
|
||||
nodeRef,
|
||||
workflowMakerNodeIdCounter: nodeIdCounter
|
||||
};
|
||||
}
|
||||
};
|
||||
}];
|
@ -6,10 +6,10 @@
|
||||
|
||||
export default ['$scope', 'TemplatesService',
|
||||
'ProcessErrors', 'CreateSelect2', '$q', 'JobTemplateModel',
|
||||
'Empty', 'PromptService', 'Rest', 'TemplatesStrings',
|
||||
'Empty', 'PromptService', 'Rest', 'TemplatesStrings', 'WorkflowChartService',
|
||||
function ($scope, TemplatesService,
|
||||
ProcessErrors, CreateSelect2, $q, JobTemplate,
|
||||
Empty, PromptService, Rest, TemplatesStrings) {
|
||||
Empty, PromptService, Rest, TemplatesStrings, WorkflowChartService) {
|
||||
|
||||
$scope.strings = TemplatesStrings;
|
||||
// TODO: I don't think this needs to be on scope but changing it will require changes to
|
||||
@ -19,13 +19,10 @@ export default ['$scope', 'TemplatesService',
|
||||
let credentialRequests = [];
|
||||
let deletedNodeIds = [];
|
||||
let workflowMakerNodeIdCounter = 1;
|
||||
let nodeIdToMakerIdMapping = {};
|
||||
let nodeIdToChartNodeIdMapping = {};
|
||||
let chartNodeIdToIndexMapping = {};
|
||||
let nodeRef = {};
|
||||
|
||||
// TODO: fix this
|
||||
$scope.totalNodes = 0;
|
||||
|
||||
$scope.showKey = false;
|
||||
$scope.toggleKey = () => $scope.showKey = !$scope.showKey;
|
||||
$scope.keyClassList = `{ 'Key-menuIcon--active': showKey }`;
|
||||
@ -108,7 +105,7 @@ export default ['$scope', 'TemplatesService',
|
||||
}).then(({data}) => {
|
||||
nodeRef[workflowMakerNodeId].originalNodeObject = data;
|
||||
// TODO: do we need this?
|
||||
nodeIdToMakerIdMapping[data.id] = parseInt(workflowMakerNodeId);
|
||||
nodeIdToChartNodeIdMapping[data.id] = parseInt(workflowMakerNodeId);
|
||||
// if (_.get(params, 'node.promptData.launchConf.ask_credential_on_launch')) {
|
||||
// // This finds the credentials that were selected in the prompt but don't occur
|
||||
// // in the template defaults
|
||||
@ -222,8 +219,8 @@ export default ['$scope', 'TemplatesService',
|
||||
|
||||
Object.keys(linkMap).map((sourceNodeId) => {
|
||||
Object.keys(linkMap[sourceNodeId]).map((targetNodeId) => {
|
||||
const foo = nodeIdToMakerIdMapping[sourceNodeId];
|
||||
const bar = nodeIdToMakerIdMapping[targetNodeId];
|
||||
const foo = nodeIdToChartNodeIdMapping[sourceNodeId];
|
||||
const bar = nodeIdToChartNodeIdMapping[targetNodeId];
|
||||
switch(linkMap[sourceNodeId][targetNodeId]) {
|
||||
case "success":
|
||||
if (
|
||||
@ -340,6 +337,8 @@ export default ['$scope', 'TemplatesService',
|
||||
|
||||
workflowMakerNodeIdCounter++;
|
||||
|
||||
$scope.treeState.depthMap = WorkflowChartService.generateDepthMap($scope.treeState.arrayOfLinksForChart);
|
||||
|
||||
$scope.$broadcast("refreshWorkflowChart");
|
||||
|
||||
$scope.formState.showNodeForm = true;
|
||||
@ -381,6 +380,8 @@ export default ['$scope', 'TemplatesService',
|
||||
|
||||
workflowMakerNodeIdCounter++;
|
||||
|
||||
$scope.treeState.depthMap = WorkflowChartService.generateDepthMap($scope.treeState.arrayOfLinksForChart);
|
||||
|
||||
$scope.$broadcast("refreshWorkflowChart");
|
||||
|
||||
$scope.formState.showNodeForm = true;
|
||||
@ -476,6 +477,8 @@ export default ['$scope', 'TemplatesService',
|
||||
chartNodeIdToIndexMapping[key]--;
|
||||
}
|
||||
}
|
||||
|
||||
$scope.treeState.depthMap = WorkflowChartService.generateDepthMap($scope.treeState.arrayOfLinksForChart);
|
||||
} else if ($scope.nodeConfig.mode === "edit") {
|
||||
$scope.treeState.arrayOfNodesForChart.map( (node) => {
|
||||
if (node.index === $scope.nodeConfig.nodeId) {
|
||||
@ -562,6 +565,7 @@ export default ['$scope', 'TemplatesService',
|
||||
// User is going from editing one link to editing another
|
||||
if ($scope.linkConfig.mode === "add") {
|
||||
$scope.treeState.arrayOfLinksForChart.splice($scope.treeState.arrayOfLinksForChart.length-1, 1);
|
||||
$scope.treeState.depthMap = WorkflowChartService.generateDepthMap($scope.treeState.arrayOfLinksForChart);
|
||||
}
|
||||
$scope.treeState.arrayOfLinksForChart.forEach((link) => {
|
||||
link.isLinkBeingEdited = false;
|
||||
@ -575,7 +579,6 @@ export default ['$scope', 'TemplatesService',
|
||||
};
|
||||
|
||||
$scope.selectNodeForLinking = (node) => {
|
||||
// start here
|
||||
if ($scope.linkConfig) {
|
||||
// This is the second node selected
|
||||
$scope.linkConfig.child = {
|
||||
@ -595,6 +598,14 @@ export default ['$scope', 'TemplatesService',
|
||||
isLinkBeingEdited: true
|
||||
});
|
||||
|
||||
$scope.treeState.arrayOfLinksForChart.forEach((link, index) => {
|
||||
if (link.source.id === 1 && link.target.id === node.id) {
|
||||
$scope.treeState.arrayOfLinksForChart.splice(index, 1);
|
||||
}
|
||||
});
|
||||
|
||||
$scope.treeState.depthMap = WorkflowChartService.generateDepthMap($scope.treeState.arrayOfLinksForChart);
|
||||
|
||||
$scope.treeState.isLinkMode = false;
|
||||
} else {
|
||||
// This is the first node selected
|
||||
@ -681,6 +692,8 @@ export default ['$scope', 'TemplatesService',
|
||||
}
|
||||
}
|
||||
|
||||
$scope.treeState.depthMap = WorkflowChartService.generateDepthMap($scope.treeState.arrayOfLinksForChart);
|
||||
|
||||
$scope.formState.showLinkForm = false;
|
||||
$scope.linkConfig = null;
|
||||
$scope.$broadcast("refreshWorkflowChart");
|
||||
@ -689,6 +702,21 @@ export default ['$scope', 'TemplatesService',
|
||||
$scope.cancelLinkForm = () => {
|
||||
if ($scope.linkConfig.mode === "add" && $scope.linkConfig.child) {
|
||||
$scope.treeState.arrayOfLinksForChart.splice($scope.treeState.arrayOfLinksForChart.length-1, 1);
|
||||
let targetIsOrphaned = true;
|
||||
$scope.treeState.arrayOfLinksForChart.forEach((link) => {
|
||||
if (link.target.id === $scope.linkConfig.child.id) {
|
||||
targetIsOrphaned = false;
|
||||
}
|
||||
});
|
||||
if (targetIsOrphaned) {
|
||||
// Link it to the start node
|
||||
$scope.treeState.arrayOfLinksForChart.push({
|
||||
source: $scope.treeState.arrayOfNodesForChart[0],
|
||||
target: $scope.treeState.arrayOfNodesForChart[chartNodeIdToIndexMapping[$scope.linkConfig.child.id]],
|
||||
edgeType: "always"
|
||||
});
|
||||
}
|
||||
$scope.treeState.depthMap = WorkflowChartService.generateDepthMap($scope.treeState.arrayOfLinksForChart);
|
||||
}
|
||||
$scope.treeState.addLinkSource = null;
|
||||
$scope.treeState.isLinkMode = false;
|
||||
@ -779,6 +807,8 @@ export default ['$scope', 'TemplatesService',
|
||||
}
|
||||
}
|
||||
|
||||
$scope.treeState.depthMap = WorkflowChartService.generateDepthMap($scope.treeState.arrayOfLinksForChart);
|
||||
|
||||
$scope.nodeToBeDeleted = null;
|
||||
$scope.deleteOverlayVisible = false;
|
||||
|
||||
@ -832,87 +862,14 @@ export default ['$scope', 'TemplatesService',
|
||||
page++;
|
||||
getNodes();
|
||||
} else {
|
||||
let nonRootNodeIds = [];
|
||||
let allNodeIds = [];
|
||||
let arrayOfLinksForChart = [];
|
||||
let arrayOfNodesForChart = [
|
||||
{
|
||||
index: 0,
|
||||
id: workflowMakerNodeIdCounter,
|
||||
isStartNode: true,
|
||||
unifiedJobTemplate: {
|
||||
name: "START"
|
||||
},
|
||||
fixed: true,
|
||||
x: 0,
|
||||
y: 0
|
||||
}
|
||||
];
|
||||
workflowMakerNodeIdCounter++;
|
||||
// Assign each node an ID - 0 is reserved for the start node. We need to
|
||||
// make sure that we have an ID on every node including new nodes so the
|
||||
// ID returned by the api won't do
|
||||
allNodes.forEach((node) => {
|
||||
node.workflowMakerNodeId = workflowMakerNodeIdCounter;
|
||||
nodeRef[workflowMakerNodeIdCounter] = {
|
||||
originalNodeObject: node
|
||||
};
|
||||
arrayOfNodesForChart.push({
|
||||
index: workflowMakerNodeIdCounter-1,
|
||||
id: workflowMakerNodeIdCounter,
|
||||
unifiedJobTemplate: node.summary_fields.unified_job_template
|
||||
});
|
||||
allNodeIds.push(node.id);
|
||||
nodeIdToMakerIdMapping[node.id] = node.workflowMakerNodeId;
|
||||
chartNodeIdToIndexMapping[workflowMakerNodeIdCounter] = workflowMakerNodeIdCounter-1;
|
||||
workflowMakerNodeIdCounter++;
|
||||
});
|
||||
let arrayOfNodesForChart = [];
|
||||
|
||||
allNodes.forEach((node) => {
|
||||
const sourceIndex = chartNodeIdToIndexMapping[node.workflowMakerNodeId];
|
||||
node.success_nodes.forEach((nodeId) => {
|
||||
const targetIndex = chartNodeIdToIndexMapping[nodeIdToMakerIdMapping[nodeId]];
|
||||
arrayOfLinksForChart.push({
|
||||
source: arrayOfNodesForChart[sourceIndex],
|
||||
target: arrayOfNodesForChart[targetIndex],
|
||||
edgeType: "success"
|
||||
});
|
||||
nonRootNodeIds.push(nodeId);
|
||||
});
|
||||
node.failure_nodes.forEach((nodeId) => {
|
||||
const targetIndex = chartNodeIdToIndexMapping[nodeIdToMakerIdMapping[nodeId]];
|
||||
arrayOfLinksForChart.push({
|
||||
source: arrayOfNodesForChart[sourceIndex],
|
||||
target: arrayOfNodesForChart[targetIndex],
|
||||
edgeType: "failure"
|
||||
});
|
||||
nonRootNodeIds.push(nodeId);
|
||||
});
|
||||
node.always_nodes.forEach((nodeId) => {
|
||||
const targetIndex = chartNodeIdToIndexMapping[nodeIdToMakerIdMapping[nodeId]];
|
||||
arrayOfLinksForChart.push({
|
||||
source: arrayOfNodesForChart[sourceIndex],
|
||||
target: arrayOfNodesForChart[targetIndex],
|
||||
edgeType: "always"
|
||||
});
|
||||
nonRootNodeIds.push(nodeId);
|
||||
});
|
||||
});
|
||||
({arrayOfNodesForChart, arrayOfLinksForChart, chartNodeIdToIndexMapping, nodeIdToChartNodeIdMapping, nodeRef, workflowMakerNodeIdCounter} = WorkflowChartService.generateArraysOfNodesAndLinks(allNodes));
|
||||
|
||||
let uniqueNonRootNodeIds = Array.from(new Set(nonRootNodeIds));
|
||||
let depthMap = WorkflowChartService.generateDepthMap(arrayOfLinksForChart);
|
||||
|
||||
let rootNodes = _.difference(allNodeIds, uniqueNonRootNodeIds);
|
||||
|
||||
rootNodes.forEach((rootNodeId) => {
|
||||
const targetIndex = chartNodeIdToIndexMapping[nodeIdToMakerIdMapping[rootNodeId]];
|
||||
arrayOfLinksForChart.push({
|
||||
source: arrayOfNodesForChart[0],
|
||||
target: arrayOfNodesForChart[targetIndex],
|
||||
edgeType: "always"
|
||||
});
|
||||
});
|
||||
|
||||
$scope.treeState = { arrayOfNodesForChart, arrayOfLinksForChart };
|
||||
$scope.treeState = { arrayOfNodesForChart, arrayOfLinksForChart, depthMap };
|
||||
}
|
||||
}, function ({ data, status, config }) {
|
||||
ProcessErrors($scope, data, status, null, {
|
||||
|
@ -1,12 +1,12 @@
|
||||
export default ['workflowData', 'workflowResultsService', 'workflowDataOptions',
|
||||
'jobLabels', 'workflowNodes', '$scope', 'ParseTypeChange',
|
||||
'ParseVariableString', 'count', '$state', 'i18n',
|
||||
'ParseVariableString', 'count', '$state', 'i18n', 'WorkflowChartService',
|
||||
'moment', function(workflowData, workflowResultsService,
|
||||
workflowDataOptions, jobLabels, workflowNodes, $scope, ParseTypeChange,
|
||||
ParseVariableString, count, $state, i18n, moment) {
|
||||
ParseVariableString, count, $state, i18n, WorkflowChartService,
|
||||
moment) {
|
||||
var runTimeElapsedTimer = null;
|
||||
let workflowMakerNodeIdCounter = 1;
|
||||
let nodeIdToMakerIdMapping = {};
|
||||
let nodeIdToChartNodeIdMapping = {};
|
||||
let chartNodeIdToIndexMapping = {};
|
||||
|
||||
var getLinks = function() {
|
||||
@ -170,93 +170,14 @@ export default ['workflowData', 'workflowResultsService', 'workflowDataOptions',
|
||||
// Click binding for the expand/collapse button on the standard out log
|
||||
$scope.stdoutFullScreen = false;
|
||||
|
||||
let nonRootNodeIds = [];
|
||||
let allNodeIds = [];
|
||||
let arrayOfLinksForChart = [];
|
||||
let arrayOfNodesForChart = [
|
||||
{
|
||||
index: 0,
|
||||
id: workflowMakerNodeIdCounter,
|
||||
isStartNode: true,
|
||||
unifiedJobTemplate: {
|
||||
name: "START"
|
||||
},
|
||||
fixed: true,
|
||||
x: 0,
|
||||
y: 0
|
||||
}
|
||||
];
|
||||
let arrayOfNodesForChart = [];
|
||||
|
||||
workflowMakerNodeIdCounter++;
|
||||
// Assign each node an ID - 0 is reserved for the start node. We need to
|
||||
// make sure that we have an ID on every node including new nodes so the
|
||||
// ID returned by the api won't do
|
||||
workflowNodes.forEach((node) => {
|
||||
node.workflowMakerNodeId = workflowMakerNodeIdCounter;
|
||||
const nodeObj = {
|
||||
index: workflowMakerNodeIdCounter-1,
|
||||
id: workflowMakerNodeIdCounter,
|
||||
unifiedJobTemplate: node.summary_fields.unified_job_template
|
||||
};
|
||||
if(node.summary_fields.job) {
|
||||
nodeObj.job = node.summary_fields.job;
|
||||
}
|
||||
if(node.summary_fields.unified_job_template) {
|
||||
nodeObj.unifiedJobTemplate = node.summary_fields.unified_job_template;
|
||||
}
|
||||
arrayOfNodesForChart.push(nodeObj);
|
||||
allNodeIds.push(node.id);
|
||||
nodeIdToMakerIdMapping[node.id] = node.workflowMakerNodeId;
|
||||
chartNodeIdToIndexMapping[workflowMakerNodeIdCounter] = workflowMakerNodeIdCounter-1;
|
||||
workflowMakerNodeIdCounter++;
|
||||
});
|
||||
({arrayOfNodesForChart, arrayOfLinksForChart, chartNodeIdToIndexMapping, nodeIdToChartNodeIdMapping} = WorkflowChartService.generateArraysOfNodesAndLinks(workflowNodes));
|
||||
|
||||
workflowNodes.forEach((node) => {
|
||||
const sourceIndex = chartNodeIdToIndexMapping[node.workflowMakerNodeId];
|
||||
node.success_nodes.forEach((nodeId) => {
|
||||
const targetIndex = chartNodeIdToIndexMapping[nodeIdToMakerIdMapping[nodeId]];
|
||||
arrayOfLinksForChart.push({
|
||||
source: arrayOfNodesForChart[sourceIndex],
|
||||
target: arrayOfNodesForChart[targetIndex],
|
||||
edgeType: "success"
|
||||
});
|
||||
nonRootNodeIds.push(nodeId);
|
||||
});
|
||||
node.failure_nodes.forEach((nodeId) => {
|
||||
const targetIndex = chartNodeIdToIndexMapping[nodeIdToMakerIdMapping[nodeId]];
|
||||
arrayOfLinksForChart.push({
|
||||
source: arrayOfNodesForChart[sourceIndex],
|
||||
target: arrayOfNodesForChart[targetIndex],
|
||||
edgeType: "failure"
|
||||
});
|
||||
nonRootNodeIds.push(nodeId);
|
||||
});
|
||||
node.always_nodes.forEach((nodeId) => {
|
||||
const targetIndex = chartNodeIdToIndexMapping[nodeIdToMakerIdMapping[nodeId]];
|
||||
arrayOfLinksForChart.push({
|
||||
source: arrayOfNodesForChart[sourceIndex],
|
||||
target: arrayOfNodesForChart[targetIndex],
|
||||
edgeType: "always"
|
||||
});
|
||||
nonRootNodeIds.push(nodeId);
|
||||
});
|
||||
});
|
||||
|
||||
let uniqueNonRootNodeIds = Array.from(new Set(nonRootNodeIds));
|
||||
|
||||
let rootNodes = _.difference(allNodeIds, uniqueNonRootNodeIds);
|
||||
|
||||
rootNodes.forEach((rootNodeId) => {
|
||||
const targetIndex = chartNodeIdToIndexMapping[nodeIdToMakerIdMapping[rootNodeId]];
|
||||
arrayOfLinksForChart.push({
|
||||
source: arrayOfNodesForChart[0],
|
||||
target: arrayOfNodesForChart[targetIndex],
|
||||
edgeType: "always"
|
||||
});
|
||||
});
|
||||
|
||||
$scope.treeState = { arrayOfNodesForChart, arrayOfLinksForChart };
|
||||
let depthMap = WorkflowChartService.generateDepthMap(arrayOfLinksForChart);
|
||||
|
||||
$scope.treeState = { arrayOfNodesForChart, arrayOfLinksForChart, depthMap };
|
||||
}
|
||||
|
||||
$scope.toggleStdoutFullscreen = function() {
|
||||
@ -356,12 +277,11 @@ export default ['workflowData', 'workflowResultsService', 'workflowDataOptions',
|
||||
runTimeElapsedTimer = workflowResultsService.createOneSecondTimer(moment(), updateWorkflowJobElapsedTimer);
|
||||
}
|
||||
|
||||
$scope.treeState.arrayOfNodesForChart[chartNodeIdToIndexMapping[nodeIdToMakerIdMapping[data.workflow_node_id]]].job = {
|
||||
$scope.treeState.arrayOfNodesForChart[chartNodeIdToIndexMapping[nodeIdToChartNodeIdMapping[data.workflow_node_id]]].job = {
|
||||
id: data.unified_job_id,
|
||||
status: data.status
|
||||
};
|
||||
|
||||
|
||||
$scope.workflow_nodes.forEach(node => {
|
||||
if(parseInt(node.id) === parseInt(data.workflow_node_id)){
|
||||
node.summary_fields.job = {
|
||||
|
Loading…
Reference in New Issue
Block a user