From 04844aa44fe0426d2e03f225fc88d065cf15d059 Mon Sep 17 00:00:00 2001 From: Jake McDermott Date: Fri, 24 Jan 2020 15:18:05 -0500 Subject: [PATCH] Add 'ALL' indicator to 'ALL' nodes --- .../workflow-chart/workflow-chart.block.less | 9 ++++ .../workflow-chart.directive.js | 42 ++++++++++++++++++- .../workflow-chart/workflow-chart.service.js | 3 +- .../workflow-maker.controller.js | 2 +- 4 files changed, 53 insertions(+), 3 deletions(-) diff --git a/awx/ui/client/src/templates/workflows/workflow-chart/workflow-chart.block.less b/awx/ui/client/src/templates/workflows/workflow-chart/workflow-chart.block.less index 6f2e0584e6..268be6ba04 100644 --- a/awx/ui/client/src/templates/workflows/workflow-chart/workflow-chart.block.less +++ b/awx/ui/client/src/templates/workflows/workflow-chart/workflow-chart.block.less @@ -115,11 +115,20 @@ fill: @default-icon; } +.WorkflowChart-convergenceTypeRectangle { + fill: @default-icon; +} + .WorkflowChart-nodeTypeLetter { fill: @default-bg; font-size: 10px; } +.WorkflowChart-convergenceTypeLetter { + fill: @default-bg; + font-size: 10px; +} + .WorkflowChart-nodeStatus--running { fill: @default-icon; } diff --git a/awx/ui/client/src/templates/workflows/workflow-chart/workflow-chart.directive.js b/awx/ui/client/src/templates/workflows/workflow-chart/workflow-chart.directive.js index e952f4695b..ce74f9355e 100644 --- a/awx/ui/client/src/templates/workflows/workflow-chart/workflow-chart.directive.js +++ b/awx/ui/client/src/templates/workflows/workflow-chart/workflow-chart.directive.js @@ -34,6 +34,7 @@ export default ['moment', '$timeout', '$window', '$filter', 'TemplatesStrings', nodeH = 60, rootW = startNodeTextWidth + 25, rootH = 40, + strokeW = 2, // px startNodeOffsetY = scope.mode === 'details' ? 17 : 10, maxNodeTextLength = 27, windowHeight, @@ -118,6 +119,14 @@ export default ['moment', '$timeout', '$window', '$filter', 'TemplatesStrings', }; const rounded_rect = (x, y, w, h, r, tl, tr, bl, br) => { + // x, y - position coordinates + // w - width + // h - height + // r - border radius + // round the top-left corner (bool) + // round the top-right corner (bool) + // round the bottom-left corner (bool) + // round the bottom-right corner (bool) let retval; retval = "M" + (x + r) + "," + y; retval += "h" + (w - 2*r); @@ -855,6 +864,9 @@ export default ['moment', '$timeout', '$window', '$filter', 'TemplatesStrings', .attr("fill", (d) => { return scope.graphState.addLinkSource === d.id ? "#337AB7" : "#D7D7D7"; }) .style("display", (d) => { return scope.graphState.isLinkMode && !d.isInvalidLinkTarget ? null : "none"; }); + baseSvg.selectAll(".WorkflowChart-convergenceTypeRectangle") + .style("display", (d) => d.all_parents_must_converge ? null : "none"); + // Add new nodes const nodeEnter = nodes .enter() @@ -924,7 +936,7 @@ export default ['moment', '$timeout', '$window', '$filter', 'TemplatesStrings', return "#D7D7D7"; } }) - .attr('stroke-width', "2px") + .attr('stroke-width', `${strokeW}px`) .attr("class", (d) => { let classString = d.id === scope.graphState.nodeBeingAdded ? "WorkflowChart-rect WorkflowChart-isNodeBeingAdded" : "WorkflowChart-rect"; classString += !_.get(d, 'unifiedJobTemplate.name') ? " WorkflowChart-dashedNode" : ""; @@ -980,6 +992,34 @@ export default ['moment', '$timeout', '$window', '$filter', 'TemplatesStrings', .html(`${TemplatesStrings.get('workflow_maker.APPROVED')}`) .style("display", (d) => { return d.job && d.job.type === "workflow_approval" && d.job.status === "successful" && !d.job.timed_out ? null : "none"; }); + // Build the 'ALL' symbol for all-convergence nodes + const convergenceTypeHeight = nodeH / 5; + const convergenceTypeWidth = nodeW / 5; + const convergenceTypeXCoord = nodeW / 2 - convergenceTypeWidth / 2; + const convergenceTypeYCoord = -convergenceTypeHeight + (strokeW / 2); + const convergenceTypeBorderRadius = 3; + + const convergenceRectangle = rounded_rect( + convergenceTypeXCoord, + convergenceTypeYCoord, + convergenceTypeWidth, + convergenceTypeHeight, + convergenceTypeBorderRadius, + true, // round top-left + true, // round top-right + false, // round bottom-left + false // round bottom-right + ); + thisNode.append("path") + .attr("d", convergenceRectangle) + .attr("class", "WorkflowChart-convergenceTypeRectangle") + .style("display", (d) => d.all_parents_must_converge ? null : "none"); + thisNode.append("text") + .attr("y", ((convergenceTypeYCoord + convergenceTypeHeight) / 2) - Math.min(strokeW, 2)) + .attr("x", convergenceTypeXCoord + (convergenceTypeWidth / 4)) + .attr("class", "WorkflowChart-convergenceTypeLetter") + .text("ALL"); + thisNode.append("circle") .attr("cy", nodeH) .attr("r", 10) diff --git a/awx/ui/client/src/templates/workflows/workflow-chart/workflow-chart.service.js b/awx/ui/client/src/templates/workflows/workflow-chart/workflow-chart.service.js index beec159e37..a93957e2de 100644 --- a/awx/ui/client/src/templates/workflows/workflow-chart/workflow-chart.service.js +++ b/awx/ui/client/src/templates/workflows/workflow-chart/workflow-chart.service.js @@ -28,7 +28,8 @@ export default [function(){ const nodeObj = { index: nodeIdCounter-1, - id: nodeIdCounter + id: nodeIdCounter, + all_parents_must_converge: node.all_parents_must_converge, }; if(node.summary_fields.job) { diff --git a/awx/ui/client/src/templates/workflows/workflow-maker/workflow-maker.controller.js b/awx/ui/client/src/templates/workflows/workflow-maker/workflow-maker.controller.js index 17d3d0b05e..e63735d84b 100644 --- a/awx/ui/client/src/templates/workflows/workflow-maker/workflow-maker.controller.js +++ b/awx/ui/client/src/templates/workflows/workflow-maker/workflow-maker.controller.js @@ -642,6 +642,7 @@ export default ['$scope', 'TemplatesService', $scope.graphState.arrayOfNodesForChart.map( (node) => { if (node.id === nodeId) { + node.all_parents_must_converge = nodeFormData.all_parents_must_converge; if (isPauseNode) { node.unifiedJobTemplate = { unified_job_type: 'workflow_approval', @@ -652,7 +653,6 @@ export default ['$scope', 'TemplatesService', } else { node.unifiedJobTemplate = selectedTemplate; } - } });