mirror of
https://github.com/ansible/awx.git
synced 2026-03-21 19:07:39 -02:30
Addresses a number of workflow related bugs
This commit is contained in:
@@ -186,16 +186,8 @@
|
|||||||
margin: auto;
|
margin: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.WorkflowChart-tooltipArrow--right {
|
.WorkflowChart-tooltipArrow {
|
||||||
width: 0;
|
fill: @default-interface-txt;
|
||||||
height: 0;
|
|
||||||
border-top: 10px solid transparent;
|
|
||||||
border-bottom: 10px solid transparent;
|
|
||||||
border-left: 10px solid @default-interface-txt;
|
|
||||||
margin: auto;
|
|
||||||
position: relative;
|
|
||||||
right: -55px;
|
|
||||||
top: -34px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.WorkflowChart-dashedNode {
|
.WorkflowChart-dashedNode {
|
||||||
|
|||||||
@@ -240,6 +240,81 @@ export default ['$state','moment', '$timeout', '$window', '$filter', 'Rest', 'Ge
|
|||||||
|
|
||||||
function update() {
|
function update() {
|
||||||
if(scope.dimensionsSet) {
|
if(scope.dimensionsSet) {
|
||||||
|
const buildLinkTooltip = (d) => {
|
||||||
|
let sourceNode = d3.select(`#node-${d.source.id}`);
|
||||||
|
const sourceNodeX = d3.transform(sourceNode.attr("transform")).translate[0];
|
||||||
|
const sourceNodeY = d3.transform(sourceNode.attr("transform")).translate[1];
|
||||||
|
let targetNode = d3.select(`#node-${d.target.id}`);
|
||||||
|
const targetNodeX = d3.transform(targetNode.attr("transform")).translate[0];
|
||||||
|
const targetNodeY = d3.transform(targetNode.attr("transform")).translate[1];
|
||||||
|
let xPos, yPos, arrowPoints;
|
||||||
|
if (nodePositionMap[d.source.id].y === nodePositionMap[d.target.id].y) {
|
||||||
|
xPos = (sourceNodeX + nodeW + targetNodeX)/2 - 50;
|
||||||
|
yPos = (sourceNodeY + nodeH + targetNodeY)/2 - 70;
|
||||||
|
arrowPoints = {
|
||||||
|
pt1: {
|
||||||
|
x: xPos + 40,
|
||||||
|
y: yPos + 47
|
||||||
|
},
|
||||||
|
pt2: {
|
||||||
|
x: xPos + 60,
|
||||||
|
y: yPos + 47
|
||||||
|
},
|
||||||
|
pt3: {
|
||||||
|
x: xPos + 50,
|
||||||
|
y: yPos + 57
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
xPos = (sourceNodeX + nodeW + targetNodeX)/2 - 120;
|
||||||
|
yPos = (sourceNodeY + nodeH + targetNodeY)/2 - 30;
|
||||||
|
arrowPoints = {
|
||||||
|
pt1: {
|
||||||
|
x: xPos + 100,
|
||||||
|
y: yPos + 17
|
||||||
|
},
|
||||||
|
pt2: {
|
||||||
|
x: xPos + 100,
|
||||||
|
y: yPos + 33
|
||||||
|
},
|
||||||
|
pt3: {
|
||||||
|
x: xPos + 110,
|
||||||
|
y: yPos + 25
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
let edgeTypeLabel;
|
||||||
|
switch(d.edgeType) {
|
||||||
|
case "always":
|
||||||
|
edgeTypeLabel = TemplatesStrings.get('workflow_maker.ALWAYS');
|
||||||
|
break;
|
||||||
|
case "success":
|
||||||
|
edgeTypeLabel = TemplatesStrings.get('workflow_maker.ON_SUCCESS');
|
||||||
|
break;
|
||||||
|
case "failure":
|
||||||
|
edgeTypeLabel = TemplatesStrings.get('workflow_maker.ON_FAILURE');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
let linkInstructionText = !scope.readOnly ? TemplatesStrings.get('workflow_maker.EDIT_LINK_TOOLTIP') : TemplatesStrings.get('workflow_maker.VIEW_LINK_TOOLTIP');
|
||||||
|
let linkTooltip = svgGroup.append("g")
|
||||||
|
.attr("class", "WorkflowChart-tooltip");
|
||||||
|
linkTooltip.append("foreignObject")
|
||||||
|
.attr("transform", `translate(${xPos},${yPos})`)
|
||||||
|
.attr("width", 100)
|
||||||
|
.attr("height", 50)
|
||||||
|
.html(function(){
|
||||||
|
return `<div class='WorkflowChart-tooltipContents'>
|
||||||
|
<div>${TemplatesStrings.get('workflow_maker.RUN')}: ${edgeTypeLabel}</div>
|
||||||
|
<div>${linkInstructionText}</div>
|
||||||
|
</div>`;
|
||||||
|
});
|
||||||
|
linkTooltip.append("polygon")
|
||||||
|
.attr("class", "WorkflowChart-tooltipArrow")
|
||||||
|
.attr("points", function() {
|
||||||
|
return `${arrowPoints.pt1.x},${arrowPoints.pt1.y} ${arrowPoints.pt2.x},${arrowPoints.pt2.y} ${arrowPoints.pt3.x},${arrowPoints.pt3.y}`;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
var g = new dagre.graphlib.Graph();
|
var g = new dagre.graphlib.Graph();
|
||||||
|
|
||||||
g.setGraph({rankdir: 'LR', nodesep: 30, ranksep: 120});
|
g.setGraph({rankdir: 'LR', nodesep: 30, ranksep: 120});
|
||||||
@@ -336,7 +411,7 @@ export default ['$state','moment', '$timeout', '$window', '$filter', 'Rest', 'Ge
|
|||||||
|
|
||||||
baseSvg.selectAll(".WorkflowChart-circleBetweenNodes")
|
baseSvg.selectAll(".WorkflowChart-circleBetweenNodes")
|
||||||
.attr("id", function(d){return "link-" + d.source.id + "-" + d.target.id + "-add";})
|
.attr("id", function(d){return "link-" + d.source.id + "-" + d.target.id + "-add";})
|
||||||
.style("display", function(d) { return (scope.graphState.isLinkMode || d.source.id === scope.graphState.nodeBeingAdded || d.target.id === scope.graphState.nodeBeingAdded || scope.readOnly) ? "none" : null; })
|
.style("display", function(d) { return (d.edgeType === 'placeholder' || scope.graphState.isLinkMode || d.source.id === scope.graphState.nodeBeingAdded || d.target.id === scope.graphState.nodeBeingAdded || scope.readOnly) ? "none" : null; })
|
||||||
.attr("cx", function(d) {
|
.attr("cx", function(d) {
|
||||||
return (nodePositionMap[d.source.id].x + nodePositionMap[d.source.id].width + nodePositionMap[d.target.id].x)/2;
|
return (nodePositionMap[d.source.id].x + nodePositionMap[d.source.id].width + nodePositionMap[d.target.id].x)/2;
|
||||||
})
|
})
|
||||||
@@ -356,7 +431,7 @@ export default ['$state','moment', '$timeout', '$window', '$filter', 'Rest', 'Ge
|
|||||||
});
|
});
|
||||||
|
|
||||||
baseSvg.selectAll(".WorkflowChart-betweenNodesIcon")
|
baseSvg.selectAll(".WorkflowChart-betweenNodesIcon")
|
||||||
.style("display", function(d) { return (scope.graphState.isLinkMode || d.source.id === scope.graphState.nodeBeingAdded || d.target.id === scope.graphState.nodeBeingAdded || scope.readOnly) ? "none" : null; })
|
.style("display", function(d) { return (d.edgeType === 'placeholder' || scope.graphState.isLinkMode || d.source.id === scope.graphState.nodeBeingAdded || d.target.id === scope.graphState.nodeBeingAdded || scope.readOnly) ? "none" : null; })
|
||||||
.attr("transform", function(d) {
|
.attr("transform", function(d) {
|
||||||
let translate;
|
let translate;
|
||||||
|
|
||||||
@@ -411,48 +486,20 @@ export default ['$state','moment', '$timeout', '$window', '$filter', 'Rest', 'Ge
|
|||||||
return [pt1, pt2, pt3, pt4].join(" ");
|
return [pt1, pt2, pt3, pt4].join(" ");
|
||||||
})
|
})
|
||||||
.on("mouseover", function(d) {
|
.on("mouseover", function(d) {
|
||||||
if(!scope.graphState.isLinkMode && !d.source.isStartNode && d.source.id !== scope.graphState.nodeBeingAdded && d.target.id !== scope.graphState.nodeBeingAdded && scope.mode !== 'details') {
|
if(
|
||||||
|
d.edgeType !== 'placeholder' &&
|
||||||
|
!scope.graphState.isLinkMode &&
|
||||||
|
!d.source.isStartNode &&
|
||||||
|
d.source.id !== scope.graphState.nodeBeingAdded &&
|
||||||
|
d.target.id !== scope.graphState.nodeBeingAdded &&
|
||||||
|
scope.mode !== 'details'
|
||||||
|
) {
|
||||||
$(`#link-${d.source.id}-${d.target.id}`).appendTo(`#aw-workflow-chart-g`);
|
$(`#link-${d.source.id}-${d.target.id}`).appendTo(`#aw-workflow-chart-g`);
|
||||||
d3.select(`#link-${d.source.id}-${d.target.id}`)
|
d3.select(`#link-${d.source.id}-${d.target.id}`)
|
||||||
.classed("WorkflowChart-linkHovering", true);
|
.classed("WorkflowChart-linkHovering", true);
|
||||||
|
|
||||||
let xPos, yPos, arrowClass;
|
buildLinkTooltip(d);
|
||||||
if (nodePositionMap[d.source.id].y === nodePositionMap[d.target.id].y) {
|
|
||||||
xPos = (nodePositionMap[d.source.id].x + nodePositionMap[d.target.id].x)/2 + 45;
|
|
||||||
yPos = (nodePositionMap[d.source.id].y + nodePositionMap[d.target.id].y)/2 - 107;
|
|
||||||
arrowClass = 'WorkflowChart-tooltipArrow--down';
|
|
||||||
} else {
|
|
||||||
xPos = (nodePositionMap[d.source.id].x + nodePositionMap[d.target.id].x)/2 - 30;
|
|
||||||
yPos = (nodePositionMap[d.source.id].y + nodePositionMap[d.target.id].y)/2 - 70;
|
|
||||||
arrowClass = 'WorkflowChart-tooltipArrow--right';
|
|
||||||
}
|
|
||||||
|
|
||||||
let edgeTypeLabel;
|
|
||||||
|
|
||||||
switch(d.edgeType) {
|
|
||||||
case "always":
|
|
||||||
edgeTypeLabel = TemplatesStrings.get('workflow_maker.ALWAYS');
|
|
||||||
break;
|
|
||||||
case "success":
|
|
||||||
edgeTypeLabel = TemplatesStrings.get('workflow_maker.ON_SUCCESS');
|
|
||||||
break;
|
|
||||||
case "failure":
|
|
||||||
edgeTypeLabel = TemplatesStrings.get('workflow_maker.ON_FAILURE');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
let linkInstructionText = !scope.readOnly ? TemplatesStrings.get('workflow_maker.EDIT_LINK_TOOLTIP') : TemplatesStrings.get('workflow_maker.VIEW_LINK_TOOLTIP');
|
|
||||||
|
|
||||||
svgGroup.append("foreignObject")
|
|
||||||
.attr("transform", `translate(${xPos},${yPos})`)
|
|
||||||
.attr("width", 100)
|
|
||||||
.attr("height", 60)
|
|
||||||
.attr("class", "WorkflowChart-tooltip")
|
|
||||||
.html(function(){
|
|
||||||
return `<div class='WorkflowChart-tooltipContents'><div>${TemplatesStrings.get('workflow_maker.RUN')}: ${edgeTypeLabel}</div><div>${linkInstructionText}</div></div><div class='${arrowClass}'></div>`;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
.on("mouseout", function(d){
|
.on("mouseout", function(d){
|
||||||
if(!d.source.isStartNode && d.target.id !== scope.graphState.nodeBeingAdded && scope.mode !== 'details') {
|
if(!d.source.isStartNode && d.target.id !== scope.graphState.nodeBeingAdded && scope.mode !== 'details') {
|
||||||
@@ -471,46 +518,19 @@ export default ['$state','moment', '$timeout', '$window', '$filter', 'Rest', 'Ge
|
|||||||
.attr("d", lineData)
|
.attr("d", lineData)
|
||||||
.call(edit_link)
|
.call(edit_link)
|
||||||
.on("mouseenter", function(d) {
|
.on("mouseenter", function(d) {
|
||||||
if(!scope.graphState.isLinkMode && !d.source.isStartNode && d.source.id !== scope.graphState.nodeBeingAdded && d.target.id !== scope.graphState.nodeBeingAdded && scope.mode !== 'details') {
|
if(
|
||||||
|
d.edgeType !== 'placeholder' &&
|
||||||
|
!scope.graphState.isLinkMode &&
|
||||||
|
!d.source.isStartNode &&
|
||||||
|
d.source.id !== scope.graphState.nodeBeingAdded &&
|
||||||
|
d.target.id !== scope.graphState.nodeBeingAdded &&
|
||||||
|
scope.mode !== 'details'
|
||||||
|
) {
|
||||||
$(`#link-${d.source.id}-${d.target.id}`).appendTo(`#aw-workflow-chart-g`);
|
$(`#link-${d.source.id}-${d.target.id}`).appendTo(`#aw-workflow-chart-g`);
|
||||||
d3.select("#link-" + d.source.id + "-" + d.target.id)
|
d3.select(`#link-${d.source.id}-${d.target.id}`)
|
||||||
.classed("WorkflowChart-linkHovering", true);
|
.classed("WorkflowChart-linkHovering", true);
|
||||||
|
|
||||||
let xPos, yPos, arrowClass;
|
buildLinkTooltip(d);
|
||||||
if (nodePositionMap[d.source.id].y === nodePositionMap[d.target.id].y) {
|
|
||||||
xPos = (nodePositionMap[d.source.id].x + nodePositionMap[d.target.id].x)/2 + 45;
|
|
||||||
yPos = (nodePositionMap[d.source.id].y + nodePositionMap[d.target.id].y)/2 - 107;
|
|
||||||
arrowClass = 'WorkflowChart-tooltipArrow--down';
|
|
||||||
} else {
|
|
||||||
xPos = (nodePositionMap[d.source.id].x + nodePositionMap[d.target.id].x)/2 - 30;
|
|
||||||
yPos = (nodePositionMap[d.source.id].y + nodePositionMap[d.target.id].y)/2 - 70;
|
|
||||||
arrowClass = 'WorkflowChart-tooltipArrow--right';
|
|
||||||
}
|
|
||||||
|
|
||||||
let edgeTypeLabel;
|
|
||||||
|
|
||||||
switch(d.edgeType) {
|
|
||||||
case "always":
|
|
||||||
edgeTypeLabel = TemplatesStrings.get('workflow_maker.ALWAYS');
|
|
||||||
break;
|
|
||||||
case "success":
|
|
||||||
edgeTypeLabel = TemplatesStrings.get('workflow_maker.ON_SUCCESS');
|
|
||||||
break;
|
|
||||||
case "failure":
|
|
||||||
edgeTypeLabel = TemplatesStrings.get('workflow_maker.ON_FAILURE');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
let linkInstructionText = !scope.readOnly ? TemplatesStrings.get('workflow_maker.EDIT_LINK_TOOLTIP') : TemplatesStrings.get('workflow_maker.VIEW_LINK_TOOLTIP');
|
|
||||||
|
|
||||||
svgGroup.append("foreignObject")
|
|
||||||
.attr("transform", `translate(${xPos},${yPos})`)
|
|
||||||
.attr("width", 100)
|
|
||||||
.attr("height", 60)
|
|
||||||
.attr("class", "WorkflowChart-tooltip")
|
|
||||||
.html(function(){
|
|
||||||
return `<div class='WorkflowChart-tooltipContents'><div>${TemplatesStrings.get('workflow_maker.RUN')}: ${edgeTypeLabel}</div><div>${linkInstructionText}</div></div><div class='${arrowClass}'></div>`;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.on("mouseleave", function(d){
|
.on("mouseleave", function(d){
|
||||||
@@ -543,7 +563,7 @@ export default ['$state','moment', '$timeout', '$window', '$filter', 'Rest', 'Ge
|
|||||||
.attr("id", function(d){return "link-" + d.source.id + "-" + d.target.id + "-add";})
|
.attr("id", function(d){return "link-" + d.source.id + "-" + d.target.id + "-add";})
|
||||||
.attr("r", 10)
|
.attr("r", 10)
|
||||||
.attr("class", "WorkflowChart-addCircle WorkflowChart-circleBetweenNodes")
|
.attr("class", "WorkflowChart-addCircle WorkflowChart-circleBetweenNodes")
|
||||||
.style("display", function(d) { return (scope.graphState.isLinkMode || d.source.id === scope.graphState.nodeBeingAdded || d.target.id === scope.graphState.nodeBeingAdded || scope.readOnly) ? "none" : null; })
|
.style("display", function(d) { return (d.edgeType === 'placeholder' || scope.graphState.isLinkMode || d.source.id === scope.graphState.nodeBeingAdded || d.target.id === scope.graphState.nodeBeingAdded || scope.readOnly) ? "none" : null; })
|
||||||
.attr("cx", function(d) {
|
.attr("cx", function(d) {
|
||||||
return (nodePositionMap[d.source.id].x + nodePositionMap[d.source.id].width + nodePositionMap[d.target.id].x)/2;
|
return (nodePositionMap[d.source.id].x + nodePositionMap[d.source.id].width + nodePositionMap[d.target.id].x)/2;
|
||||||
})
|
})
|
||||||
@@ -580,7 +600,7 @@ export default ['$state','moment', '$timeout', '$window', '$filter', 'Rest', 'Ge
|
|||||||
.size(60)
|
.size(60)
|
||||||
.type("cross")
|
.type("cross")
|
||||||
)
|
)
|
||||||
.style("display", function(d) { return (scope.graphState.isLinkMode || d.source.id === scope.graphState.nodeBeingAdded || d.target.id === scope.graphState.nodeBeingAdded || scope.readOnly) ? "none" : null; })
|
.style("display", function(d) { return (d.edgeType === 'placeholder' || scope.graphState.isLinkMode || d.source.id === scope.graphState.nodeBeingAdded || d.target.id === scope.graphState.nodeBeingAdded || scope.readOnly) ? "none" : null; })
|
||||||
.attr("transform", function(d) {
|
.attr("transform", function(d) {
|
||||||
let translate;
|
let translate;
|
||||||
|
|
||||||
@@ -1263,7 +1283,7 @@ export default ['$state','moment', '$timeout', '$window', '$filter', 'Rest', 'Ge
|
|||||||
|
|
||||||
function add_node_with_child() {
|
function add_node_with_child() {
|
||||||
this.on("click", function(d) {
|
this.on("click", function(d) {
|
||||||
if(!scope.readOnly && !scope.graphState.isLinkMode) {
|
if(!scope.readOnly && !scope.graphState.isLinkMode && d.edgeType !== 'placeholder') {
|
||||||
scope.addNodeWithChild({
|
scope.addNodeWithChild({
|
||||||
link: d
|
link: d
|
||||||
});
|
});
|
||||||
@@ -1340,25 +1360,32 @@ export default ['$state','moment', '$timeout', '$window', '$filter', 'Rest', 'Ge
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if(d.job.id) {
|
if(d.job.type) {
|
||||||
if(d.unifiedJobTemplate) {
|
if(d.unifiedJobTemplate) {
|
||||||
goToJobResults(d.unifiedJobTemplate.unified_job_type);
|
goToJobResults(d.unifiedJobTemplate.unified_job_type);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// We don't have access to the unified resource and have to make
|
// We don't have access to the job type and have to make
|
||||||
// a GET request in order to find out what type job this was
|
// a GET request in order to find out what type job this was
|
||||||
// so that we can route the user to the correct stdout view
|
// so that we can route the user to the correct stdout view
|
||||||
|
Rest.setUrl(GetBasePath("workflow_jobs") + `${d.originalNodeObj.workflow_job}/workflow_nodes/?order_by=id`);
|
||||||
Rest.setUrl(GetBasePath("unified_jobs") + "?id=" + d.job.id);
|
|
||||||
Rest.get()
|
Rest.get()
|
||||||
.then(function (res) {
|
.then(function (res) {
|
||||||
if(res.data.results && res.data.results.length > 0) {
|
if (res.data.results && res.data.results.length > 0) {
|
||||||
goToJobResults(res.data.results[0].type);
|
const { results } = res.data;
|
||||||
}
|
const job = results.filter(result => result.summary_fields.job.id === d.job.id);
|
||||||
})
|
goToJobResults(job[0].summary_fields.job.type);
|
||||||
.catch(({data, status}) => {
|
}
|
||||||
ProcessErrors(scope, data, status, null, { hdr: 'Error!', msg: 'Unable to get job: ' + status });
|
})
|
||||||
});
|
.catch(({
|
||||||
|
data,
|
||||||
|
status
|
||||||
|
}) => {
|
||||||
|
ProcessErrors(scope, data, status, null, {
|
||||||
|
hdr: 'Error!',
|
||||||
|
msg: 'Unable to get job: ' + status
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -97,7 +97,6 @@ export default [function(){
|
|||||||
return {
|
return {
|
||||||
arrayOfNodesForChart,
|
arrayOfNodesForChart,
|
||||||
arrayOfLinksForChart,
|
arrayOfLinksForChart,
|
||||||
chartNodeIdToIndexMapping,
|
|
||||||
nodeIdToChartNodeIdMapping,
|
nodeIdToChartNodeIdMapping,
|
||||||
nodeRef,
|
nodeRef,
|
||||||
workflowMakerNodeIdCounter: nodeIdCounter
|
workflowMakerNodeIdCounter: nodeIdCounter
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<div class="WorkflowMaker-formTitle">{{readOnly ? strings.get('workflow_maker.VIEW_LINK') : (linkConfig.mode === 'add' ? strings.get('workflow_maker.ADD_LINK') : strings.get('workflow_maker.EDIT_LINK')) }} | {{linkConfig.parent.name}} {{linkConfig.child ? 'to ' + linkConfig.child.name : ''}}</div>
|
<div class="WorkflowMaker-formTitle">{{readOnly ? strings.get('workflow_maker.VIEW_LINK') : (linkConfig.mode === 'add' ? strings.get('workflow_maker.ADD_LINK') : strings.get('workflow_maker.EDIT_LINK')) }} | {{linkConfig.source.name}} {{linkConfig.target ? 'to ' + linkConfig.target.name : ''}}</div>
|
||||||
<div class="WorkflowMaker-form">
|
<div class="WorkflowMaker-form">
|
||||||
<div class="form-group Form-formGroup Form-formGroup--singleColumn">
|
<div class="form-group Form-formGroup Form-formGroup--singleColumn">
|
||||||
<div ng-show="linkConfig.mode === 'add' && !linkConfig.child">{{:: strings.get('workflow_maker.NEW_LINK')}}</div>
|
<div ng-show="linkConfig.mode === 'add' && !linkConfig.target">{{:: strings.get('workflow_maker.NEW_LINK')}}</div>
|
||||||
<span ng-show="linkConfig.child">
|
<span ng-show="linkConfig.target">
|
||||||
<label for="edgeType" class="Form-inputLabelContainer">
|
<label for="edgeType" class="Form-inputLabelContainer">
|
||||||
<span class="Form-requiredAsterisk">*</span>
|
<span class="Form-requiredAsterisk">*</span>
|
||||||
<span class="Form-inputLabel">{{:: strings.get('workflow_maker.RUN') }}</span>
|
<span class="Form-inputLabel">{{:: strings.get('workflow_maker.RUN') }}</span>
|
||||||
@@ -25,6 +25,6 @@
|
|||||||
<button type="button" class="btn btn-sm Form-primaryButton Form-primaryButton--noMargin" id="workflow_maker_unlink_btn" ng-show="!readOnly && linkConfig.canUnlink" ng-click="unlink()"> {{:: strings.get('workflow_maker.UNLINK') }}</button>
|
<button type="button" class="btn btn-sm Form-primaryButton Form-primaryButton--noMargin" id="workflow_maker_unlink_btn" ng-show="!readOnly && linkConfig.canUnlink" ng-click="unlink()"> {{:: strings.get('workflow_maker.UNLINK') }}</button>
|
||||||
<button type="button" class="btn btn-sm Form-cancelButton" id="workflow_maker_cancel_link_btn" ng-show="!readOnly" ng-click="cancel()"> {{:: strings.get('CANCEL') }}</button>
|
<button type="button" class="btn btn-sm Form-cancelButton" id="workflow_maker_cancel_link_btn" ng-show="!readOnly" ng-click="cancel()"> {{:: strings.get('CANCEL') }}</button>
|
||||||
<button type="button" class="btn btn-sm Form-cancelButton" id="workflow_maker_cancel_link_btn" ng-show="readOnly" ng-click="cancel()"> {{:: strings.get('CLOSE') }}</button>
|
<button type="button" class="btn btn-sm Form-cancelButton" id="workflow_maker_cancel_link_btn" ng-show="readOnly" ng-click="cancel()"> {{:: strings.get('CLOSE') }}</button>
|
||||||
<button type="button" class="btn btn-sm Form-saveButton" id="workflow_maker_select_link_btn" ng-show="!readOnly && linkConfig.child" ng-click="select({edgeType: edgeType.value})" ng-disabled="!edgeType"> {{:: strings.get('SAVE') }}</button>
|
<button type="button" class="btn btn-sm Form-saveButton" id="workflow_maker_select_link_btn" ng-show="!readOnly && linkConfig.target" ng-click="select({edgeType: edgeType.value})" ng-disabled="!edgeType"> {{:: strings.get('SAVE') }}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
<div ng-show="nodeFormDataLoaded">
|
<div ng-show="nodeFormDataLoaded">
|
||||||
<div class="WorkflowMaker-formTitle">{{nodeConfig.mode === 'edit' ? nodeConfig.node.unifiedJobTemplate.name : strings.get('workflow_maker.ADD_A_TEMPLATE')}}</div>
|
<div class="WorkflowMaker-formTitle">{{nodeConfig.mode === 'edit' ? nodeConfig.node.fullUnifiedJobTemplateObject.name || nodeConfig.node.unifiedJobTemplate.name : strings.get('workflow_maker.ADD_A_TEMPLATE')}}</div>
|
||||||
<div class="Form-tabHolder" ng-if="!readOnly">
|
<div class="Form-tabHolder" ng-show="!readOnly">
|
||||||
<div class="Form-tab WorkflowMaker-formTab" ng-class="{'is-selected': activeTab === 'jobs'}" ng-click="activeTab = 'jobs'">{{strings.get('workflow_maker.JOBS')}}</div>
|
<div class="Form-tab WorkflowMaker-formTab" ng-class="{'is-selected': activeTab === 'jobs'}" ng-click="activeTab = 'jobs'">{{strings.get('workflow_maker.JOBS')}}</div>
|
||||||
<div class="Form-tab WorkflowMaker-formTab" ng-class="{'is-selected': activeTab === 'project_syncs'}" ng-click="activeTab = 'project_syncs'">{{strings.get('workflow_maker.PROJECT_SYNC')}}</div>
|
<div class="Form-tab WorkflowMaker-formTab" ng-class="{'is-selected': activeTab === 'project_syncs'}" ng-click="activeTab = 'project_syncs'">{{strings.get('workflow_maker.PROJECT_SYNC')}}</div>
|
||||||
<div class="Form-tab WorkflowMaker-formTab" ng-class="{'is-selected': activeTab === 'inventory_syncs'}" ng-click="activeTab = 'inventory_syncs'">{{strings.get('workflow_maker.INVENTORY_SYNC')}}</div>
|
<div class="Form-tab WorkflowMaker-formTab" ng-class="{'is-selected': activeTab === 'inventory_syncs'}" ng-click="activeTab = 'inventory_syncs'">{{strings.get('workflow_maker.INVENTORY_SYNC')}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="WorkflowMaker-formLists" ng-if="!readOnly">
|
<div class="WorkflowMaker-formLists" ng-show="!readOnly">
|
||||||
<div id="workflow-jobs-list" ng-show="activeTab === 'jobs'">
|
<div id="workflow-jobs-list" ng-show="activeTab === 'jobs'">
|
||||||
<div ng-hide="wf_maker_templates.length === 0 && (searchTags | isEmpty)">
|
<div ng-hide="wf_maker_templates.length === 0 && (searchTags | isEmpty)">
|
||||||
<smart-search django-model="unified_job_templates" base-path="unified_job_templates" iterator="wf_maker_template" dataset="wf_maker_template_dataset" list="templateList" collection="wf_maker_templates" default-params="wf_maker_template_default_params" query-set="wf_maker_template_queryset" search-bar-full-width="true" search-tags="searchTags">
|
<smart-search django-model="unified_job_templates" base-path="unified_job_templates" iterator="wf_maker_template" dataset="wf_maker_template_dataset" list="templateList" collection="wf_maker_templates" default-params="wf_maker_template_default_params" query-set="wf_maker_template_queryset" search-bar-full-width="true" search-tags="searchTags">
|
||||||
@@ -141,7 +141,7 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div ng-if="readOnly">
|
<div ng-show="readOnly">
|
||||||
<div
|
<div
|
||||||
class="WorkflowMaker-readOnlyPromptText"
|
class="WorkflowMaker-readOnlyPromptText"
|
||||||
ng-show="nodeConfig.node.originalNodeObject.job_type !== null ||
|
ng-show="nodeConfig.node.originalNodeObject.job_type !== null ||
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ export default ['$scope', 'TemplatesService',
|
|||||||
let deletedNodeIds = [];
|
let deletedNodeIds = [];
|
||||||
let workflowMakerNodeIdCounter = 1;
|
let workflowMakerNodeIdCounter = 1;
|
||||||
let nodeIdToChartNodeIdMapping = {};
|
let nodeIdToChartNodeIdMapping = {};
|
||||||
let chartNodeIdToIndexMapping = {};
|
|
||||||
let nodeRef = {};
|
let nodeRef = {};
|
||||||
|
|
||||||
$scope.showKey = false;
|
$scope.showKey = false;
|
||||||
@@ -364,25 +363,22 @@ export default ['$scope', 'TemplatesService',
|
|||||||
}
|
}
|
||||||
|
|
||||||
$scope.graphState.arrayOfNodesForChart.push({
|
$scope.graphState.arrayOfNodesForChart.push({
|
||||||
index: $scope.graphState.arrayOfNodesForChart.length,
|
|
||||||
id: workflowMakerNodeIdCounter,
|
id: workflowMakerNodeIdCounter,
|
||||||
unifiedJobTemplate: null
|
unifiedJobTemplate: null
|
||||||
});
|
});
|
||||||
|
|
||||||
$scope.graphState.nodeBeingAdded = workflowMakerNodeIdCounter;
|
$scope.graphState.nodeBeingAdded = workflowMakerNodeIdCounter;
|
||||||
|
|
||||||
chartNodeIdToIndexMapping[workflowMakerNodeIdCounter] = $scope.graphState.arrayOfNodesForChart.length - 1;
|
|
||||||
|
|
||||||
$scope.graphState.arrayOfLinksForChart.push({
|
$scope.graphState.arrayOfLinksForChart.push({
|
||||||
source: $scope.graphState.arrayOfNodesForChart[parent.index],
|
source: {id: parent.id},
|
||||||
target: $scope.graphState.arrayOfNodesForChart[chartNodeIdToIndexMapping[workflowMakerNodeIdCounter]],
|
target: {id: workflowMakerNodeIdCounter},
|
||||||
edgeType: "placeholder"
|
edgeType: "placeholder"
|
||||||
});
|
});
|
||||||
|
|
||||||
$scope.nodeConfig = {
|
$scope.nodeConfig = {
|
||||||
mode: "add",
|
mode: "add",
|
||||||
nodeId: workflowMakerNodeIdCounter,
|
nodeId: workflowMakerNodeIdCounter,
|
||||||
newNodeIsRoot: parent.index === 0
|
newNodeIsRoot: parent.id === 1
|
||||||
};
|
};
|
||||||
|
|
||||||
workflowMakerNodeIdCounter++;
|
workflowMakerNodeIdCounter++;
|
||||||
@@ -402,18 +398,15 @@ export default ['$scope', 'TemplatesService',
|
|||||||
}
|
}
|
||||||
|
|
||||||
$scope.graphState.arrayOfNodesForChart.push({
|
$scope.graphState.arrayOfNodesForChart.push({
|
||||||
index: $scope.graphState.arrayOfNodesForChart.length,
|
|
||||||
id: workflowMakerNodeIdCounter,
|
id: workflowMakerNodeIdCounter,
|
||||||
unifiedJobTemplate: null
|
unifiedJobTemplate: null
|
||||||
});
|
});
|
||||||
|
|
||||||
$scope.graphState.nodeBeingAdded = workflowMakerNodeIdCounter;
|
$scope.graphState.nodeBeingAdded = workflowMakerNodeIdCounter;
|
||||||
|
|
||||||
chartNodeIdToIndexMapping[workflowMakerNodeIdCounter] = $scope.graphState.arrayOfNodesForChart.length - 1;
|
|
||||||
|
|
||||||
$scope.graphState.arrayOfLinksForChart.push({
|
$scope.graphState.arrayOfLinksForChart.push({
|
||||||
source: $scope.graphState.arrayOfNodesForChart[link.source.index],
|
source: {id: link.source.id},
|
||||||
target: $scope.graphState.arrayOfNodesForChart[chartNodeIdToIndexMapping[workflowMakerNodeIdCounter]],
|
target: {id: workflowMakerNodeIdCounter},
|
||||||
edgeType: "placeholder"
|
edgeType: "placeholder"
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -425,9 +418,9 @@ export default ['$scope', 'TemplatesService',
|
|||||||
|
|
||||||
// Search for the link that used to exist between source and target and shift it to
|
// Search for the link that used to exist between source and target and shift it to
|
||||||
// go from our new node to the target
|
// go from our new node to the target
|
||||||
$scope.graphState.arrayOfLinksForChart.forEach((foo) => {
|
$scope.graphState.arrayOfLinksForChart.forEach((linkToCompare) => {
|
||||||
if (foo.source.id === link.source.id && foo.target.id === link.target.id) {
|
if (linkToCompare.source.id === link.source.id && linkToCompare.target.id === link.target.id) {
|
||||||
foo.source = $scope.graphState.arrayOfNodesForChart[chartNodeIdToIndexMapping[workflowMakerNodeIdCounter]];
|
linkToCompare.source = {id: workflowMakerNodeIdCounter};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -439,7 +432,7 @@ export default ['$scope', 'TemplatesService',
|
|||||||
};
|
};
|
||||||
|
|
||||||
$scope.confirmNodeForm = function(selectedTemplate, promptData, edgeType) {
|
$scope.confirmNodeForm = function(selectedTemplate, promptData, edgeType) {
|
||||||
const nodeIndex = chartNodeIdToIndexMapping[$scope.nodeConfig.nodeId];
|
const nodeId = $scope.nodeConfig.nodeId;
|
||||||
if ($scope.nodeConfig.mode === "add") {
|
if ($scope.nodeConfig.mode === "add") {
|
||||||
if (selectedTemplate && edgeType && edgeType.value) {
|
if (selectedTemplate && edgeType && edgeType.value) {
|
||||||
nodeRef[$scope.nodeConfig.nodeId] = {
|
nodeRef[$scope.nodeConfig.nodeId] = {
|
||||||
@@ -448,11 +441,10 @@ export default ['$scope', 'TemplatesService',
|
|||||||
isNew: true
|
isNew: true
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.graphState.arrayOfNodesForChart[nodeIndex].unifiedJobTemplate = selectedTemplate;
|
|
||||||
$scope.graphState.nodeBeingAdded = null;
|
$scope.graphState.nodeBeingAdded = null;
|
||||||
|
|
||||||
$scope.graphState.arrayOfLinksForChart.map( (link) => {
|
$scope.graphState.arrayOfLinksForChart.map( (link) => {
|
||||||
if (link.target.index === nodeIndex) {
|
if (link.target.id === nodeId) {
|
||||||
link.edgeType = edgeType.value;
|
link.edgeType = edgeType.value;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -462,11 +454,16 @@ export default ['$scope', 'TemplatesService',
|
|||||||
nodeRef[$scope.nodeConfig.nodeId].fullUnifiedJobTemplateObject = selectedTemplate;
|
nodeRef[$scope.nodeConfig.nodeId].fullUnifiedJobTemplateObject = selectedTemplate;
|
||||||
nodeRef[$scope.nodeConfig.nodeId].promptData = _.cloneDeep(promptData);
|
nodeRef[$scope.nodeConfig.nodeId].promptData = _.cloneDeep(promptData);
|
||||||
nodeRef[$scope.nodeConfig.nodeId].isEdited = true;
|
nodeRef[$scope.nodeConfig.nodeId].isEdited = true;
|
||||||
$scope.graphState.arrayOfNodesForChart[nodeIndex].unifiedJobTemplate = selectedTemplate;
|
|
||||||
$scope.graphState.nodeBeingEdited = null;
|
$scope.graphState.nodeBeingEdited = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$scope.graphState.arrayOfNodesForChart.map( (node) => {
|
||||||
|
if (node.id === nodeId) {
|
||||||
|
node.unifiedJobTemplate = selectedTemplate;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
$scope.formState.showNodeForm = false;
|
$scope.formState.showNodeForm = false;
|
||||||
$scope.nodeConfig = null;
|
$scope.nodeConfig = null;
|
||||||
|
|
||||||
@@ -474,10 +471,15 @@ export default ['$scope', 'TemplatesService',
|
|||||||
};
|
};
|
||||||
|
|
||||||
$scope.cancelNodeForm = function() {
|
$scope.cancelNodeForm = function() {
|
||||||
const nodeIndex = chartNodeIdToIndexMapping[$scope.nodeConfig.nodeId];
|
const nodeId = $scope.nodeConfig.nodeId;
|
||||||
if ($scope.nodeConfig.mode === "add") {
|
if ($scope.nodeConfig.mode === "add") {
|
||||||
// Remove the placeholder node from the array
|
// Remove the placeholder node from the array
|
||||||
$scope.graphState.arrayOfNodesForChart.splice(nodeIndex, 1);
|
for( let i = $scope.graphState.arrayOfNodesForChart.length; i--; ){
|
||||||
|
if ($scope.graphState.arrayOfNodesForChart[i].id === nodeId) {
|
||||||
|
$scope.graphState.arrayOfNodesForChart.splice(i, 1);
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Update the links
|
// Update the links
|
||||||
let parents = [];
|
let parents = [];
|
||||||
@@ -487,47 +489,30 @@ export default ['$scope', 'TemplatesService',
|
|||||||
for( let i = $scope.graphState.arrayOfLinksForChart.length; i--; ){
|
for( let i = $scope.graphState.arrayOfLinksForChart.length; i--; ){
|
||||||
const link = $scope.graphState.arrayOfLinksForChart[i];
|
const link = $scope.graphState.arrayOfLinksForChart[i];
|
||||||
|
|
||||||
if (link.source.index === nodeIndex || link.target.index === nodeIndex) {
|
if (link.source.id === nodeId || link.target.id === nodeId) {
|
||||||
if (link.source.index === nodeIndex) {
|
if (link.source.id === nodeId) {
|
||||||
const targetIndex = link.target.index < nodeIndex ? link.target.index : link.target.index - 1;
|
children.push({id: link.target.id, edgeType: link.edgeType});
|
||||||
children.push({index: targetIndex, edgeType: link.edgeType});
|
} else if (link.target.id === nodeId) {
|
||||||
} else if (link.target.index === nodeIndex) {
|
parents.push(link.source.id);
|
||||||
const sourceIndex = link.source.index < nodeIndex ? link.source.index : link.source.index - 1;
|
|
||||||
parents.push(sourceIndex);
|
|
||||||
}
|
}
|
||||||
$scope.graphState.arrayOfLinksForChart.splice(i, 1);
|
$scope.graphState.arrayOfLinksForChart.splice(i, 1);
|
||||||
} else {
|
|
||||||
if (link.source.index > nodeIndex) {
|
|
||||||
link.source.index--;
|
|
||||||
}
|
|
||||||
if (link.target.index > nodeIndex) {
|
|
||||||
link.target.index--;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the new links
|
// Add the new links
|
||||||
parents.forEach((parentIndex) => {
|
parents.forEach((parentId) => {
|
||||||
children.forEach((child) => {
|
children.forEach((child) => {
|
||||||
if (parentIndex === 0) {
|
if (parentId === 1) {
|
||||||
child.edgeType = "always";
|
child.edgeType = "always";
|
||||||
}
|
}
|
||||||
$scope.graphState.arrayOfLinksForChart.push({
|
$scope.graphState.arrayOfLinksForChart.push({
|
||||||
source: $scope.graphState.arrayOfNodesForChart[parentIndex],
|
source: {id: parentId},
|
||||||
target: $scope.graphState.arrayOfNodesForChart[child.index],
|
target: {id: child.id},
|
||||||
edgeType: child.edgeType
|
edgeType: child.edgeType
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
delete chartNodeIdToIndexMapping[$scope.nodeConfig.nodeId];
|
|
||||||
|
|
||||||
for (const key in chartNodeIdToIndexMapping) {
|
|
||||||
if (chartNodeIdToIndexMapping[key] > nodeIndex) {
|
|
||||||
chartNodeIdToIndexMapping[key]--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if ($scope.nodeConfig.mode === "edit") {
|
} else if ($scope.nodeConfig.mode === "edit") {
|
||||||
$scope.graphState.nodeBeingEdited = null;
|
$scope.graphState.nodeBeingEdited = null;
|
||||||
}
|
}
|
||||||
@@ -543,7 +528,7 @@ export default ['$scope', 'TemplatesService',
|
|||||||
$scope.cancelLinkForm();
|
$scope.cancelLinkForm();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$scope.nodeConfig || ($scope.nodeConfig && $scope.nodeConfig.nodeId !== nodeToEdit.index)) {
|
if (!$scope.nodeConfig || ($scope.nodeConfig && $scope.nodeConfig.nodeId !== nodeToEdit.id)) {
|
||||||
if ($scope.nodeConfig) {
|
if ($scope.nodeConfig) {
|
||||||
$scope.cancelNodeForm();
|
$scope.cancelNodeForm();
|
||||||
}
|
}
|
||||||
@@ -582,11 +567,11 @@ export default ['$scope', 'TemplatesService',
|
|||||||
|
|
||||||
$scope.linkConfig = {
|
$scope.linkConfig = {
|
||||||
mode: "edit",
|
mode: "edit",
|
||||||
parent: {
|
source: {
|
||||||
id: linkToEdit.source.id,
|
id: linkToEdit.source.id,
|
||||||
name: _.get(linkToEdit, 'source.unifiedJobTemplate.name') || ""
|
name: _.get(linkToEdit, 'source.unifiedJobTemplate.name') || ""
|
||||||
},
|
},
|
||||||
child: {
|
target: {
|
||||||
id: linkToEdit.target.id,
|
id: linkToEdit.target.id,
|
||||||
name: _.get(linkToEdit, 'target.unifiedJobTemplate.name') || ""
|
name: _.get(linkToEdit, 'target.unifiedJobTemplate.name') || ""
|
||||||
},
|
},
|
||||||
@@ -603,7 +588,7 @@ export default ['$scope', 'TemplatesService',
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($scope.linkConfig) {
|
if ($scope.linkConfig) {
|
||||||
if ($scope.linkConfig.parent.id !== linkToEdit.source.id || $scope.linkConfig.child.id !== linkToEdit.target.id) {
|
if ($scope.linkConfig.source.id !== linkToEdit.source.id || $scope.linkConfig.target.id !== linkToEdit.target.id) {
|
||||||
// User is going from editing one link to editing another
|
// User is going from editing one link to editing another
|
||||||
if ($scope.linkConfig.mode === "add") {
|
if ($scope.linkConfig.mode === "add") {
|
||||||
$scope.graphState.arrayOfLinksForChart.splice($scope.graphState.arrayOfLinksForChart.length-1, 1);
|
$scope.graphState.arrayOfLinksForChart.splice($scope.graphState.arrayOfLinksForChart.length-1, 1);
|
||||||
@@ -620,27 +605,31 @@ export default ['$scope', 'TemplatesService',
|
|||||||
if ($scope.nodeConfig) {
|
if ($scope.nodeConfig) {
|
||||||
$scope.cancelNodeForm();
|
$scope.cancelNodeForm();
|
||||||
}
|
}
|
||||||
|
// User was add/editing a link and then hit the link icon
|
||||||
|
if ($scope.linkConfig && $scope.linkConfig.target) {
|
||||||
|
$scope.cancelLinkForm();
|
||||||
|
}
|
||||||
if ($scope.linkConfig) {
|
if ($scope.linkConfig) {
|
||||||
// This is the second node selected
|
// This is the second node selected
|
||||||
$scope.linkConfig.child = {
|
$scope.linkConfig.target = {
|
||||||
id: node.id,
|
id: node.id,
|
||||||
name: node.unifiedJobTemplate.name
|
name: node.unifiedJobTemplate.name
|
||||||
};
|
};
|
||||||
$scope.linkConfig.edgeType = "success";
|
$scope.linkConfig.edgeType = "success";
|
||||||
|
|
||||||
$scope.graphState.arrayOfNodesForChart.forEach((node) => {
|
$scope.graphState.arrayOfNodesForChart.forEach((nodeToUpdate) => {
|
||||||
node.isInvalidLinkTarget = false;
|
nodeToUpdate.isInvalidLinkTarget = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
$scope.graphState.arrayOfLinksForChart.push({
|
$scope.graphState.arrayOfLinksForChart.push({
|
||||||
target: $scope.graphState.arrayOfNodesForChart[node.index],
|
source: {id: $scope.linkConfig.source.id},
|
||||||
source: $scope.graphState.arrayOfNodesForChart[chartNodeIdToIndexMapping[$scope.linkConfig.parent.id]],
|
target: {id: node.id},
|
||||||
edgeType: "placeholder"
|
edgeType: "placeholder"
|
||||||
});
|
});
|
||||||
|
|
||||||
$scope.graphState.linkBeingEdited = {
|
$scope.graphState.linkBeingEdited = {
|
||||||
source: $scope.graphState.arrayOfNodesForChart[node.index].id,
|
source: {id: $scope.linkConfig.source.id},
|
||||||
target: $scope.graphState.arrayOfNodesForChart[chartNodeIdToIndexMapping[$scope.linkConfig.parent.id]].id
|
target: {id: node.id}
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.graphState.arrayOfLinksForChart.forEach((link, index) => {
|
$scope.graphState.arrayOfLinksForChart.forEach((link, index) => {
|
||||||
@@ -655,7 +644,7 @@ export default ['$scope', 'TemplatesService',
|
|||||||
$scope.graphState.addLinkSource = node.id;
|
$scope.graphState.addLinkSource = node.id;
|
||||||
$scope.linkConfig = {
|
$scope.linkConfig = {
|
||||||
mode: "add",
|
mode: "add",
|
||||||
parent: {
|
source: {
|
||||||
id: node.id,
|
id: node.id,
|
||||||
name: node.unifiedJobTemplate.name
|
name: node.unifiedJobTemplate.name
|
||||||
}
|
}
|
||||||
@@ -692,7 +681,11 @@ export default ['$scope', 'TemplatesService',
|
|||||||
|
|
||||||
// Filter out the duplicates
|
// Filter out the duplicates
|
||||||
invalidLinkTargetIds.filter((element, index, array) => index === array.indexOf(element)).forEach((ancestorId) => {
|
invalidLinkTargetIds.filter((element, index, array) => index === array.indexOf(element)).forEach((ancestorId) => {
|
||||||
$scope.graphState.arrayOfNodesForChart[chartNodeIdToIndexMapping[ancestorId]].isInvalidLinkTarget = true;
|
$scope.graphState.arrayOfNodesForChart.forEach((node) => {
|
||||||
|
if (node.id === ancestorId) {
|
||||||
|
node.isInvalidLinkTarget = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
$scope.graphState.isLinkMode = true;
|
$scope.graphState.isLinkMode = true;
|
||||||
@@ -705,7 +698,7 @@ export default ['$scope', 'TemplatesService',
|
|||||||
|
|
||||||
$scope.confirmLinkForm = (newEdgeType) => {
|
$scope.confirmLinkForm = (newEdgeType) => {
|
||||||
$scope.graphState.arrayOfLinksForChart.forEach((link) => {
|
$scope.graphState.arrayOfLinksForChart.forEach((link) => {
|
||||||
if (link.source.id === $scope.linkConfig.parent.id && link.target.id === $scope.linkConfig.child.id) {
|
if (link.source.id === $scope.linkConfig.source.id && link.target.id === $scope.linkConfig.target.id) {
|
||||||
link.edgeType = newEdgeType;
|
link.edgeType = newEdgeType;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -728,7 +721,7 @@ export default ['$scope', 'TemplatesService',
|
|||||||
for( let i = $scope.graphState.arrayOfLinksForChart.length; i--; ){
|
for( let i = $scope.graphState.arrayOfLinksForChart.length; i--; ){
|
||||||
const link = $scope.graphState.arrayOfLinksForChart[i];
|
const link = $scope.graphState.arrayOfLinksForChart[i];
|
||||||
|
|
||||||
if (link.source.id === $scope.linkConfig.parent.id && link.target.id === $scope.linkConfig.child.id) {
|
if (link.source.id === $scope.linkConfig.source.id && link.target.id === $scope.linkConfig.target.id) {
|
||||||
$scope.graphState.arrayOfLinksForChart.splice(i, 1);
|
$scope.graphState.arrayOfLinksForChart.splice(i, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -739,19 +732,19 @@ export default ['$scope', 'TemplatesService',
|
|||||||
};
|
};
|
||||||
|
|
||||||
$scope.cancelLinkForm = () => {
|
$scope.cancelLinkForm = () => {
|
||||||
if ($scope.linkConfig.mode === "add" && $scope.linkConfig.child) {
|
if ($scope.linkConfig.mode === "add" && $scope.linkConfig.target) {
|
||||||
$scope.graphState.arrayOfLinksForChart.splice($scope.graphState.arrayOfLinksForChart.length-1, 1);
|
$scope.graphState.arrayOfLinksForChart.splice($scope.graphState.arrayOfLinksForChart.length-1, 1);
|
||||||
let targetIsOrphaned = true;
|
let targetIsOrphaned = true;
|
||||||
$scope.graphState.arrayOfLinksForChart.forEach((link) => {
|
$scope.graphState.arrayOfLinksForChart.forEach((link) => {
|
||||||
if (link.target.id === $scope.linkConfig.child.id) {
|
if (link.target.id === $scope.linkConfig.target.id) {
|
||||||
targetIsOrphaned = false;
|
targetIsOrphaned = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (targetIsOrphaned) {
|
if (targetIsOrphaned) {
|
||||||
// Link it to the start node
|
// Link it to the start node
|
||||||
$scope.graphState.arrayOfLinksForChart.push({
|
$scope.graphState.arrayOfLinksForChart.push({
|
||||||
source: $scope.graphState.arrayOfNodesForChart[0],
|
source: {id: 1},
|
||||||
target: $scope.graphState.arrayOfNodesForChart[chartNodeIdToIndexMapping[$scope.linkConfig.child.id]],
|
target: {id: $scope.linkConfig.target.id},
|
||||||
edgeType: "always"
|
edgeType: "always"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -781,53 +774,69 @@ export default ['$scope', 'TemplatesService',
|
|||||||
|
|
||||||
$scope.confirmDeleteNode = function () {
|
$scope.confirmDeleteNode = function () {
|
||||||
if ($scope.nodeToBeDeleted) {
|
if ($scope.nodeToBeDeleted) {
|
||||||
const nodeIndex = $scope.nodeToBeDeleted.index;
|
const nodeId = $scope.nodeToBeDeleted.id;
|
||||||
|
|
||||||
if ($scope.linkBeingWorkedOn) {
|
if ($scope.linkConfig) {
|
||||||
$scope.cancelLinkForm();
|
$scope.cancelLinkForm();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the node from the array
|
// Remove the node from the array
|
||||||
$scope.graphState.arrayOfNodesForChart.splice(nodeIndex, 1);
|
for( let i = $scope.graphState.arrayOfNodesForChart.length; i--; ){
|
||||||
|
if ($scope.graphState.arrayOfNodesForChart[i].id === nodeId) {
|
||||||
|
$scope.graphState.arrayOfNodesForChart.splice(i, 1);
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Update the links
|
// Update the links
|
||||||
let parents = [];
|
let parents = [];
|
||||||
let children = [];
|
let children = [];
|
||||||
|
let linkParentMapping = {};
|
||||||
|
|
||||||
// Remove any links that reference this node
|
// Remove any links that reference this node
|
||||||
for( let i = $scope.graphState.arrayOfLinksForChart.length; i--; ){
|
for( let i = $scope.graphState.arrayOfLinksForChart.length; i--; ){
|
||||||
const link = $scope.graphState.arrayOfLinksForChart[i];
|
const link = $scope.graphState.arrayOfLinksForChart[i];
|
||||||
|
|
||||||
if (link.source.index === nodeIndex || link.target.index === nodeIndex) {
|
if (!linkParentMapping[link.target.id]) {
|
||||||
if (link.source.index === nodeIndex) {
|
linkParentMapping[link.target.id] = [];
|
||||||
const targetIndex = link.target.index < nodeIndex ? link.target.index : link.target.index - 1;
|
}
|
||||||
children.push({index: targetIndex, edgeType: link.edgeType});
|
|
||||||
} else if (link.target.index === nodeIndex) {
|
linkParentMapping[link.target.id].push(link.source.id);
|
||||||
const sourceIndex = link.source.index < nodeIndex ? link.source.index : link.source.index - 1;
|
|
||||||
parents.push(sourceIndex);
|
if (link.source.id === nodeId || link.target.id === nodeId) {
|
||||||
|
if (link.source.id === nodeId) {
|
||||||
|
children.push({id: link.target.id, edgeType: link.edgeType});
|
||||||
|
} else if (link.target.id === nodeId) {
|
||||||
|
parents.push(link.source.id);
|
||||||
}
|
}
|
||||||
$scope.graphState.arrayOfLinksForChart.splice(i, 1);
|
$scope.graphState.arrayOfLinksForChart.splice(i, 1);
|
||||||
} else {
|
|
||||||
// if (link.source.index > nodeIndex) {
|
|
||||||
// link.source.index = link.source.index - 1;
|
|
||||||
// }
|
|
||||||
// if (link.target.index > nodeIndex) {
|
|
||||||
// link.target.index = link.target.index - 1;
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the new links
|
// Add the new links
|
||||||
parents.forEach((parentIndex) => {
|
parents.forEach((parentId) => {
|
||||||
children.forEach((child) => {
|
children.forEach((child) => {
|
||||||
if (parentIndex === 0) {
|
if (parentId === 1) {
|
||||||
child.edgeType = "always";
|
// We only want to create a link from the start node to this node if it
|
||||||
|
// doesn't have any other parents
|
||||||
|
if(linkParentMapping[child.id].length === 1) {
|
||||||
|
$scope.graphState.arrayOfLinksForChart.push({
|
||||||
|
source: {id: parentId},
|
||||||
|
target: {id: child.id},
|
||||||
|
edgeType: "always"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// We don't want to add a link that already exists
|
||||||
|
if (!linkParentMapping[child.id].includes(parentId)) {
|
||||||
|
$scope.graphState.arrayOfLinksForChart.push({
|
||||||
|
source: {id: parentId},
|
||||||
|
target: {id: child.id},
|
||||||
|
edgeType: child.edgeType
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$scope.graphState.arrayOfLinksForChart.push({
|
|
||||||
source: $scope.graphState.arrayOfNodesForChart[parentIndex],
|
|
||||||
target: $scope.graphState.arrayOfNodesForChart[child.index],
|
|
||||||
edgeType: child.edgeType
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -837,12 +846,6 @@ export default ['$scope', 'TemplatesService',
|
|||||||
|
|
||||||
delete nodeRef[$scope.nodeToBeDeleted.id];
|
delete nodeRef[$scope.nodeToBeDeleted.id];
|
||||||
|
|
||||||
for (const key in chartNodeIdToIndexMapping) {
|
|
||||||
if (chartNodeIdToIndexMapping[key] > $scope.nodeToBeDeleted.index) {
|
|
||||||
chartNodeIdToIndexMapping[key]--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$scope.deleteOverlayVisible = false;
|
$scope.deleteOverlayVisible = false;
|
||||||
|
|
||||||
$scope.nodeToBeDeleted = null;
|
$scope.nodeToBeDeleted = null;
|
||||||
@@ -901,7 +904,7 @@ export default ['$scope', 'TemplatesService',
|
|||||||
let arrayOfLinksForChart = [];
|
let arrayOfLinksForChart = [];
|
||||||
let arrayOfNodesForChart = [];
|
let arrayOfNodesForChart = [];
|
||||||
|
|
||||||
({arrayOfNodesForChart, arrayOfLinksForChart, chartNodeIdToIndexMapping, nodeIdToChartNodeIdMapping, nodeRef, workflowMakerNodeIdCounter} = WorkflowChartService.generateArraysOfNodesAndLinks(allNodes));
|
({arrayOfNodesForChart, arrayOfLinksForChart, nodeIdToChartNodeIdMapping, nodeRef, workflowMakerNodeIdCounter} = WorkflowChartService.generateArraysOfNodesAndLinks(allNodes));
|
||||||
|
|
||||||
$scope.graphState = { arrayOfNodesForChart, arrayOfLinksForChart };
|
$scope.graphState = { arrayOfNodesForChart, arrayOfLinksForChart };
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user