From 7f66053654b6d2a905566aa00eec9812ee42a6f9 Mon Sep 17 00:00:00 2001 From: mabashian Date: Fri, 14 Dec 2018 14:59:19 -0500 Subject: [PATCH 1/9] Changed workflow node details link to href so that i can be opened in new tab --- .../workflow-chart.directive.js | 90 ++++++++++++------- 1 file changed, 60 insertions(+), 30 deletions(-) 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 375b2b5acd..7c6791c601 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 @@ -764,7 +764,24 @@ export default ['$state','moment', '$timeout', '$window', '$filter', 'Rest', 'Ge }); baseSvg.selectAll(".WorkflowChart-detailsLink") - .style("display", function(d){ return d.job && d.job.status && d.job.id ? null : "none"; }); + .style("display", function(d){ return d.job && d.job.status && d.job.id ? null : "none"; }) + .html(function (d) { + let href = ""; + if (d.job) { + if(d.job.type === 'job') { + href = `/#/jobs/playbook/${d.job.id}`; + } + else if(d.job.type === 'inventory_update') { + href = `/#/jobs/inventory/${d.job.id}`; + } + else if(d.job.type === 'project_update') { + href = `/#/jobs/project/${d.job.id}`; + } else if (d.job.type === 'workflow_job') { + href = `/#/workflows/${d.job.id}`; + } + } + return `${TemplatesStrings.get('workflow_maker.DETAILS')}`; + }); baseSvg.selectAll(".WorkflowChart-deletedText") .style("display", function(d){ return d.unifiedJobTemplate || d.id === scope.graphState.nodeBeingAdded ? "none" : null; }); @@ -1043,16 +1060,29 @@ export default ['$state','moment', '$timeout', '$window', '$filter', 'Rest', 'Ge .classed("WorkflowChart-nodeHovering", false); } }); - thisNode.append("text") + thisNode.append("foreignObject") .attr("x", nodeW - 45) - .attr("y", nodeH - 10) + .attr("y", nodeH - 15) .attr("dy", ".35em") .attr("class", "WorkflowChart-detailsLink") .style("display", function(d){ return d.job && d.job.status && d.job.id ? null : "none"; }) - .text(function () { - return TemplatesStrings.get('workflow_maker.DETAILS'); - }) - .call(details); + .html(function () { + let href = ""; + if (d.job) { + if(d.job.type === 'job') { + href = `/#/jobs/playbook/${d.job.id}`; + } + else if(d.job.type === 'inventory_update') { + href = `/#/jobs/inventory/${d.job.id}`; + } + else if(d.job.type === 'project_update') { + href = `/#/jobs/project/${d.job.id}`; + } else if (d.job.type === 'workflow_job') { + href = `/#/workflows/${d.job.id}`; + } + } + return `${TemplatesStrings.get('workflow_maker.DETAILS')}`; + }); thisNode.append("circle") .attr("id", function(d){return "node-" + d.id + "-add";}) .attr("cx", nodeW) @@ -1328,29 +1358,29 @@ export default ['$state','moment', '$timeout', '$window', '$filter', 'Rest', 'Ge }); } - function details() { - this.on("mouseover", function() { - d3.select(this).style("text-decoration", "underline"); - }); - this.on("mouseout", function() { - d3.select(this).style("text-decoration", null); - }); - this.on("click", function(d) { - if(d.job.type === 'job') { - $state.go('output', {id: d.job.id, type: 'playbook'}); - } - else if(d.job.type === 'inventory_update') { - $state.go('output', {id: d.job.id, type: 'inventory'}); - } - else if(d.job.type === 'project_update') { - $state.go('output', {id: d.job.id, type: 'project'}); - } else if (d.job.type === 'workflow_job') { - $state.go('workflowResults', { - id: d.job.id, - }); - } - }); - } + // function details() { + // this.on("mouseover", function() { + // d3.select(this).style("text-decoration", "underline"); + // }); + // this.on("mouseout", function() { + // d3.select(this).style("text-decoration", null); + // }); + // this.on("click", function(d) { + // if(d.job.type === 'job') { + // $state.go('output', {id: d.job.id, type: 'playbook'}); + // } + // else if(d.job.type === 'inventory_update') { + // $state.go('output', {id: d.job.id, type: 'inventory'}); + // } + // else if(d.job.type === 'project_update') { + // $state.go('output', {id: d.job.id, type: 'project'}); + // } else if (d.job.type === 'workflow_job') { + // $state.go('workflowResults', { + // id: d.job.id, + // }); + // } + // }); + // } scope.$on('refreshWorkflowChart', function(){ if(scope.graphState) { From a8e1c8960fba06dd27f56501db6c37399264855a Mon Sep 17 00:00:00 2001 From: mabashian Date: Fri, 14 Dec 2018 16:27:35 -0500 Subject: [PATCH 2/9] Remove details function --- .../workflow-chart.directive.js | 24 ------------------- 1 file changed, 24 deletions(-) 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 7c6791c601..91d2f82e30 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 @@ -1358,30 +1358,6 @@ export default ['$state','moment', '$timeout', '$window', '$filter', 'Rest', 'Ge }); } - // function details() { - // this.on("mouseover", function() { - // d3.select(this).style("text-decoration", "underline"); - // }); - // this.on("mouseout", function() { - // d3.select(this).style("text-decoration", null); - // }); - // this.on("click", function(d) { - // if(d.job.type === 'job') { - // $state.go('output', {id: d.job.id, type: 'playbook'}); - // } - // else if(d.job.type === 'inventory_update') { - // $state.go('output', {id: d.job.id, type: 'inventory'}); - // } - // else if(d.job.type === 'project_update') { - // $state.go('output', {id: d.job.id, type: 'project'}); - // } else if (d.job.type === 'workflow_job') { - // $state.go('workflowResults', { - // id: d.job.id, - // }); - // } - // }); - // } - scope.$on('refreshWorkflowChart', function(){ if(scope.graphState) { updateGraph(); From 9f18f8dbdbc59fe9307fb8d4248dc8627c102055 Mon Sep 17 00:00:00 2001 From: mabashian Date: Fri, 14 Dec 2018 18:04:39 -0500 Subject: [PATCH 3/9] Fixes split job inside workflow details link bug --- .../workflow-chart.directive.js | 6 +-- .../workflow-chart/workflow-chart.service.js | 1 + .../workflow-results.controller.js | 37 ++++++++++++++----- .../workflow-results.service.js | 4 ++ 4 files changed, 36 insertions(+), 12 deletions(-) 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 91d2f82e30..b3f4110050 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 @@ -764,7 +764,7 @@ export default ['$state','moment', '$timeout', '$window', '$filter', 'Rest', 'Ge }); baseSvg.selectAll(".WorkflowChart-detailsLink") - .style("display", function(d){ return d.job && d.job.status && d.job.id ? null : "none"; }) + .style("display", function(d){ return d.job && d.job.status && d.job.id && d.job.type ? null : "none"; }) .html(function (d) { let href = ""; if (d.job) { @@ -1065,8 +1065,8 @@ export default ['$state','moment', '$timeout', '$window', '$filter', 'Rest', 'Ge .attr("y", nodeH - 15) .attr("dy", ".35em") .attr("class", "WorkflowChart-detailsLink") - .style("display", function(d){ return d.job && d.job.status && d.job.id ? null : "none"; }) - .html(function () { + .style("display", function(d){ return d.job && d.job.status && d.job.id && d.job.type ? null : "none"; }) + .html(function (d) { let href = ""; if (d.job) { if(d.job.type === 'job') { 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..d38fc23031 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 @@ -33,6 +33,7 @@ export default [function(){ if(node.summary_fields.job) { nodeObj.job = node.summary_fields.job; + nodeRef[nodeIdCounter].jobType = node.summary_fields.job.type; } if(node.summary_fields.unified_job_template) { nodeRef[nodeIdCounter].unifiedJobTemplate = nodeObj.unifiedJobTemplate = node.summary_fields.unified_job_template; diff --git a/awx/ui/client/src/workflow-results/workflow-results.controller.js b/awx/ui/client/src/workflow-results/workflow-results.controller.js index 0ec32ad69c..9f20e2b5b2 100644 --- a/awx/ui/client/src/workflow-results/workflow-results.controller.js +++ b/awx/ui/client/src/workflow-results/workflow-results.controller.js @@ -1,10 +1,10 @@ export default ['workflowData', 'workflowResultsService', 'workflowDataOptions', 'jobLabels', 'workflowNodes', '$scope', 'ParseTypeChange', 'ParseVariableString', 'count', '$state', 'i18n', 'WorkflowChartService', '$filter', - 'moment', function(workflowData, workflowResultsService, + 'moment', 'ProcessErrors', function(workflowData, workflowResultsService, workflowDataOptions, jobLabels, workflowNodes, $scope, ParseTypeChange, ParseVariableString, count, $state, i18n, WorkflowChartService, $filter, - moment) { + moment, ProcessErrors) { let nodeRef; var runTimeElapsedTimer = null; @@ -279,15 +279,34 @@ export default ['workflowData', 'workflowResultsService', 'workflowDataOptions', $scope.graphState.arrayOfNodesForChart.forEach((node) => { if (nodeRef[node.id] && nodeRef[node.id].originalNodeObject.id === data.workflow_node_id) { - node.job = { - id: data.unified_job_id, - status: data.status, - type: nodeRef[node.id].unifiedJobTemplate.unified_job_type - }; + if (!nodeRef[node.id].jobType && nodeRef[node.id].unifiedJobTemplate.unified_job_type === "job") { + workflowResultsService.getWorkflowNode(nodeRef[node.id].originalNodeObject.url) + .then((nodeData) => { + nodeRef[node.id].jobType = nodeData.data.summary_fields.job.type; + + node.job = { + id: data.unified_job_id, + status: data.status, + type: nodeRef[node.id].jobType + }; + + $scope.$broadcast("refreshWorkflowChart"); + }) + .catch(({ data, status }) => { + const params = { hdr: 'Error!', msg: `Call to get workflow node failed. Return status: ${status}` }; + ProcessErrors($scope, data, status, null, params); + }); + } else { + node.job = { + id: data.unified_job_id, + status: data.status, + type: nodeRef[node.id].jobType || nodeRef[node.id].unifiedJobTemplate.unified_job_type + }; + + $scope.$broadcast("refreshWorkflowChart"); + } } }); - - $scope.$broadcast("refreshWorkflowChart"); } getLabelsAndTooltips(); }); diff --git a/awx/ui/client/src/workflow-results/workflow-results.service.js b/awx/ui/client/src/workflow-results/workflow-results.service.js index 0db1f7a78c..9860b3726b 100644 --- a/awx/ui/client/src/workflow-results/workflow-results.service.js +++ b/awx/ui/client/src/workflow-results/workflow-results.service.js @@ -133,6 +133,10 @@ export default ['$q', 'Prompt', '$filter', 'Wait', 'Rest', '$state', 'ProcessErr } return false; }, + getWorkflowNode: (nodeUrl) => { + Rest.setUrl(nodeUrl); + return Rest.get(); + } }; return val; }]; From a5c435069501fe3866305560bc26d81548b6009f Mon Sep 17 00:00:00 2001 From: Jake McDermott Date: Fri, 14 Dec 2018 19:20:01 -0500 Subject: [PATCH 4/9] add redirect route for workflow viewer --- awx/ui/client/features/output/legacy.route.js | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/awx/ui/client/features/output/legacy.route.js b/awx/ui/client/features/output/legacy.route.js index 2db75d01d7..b2425c85af 100644 --- a/awx/ui/client/features/output/legacy.route.js +++ b/awx/ui/client/features/output/legacy.route.js @@ -1,4 +1,4 @@ -function LegacyRedirect ($stateRegistry) { +function LegacyRedirect ($http, $stateRegistry) { const destination = 'output'; const routes = [ { @@ -66,11 +66,35 @@ function LegacyRedirect ($stateRegistry) { return { state: 'schedules.edit', params: { schedule_id, schedule_search } }; } }, + { + name: 'workflowPlaybookNodeRedirect', + url: '/workflow_node_playbook_results/:id', + redirectTo: (trans) => { + // The workflow job viewer uses this route for playbook job nodes. The provided id + // is used to lookup the corresponding unified job, which is then inspected to + // determine if we need to redirect to a split (workflow) job or a playbook job. + const { id } = trans.params(); + const endpoint = '/api/v2/unified_jobs/'; + + return $http.get(endpoint, { params: { id } }) + .then(({ data }) => { + const { results } = data; + const [obj] = results; + + if (obj && obj.type === 'workflow_job') { + return { state: 'workflowResults', params: { id } }; + } + + return { state: destination, params: { type: 'playbook', id } }; + }) + .catch(() => ({ state: 'dashboard' })); + } + }, ]; routes.forEach(state => $stateRegistry.register(state)); } -LegacyRedirect.$inject = ['$stateRegistry']; +LegacyRedirect.$inject = ['$http', '$stateRegistry']; export default LegacyRedirect; From c8b15005b4e3c58cba29e6210e1cb0bec951db2e Mon Sep 17 00:00:00 2001 From: Jake McDermott Date: Fri, 14 Dec 2018 19:22:23 -0500 Subject: [PATCH 5/9] link to workflow playbook node route from workflow viewer --- .../workflows/workflow-chart/workflow-chart.directive.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 b3f4110050..aa37b1a1d5 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 @@ -769,7 +769,7 @@ export default ['$state','moment', '$timeout', '$window', '$filter', 'Rest', 'Ge let href = ""; if (d.job) { if(d.job.type === 'job') { - href = `/#/jobs/playbook/${d.job.id}`; + href = `/#/workflow_node_playbook_results/${d.job.id}`; } else if(d.job.type === 'inventory_update') { href = `/#/jobs/inventory/${d.job.id}`; @@ -1070,7 +1070,7 @@ export default ['$state','moment', '$timeout', '$window', '$filter', 'Rest', 'Ge let href = ""; if (d.job) { if(d.job.type === 'job') { - href = `/#/jobs/playbook/${d.job.id}`; + href = `/#/workflow_node_playbook_results/${d.job.id}`; } else if(d.job.type === 'inventory_update') { href = `/#/jobs/inventory/${d.job.id}`; From 2697615dbf6997868bf7fb4acc7fb9b01bd27dac Mon Sep 17 00:00:00 2001 From: mabashian Date: Mon, 17 Dec 2018 10:26:01 -0500 Subject: [PATCH 6/9] Undo GET request that was made for workflow node jobs missing a type and instead leverage the redirect route. The workflow node results redirect now works for all job types. --- awx/ui/client/features/output/legacy.route.js | 18 +++++++---- .../workflow-chart.directive.js | 28 +++-------------- .../workflow-chart/workflow-chart.service.js | 1 - .../workflow-results.controller.js | 30 ++++--------------- .../workflow-results.service.js | 4 --- 5 files changed, 22 insertions(+), 59 deletions(-) diff --git a/awx/ui/client/features/output/legacy.route.js b/awx/ui/client/features/output/legacy.route.js index b2425c85af..838cc5c25d 100644 --- a/awx/ui/client/features/output/legacy.route.js +++ b/awx/ui/client/features/output/legacy.route.js @@ -67,8 +67,8 @@ function LegacyRedirect ($http, $stateRegistry) { } }, { - name: 'workflowPlaybookNodeRedirect', - url: '/workflow_node_playbook_results/:id', + name: 'workflowNodeRedirect', + url: '/workflow_node_results/:id', redirectTo: (trans) => { // The workflow job viewer uses this route for playbook job nodes. The provided id // is used to lookup the corresponding unified job, which is then inspected to @@ -81,11 +81,19 @@ function LegacyRedirect ($http, $stateRegistry) { const { results } = data; const [obj] = results; - if (obj && obj.type === 'workflow_job') { - return { state: 'workflowResults', params: { id } }; + if (obj) { + if (obj.type === 'workflow_job') { + return { state: 'workflowResults', params: { id } }; + } else if (obj.type === 'job') { + return { state: 'output', params: { type: 'playbook', id } }; + } else if (obj.type === 'inventory_update') { + return { state: 'output', params: { type: 'inventory', id } }; + } else if (obj.type === 'project_update') { + return { state: 'output', params: { type: 'project', id } }; + } } - return { state: destination, params: { type: 'playbook', id } }; + return { state: 'jobs' }; }) .catch(() => ({ state: 'dashboard' })); } 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 aa37b1a1d5..bea6c7d1a3 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 @@ -764,21 +764,11 @@ export default ['$state','moment', '$timeout', '$window', '$filter', 'Rest', 'Ge }); baseSvg.selectAll(".WorkflowChart-detailsLink") - .style("display", function(d){ return d.job && d.job.status && d.job.id && d.job.type ? null : "none"; }) + .style("display", function(d){ return d.job && d.job.status && d.job.id ? null : "none"; }) .html(function (d) { let href = ""; if (d.job) { - if(d.job.type === 'job') { - href = `/#/workflow_node_playbook_results/${d.job.id}`; - } - else if(d.job.type === 'inventory_update') { - href = `/#/jobs/inventory/${d.job.id}`; - } - else if(d.job.type === 'project_update') { - href = `/#/jobs/project/${d.job.id}`; - } else if (d.job.type === 'workflow_job') { - href = `/#/workflows/${d.job.id}`; - } + href = `/#/workflow_node_results/${d.job.id}`; } return `${TemplatesStrings.get('workflow_maker.DETAILS')}`; }); @@ -1065,21 +1055,11 @@ export default ['$state','moment', '$timeout', '$window', '$filter', 'Rest', 'Ge .attr("y", nodeH - 15) .attr("dy", ".35em") .attr("class", "WorkflowChart-detailsLink") - .style("display", function(d){ return d.job && d.job.status && d.job.id && d.job.type ? null : "none"; }) + .style("display", function(d){ return d.job && d.job.status && d.job.id ? null : "none"; }) .html(function (d) { let href = ""; if (d.job) { - if(d.job.type === 'job') { - href = `/#/workflow_node_playbook_results/${d.job.id}`; - } - else if(d.job.type === 'inventory_update') { - href = `/#/jobs/inventory/${d.job.id}`; - } - else if(d.job.type === 'project_update') { - href = `/#/jobs/project/${d.job.id}`; - } else if (d.job.type === 'workflow_job') { - href = `/#/workflows/${d.job.id}`; - } + href = `/#/workflow_node_results/${d.job.id}`; } return `${TemplatesStrings.get('workflow_maker.DETAILS')}`; }); 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 d38fc23031..beec159e37 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 @@ -33,7 +33,6 @@ export default [function(){ if(node.summary_fields.job) { nodeObj.job = node.summary_fields.job; - nodeRef[nodeIdCounter].jobType = node.summary_fields.job.type; } if(node.summary_fields.unified_job_template) { nodeRef[nodeIdCounter].unifiedJobTemplate = nodeObj.unifiedJobTemplate = node.summary_fields.unified_job_template; diff --git a/awx/ui/client/src/workflow-results/workflow-results.controller.js b/awx/ui/client/src/workflow-results/workflow-results.controller.js index 9f20e2b5b2..8b8f60e859 100644 --- a/awx/ui/client/src/workflow-results/workflow-results.controller.js +++ b/awx/ui/client/src/workflow-results/workflow-results.controller.js @@ -279,32 +279,12 @@ export default ['workflowData', 'workflowResultsService', 'workflowDataOptions', $scope.graphState.arrayOfNodesForChart.forEach((node) => { if (nodeRef[node.id] && nodeRef[node.id].originalNodeObject.id === data.workflow_node_id) { - if (!nodeRef[node.id].jobType && nodeRef[node.id].unifiedJobTemplate.unified_job_type === "job") { - workflowResultsService.getWorkflowNode(nodeRef[node.id].originalNodeObject.url) - .then((nodeData) => { - nodeRef[node.id].jobType = nodeData.data.summary_fields.job.type; + node.job = { + id: data.unified_job_id, + status: data.status + }; - node.job = { - id: data.unified_job_id, - status: data.status, - type: nodeRef[node.id].jobType - }; - - $scope.$broadcast("refreshWorkflowChart"); - }) - .catch(({ data, status }) => { - const params = { hdr: 'Error!', msg: `Call to get workflow node failed. Return status: ${status}` }; - ProcessErrors($scope, data, status, null, params); - }); - } else { - node.job = { - id: data.unified_job_id, - status: data.status, - type: nodeRef[node.id].jobType || nodeRef[node.id].unifiedJobTemplate.unified_job_type - }; - - $scope.$broadcast("refreshWorkflowChart"); - } + $scope.$broadcast("refreshWorkflowChart"); } }); } diff --git a/awx/ui/client/src/workflow-results/workflow-results.service.js b/awx/ui/client/src/workflow-results/workflow-results.service.js index 9860b3726b..6fbfc59371 100644 --- a/awx/ui/client/src/workflow-results/workflow-results.service.js +++ b/awx/ui/client/src/workflow-results/workflow-results.service.js @@ -132,10 +132,6 @@ export default ['$q', 'Prompt', '$filter', 'Wait', 'Rest', '$state', 'ProcessErr return true; } return false; - }, - getWorkflowNode: (nodeUrl) => { - Rest.setUrl(nodeUrl); - return Rest.get(); } }; return val; From f9854abfa120662843c9a6b4ee4e678b4783970c Mon Sep 17 00:00:00 2001 From: mabashian Date: Mon, 17 Dec 2018 10:40:20 -0500 Subject: [PATCH 7/9] Fixed linting error --- .../src/workflow-results/workflow-results.controller.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/awx/ui/client/src/workflow-results/workflow-results.controller.js b/awx/ui/client/src/workflow-results/workflow-results.controller.js index 8b8f60e859..9870d2c7b1 100644 --- a/awx/ui/client/src/workflow-results/workflow-results.controller.js +++ b/awx/ui/client/src/workflow-results/workflow-results.controller.js @@ -1,10 +1,10 @@ export default ['workflowData', 'workflowResultsService', 'workflowDataOptions', 'jobLabels', 'workflowNodes', '$scope', 'ParseTypeChange', 'ParseVariableString', 'count', '$state', 'i18n', 'WorkflowChartService', '$filter', - 'moment', 'ProcessErrors', function(workflowData, workflowResultsService, + 'moment', function(workflowData, workflowResultsService, workflowDataOptions, jobLabels, workflowNodes, $scope, ParseTypeChange, ParseVariableString, count, $state, i18n, WorkflowChartService, $filter, - moment, ProcessErrors) { + moment) { let nodeRef; var runTimeElapsedTimer = null; From 67d6a9f9eae23997b1b5cb8ee0534d98b1e392bc Mon Sep 17 00:00:00 2001 From: mabashian Date: Mon, 17 Dec 2018 14:33:48 -0500 Subject: [PATCH 8/9] Fixes display of wf node details link in FF by adding height and width --- .../workflows/workflow-chart/workflow-chart.directive.js | 2 ++ 1 file changed, 2 insertions(+) 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 bea6c7d1a3..84ea6cf8ef 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 @@ -1053,6 +1053,8 @@ export default ['$state','moment', '$timeout', '$window', '$filter', 'Rest', 'Ge thisNode.append("foreignObject") .attr("x", nodeW - 45) .attr("y", nodeH - 15) + .attr("height", "15px") + .attr("width", "40px") .attr("dy", ".35em") .attr("class", "WorkflowChart-detailsLink") .style("display", function(d){ return d.job && d.job.status && d.job.id ? null : "none"; }) From c0730aa5623a3ac3ec8b1fbc4a2cbd2e4e8fbccd Mon Sep 17 00:00:00 2001 From: mabashian Date: Mon, 17 Dec 2018 15:20:34 -0500 Subject: [PATCH 9/9] Prevent mousedown on details link from triggering pan functionality --- .../workflows/workflow-chart/workflow-chart.directive.js | 3 +++ 1 file changed, 3 insertions(+) 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 84ea6cf8ef..18275d4655 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 @@ -1058,6 +1058,9 @@ export default ['$state','moment', '$timeout', '$window', '$filter', 'Rest', 'Ge .attr("dy", ".35em") .attr("class", "WorkflowChart-detailsLink") .style("display", function(d){ return d.job && d.job.status && d.job.id ? null : "none"; }) + .on("mousedown", function(){ + d3.event.stopPropagation(); + }) .html(function (d) { let href = ""; if (d.job) {