mirror of
https://github.com/ansible/awx.git
synced 2026-05-20 23:37:39 -02:30
Decouple editing a wf node with editing a node link
This commit is contained in:
@@ -122,6 +122,7 @@ function TemplatesStrings (BaseString) {
|
|||||||
INVENTORY_WILL_NOT_OVERRIDE: t.s('The inventory of this node will not be overridden by the parent workflow inventory.'),
|
INVENTORY_WILL_NOT_OVERRIDE: t.s('The inventory of this node will not be overridden by the parent workflow inventory.'),
|
||||||
INVENTORY_PROMPT_WILL_OVERRIDE: t.s('The inventory of this node will be overridden if a parent workflow inventory is provided at launch.'),
|
INVENTORY_PROMPT_WILL_OVERRIDE: t.s('The inventory of this node will be overridden if a parent workflow inventory is provided at launch.'),
|
||||||
INVENTORY_PROMPT_WILL_NOT_OVERRIDE: t.s('The inventory of this node will not be overridden if a parent workflow inventory is provided at launch.'),
|
INVENTORY_PROMPT_WILL_NOT_OVERRIDE: t.s('The inventory of this node will not be overridden if a parent workflow inventory is provided at launch.'),
|
||||||
|
EDIT_LINK: ({ parentName, childName }) => t.s('EDIT LINK | {{parentName}} to {{childName}}', { parentName, childName })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,9 @@
|
|||||||
.link circle, .link .linkCross, .node .addCircle, .node .removeCircle, .node .WorkflowChart-hoverPath {
|
.link circle,
|
||||||
|
.link polygon,
|
||||||
|
.link .linkCross,
|
||||||
|
.node circle,
|
||||||
|
.node .linkIcon,
|
||||||
|
.node .WorkflowChart-hoverPath {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -18,6 +23,18 @@
|
|||||||
fill: @default-err-hov;
|
fill: @default-err-hov;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.node .linkCircle {
|
||||||
|
fill: @default-link;
|
||||||
|
}
|
||||||
|
|
||||||
|
.node .linkIcon {
|
||||||
|
color: @default-bg;
|
||||||
|
}
|
||||||
|
|
||||||
|
.linkCircle.removeHovering {
|
||||||
|
fill: @default-link-hov;
|
||||||
|
}
|
||||||
|
|
||||||
.node {
|
.node {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
font-family: 'Open Sans', sans-serif, 'FontAwesome';
|
font-family: 'Open Sans', sans-serif, 'FontAwesome';
|
||||||
@@ -50,8 +67,12 @@
|
|||||||
.WorkflowChart-alwaysShowAdd .linkCross,
|
.WorkflowChart-alwaysShowAdd .linkCross,
|
||||||
.hovering .addCircle,
|
.hovering .addCircle,
|
||||||
.hovering .removeCircle,
|
.hovering .removeCircle,
|
||||||
|
.addHovering .betweenNodesCircle,
|
||||||
|
.hovering .linkCircle,
|
||||||
|
.hovering .linkIcon,
|
||||||
.hovering .WorkflowChart-hoverPath,
|
.hovering .WorkflowChart-hoverPath,
|
||||||
.hovering .linkCross {
|
.addHovering .linkCross {
|
||||||
|
cursor: pointer;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,3 +157,17 @@
|
|||||||
.WorkflowChart-dashedNode {
|
.WorkflowChart-dashedNode {
|
||||||
stroke-dasharray: 5,5;
|
stroke-dasharray: 5,5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.linkOverlay {
|
||||||
|
fill: @default-interface-txt;
|
||||||
|
}
|
||||||
|
|
||||||
|
.linkActiveEdit.linkOverlay,
|
||||||
|
.overlayHovering .linkOverlay {
|
||||||
|
cursor: pointer;
|
||||||
|
opacity: 0.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.overlayHovering .linkPath {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ export default ['$state', 'moment', '$timeout', '$window', '$filter', 'Rest', 'G
|
|||||||
addNode: '&',
|
addNode: '&',
|
||||||
editNode: '&',
|
editNode: '&',
|
||||||
deleteNode: '&',
|
deleteNode: '&',
|
||||||
|
editLink: '&',
|
||||||
workflowZoomed: '&',
|
workflowZoomed: '&',
|
||||||
mode: '@'
|
mode: '@'
|
||||||
},
|
},
|
||||||
@@ -63,12 +64,8 @@ export default ['$state', 'moment', '$timeout', '$window', '$filter', 'Rest', 'G
|
|||||||
});
|
});
|
||||||
|
|
||||||
line = d3.svg.line()
|
line = d3.svg.line()
|
||||||
.x(function (d) {
|
.x(function(d){return d.x;})
|
||||||
return d.x;
|
.y(function(d){return d.y;});
|
||||||
})
|
|
||||||
.y(function (d) {
|
|
||||||
return d.y;
|
|
||||||
});
|
|
||||||
|
|
||||||
zoomObj = d3.behavior.zoom().scaleExtent([0.5, 2]);
|
zoomObj = d3.behavior.zoom().scaleExtent([0.5, 2]);
|
||||||
|
|
||||||
@@ -90,7 +87,8 @@ export default ['$state', 'moment', '$timeout', '$window', '$filter', 'Rest', 'G
|
|||||||
// This is the workflow editor
|
// This is the workflow editor
|
||||||
dimensions.height = $('.WorkflowMaker-contentLeft').outerHeight() - $('.WorkflowLegend-maker').outerHeight();
|
dimensions.height = $('.WorkflowMaker-contentLeft').outerHeight() - $('.WorkflowLegend-maker').outerHeight();
|
||||||
dimensions.width = $('#workflow-modal-dialog').width() - $('.WorkflowMaker-contentRight').outerWidth();
|
dimensions.width = $('#workflow-modal-dialog').width() - $('.WorkflowMaker-contentRight').outerWidth();
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
// This is the workflow details view
|
// This is the workflow details view
|
||||||
let panel = $('.WorkflowResults-rightSide').children('.Panel')[0];
|
let panel = $('.WorkflowResults-rightSide').children('.Panel')[0];
|
||||||
let panelWidth = $(panel).width();
|
let panelWidth = $(panel).width();
|
||||||
@@ -113,7 +111,8 @@ export default ['$state', 'moment', '$timeout', '$window', '$filter', 'Rest', 'G
|
|||||||
let targetX = d.target.y;
|
let targetX = d.target.y;
|
||||||
let targetY = d.target.x + nodeH / 2;
|
let targetY = d.target.x + nodeH / 2;
|
||||||
|
|
||||||
let points = [{
|
let points = [
|
||||||
|
{
|
||||||
x: sourceX,
|
x: sourceX,
|
||||||
y: sourceY
|
y: sourceY
|
||||||
},
|
},
|
||||||
@@ -131,7 +130,8 @@ export default ['$state', 'moment', '$timeout', '$window', '$filter', 'Rest', 'G
|
|||||||
function wrap(text) {
|
function wrap(text) {
|
||||||
if(text && text.length > maxNodeTextLength) {
|
if(text && text.length > maxNodeTextLength) {
|
||||||
return text.substring(0,maxNodeTextLength) + '...';
|
return text.substring(0,maxNodeTextLength) + '...';
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -140,33 +140,17 @@ export default ['$state', 'moment', '$timeout', '$window', '$filter', 'Rest', 'G
|
|||||||
var retval;
|
var retval;
|
||||||
retval = "M" + (x + r) + "," + y;
|
retval = "M" + (x + r) + "," + y;
|
||||||
retval += "h" + (w - 2*r);
|
retval += "h" + (w - 2*r);
|
||||||
if (tr) {
|
if (tr) { retval += "a" + r + "," + r + " 0 0 1 " + r + "," + r; }
|
||||||
retval += "a" + r + "," + r + " 0 0 1 " + r + "," + r;
|
else { retval += "h" + r; retval += "v" + r; }
|
||||||
} else {
|
|
||||||
retval += "h" + r;
|
|
||||||
retval += "v" + r;
|
|
||||||
}
|
|
||||||
retval += "v" + (h - 2*r);
|
retval += "v" + (h - 2*r);
|
||||||
if (br) {
|
if (br) { retval += "a" + r + "," + r + " 0 0 1 " + -r + "," + r; }
|
||||||
retval += "a" + r + "," + r + " 0 0 1 " + -r + "," + r;
|
else { retval += "v" + r; retval += "h" + -r; }
|
||||||
} else {
|
|
||||||
retval += "v" + r;
|
|
||||||
retval += "h" + -r;
|
|
||||||
}
|
|
||||||
retval += "h" + (2*r - w);
|
retval += "h" + (2*r - w);
|
||||||
if (bl) {
|
if (bl) { retval += "a" + r + "," + r + " 0 0 1 " + -r + "," + -r; }
|
||||||
retval += "a" + r + "," + r + " 0 0 1 " + -r + "," + -r;
|
else { retval += "h" + -r; retval += "v" + -r; }
|
||||||
} else {
|
|
||||||
retval += "h" + -r;
|
|
||||||
retval += "v" + -r;
|
|
||||||
}
|
|
||||||
retval += "v" + (2*r - h);
|
retval += "v" + (2*r - h);
|
||||||
if (tl) {
|
if (tl) { retval += "a" + r + "," + r + " 0 0 1 " + r + "," + -r; }
|
||||||
retval += "a" + r + "," + r + " 0 0 1 " + r + "," + -r;
|
else { retval += "v" + -r; retval += "h" + r; }
|
||||||
} else {
|
|
||||||
retval += "v" + -r;
|
|
||||||
retval += "h" + r;
|
|
||||||
}
|
|
||||||
retval += "z";
|
retval += "z";
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
@@ -254,6 +238,7 @@ export default ['$state', 'moment', '$timeout', '$window', '$filter', 'Rest', 'G
|
|||||||
// Declare the nodes
|
// Declare the nodes
|
||||||
let nodes = tree.nodes(scope.treeData),
|
let nodes = tree.nodes(scope.treeData),
|
||||||
links = tree.links(nodes);
|
links = tree.links(nodes);
|
||||||
|
|
||||||
let node = svgGroup.selectAll("g.node")
|
let node = svgGroup.selectAll("g.node")
|
||||||
.data(nodes, function(d) {
|
.data(nodes, function(d) {
|
||||||
d.y = d.depth * 240;
|
d.y = d.depth * 240;
|
||||||
@@ -262,15 +247,9 @@ export default ['$state', 'moment', '$timeout', '$window', '$filter', 'Rest', 'G
|
|||||||
|
|
||||||
let nodeEnter = node.enter().append("g")
|
let nodeEnter = node.enter().append("g")
|
||||||
.attr("class", "node")
|
.attr("class", "node")
|
||||||
.attr("id", function (d) {
|
.attr("id", function(d){return "node-" + d.id;})
|
||||||
return "node-" + d.id;
|
.attr("parent", function(d){return d.parent ? d.parent.id : null;})
|
||||||
})
|
.attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; });
|
||||||
.attr("parent", function (d) {
|
|
||||||
return d.parent ? d.parent.id : null;
|
|
||||||
})
|
|
||||||
.attr("transform", function (d) {
|
|
||||||
return "translate(" + d.y + "," + d.x + ")";
|
|
||||||
});
|
|
||||||
|
|
||||||
nodeEnter.each(function(d) {
|
nodeEnter.each(function(d) {
|
||||||
let thisNode = d3.select(this);
|
let thisNode = d3.select(this);
|
||||||
@@ -286,7 +265,8 @@ export default ['$state', 'moment', '$timeout', '$window', '$filter', 'Rest', 'G
|
|||||||
.attr("ry", 5)
|
.attr("ry", 5)
|
||||||
.attr("fill", "#337ab7")
|
.attr("fill", "#337ab7")
|
||||||
.attr("class", "WorkflowChart-rootNode");
|
.attr("class", "WorkflowChart-rootNode");
|
||||||
} else if (d.isStartNode && scope.mode !== 'details') {
|
}
|
||||||
|
else if(d.isStartNode && scope.mode !== 'details') {
|
||||||
thisNode.append("rect")
|
thisNode.append("rect")
|
||||||
.attr("width", rootW)
|
.attr("width", rootW)
|
||||||
.attr("height", rootH)
|
.attr("height", rootH)
|
||||||
@@ -301,11 +281,10 @@ export default ['$state', 'moment', '$timeout', '$window', '$filter', 'Rest', 'G
|
|||||||
.attr("y", 30)
|
.attr("y", 30)
|
||||||
.attr("dy", ".35em")
|
.attr("dy", ".35em")
|
||||||
.attr("class", "WorkflowChart-startText")
|
.attr("class", "WorkflowChart-startText")
|
||||||
.text(function () {
|
.text(function () { return TemplatesStrings.get('workflow_maker.START'); })
|
||||||
return TemplatesStrings.get('workflow_maker.START');
|
|
||||||
})
|
|
||||||
.call(add_node);
|
.call(add_node);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
thisNode.append("rect")
|
thisNode.append("rect")
|
||||||
.attr("width", nodeW)
|
.attr("width", nodeW)
|
||||||
.attr("height", nodeH)
|
.attr("height", nodeH)
|
||||||
@@ -315,12 +294,15 @@ export default ['$state', 'moment', '$timeout', '$window', '$filter', 'Rest', 'G
|
|||||||
if(d.job && d.job.status) {
|
if(d.job && d.job.status) {
|
||||||
if(d.job.status === "successful"){
|
if(d.job.status === "successful"){
|
||||||
return "#5cb85c";
|
return "#5cb85c";
|
||||||
} else if (d.job.status === "failed" || d.job.status === "error" || d.job.status === "cancelled") {
|
}
|
||||||
|
else if (d.job.status === "failed" || d.job.status === "error" || d.job.status === "cancelled") {
|
||||||
return "#d9534f";
|
return "#d9534f";
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return "#D7D7D7";
|
return "#D7D7D7";
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return "#D7D7D7";
|
return "#D7D7D7";
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -334,38 +316,18 @@ export default ['$state', 'moment', '$timeout', '$window', '$filter', 'Rest', 'G
|
|||||||
thisNode.append("path")
|
thisNode.append("path")
|
||||||
.attr("d", rounded_rect(1, 0, 5, nodeH, 5, 1, 0, 1, 0))
|
.attr("d", rounded_rect(1, 0, 5, nodeH, 5, 1, 0, 1, 0))
|
||||||
.attr("class", "WorkflowChart-activeNode")
|
.attr("class", "WorkflowChart-activeNode")
|
||||||
.style("display", function (d) {
|
.style("display", function(d) { return d.isActiveEdit ? null : "none"; });
|
||||||
return d.isActiveEdit ? null : "none";
|
|
||||||
});
|
|
||||||
|
|
||||||
thisNode.append("text")
|
thisNode.append("text")
|
||||||
.attr("x", function (d) {
|
.attr("x", function(d){ return (scope.mode === 'details' && d.job && d.job.status) ? 20 : nodeW / 2; })
|
||||||
return (scope.mode === 'details' && d.job && d.job.status) ? 20 : nodeW / 2;
|
.attr("y", function(d){ return (scope.mode === 'details' && d.job && d.job.status) ? 10 : nodeH / 2; })
|
||||||
})
|
|
||||||
.attr("y", function (d) {
|
|
||||||
return (scope.mode === 'details' && d.job && d.job.status) ? 10 : nodeH / 2;
|
|
||||||
})
|
|
||||||
.attr("dy", ".35em")
|
.attr("dy", ".35em")
|
||||||
.attr("text-anchor", function (d) {
|
.attr("text-anchor", function(d){ return (scope.mode === 'details' && d.job && d.job.status) ? "inherit" : "middle"; })
|
||||||
return (scope.mode === 'details' && d.job && d.job.status) ? "inherit" : "middle";
|
|
||||||
})
|
|
||||||
.attr("class", "WorkflowChart-defaultText WorkflowChart-nameText")
|
.attr("class", "WorkflowChart-defaultText WorkflowChart-nameText")
|
||||||
.text(function (d) {
|
.text(function (d) {
|
||||||
return (d.unifiedJobTemplate && d.unifiedJobTemplate.name) ? d.unifiedJobTemplate.name : "";
|
return (d.unifiedJobTemplate && d.unifiedJobTemplate.name) ? d.unifiedJobTemplate.name : "";
|
||||||
}).each(wrap);
|
}).each(wrap);
|
||||||
|
|
||||||
thisNode.append("foreignObject")
|
|
||||||
.attr("x", 54)
|
|
||||||
.attr("y", 45)
|
|
||||||
.style("font-size", "0.7em")
|
|
||||||
.attr("class", "WorkflowChart-conflictText")
|
|
||||||
.html(function () {
|
|
||||||
return `<span class=\"WorkflowChart-conflictIcon\">\uf06a</span><span> ${TemplatesStrings.get('workflow_maker.EDGE_CONFLICT')}</span>`;
|
|
||||||
})
|
|
||||||
.style("display", function (d) {
|
|
||||||
return (d.edgeConflict && !d.placeholder) ? null : "none";
|
|
||||||
});
|
|
||||||
|
|
||||||
thisNode.append("foreignObject")
|
thisNode.append("foreignObject")
|
||||||
.attr("x", 62)
|
.attr("x", 62)
|
||||||
.attr("y", 22)
|
.attr("y", 22)
|
||||||
@@ -375,9 +337,7 @@ export default ['$state', 'moment', '$timeout', '$window', '$filter', 'Rest', 'G
|
|||||||
.html(function () {
|
.html(function () {
|
||||||
return `<span>${TemplatesStrings.get('workflow_maker.DELETED')}</span>`;
|
return `<span>${TemplatesStrings.get('workflow_maker.DELETED')}</span>`;
|
||||||
})
|
})
|
||||||
.style("display", function (d) {
|
.style("display", function(d) { return d.unifiedJobTemplate || d.placeholder ? "none" : null; });
|
||||||
return d.unifiedJobTemplate || d.placeholder ? "none" : null;
|
|
||||||
});
|
|
||||||
|
|
||||||
thisNode.append("circle")
|
thisNode.append("circle")
|
||||||
.attr("cy", nodeH)
|
.attr("cy", nodeH)
|
||||||
@@ -391,7 +351,6 @@ export default ['$state', 'moment', '$timeout', '$window', '$filter', 'Rest', 'G
|
|||||||
d.unifiedJobTemplate.type === "workflow_job_template" ||
|
d.unifiedJobTemplate.type === "workflow_job_template" ||
|
||||||
d.unifiedJobTemplate.unified_job_type === "workflow_job") ? null : "none";
|
d.unifiedJobTemplate.unified_job_type === "workflow_job") ? null : "none";
|
||||||
});
|
});
|
||||||
|
|
||||||
thisNode.append("text")
|
thisNode.append("text")
|
||||||
.attr("y", nodeH)
|
.attr("y", nodeH)
|
||||||
.attr("dy", ".35em")
|
.attr("dy", ".35em")
|
||||||
@@ -493,23 +452,17 @@ export default ['$state', 'moment', '$timeout', '$window', '$filter', 'Rest', 'G
|
|||||||
.attr("y", nodeH - 10)
|
.attr("y", nodeH - 10)
|
||||||
.attr("dy", ".35em")
|
.attr("dy", ".35em")
|
||||||
.attr("class", "WorkflowChart-detailsLink")
|
.attr("class", "WorkflowChart-detailsLink")
|
||||||
.style("display", function (d) {
|
.style("display", function(d){ return d.job && d.job.status && d.job.id ? null : "none"; })
|
||||||
return d.job && d.job.status && d.job.id ? null : "none";
|
|
||||||
})
|
|
||||||
.text(function () {
|
.text(function () {
|
||||||
return TemplatesStrings.get('workflow_maker.DETAILS');
|
return TemplatesStrings.get('workflow_maker.DETAILS');
|
||||||
})
|
})
|
||||||
.call(details);
|
.call(details);
|
||||||
thisNode.append("circle")
|
thisNode.append("circle")
|
||||||
.attr("id", function (d) {
|
.attr("id", function(d){return "node-" + d.id + "-add";})
|
||||||
return "node-" + d.id + "-add";
|
|
||||||
})
|
|
||||||
.attr("cx", nodeW)
|
.attr("cx", nodeW)
|
||||||
.attr("r", 10)
|
.attr("r", 10)
|
||||||
.attr("class", "addCircle nodeCircle")
|
.attr("class", "addCircle nodeCircle")
|
||||||
.style("display", function (d) {
|
.style("display", function(d) { return d.placeholder || !(userCanAddEdit) ? "none" : null; })
|
||||||
return d.placeholder || !(userCanAddEdit) ? "none" : null;
|
|
||||||
})
|
|
||||||
.call(add_node)
|
.call(add_node)
|
||||||
.on("mouseover", function(d) {
|
.on("mouseover", function(d) {
|
||||||
d3.select("#node-" + d.id)
|
d3.select("#node-" + d.id)
|
||||||
@@ -526,16 +479,12 @@ export default ['$state', 'moment', '$timeout', '$window', '$filter', 'Rest', 'G
|
|||||||
thisNode.append("path")
|
thisNode.append("path")
|
||||||
.attr("class", "nodeAddCross WorkflowChart-hoverPath")
|
.attr("class", "nodeAddCross WorkflowChart-hoverPath")
|
||||||
.style("fill", "white")
|
.style("fill", "white")
|
||||||
.attr("transform", function () {
|
.attr("transform", function() { return "translate(" + nodeW + "," + 0 + ")"; })
|
||||||
return "translate(" + nodeW + "," + 0 + ")";
|
|
||||||
})
|
|
||||||
.attr("d", d3.svg.symbol()
|
.attr("d", d3.svg.symbol()
|
||||||
.size(60)
|
.size(60)
|
||||||
.type("cross")
|
.type("cross")
|
||||||
)
|
)
|
||||||
.style("display", function (d) {
|
.style("display", function(d) { return d.placeholder || !(userCanAddEdit) ? "none" : null; })
|
||||||
return d.placeholder || !(userCanAddEdit) ? "none" : null;
|
|
||||||
})
|
|
||||||
.call(add_node)
|
.call(add_node)
|
||||||
.on("mouseover", function(d) {
|
.on("mouseover", function(d) {
|
||||||
d3.select("#node-" + d.id)
|
d3.select("#node-" + d.id)
|
||||||
@@ -550,16 +499,12 @@ export default ['$state', 'moment', '$timeout', '$window', '$filter', 'Rest', 'G
|
|||||||
.classed("addHovering", false);
|
.classed("addHovering", false);
|
||||||
});
|
});
|
||||||
thisNode.append("circle")
|
thisNode.append("circle")
|
||||||
.attr("id", function (d) {
|
.attr("id", function(d){return "node-" + d.id + "-remove";})
|
||||||
return "node-" + d.id + "-remove";
|
|
||||||
})
|
|
||||||
.attr("cx", nodeW)
|
.attr("cx", nodeW)
|
||||||
.attr("cy", nodeH)
|
.attr("cy", nodeH)
|
||||||
.attr("r", 10)
|
.attr("r", 10)
|
||||||
.attr("class", "removeCircle")
|
.attr("class", "removeCircle")
|
||||||
.style("display", function (d) {
|
.style("display", function(d) { return (d.canDelete === false || d.placeholder || !(userCanAddEdit)) ? "none" : null; })
|
||||||
return (d.canDelete === false || d.placeholder || !(userCanAddEdit)) ? "none" : null;
|
|
||||||
})
|
|
||||||
.call(remove_node)
|
.call(remove_node)
|
||||||
.on("mouseover", function(d) {
|
.on("mouseover", function(d) {
|
||||||
d3.select("#node-" + d.id)
|
d3.select("#node-" + d.id)
|
||||||
@@ -576,16 +521,12 @@ export default ['$state', 'moment', '$timeout', '$window', '$filter', 'Rest', 'G
|
|||||||
thisNode.append("path")
|
thisNode.append("path")
|
||||||
.attr("class", "nodeRemoveCross WorkflowChart-hoverPath")
|
.attr("class", "nodeRemoveCross WorkflowChart-hoverPath")
|
||||||
.style("fill", "white")
|
.style("fill", "white")
|
||||||
.attr("transform", function () {
|
.attr("transform", function() { return "translate(" + nodeW + "," + nodeH + ") rotate(-45)"; })
|
||||||
return "translate(" + nodeW + "," + nodeH + ") rotate(-45)";
|
|
||||||
})
|
|
||||||
.attr("d", d3.svg.symbol()
|
.attr("d", d3.svg.symbol()
|
||||||
.size(60)
|
.size(60)
|
||||||
.type("cross")
|
.type("cross")
|
||||||
)
|
)
|
||||||
.style("display", function (d) {
|
.style("display", function(d) { return (d.canDelete === false || d.placeholder || !(userCanAddEdit)) ? "none" : null; })
|
||||||
return (d.canDelete === false || d.placeholder || !(userCanAddEdit)) ? "none" : null;
|
|
||||||
})
|
|
||||||
.call(remove_node)
|
.call(remove_node)
|
||||||
.on("mouseover", function(d) {
|
.on("mouseover", function(d) {
|
||||||
d3.select("#node-" + d.id)
|
d3.select("#node-" + d.id)
|
||||||
@@ -599,6 +540,50 @@ export default ['$state', 'moment', '$timeout', '$window', '$filter', 'Rest', 'G
|
|||||||
d3.select("#node-" + d.id + "-remove")
|
d3.select("#node-" + d.id + "-remove")
|
||||||
.classed("removeHovering", false);
|
.classed("removeHovering", false);
|
||||||
});
|
});
|
||||||
|
// thisNode.append("circle")
|
||||||
|
// .attr("id", function(d){return "node-" + d.id + "-link";})
|
||||||
|
// .attr("cx", nodeW)
|
||||||
|
// .attr("cy", nodeH/2)
|
||||||
|
// .attr("r", 10)
|
||||||
|
// .attr("class", "linkCircle nodeCircle")
|
||||||
|
// .style("display", function(d) { return d.placeholder || !(userCanAddEdit) ? "none" : null; })
|
||||||
|
// .call(link_node)
|
||||||
|
// .on("mouseover", function(d) {
|
||||||
|
// d3.select("#node-" + d.id)
|
||||||
|
// .classed("hovering", true);
|
||||||
|
// d3.select("#node-" + d.id + "-link")
|
||||||
|
// .classed("addHovering", true);
|
||||||
|
// })
|
||||||
|
// .on("mouseout", function(d){
|
||||||
|
// d3.select("#node-" + d.id)
|
||||||
|
// .classed("hovering", false);
|
||||||
|
// d3.select("#node-" + d.id + "-link")
|
||||||
|
// .classed("addHovering", false);
|
||||||
|
// });
|
||||||
|
// // TODO: clean up the placement of this icon... this works but it's not
|
||||||
|
// // clean
|
||||||
|
// thisNode.append("foreignObject")
|
||||||
|
// .attr("x", nodeW - 6)
|
||||||
|
// .attr("y", nodeH/2 - 9)
|
||||||
|
// .style("font-size","14px")
|
||||||
|
// .html(function () {
|
||||||
|
// return `<span class="fa fa-link" />`;
|
||||||
|
// })
|
||||||
|
// .attr("class", "linkIcon")
|
||||||
|
// .style("display", function(d) { return d.placeholder || !(userCanAddEdit) ? "none" : null; })
|
||||||
|
// .call(link_node)
|
||||||
|
// .on("mouseover", function(d) {
|
||||||
|
// d3.select("#node-" + d.id)
|
||||||
|
// .classed("hovering", true);
|
||||||
|
// d3.select("#node-" + d.id + "-link")
|
||||||
|
// .classed("addHovering", true);
|
||||||
|
// })
|
||||||
|
// .on("mouseout", function(d){
|
||||||
|
// d3.select("#node-" + d.id)
|
||||||
|
// .classed("hovering", false);
|
||||||
|
// d3.select("#node-" + d.id + "-link")
|
||||||
|
// .classed("addHovering", false);
|
||||||
|
// });
|
||||||
|
|
||||||
thisNode.append("circle")
|
thisNode.append("circle")
|
||||||
.attr("class", function(d) {
|
.attr("class", function(d) {
|
||||||
@@ -633,9 +618,7 @@ export default ['$state', 'moment', '$timeout', '$window', '$filter', 'Rest', 'G
|
|||||||
|
|
||||||
return statusClass;
|
return statusClass;
|
||||||
})
|
})
|
||||||
.style("display", function (d) {
|
.style("display", function(d) { return d.job && d.job.status ? null : "none"; })
|
||||||
return d.job && d.job.status ? null : "none";
|
|
||||||
})
|
|
||||||
.attr("cy", 10)
|
.attr("cy", 10)
|
||||||
.attr("cx", 10)
|
.attr("cx", 10)
|
||||||
.attr("r", 6);
|
.attr("r", 6);
|
||||||
@@ -652,13 +635,12 @@ export default ['$state', 'moment', '$timeout', '$window', '$filter', 'Rest', 'G
|
|||||||
let paddedElapsedMoment = Math.floor(elapsedMoment.asHours()) < 10 ? "0" + Math.floor(elapsedMoment.asHours()) : Math.floor(elapsedMoment.asHours());
|
let paddedElapsedMoment = Math.floor(elapsedMoment.asHours()) < 10 ? "0" + Math.floor(elapsedMoment.asHours()) : Math.floor(elapsedMoment.asHours());
|
||||||
let elapsedString = paddedElapsedMoment + moment.utc(elapsedMs).format(":mm:ss");
|
let elapsedString = paddedElapsedMoment + moment.utc(elapsedMs).format(":mm:ss");
|
||||||
return "<div class=\"WorkflowChart-elapsedHolder\"><span>" + elapsedString + "</span></div>";
|
return "<div class=\"WorkflowChart-elapsedHolder\"><span>" + elapsedString + "</span></div>";
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.style("display", function (d) {
|
.style("display", function(d) { return (d.job && d.job.elapsed) ? null : "none"; });
|
||||||
return (d.job && d.job.elapsed) ? null : "none";
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -677,34 +659,76 @@ export default ['$state', 'moment', '$timeout', '$window', '$filter', 'Rest', 'G
|
|||||||
|
|
||||||
let linkEnter = link.enter().append("g")
|
let linkEnter = link.enter().append("g")
|
||||||
.attr("class", "link")
|
.attr("class", "link")
|
||||||
.attr("id", function (d) {
|
.attr("id", function(d){return "link-" + d.source.id + "-" + d.target.id;});
|
||||||
return "link-" + d.source.id + "-" + d.target.id;
|
|
||||||
|
linkEnter.append("polygon", "g")
|
||||||
|
.attr("class", function(d) {
|
||||||
|
let linkClasses = ["linkOverlay"];
|
||||||
|
if (d.source.isLinkEditParent && d.target.isLinkEditChild) {
|
||||||
|
linkClasses.push("linkActiveEdit");
|
||||||
|
}
|
||||||
|
return linkClasses.join(' ');
|
||||||
|
})
|
||||||
|
.attr("id", function(d){return "link-" + d.source.id + "-" + d.target.id + "-overlay";})
|
||||||
|
.attr("points",function(d) {
|
||||||
|
const pt1 = [d.source.y + nodeW, d.source.x + 10 + nodeH/2].join(",");
|
||||||
|
const pt2 = [d.target.y,d.target.x + 10 + nodeH/2].join(",");
|
||||||
|
const pt3 = [d.target.y,d.target.x - 10 + nodeH/2].join(",");
|
||||||
|
const pt4 = [d.source.y + nodeW,d.source.x - 10 + nodeH/2].join(",");
|
||||||
|
return [pt1, pt2, pt3, pt4].join(" ");
|
||||||
|
})
|
||||||
|
.call(edit_link)
|
||||||
|
.on("mouseover", function(d) {
|
||||||
|
if(!d.source.isStartNode && !d.target.placeholder && scope.mode !== 'details') {
|
||||||
|
d3.select("#link-" + d.source.id + "-" + d.target.id)
|
||||||
|
.classed("overlayHovering", true);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.on("mouseout", function(d){
|
||||||
|
if(!d.source.isStartNode && !d.target.placeholder && scope.mode !== 'details') {
|
||||||
|
d3.select("#link-" + d.source.id + "-" + d.target.id)
|
||||||
|
.classed("overlayHovering", false);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add entering links in the parent’s old position.
|
// Add entering links in the parent’s old position.
|
||||||
linkEnter.insert("path", "g")
|
linkEnter.append("path", "g")
|
||||||
.attr("class", function(d) {
|
.attr("class", function(d) {
|
||||||
return (d.source.placeholder || d.target.placeholder) ? "linkPath placeholder" : "linkPath";
|
return (d.source.placeholder || d.target.placeholder) ? "linkPath placeholder" : "linkPath";
|
||||||
})
|
})
|
||||||
.attr("d", lineData)
|
.attr("d", lineData)
|
||||||
|
.call(edit_link)
|
||||||
|
.on("mouseover", function(d) {
|
||||||
|
if(!d.source.isStartNode && !d.target.placeholder && scope.mode !== 'details') {
|
||||||
|
d3.select("#link-" + d.source.id + "-" + d.target.id)
|
||||||
|
.classed("overlayHovering", true);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.on("mouseout", function(d){
|
||||||
|
if(!d.source.isStartNode && !d.target.placeholder && scope.mode !== 'details') {
|
||||||
|
d3.select("#link-" + d.source.id + "-" + d.target.id)
|
||||||
|
.classed("overlayHovering", false);
|
||||||
|
}
|
||||||
|
})
|
||||||
.attr('stroke', function(d) {
|
.attr('stroke', function(d) {
|
||||||
if(d.target.edgeType) {
|
if(d.target.edgeType) {
|
||||||
if(d.target.edgeType === "failure") {
|
if(d.target.edgeType === "failure") {
|
||||||
return "#d9534f";
|
return "#d9534f";
|
||||||
} else if (d.target.edgeType === "success") {
|
}
|
||||||
|
else if(d.target.edgeType === "success") {
|
||||||
return "#5cb85c";
|
return "#5cb85c";
|
||||||
} else if (d.target.edgeType === "always") {
|
}
|
||||||
|
else if(d.target.edgeType === "always"){
|
||||||
return "#337ab7";
|
return "#337ab7";
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return "#D7D7D7";
|
return "#D7D7D7";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
linkEnter.append("circle")
|
linkEnter.append("circle")
|
||||||
.attr("id", function (d) {
|
.attr("id", function(d){return "link-" + d.source.id + "-" + d.target.id + "-add";})
|
||||||
return "link-" + d.source.id + "-" + d.target.id + "-add";
|
|
||||||
})
|
|
||||||
.attr("cx", function(d) {
|
.attr("cx", function(d) {
|
||||||
return (d.source.isStartNode) ? (d.target.y + d.source.y + rootW) / 2 : (d.target.y + d.source.y + nodeW) / 2;
|
return (d.source.isStartNode) ? (d.target.y + d.source.y + rootW) / 2 : (d.target.y + d.source.y + nodeW) / 2;
|
||||||
})
|
})
|
||||||
@@ -712,21 +736,15 @@ export default ['$state', 'moment', '$timeout', '$window', '$filter', 'Rest', 'G
|
|||||||
return (d.source.isStartNode) ? ((d.target.x + startNodeOffsetY + rootH/2) + (d.source.x + nodeH/2)) / 2 : (d.target.x + d.source.x + nodeH) / 2;
|
return (d.source.isStartNode) ? ((d.target.x + startNodeOffsetY + rootH/2) + (d.source.x + nodeH/2)) / 2 : (d.target.x + d.source.x + nodeH) / 2;
|
||||||
})
|
})
|
||||||
.attr("r", 10)
|
.attr("r", 10)
|
||||||
.attr("class", "addCircle linkCircle")
|
.attr("class", "addCircle betweenNodesCircle")
|
||||||
.style("display", function (d) {
|
.style("display", function(d) { return (d.source.placeholder || d.target.placeholder || !(userCanAddEdit)) ? "none" : null; })
|
||||||
return (d.source.placeholder || d.target.placeholder || !(userCanAddEdit)) ? "none" : null;
|
|
||||||
})
|
|
||||||
.call(add_node_between)
|
.call(add_node_between)
|
||||||
.on("mouseover", function(d) {
|
.on("mouseover", function(d) {
|
||||||
d3.select("#link-" + d.source.id + "-" + d.target.id)
|
d3.select("#link-" + d.source.id + "-" + d.target.id)
|
||||||
.classed("hovering", true);
|
|
||||||
d3.select("#link-" + d.source.id + "-" + d.target.id + "-add")
|
|
||||||
.classed("addHovering", true);
|
.classed("addHovering", true);
|
||||||
})
|
})
|
||||||
.on("mouseout", function(d){
|
.on("mouseout", function(d){
|
||||||
d3.select("#link-" + d.source.id + "-" + d.target.id)
|
d3.select("#link-" + d.source.id + "-" + d.target.id)
|
||||||
.classed("hovering", false);
|
|
||||||
d3.select("#link-" + d.source.id + "-" + d.target.id + "-add")
|
|
||||||
.classed("addHovering", false);
|
.classed("addHovering", false);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -737,7 +755,8 @@ export default ['$state', 'moment', '$timeout', '$window', '$filter', 'Rest', 'G
|
|||||||
let translate;
|
let translate;
|
||||||
if(d.source.isStartNode) {
|
if(d.source.isStartNode) {
|
||||||
translate = "translate(" + (d.target.y + d.source.y + rootW) / 2 + "," + ((d.target.x + startNodeOffsetY + rootH/2) + (d.source.x + nodeH/2)) / 2 + ")";
|
translate = "translate(" + (d.target.y + d.source.y + rootW) / 2 + "," + ((d.target.x + startNodeOffsetY + rootH/2) + (d.source.x + nodeH/2)) / 2 + ")";
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
translate = "translate(" + (d.target.y + d.source.y + nodeW) / 2 + "," + (d.target.x + d.source.x + nodeH) / 2 + ")";
|
translate = "translate(" + (d.target.y + d.source.y + nodeW) / 2 + "," + (d.target.x + d.source.x + nodeH) / 2 + ")";
|
||||||
}
|
}
|
||||||
return translate;
|
return translate;
|
||||||
@@ -746,20 +765,14 @@ export default ['$state', 'moment', '$timeout', '$window', '$filter', 'Rest', 'G
|
|||||||
.size(60)
|
.size(60)
|
||||||
.type("cross")
|
.type("cross")
|
||||||
)
|
)
|
||||||
.style("display", function (d) {
|
.style("display", function(d) { return (d.source.placeholder || d.target.placeholder || !(userCanAddEdit)) ? "none" : null; })
|
||||||
return (d.source.placeholder || d.target.placeholder || !(userCanAddEdit)) ? "none" : null;
|
|
||||||
})
|
|
||||||
.call(add_node_between)
|
.call(add_node_between)
|
||||||
.on("mouseover", function(d) {
|
.on("mouseover", function(d) {
|
||||||
d3.select("#link-" + d.source.id + "-" + d.target.id)
|
d3.select("#link-" + d.source.id + "-" + d.target.id)
|
||||||
.classed("hovering", true);
|
|
||||||
d3.select("#link-" + d.source.id + "-" + d.target.id + "-add")
|
|
||||||
.classed("addHovering", true);
|
.classed("addHovering", true);
|
||||||
})
|
})
|
||||||
.on("mouseout", function(d){
|
.on("mouseout", function(d){
|
||||||
d3.select("#link-" + d.source.id + "-" + d.target.id)
|
d3.select("#link-" + d.source.id + "-" + d.target.id)
|
||||||
.classed("hovering", false);
|
|
||||||
d3.select("#link-" + d.source.id + "-" + d.target.id + "-add")
|
|
||||||
.classed("addHovering", false);
|
.classed("addHovering", false);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -769,24 +782,16 @@ export default ['$state', 'moment', '$timeout', '$window', '$filter', 'Rest', 'G
|
|||||||
let t = baseSvg.transition();
|
let t = baseSvg.transition();
|
||||||
|
|
||||||
t.selectAll(".nodeCircle")
|
t.selectAll(".nodeCircle")
|
||||||
.style("display", function (d) {
|
.style("display", function(d) { return d.placeholder || !(userCanAddEdit) ? "none" : null; });
|
||||||
return d.placeholder || !(userCanAddEdit) ? "none" : null;
|
|
||||||
});
|
|
||||||
|
|
||||||
t.selectAll(".nodeAddCross")
|
t.selectAll(".nodeAddCross")
|
||||||
.style("display", function (d) {
|
.style("display", function(d) { return d.placeholder || !(userCanAddEdit) ? "none" : null; });
|
||||||
return d.placeholder || !(userCanAddEdit) ? "none" : null;
|
|
||||||
});
|
|
||||||
|
|
||||||
t.selectAll(".removeCircle")
|
t.selectAll(".removeCircle")
|
||||||
.style("display", function (d) {
|
.style("display", function(d) { return (d.canDelete === false || d.placeholder || !(userCanAddEdit)) ? "none" : null; });
|
||||||
return (d.canDelete === false || d.placeholder || !(userCanAddEdit)) ? "none" : null;
|
|
||||||
});
|
|
||||||
|
|
||||||
t.selectAll(".nodeRemoveCross")
|
t.selectAll(".nodeRemoveCross")
|
||||||
.style("display", function (d) {
|
.style("display", function(d) { return (d.canDelete === false || d.placeholder || !(userCanAddEdit)) ? "none" : null; });
|
||||||
return (d.canDelete === false || d.placeholder || !(userCanAddEdit)) ? "none" : null;
|
|
||||||
});
|
|
||||||
|
|
||||||
t.selectAll(".linkPath")
|
t.selectAll(".linkPath")
|
||||||
.attr("class", function(d) {
|
.attr("class", function(d) {
|
||||||
@@ -797,20 +802,20 @@ export default ['$state', 'moment', '$timeout', '$window', '$filter', 'Rest', 'G
|
|||||||
if(d.target.edgeType) {
|
if(d.target.edgeType) {
|
||||||
if(d.target.edgeType === "failure") {
|
if(d.target.edgeType === "failure") {
|
||||||
return "#d9534f";
|
return "#d9534f";
|
||||||
} else if (d.target.edgeType === "success") {
|
}
|
||||||
|
else if(d.target.edgeType === "success") {
|
||||||
return "#5cb85c";
|
return "#5cb85c";
|
||||||
} else if (d.target.edgeType === "always") {
|
}
|
||||||
|
else if(d.target.edgeType === "always"){
|
||||||
return "#337ab7";
|
return "#337ab7";
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return "#D7D7D7";
|
return "#D7D7D7";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
t.selectAll(".linkCircle")
|
t.selectAll(".betweenNodesCircle")
|
||||||
.style("display", function (d) {
|
|
||||||
return (d.source.placeholder || d.target.placeholder || !(userCanAddEdit)) ? "none" : null;
|
|
||||||
})
|
|
||||||
.attr("cx", function(d) {
|
.attr("cx", function(d) {
|
||||||
return (d.source.isStartNode) ? (d.target.y + d.source.y + rootW) / 2 : (d.target.y + d.source.y + nodeW) / 2;
|
return (d.source.isStartNode) ? (d.target.y + d.source.y + rootW) / 2 : (d.target.y + d.source.y + nodeW) / 2;
|
||||||
})
|
})
|
||||||
@@ -818,15 +823,30 @@ export default ['$state', 'moment', '$timeout', '$window', '$filter', 'Rest', 'G
|
|||||||
return (d.source.isStartNode) ? ((d.target.x + startNodeOffsetY + rootH/2) + (d.source.x + nodeH/2)) / 2 : (d.target.x + d.source.x + nodeH) / 2;
|
return (d.source.isStartNode) ? ((d.target.x + startNodeOffsetY + rootH/2) + (d.source.x + nodeH/2)) / 2 : (d.target.x + d.source.x + nodeH) / 2;
|
||||||
});
|
});
|
||||||
|
|
||||||
t.selectAll(".linkCross")
|
t.selectAll(".linkOverlay")
|
||||||
.style("display", function (d) {
|
.attr("class", function(d) {
|
||||||
return (d.source.placeholder || d.target.placeholder || !(userCanAddEdit)) ? "none" : null;
|
let linkClasses = ["linkOverlay"];
|
||||||
|
if (d.source.isLinkEditParent && d.target.isLinkEditChild) {
|
||||||
|
linkClasses.push("linkActiveEdit");
|
||||||
|
}
|
||||||
|
return linkClasses.join(' ');
|
||||||
})
|
})
|
||||||
|
.attr("points",function(d) {
|
||||||
|
const pt1 = [d.source.y + nodeW, d.source.x + 10 + nodeH/2].join(",");
|
||||||
|
const pt2 = [d.target.y,d.target.x + 10 + nodeH/2].join(",");
|
||||||
|
const pt3 = [d.target.y,d.target.x - 10 + nodeH/2].join(",");
|
||||||
|
const pt4 = [d.source.y + nodeW,d.source.x - 10 + nodeH/2].join(",");
|
||||||
|
return [pt1, pt2, pt3, pt4].join(" ");
|
||||||
|
});
|
||||||
|
|
||||||
|
t.selectAll(".linkCross")
|
||||||
|
.style("display", function(d) { return (d.source.placeholder || d.target.placeholder || !(userCanAddEdit)) ? "none" : null; })
|
||||||
.attr("transform", function(d) {
|
.attr("transform", function(d) {
|
||||||
let translate;
|
let translate;
|
||||||
if(d.source.isStartNode) {
|
if(d.source.isStartNode) {
|
||||||
translate = "translate(" + (d.target.y + d.source.y + rootW) / 2 + "," + ((d.target.x + startNodeOffsetY + rootH/2) + (d.source.x + nodeH/2)) / 2 + ")";
|
translate = "translate(" + (d.target.y + d.source.y + rootW) / 2 + "," + ((d.target.x + startNodeOffsetY + rootH/2) + (d.source.x + nodeH/2)) / 2 + ")";
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
translate = "translate(" + (d.target.y + d.source.y + nodeW) / 2 + "," + (d.target.x + d.source.x + nodeH) / 2 + ")";
|
translate = "translate(" + (d.target.y + d.source.y + nodeW) / 2 + "," + (d.target.x + d.source.x + nodeH) / 2 + ")";
|
||||||
}
|
}
|
||||||
return translate;
|
return translate;
|
||||||
@@ -837,12 +857,15 @@ export default ['$state', 'moment', '$timeout', '$window', '$filter', 'Rest', 'G
|
|||||||
if(d.job && d.job.status) {
|
if(d.job && d.job.status) {
|
||||||
if(d.job.status === "successful"){
|
if(d.job.status === "successful"){
|
||||||
return "#5cb85c";
|
return "#5cb85c";
|
||||||
} else if (d.job.status === "failed" || d.job.status === "error" || d.job.status === "cancelled") {
|
}
|
||||||
|
else if (d.job.status === "failed" || d.job.status === "error" || d.job.status === "cancelled") {
|
||||||
return "#d9534f";
|
return "#d9534f";
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return "#D7D7D7";
|
return "#D7D7D7";
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return "#D7D7D7";
|
return "#D7D7D7";
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -853,14 +876,8 @@ export default ['$state', 'moment', '$timeout', '$window', '$filter', 'Rest', 'G
|
|||||||
});
|
});
|
||||||
|
|
||||||
t.selectAll(".node")
|
t.selectAll(".node")
|
||||||
.attr("parent", function (d) {
|
.attr("parent", function(d){return d.parent ? d.parent.id : null;})
|
||||||
return d.parent ? d.parent.id : null;
|
.attr("transform", function(d) {d.px = d.x; d.py = d.y; return "translate(" + d.y + "," + d.x + ")"; });
|
||||||
})
|
|
||||||
.attr("transform", function (d) {
|
|
||||||
d.px = d.x;
|
|
||||||
d.py = d.y;
|
|
||||||
return "translate(" + d.y + "," + d.x + ")";
|
|
||||||
});
|
|
||||||
|
|
||||||
t.selectAll(".WorkflowChart-nodeTypeCircle")
|
t.selectAll(".WorkflowChart-nodeTypeCircle")
|
||||||
.style("display", function (d) {
|
.style("display", function (d) {
|
||||||
@@ -945,9 +962,7 @@ export default ['$state', 'moment', '$timeout', '$window', '$filter', 'Rest', 'G
|
|||||||
|
|
||||||
return statusClass;
|
return statusClass;
|
||||||
})
|
})
|
||||||
.style("display", function (d) {
|
.style("display", function(d) { return d.job && d.job.status ? null : "none"; })
|
||||||
return d.job && d.job.status ? null : "none";
|
|
||||||
})
|
|
||||||
.transition()
|
.transition()
|
||||||
.duration(0)
|
.duration(0)
|
||||||
.attr("r", 6)
|
.attr("r", 6)
|
||||||
@@ -969,44 +984,26 @@ export default ['$state', 'moment', '$timeout', '$window', '$filter', 'Rest', 'G
|
|||||||
});
|
});
|
||||||
|
|
||||||
t.selectAll(".WorkflowChart-nameText")
|
t.selectAll(".WorkflowChart-nameText")
|
||||||
.attr("x", function (d) {
|
.attr("x", function(d){ return (scope.mode === 'details' && d.job && d.job.status) ? 20 : nodeW / 2; })
|
||||||
return (scope.mode === 'details' && d.job && d.job.status) ? 20 : nodeW / 2;
|
.attr("y", function(d){ return (scope.mode === 'details' && d.job && d.job.status) ? 10 : nodeH / 2; })
|
||||||
})
|
.attr("text-anchor", function(d){ return (scope.mode === 'details' && d.job && d.job.status) ? "inherit" : "middle"; })
|
||||||
.attr("y", function (d) {
|
|
||||||
return (scope.mode === 'details' && d.job && d.job.status) ? 10 : nodeH / 2;
|
|
||||||
})
|
|
||||||
.attr("text-anchor", function (d) {
|
|
||||||
return (scope.mode === 'details' && d.job && d.job.status) ? "inherit" : "middle";
|
|
||||||
})
|
|
||||||
.text(function (d) {
|
.text(function (d) {
|
||||||
return (d.unifiedJobTemplate && d.unifiedJobTemplate.name) ? wrap(d.unifiedJobTemplate.name) : "";
|
return (d.unifiedJobTemplate && d.unifiedJobTemplate.name) ? wrap(d.unifiedJobTemplate.name) : "";
|
||||||
});
|
});
|
||||||
|
|
||||||
t.selectAll(".WorkflowChart-detailsLink")
|
t.selectAll(".WorkflowChart-detailsLink")
|
||||||
.style("display", function (d) {
|
.style("display", function(d){ return d.job && d.job.status && d.job.id ? null : "none"; });
|
||||||
return d.job && d.job.status && d.job.id ? null : "none";
|
|
||||||
});
|
|
||||||
|
|
||||||
t.selectAll(".WorkflowChart-deletedText")
|
t.selectAll(".WorkflowChart-deletedText")
|
||||||
.style("display", function (d) {
|
.style("display", function(d){ return d.unifiedJobTemplate || d.placeholder ? "none" : null; });
|
||||||
return d.unifiedJobTemplate || d.placeholder ? "none" : null;
|
|
||||||
});
|
|
||||||
|
|
||||||
t.selectAll(".WorkflowChart-conflictText")
|
|
||||||
.style("display", function (d) {
|
|
||||||
return (d.edgeConflict && !d.placeholder) ? null : "none";
|
|
||||||
});
|
|
||||||
|
|
||||||
t.selectAll(".WorkflowChart-activeNode")
|
t.selectAll(".WorkflowChart-activeNode")
|
||||||
.style("display", function (d) {
|
.style("display", function(d) { return d.isActiveEdit ? null : "none"; });
|
||||||
return d.isActiveEdit ? null : "none";
|
|
||||||
});
|
|
||||||
|
|
||||||
t.selectAll(".WorkflowChart-elapsed")
|
t.selectAll(".WorkflowChart-elapsed")
|
||||||
.style("display", function (d) {
|
.style("display", function(d) { return (d.job && d.job.elapsed) ? null : "none"; });
|
||||||
return (d.job && d.job.elapsed) ? null : "none";
|
}
|
||||||
});
|
else if(!scope.watchDimensionsSet){
|
||||||
} else if (!scope.watchDimensionsSet) {
|
|
||||||
scope.watchDimensionsSet = scope.$watch('dimensionsSet', function(){
|
scope.watchDimensionsSet = scope.$watch('dimensionsSet', function(){
|
||||||
if(scope.dimensionsSet) {
|
if(scope.dimensionsSet) {
|
||||||
scope.watchDimensionsSet();
|
scope.watchDimensionsSet();
|
||||||
@@ -1059,6 +1056,24 @@ export default ['$state', 'moment', '$timeout', '$window', '$filter', 'Rest', 'G
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function edit_link() {
|
||||||
|
this.on("click", function(d) {
|
||||||
|
if(!d.source.isStartNode && !d.target.placeholder && scope.mode !== 'details'){
|
||||||
|
// What if the node is new? it won't have a nodeId right?
|
||||||
|
scope.editLink({
|
||||||
|
parentId: d.source.nodeId,
|
||||||
|
childId: d.target.nodeId
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function link_node() {
|
||||||
|
this.on("click", function(d) {
|
||||||
|
alert('this does not work, don\'t click it');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function details() {
|
function details() {
|
||||||
this.on("mouseover", function() {
|
this.on("mouseover", function() {
|
||||||
d3.select(this).style("text-decoration", "underline");
|
d3.select(this).style("text-decoration", "underline");
|
||||||
@@ -1070,53 +1085,37 @@ export default ['$state', 'moment', '$timeout', '$window', '$filter', 'Rest', 'G
|
|||||||
|
|
||||||
let goToJobResults = function(job_type) {
|
let goToJobResults = function(job_type) {
|
||||||
if(job_type === 'job') {
|
if(job_type === 'job') {
|
||||||
$state.go('output', {
|
$state.go('output', {id: d.job.id, type: 'playbook'});
|
||||||
id: d.job.id,
|
}
|
||||||
type: 'playbook'
|
else if(job_type === 'inventory_update') {
|
||||||
});
|
$state.go('output', {id: d.job.id, type: 'inventory'});
|
||||||
} else if (job_type === 'inventory_update') {
|
}
|
||||||
$state.go('output', {
|
else if(job_type === 'project_update') {
|
||||||
id: d.job.id,
|
$state.go('output', {id: d.job.id, type: 'project'});
|
||||||
type: 'inventory'
|
|
||||||
});
|
|
||||||
} else if (job_type === 'project_update') {
|
|
||||||
$state.go('output', {
|
|
||||||
id: d.job.id,
|
|
||||||
type: 'project'
|
|
||||||
});
|
|
||||||
} else if (job_type === 'workflow_job') {
|
|
||||||
$state.go('workflowResults', {
|
|
||||||
id: d.job.id,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (d.job.type) {
|
if(d.job.id) {
|
||||||
goToJobResults(d.job.type);
|
if(d.unifiedJobTemplate) {
|
||||||
|
goToJobResults(d.unifiedJobTemplate.unified_job_type);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// We don't have access to the job type and have to make
|
// We don't have access to the unified resource 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) {
|
||||||
const { results } = res.data;
|
goToJobResults(res.data.results[0].type);
|
||||||
const job = results.filter(result => result.summary_fields.job.id === d.job.id);
|
|
||||||
goToJobResults(job[0].summary_fields.job.type);
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(({
|
.catch(({data, status}) => {
|
||||||
data,
|
ProcessErrors(scope, data, status, null, { hdr: 'Error!', msg: 'Unable to get job: ' + status });
|
||||||
status
|
|
||||||
}) => {
|
|
||||||
ProcessErrors(scope, data, status, null, {
|
|
||||||
hdr: 'Error!',
|
|
||||||
msg: 'Unable to get job: ' + status
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1159,6 +1158,7 @@ export default ['$state', 'moment', '$timeout', '$window', '$filter', 'Rest', 'G
|
|||||||
function onResize(){
|
function onResize(){
|
||||||
let dimensions = calcAvailableScreenSpace();
|
let dimensions = calcAvailableScreenSpace();
|
||||||
|
|
||||||
|
$('.WorkflowMaker-chart').css("width", dimensions.width);
|
||||||
$('.WorkflowMaker-chart').css("height", dimensions.height);
|
$('.WorkflowMaker-chart').css("height", dimensions.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1177,14 +1177,15 @@ export default ['$state', 'moment', '$timeout', '$window', '$filter', 'Rest', 'G
|
|||||||
$('.WorkflowMaker-chart').show();
|
$('.WorkflowMaker-chart').show();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
scope.$on('workflowMakerModalResized', function(){
|
scope.$on('workflowMakerModalResized', function(){
|
||||||
let dimensions = calcAvailableScreenSpace();
|
let dimensions = calcAvailableScreenSpace();
|
||||||
|
|
||||||
|
$('.WorkflowMaker-chart').css("width", dimensions.width);
|
||||||
$('.WorkflowMaker-chart').css("height", dimensions.height);
|
$('.WorkflowMaker-chart').css("height", dimensions.height);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}];
|
||||||
];
|
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import workflowLinkForm from './workflow-link-form.directive';
|
||||||
|
import workflowNodeForm from './workflow-node-form.directive';
|
||||||
|
|
||||||
|
export default
|
||||||
|
angular.module('templates.workflowMaker.forms', [])
|
||||||
|
.directive('workflowLinkForm', workflowLinkForm)
|
||||||
|
.directive('workflowNodeForm', workflowNodeForm);
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/*************************************************
|
||||||
|
* Copyright (c) 2018 Ansible, Inc.
|
||||||
|
*
|
||||||
|
* All Rights Reserved
|
||||||
|
*************************************************/
|
||||||
|
|
||||||
|
export default ['$scope', 'TemplatesStrings', 'CreateSelect2', '$timeout',
|
||||||
|
function($scope, TemplatesStrings, CreateSelect2, $timeout) {
|
||||||
|
$scope.strings = TemplatesStrings;
|
||||||
|
|
||||||
|
$scope.edgeTypeOptions = [
|
||||||
|
{
|
||||||
|
label: $scope.strings.get('workflow_maker.ALWAYS'),
|
||||||
|
value: 'always'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: $scope.strings.get('workflow_maker.ON_SUCCESS'),
|
||||||
|
value: 'success'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: $scope.strings.get('workflow_maker.ON_FAILURE'),
|
||||||
|
value: 'failure'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
$scope.$watch('linkConfig.edgeType', () => {
|
||||||
|
if (_.has($scope, 'linkConfig.edgeType')) {
|
||||||
|
$scope.edgeType = {
|
||||||
|
value: $scope.linkConfig.edgeType
|
||||||
|
};
|
||||||
|
CreateSelect2({
|
||||||
|
element: '#workflow_node_edge_2',
|
||||||
|
multiple: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
];
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
/*************************************************
|
||||||
|
* Copyright (c) 2018 Ansible, Inc.
|
||||||
|
*
|
||||||
|
* All Rights Reserved
|
||||||
|
*************************************************/
|
||||||
|
|
||||||
|
import workflowLinkFormController from './workflow-link-form.controller';
|
||||||
|
|
||||||
|
export default ['templateUrl',
|
||||||
|
function(templateUrl) {
|
||||||
|
return {
|
||||||
|
scope: {
|
||||||
|
linkConfig: '<',
|
||||||
|
cancel: '&',
|
||||||
|
select: '&'
|
||||||
|
},
|
||||||
|
restrict: 'E',
|
||||||
|
templateUrl: templateUrl('templates/workflows/workflow-maker/forms/workflow-link-form'),
|
||||||
|
controller: workflowLinkFormController
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
<div class="WorkflowMaker-formTitle">{{:: strings.get('workflow_maker.EDIT_LINK', {parentName: linkConfig.parent.name, childName: linkConfig.child.name}) }}</div>
|
||||||
|
<div class="WorkflowMaker-form">
|
||||||
|
<div class="form-group Form-formGroup Form-formGroup--singleColumn">
|
||||||
|
<label for="edgeType" class="Form-inputLabelContainer">
|
||||||
|
<span class="Form-requiredAsterisk">*</span>
|
||||||
|
<span class="Form-inputLabel">{{:: strings.get('workflow_maker.RUN') }}</span>
|
||||||
|
</label>
|
||||||
|
<div>
|
||||||
|
<select
|
||||||
|
id="workflow_node_edge_2"
|
||||||
|
ng-options="v as v.label for v in edgeTypeOptions track by v.value"
|
||||||
|
ng-model="edgeType"
|
||||||
|
class="form-control Form-dropDown"
|
||||||
|
name="edgeType"
|
||||||
|
tabindex="-1"
|
||||||
|
aria-hidden="true">
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="buttons Form-buttons" id="workflow_maker_controls">
|
||||||
|
<button type="button" class="btn btn-sm Form-cancelButton" id="workflow_maker_cancel_link_btn" ng-click="cancel()"> {{:: strings.get('CANCEL') }}</button>
|
||||||
|
<button type="button" class="btn btn-sm Form-saveButton" id="workflow_maker_select_link_btn" ng-click="select({parentId: linkConfig.parent.id, childId: linkConfig.child.id, edgeType: edgeType.value})" ng-disabled="!edgeType"> {{:: strings.get('workflow_maker.SELECT') }}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
/*************************************************
|
||||||
|
* Copyright (c) 2018 Ansible, Inc.
|
||||||
|
*
|
||||||
|
* All Rights Reserved
|
||||||
|
*************************************************/
|
||||||
|
|
||||||
|
export default ['$scope',
|
||||||
|
function($scope) {
|
||||||
|
console.log('inside wnf controller');
|
||||||
|
}
|
||||||
|
];
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
/*************************************************
|
||||||
|
* Copyright (c) 2018 Ansible, Inc.
|
||||||
|
*
|
||||||
|
* All Rights Reserved
|
||||||
|
*************************************************/
|
||||||
|
|
||||||
|
import workflowNodeFormController from './workflow-node-form.controller';
|
||||||
|
|
||||||
|
export default ['templateUrl',
|
||||||
|
function(templateUrl) {
|
||||||
|
return {
|
||||||
|
scope: {},
|
||||||
|
restrict: 'E',
|
||||||
|
templateUrl: templateUrl('templates/workflows/workflow-maker/forms/workflow-node-form'),
|
||||||
|
controller: workflowNodeFormController,
|
||||||
|
link: function(scope) {
|
||||||
|
console.log('inside link function for workflow node form');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
<div class="Form-tabHolder">
|
||||||
|
<div class="Form-tab WorkflowMaker-formTab" ng-class="{'is-selected': workflowMakerFormConfig.activeTab === 'jobs'}" ng-click="toggleFormTab('jobs')">{{strings.get('workflow_maker.JOBS')}}</div>
|
||||||
|
<div class="Form-tab WorkflowMaker-formTab" ng-class="{'is-selected': workflowMakerFormConfig.activeTab === 'project_sync'}" ng-click="toggleFormTab('project_sync')">{{strings.get('workflow_maker.PROJECT_SYNC')}}</div>
|
||||||
|
<div class="Form-tab WorkflowMaker-formTab" ng-class="{'is-selected': workflowMakerFormConfig.activeTab === 'inventory_sync'}" ng-click="toggleFormTab('inventory_sync')">{{strings.get('workflow_maker.INVENTORY_SYNC')}}</div>
|
||||||
|
</div>
|
||||||
|
<div class="WorkflowMaker-formLists">
|
||||||
|
<div id="workflow-jobs-list" ui-view="jobTemplateList" ng-show="workflowMakerFormConfig.activeTab === 'jobs'"></div>
|
||||||
|
<div id="workflow-project-sync-list" ui-view="projectSyncList" ng-show="workflowMakerFormConfig.activeTab === 'project_sync'"></div>
|
||||||
|
<div id="workflow-inventory-sync-list" ui-view="inventorySyncList" ng-show="workflowMakerFormConfig.activeTab === 'inventory_sync'"></div>
|
||||||
|
</div>
|
||||||
|
<span ng-show="selectedTemplate &&
|
||||||
|
((selectedTemplate.type === 'job_template' && workflowMakerFormConfig.activeTab === 'jobs') ||
|
||||||
|
(selectedTemplate.type === 'project' && workflowMakerFormConfig.activeTab === 'project_sync') ||
|
||||||
|
(selectedTemplate.type === 'inventory_source' && workflowMakerFormConfig.activeTab === 'inventory_sync'))">
|
||||||
|
<div ng-if="selectedTemplate && selectedTemplateInvalid">
|
||||||
|
<div class="WorkflowMaker-invalidJobTemplateWarning">
|
||||||
|
<span class="fa fa-warning"></span>
|
||||||
|
<span>{{:: strings.get('workflows.INVALID_JOB_TEMPLATE') }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div ng-if="selectedTemplate && credentialRequiresPassword">
|
||||||
|
<div class="WorkflowMaker-invalidJobTemplateWarning">
|
||||||
|
<span class="fa fa-warning"></span>
|
||||||
|
<span>{{:: strings.get('workflows.CREDENTIAL_WITH_PASS') }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group Form-formGroup Form-formGroup--singleColumn" ng-show="selectedTemplate && !selectedTemplateInvalid && !(credentialRequiresPassword && !promptData.launchConf.ask_credential_on_launch)">
|
||||||
|
<label for="verbosity" class="Form-inputLabelContainer">
|
||||||
|
<span class="Form-requiredAsterisk">*</span>
|
||||||
|
<span class="Form-inputLabel">{{:: strings.get('workflow_maker.RUN') }}</span>
|
||||||
|
</label>
|
||||||
|
<div>
|
||||||
|
<select
|
||||||
|
id="workflow_node_edge"
|
||||||
|
ng-options="v as v.label for v in edgeTypeOptions track by v.value"
|
||||||
|
ng-model="edgeType"
|
||||||
|
class="form-control Form-dropDown"
|
||||||
|
name="edgeType"
|
||||||
|
tabindex="-1"
|
||||||
|
ng-disabled="!workflowJobTemplateObj.summary_fields.user_capabilities.edit"
|
||||||
|
aria-hidden="true">
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="buttons Form-buttons" id="workflow_maker_controls">
|
||||||
|
<button type="button" class="btn btn-sm Form-primaryButton Form-primaryButton--noMargin" id="workflow_maker_prompt_btn" ng-show="showPromptButton" ng-click="openPromptModal()"> {{:: strings.get('prompt.PROMPT') }}</button>
|
||||||
|
<button type="button" class="btn btn-sm Form-cancelButton" id="workflow_maker_cancel_btn" ng-show="(workflowJobTemplateObj.summary_fields.user_capabilities.edit || canAddWorkflowJobTemplate)" ng-click="cancelNodeForm()"> {{:: strings.get('CANCEL') }}</button>
|
||||||
|
<button type="button" class="btn btn-sm Form-cancelButton" id="workflow_maker_close_btn" ng-show="!(workflowJobTemplateObj.summary_fields.user_capabilities.edit || canAddWorkflowJobTemplate)" ng-click="cancelNodeForm()"> {{:: strings.get('CLOSE') }}</button>
|
||||||
|
<button type="button" class="btn btn-sm Form-saveButton" id="workflow_maker_select_btn" ng-show="(workflowJobTemplateObj.summary_fields.user_capabilities.edit || canAddWorkflowJobTemplate) && !selectedTemplateInvalid && !(credentialRequiresPassword && !promptData.launchConf.ask_credential_on_launch)" ng-click="confirmNodeForm()" ng-disabled="!selectedTemplate || promptModalMissingReqFields || credentialRequiresPassword"> {{:: strings.get('workflow_maker.SELECT') }}</button>
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
import workflowMaker from './workflow-maker.directive';
|
import workflowMaker from './workflow-maker.directive';
|
||||||
import WorkflowMakerController from './workflow-maker.controller';
|
import WorkflowMakerController from './workflow-maker.controller';
|
||||||
|
import workflowMakerForms from './forms/main';
|
||||||
|
|
||||||
export default
|
export default
|
||||||
angular.module('templates.workflowMaker', [])
|
angular.module('templates.workflowMaker', [workflowMakerForms.name])
|
||||||
// In order to test this controller I had to expose it at the module level
|
// In order to test this controller I had to expose it at the module level
|
||||||
// like so. Is this correct? Is there a better pattern for doing this?
|
// like so. Is this correct? Is there a better pattern for doing this?
|
||||||
.controller('WorkflowMakerController', WorkflowMakerController)
|
.controller('WorkflowMakerController', WorkflowMakerController)
|
||||||
|
|||||||
@@ -127,7 +127,6 @@
|
|||||||
color: @list-title-txt;
|
color: @list-title-txt;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
text-transform: uppercase;
|
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
.WorkflowMaker-formHelp {
|
.WorkflowMaker-formHelp {
|
||||||
|
|||||||
@@ -203,7 +203,7 @@ export default ['$scope', 'WorkflowService', 'TemplatesService',
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
if (params.node.edited || !params.node.originalParentId || (params.node.originalParentId && params.parentId !== params.node.originalParentId)) {
|
if (params.node.edited || !params.node.originalParentId || (params.node.originalParentId && (params.parentId !== params.node.originalParentId || params.node.originalEdge !== params.node.edgeType))) {
|
||||||
|
|
||||||
if (params.node.edited) {
|
if (params.node.edited) {
|
||||||
|
|
||||||
@@ -446,6 +446,10 @@ export default ['$scope', 'WorkflowService', 'TemplatesService',
|
|||||||
$scope.cancelNodeForm();
|
$scope.cancelNodeForm();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($scope.linkBeingEdited) {
|
||||||
|
$scope.cancelLinkForm();
|
||||||
|
}
|
||||||
|
|
||||||
$scope.workflowMakerFormConfig.nodeMode = "add";
|
$scope.workflowMakerFormConfig.nodeMode = "add";
|
||||||
$scope.addParent = parent;
|
$scope.addParent = parent;
|
||||||
$scope.betweenTwoNodes = betweenTwoNodes;
|
$scope.betweenTwoNodes = betweenTwoNodes;
|
||||||
@@ -572,6 +576,10 @@ export default ['$scope', 'WorkflowService', 'TemplatesService',
|
|||||||
$scope.startEditNode = function (nodeToEdit) {
|
$scope.startEditNode = function (nodeToEdit) {
|
||||||
$scope.editNodeHelpMessage = null;
|
$scope.editNodeHelpMessage = null;
|
||||||
|
|
||||||
|
if ($scope.linkBeingEdited) {
|
||||||
|
$scope.cancelLinkForm();
|
||||||
|
}
|
||||||
|
|
||||||
if (!$scope.nodeBeingEdited || ($scope.nodeBeingEdited && $scope.nodeBeingEdited.id !== nodeToEdit.id)) {
|
if (!$scope.nodeBeingEdited || ($scope.nodeBeingEdited && $scope.nodeBeingEdited.id !== nodeToEdit.id)) {
|
||||||
if ($scope.placeholderNode || $scope.nodeBeingEdited) {
|
if ($scope.placeholderNode || $scope.nodeBeingEdited) {
|
||||||
$scope.cancelNodeForm();
|
$scope.cancelNodeForm();
|
||||||
@@ -893,6 +901,91 @@ export default ['$scope', 'WorkflowService', 'TemplatesService',
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* EDIT LINK FUNCTIONS */
|
||||||
|
|
||||||
|
$scope.startEditLink = (parentId, childId) => {
|
||||||
|
const setupLinkEdit = () => {
|
||||||
|
const parentNode = WorkflowService.searchTree({
|
||||||
|
element: $scope.treeData.data,
|
||||||
|
matchingId: parentId,
|
||||||
|
byNodeId: true
|
||||||
|
});
|
||||||
|
|
||||||
|
parentNode.isLinkEditParent = true;
|
||||||
|
|
||||||
|
// Loop across children looking for childId
|
||||||
|
const childNode = _.find(parentNode.children, {'nodeId': childId});
|
||||||
|
|
||||||
|
childNode.isLinkEditChild = true;
|
||||||
|
|
||||||
|
$scope.linkBeingEdited = {
|
||||||
|
parent: parentNode,
|
||||||
|
child: childNode
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.linkConfig = {
|
||||||
|
parent: {
|
||||||
|
id: parentId,
|
||||||
|
name: parentNode.unifiedJobTemplate.name
|
||||||
|
},
|
||||||
|
child: {
|
||||||
|
id: childId,
|
||||||
|
name: childNode.unifiedJobTemplate.name
|
||||||
|
},
|
||||||
|
edgeType: childNode.edgeType
|
||||||
|
}
|
||||||
|
$scope.editLink = true;
|
||||||
|
|
||||||
|
$scope.$broadcast("refreshWorkflowChart");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($scope.nodeBeingEdited || $scope.placeholderNode) {
|
||||||
|
$scope.cancelNodeForm();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($scope.linkBeingEdited) {
|
||||||
|
if ($scope.linkBeingEdited.parent.nodeId !== parentId || $scope.linkBeingEdited.child.nodeId !== childId) {
|
||||||
|
$scope.linkBeingEdited.parent.isLinkEditParent = false;
|
||||||
|
$scope.linkBeingEdited.child.isLinkEditChild = false;
|
||||||
|
setupLinkEdit()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setupLinkEdit();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.confirmLinkForm = (parentId, childId, edgeType) => {
|
||||||
|
$scope.linkBeingEdited.parent.isLinkEditParent = false;
|
||||||
|
$scope.linkBeingEdited.child.isLinkEditChild = false;
|
||||||
|
const parentNode = WorkflowService.searchTree({
|
||||||
|
element: $scope.treeData.data,
|
||||||
|
matchingId: parentId,
|
||||||
|
byNodeId: true
|
||||||
|
});
|
||||||
|
|
||||||
|
// Loop across children looking for childId
|
||||||
|
const childNode = _.find(parentNode.children, {'nodeId': childId});
|
||||||
|
|
||||||
|
childNode.edgeType = edgeType;
|
||||||
|
|
||||||
|
$scope.linkBeingEdited = null;
|
||||||
|
|
||||||
|
$scope.editLink = false;
|
||||||
|
|
||||||
|
$scope.$broadcast("refreshWorkflowChart");
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.cancelLinkForm = () => {
|
||||||
|
$scope.linkBeingEdited.parent.isLinkEditParent = false;
|
||||||
|
$scope.linkBeingEdited.child.isLinkEditChild = false;
|
||||||
|
$scope.linkBeingEdited = null;
|
||||||
|
|
||||||
|
$scope.editLink = false;
|
||||||
|
|
||||||
|
$scope.$broadcast("refreshWorkflowChart");
|
||||||
|
};
|
||||||
|
|
||||||
/* DELETE NODE FUNCTIONS */
|
/* DELETE NODE FUNCTIONS */
|
||||||
|
|
||||||
function resetDeleteNode() {
|
function resetDeleteNode() {
|
||||||
@@ -912,6 +1005,10 @@ export default ['$scope', 'WorkflowService', 'TemplatesService',
|
|||||||
$scope.confirmDeleteNode = function () {
|
$scope.confirmDeleteNode = function () {
|
||||||
if ($scope.nodeToBeDeleted) {
|
if ($scope.nodeToBeDeleted) {
|
||||||
|
|
||||||
|
if ($scope.linkBeingEdited) {
|
||||||
|
$scope.cancelLinkForm();
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: turn this into a promise so that we can handle errors
|
// TODO: turn this into a promise so that we can handle errors
|
||||||
|
|
||||||
WorkflowService.removeNodeFromTree({
|
WorkflowService.removeNodeFromTree({
|
||||||
|
|||||||
@@ -81,9 +81,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<workflow-chart ng-if="modalOpen" tree-data="treeData.data" add-node="startAddNode(parent, betweenTwoNodes)" edit-node="startEditNode(nodeToEdit)" delete-node="startDeleteNode(nodeToDelete)" workflow-zoomed="workflowZoomed(zoom)" can-add-workflow-job-template="canAddWorkflowJobTemplate" workflow-job-template-obj="workflowJobTemplateObj" mode="edit" class="WorkflowMaker-chart"></workflow-chart>
|
<workflow-chart ng-if="modalOpen" tree-data="treeData.data" add-node="startAddNode(parent, betweenTwoNodes)" edit-node="startEditNode(nodeToEdit)" edit-link="startEditLink(parentId, childId)" delete-node="startDeleteNode(nodeToDelete)" workflow-zoomed="workflowZoomed(zoom)" can-add-workflow-job-template="canAddWorkflowJobTemplate" workflow-job-template-obj="workflowJobTemplateObj" mode="edit" class="WorkflowMaker-chart"></workflow-chart>
|
||||||
</div>
|
</div>
|
||||||
<div class="WorkflowMaker-contentRight">
|
<div class="WorkflowMaker-contentRight">
|
||||||
|
<span ng-show="!editLink">
|
||||||
<div class="WorkflowMaker-formTitle">{{(workflowMakerFormConfig.nodeMode === 'edit' && nodeBeingEdited) ? ((nodeBeingEdited.unifiedJobTemplate && nodeBeingEdited.unifiedJobTemplate.name) ? nodeBeingEdited.unifiedJobTemplate.name : strings.get('workflow_maker.EDIT_TEMPLATE')) : strings.get('workflow_maker.ADD_A_TEMPLATE')}}</div>
|
<div class="WorkflowMaker-formTitle">{{(workflowMakerFormConfig.nodeMode === 'edit' && nodeBeingEdited) ? ((nodeBeingEdited.unifiedJobTemplate && nodeBeingEdited.unifiedJobTemplate.name) ? nodeBeingEdited.unifiedJobTemplate.name : strings.get('workflow_maker.EDIT_TEMPLATE')) : strings.get('workflow_maker.ADD_A_TEMPLATE')}}</div>
|
||||||
<div class="WorkflowMaker-formHelp" ng-show="workflowMakerFormConfig.nodeMode === 'idle'" ng-bind="treeData.data.totalNodes === 0 ? strings.get('workflow_maker.PLEASE_CLICK_THE_START_BUTTON') : strings.get('workflow_maker.PLEASE_HOVER_OVER_A_TEMPLATE')"></div>
|
<div class="WorkflowMaker-formHelp" ng-show="workflowMakerFormConfig.nodeMode === 'idle'" ng-bind="treeData.data.totalNodes === 0 ? strings.get('workflow_maker.PLEASE_CLICK_THE_START_BUTTON') : strings.get('workflow_maker.PLEASE_HOVER_OVER_A_TEMPLATE')"></div>
|
||||||
<div class="WorkflowMaker-form" ng-show="workflowMakerFormConfig.nodeMode === 'add' || workflowMakerFormConfig.nodeMode === 'edit'">
|
<div class="WorkflowMaker-form" ng-show="workflowMakerFormConfig.nodeMode === 'add' || workflowMakerFormConfig.nodeMode === 'edit'">
|
||||||
@@ -98,10 +99,8 @@
|
|||||||
<div id="workflow-inventory-sync-list" ui-view="inventorySyncList" ng-show="workflowMakerFormConfig.activeTab === 'inventory_sync'"></div>
|
<div id="workflow-inventory-sync-list" ui-view="inventorySyncList" ng-show="workflowMakerFormConfig.activeTab === 'inventory_sync'"></div>
|
||||||
</div>
|
</div>
|
||||||
<span ng-show="selectedTemplate &&
|
<span ng-show="selectedTemplate &&
|
||||||
((selectedTemplate.type === 'job_template' || selectedTemplate.type === 'workflow_job_template' && workflowMakerFormConfig.activeTab === 'jobs') ||
|
((selectedTemplate.type === 'job_template' && workflowMakerFormConfig.activeTab === 'jobs') ||
|
||||||
(selectedTemplate.unified_job_type === 'job' || selectedTemplate.unified_job_type === 'workflow_job' && workflowMakerFormConfig.activeTab === 'jobs') ||
|
|
||||||
(selectedTemplate.type === 'project' && workflowMakerFormConfig.activeTab === 'project_sync') ||
|
(selectedTemplate.type === 'project' && workflowMakerFormConfig.activeTab === 'project_sync') ||
|
||||||
(selectedTemplate.unified_job_type === 'inventory_update' && workflowMakerFormConfig.activeTab === 'inventory_sync') ||
|
|
||||||
(selectedTemplate.type === 'inventory_source' && workflowMakerFormConfig.activeTab === 'inventory_sync'))">
|
(selectedTemplate.type === 'inventory_source' && workflowMakerFormConfig.activeTab === 'inventory_sync'))">
|
||||||
<div ng-if="selectedTemplate && selectedTemplateInvalid">
|
<div ng-if="selectedTemplate && selectedTemplateInvalid">
|
||||||
<div class="WorkflowMaker-invalidJobTemplateWarning">
|
<div class="WorkflowMaker-invalidJobTemplateWarning">
|
||||||
@@ -115,7 +114,7 @@
|
|||||||
<span>{{:: strings.get('workflows.CREDENTIAL_WITH_PASS') }}</span>
|
<span>{{:: strings.get('workflows.CREDENTIAL_WITH_PASS') }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group Form-formGroup Form-formGroup--singleColumn" ng-show="selectedTemplate && !selectedTemplateInvalid && !(credentialRequiresPassword && !promptData.launchConf.ask_credential_on_launch)">
|
<div class="form-group Form-formGroup Form-formGroup--singleColumn" ng-show="selectedTemplate && !selectedTemplateInvalid && !(credentialRequiresPassword && !promptData.launchConf.ask_credential_on_launch) && workflowMakerFormConfig.nodeMode === 'add'">
|
||||||
<label for="verbosity" class="Form-inputLabelContainer">
|
<label for="verbosity" 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>
|
||||||
@@ -133,8 +132,6 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div ng-show="editNodeHelpMessage" class="WorkflowMaker-formHelp" ng-bind="editNodeHelpMessage"></div>
|
|
||||||
<br />
|
|
||||||
<div class="buttons Form-buttons" id="workflow_maker_controls">
|
<div class="buttons Form-buttons" id="workflow_maker_controls">
|
||||||
<button type="button" class="btn btn-sm Form-primaryButton Form-primaryButton--noMargin" id="workflow_maker_prompt_btn" ng-show="showPromptButton" ng-click="openPromptModal()"> {{:: strings.get('prompt.PROMPT') }}</button>
|
<button type="button" class="btn btn-sm Form-primaryButton Form-primaryButton--noMargin" id="workflow_maker_prompt_btn" ng-show="showPromptButton" ng-click="openPromptModal()"> {{:: strings.get('prompt.PROMPT') }}</button>
|
||||||
<button type="button" class="btn btn-sm Form-cancelButton" id="workflow_maker_cancel_btn" ng-show="(workflowJobTemplateObj.summary_fields.user_capabilities.edit || canAddWorkflowJobTemplate)" ng-click="cancelNodeForm()"> {{:: strings.get('CANCEL') }}</button>
|
<button type="button" class="btn btn-sm Form-cancelButton" id="workflow_maker_cancel_btn" ng-show="(workflowJobTemplateObj.summary_fields.user_capabilities.edit || canAddWorkflowJobTemplate)" ng-click="cancelNodeForm()"> {{:: strings.get('CANCEL') }}</button>
|
||||||
@@ -143,6 +140,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
</span>
|
||||||
|
<span ng-if="editLink">
|
||||||
|
<workflow-link-form link-config="linkConfig" select="confirmLinkForm(parentId, childId, edgeType)" cancel="cancelLinkForm()"/>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="WorkflowMaker-buttonHolder">
|
<div class="WorkflowMaker-buttonHolder">
|
||||||
|
|||||||
Reference in New Issue
Block a user