From fdaee0242aa66469a8a903118d196b2317c2222a Mon Sep 17 00:00:00 2001 From: Jared Tabor Date: Wed, 2 Mar 2016 13:38:23 -0800 Subject: [PATCH 1/2] Adding Standard Out and other Job Detail things This includes the work from the Job Detail standard out panel along with fixes from feedback from UX and other UI devs. This includes: - result panel CSS fixes - selected row styling - stop job button functionality - websockets for job detail - everthing for adding stdout to the job detail: panel, styling, toggle, and websockets --- awx/ui/client/legacy-styles/job-details.less | 4 +- awx/ui/client/src/app.js | 2 +- awx/ui/client/src/helpers/JobDetail.js | 22 +- .../src/job-detail/job-detail.block.less | 55 +- .../src/job-detail/job-detail.controller.js | 26 +- .../src/job-detail/job-detail.partial.html | 810 +++++++++--------- .../src/shared/branding/colors.default.less | 3 - .../log/standard-out-log.controller.js | 11 +- 8 files changed, 509 insertions(+), 424 deletions(-) diff --git a/awx/ui/client/legacy-styles/job-details.less b/awx/ui/client/legacy-styles/job-details.less index 0adc42ea1a..d3cc2bae50 100644 --- a/awx/ui/client/legacy-styles/job-details.less +++ b/awx/ui/client/legacy-styles/job-details.less @@ -214,9 +214,7 @@ } #job-detail-container { - position: relative; - padding-left: 15px; - padding-right: 7px; + .well { overflow: hidden; } diff --git a/awx/ui/client/src/app.js b/awx/ui/client/src/app.js index a6ab910194..3c12eadfb1 100644 --- a/awx/ui/client/src/app.js +++ b/awx/ui/client/src/app.js @@ -975,7 +975,7 @@ var tower = angular.module('Tower', [ $log.debug("sending status to standard out"); $rootScope.$emit('JobStatusChange-jobStdout', data); - } else if ($state.is('jobDetail')) { + } if ($state.is('jobDetail')) { $rootScope.$emit('JobStatusChange-jobDetails', data); } else if ($state.is('dashboard')) { $rootScope.$emit('JobStatusChange-home', data); diff --git a/awx/ui/client/src/helpers/JobDetail.js b/awx/ui/client/src/helpers/JobDetail.js index d5c511e0f5..121786de3a 100644 --- a/awx/ui/client/src/helpers/JobDetail.js +++ b/awx/ui/client/src/helpers/JobDetail.js @@ -235,7 +235,7 @@ export default } if (newActivePlay) { scope.activePlay = newActivePlay; - scope.jobData.plays[scope.activePlay].playActiveClass = 'List-tableRow--selected'; + scope.jobData.plays[scope.activePlay].playActiveClass = 'JobDetail-tableRow--selected'; } } }; @@ -265,7 +265,7 @@ export default } if (newActiveTask) { scope.activeTask = newActiveTask; - scope.jobData.plays[scope.activePlay].tasks[scope.activeTask].taskActiveClass = 'List-tableRow--selected'; + scope.jobData.plays[scope.activePlay].tasks[scope.activeTask].taskActiveClass = 'JobDetail-tableRow--selected'; } } }; @@ -793,7 +793,7 @@ export default scope.selectedPlay = id; scope.plays.forEach(function(play, idx) { if (play.id === scope.selectedPlay) { - scope.plays[idx].playActiveClass = 'List-tableRow--selected'; + scope.plays[idx].playActiveClass = 'JobDetail-tableRow--selected'; } else { scope.plays[idx].playActiveClass = ''; @@ -940,7 +940,7 @@ export default scope.selectedTask = id; scope.tasks.forEach(function(task, idx) { if (task.id === scope.selectedTask) { - scope.tasks[idx].taskActiveClass = 'List-tableRow--selected'; + scope.tasks[idx].taskActiveClass = 'JobDetail-tableRow--selected'; } else { scope.tasks[idx].taskActiveClass = ''; @@ -1143,7 +1143,7 @@ export default return function(params) { var scope = params.scope, resize = params.resize, - width, height, svg_height, svg_width, svg_radius, graph_data = []; + graph_data = []; // Ready the data if (scope.host_summary.ok) { @@ -1192,7 +1192,8 @@ export default element = $("#graph-section"), colors, total,job_detail_chart; - colors = ['#60D66F', '#FF9900','#FF0000','#ff5850']; + // colors = ['#60D66F', '#FF9900','#FF0000','#ff5850']; + colors = _.map(dataset, function(d){return d.color}); total = d3.sum(dataset.map(function(d) { return d.value; })); @@ -1221,6 +1222,7 @@ export default "font-weight":400, "src": "url(/static/assets/OpenSans-Regular.ttf)" }); + d3.select(element.find(".nv-label text")[0]) .attr("class", "DashboardGraphs-hostStatusLabel--successful") .style({ @@ -1228,7 +1230,7 @@ export default "text-anchor": "start", "font-size": "16px", "text-transform" : "uppercase", - "fill" : '#3CB878', + "fill" : colors[0], "src": "url(/static/assets/OpenSans-Regular.ttf)" }); d3.select(element.find(".nv-label text")[1]) @@ -1238,7 +1240,7 @@ export default "text-anchor" : "end !imporant", "font-size": "16px", "text-transform" : "uppercase", - "fill" : "#FF9900", + "fill" : colors[1], "src": "url(/static/assets/OpenSans-Regular.ttf)" }); d3.select(element.find(".nv-label text")[2]) @@ -1248,7 +1250,7 @@ export default "text-anchor" : "end !imporant", "font-size": "16px", "text-transform" : "uppercase", - "fill" : "#FF0000", + "fill" : colors[2], "src": "url(/static/assets/OpenSans-Regular.ttf)" }); d3.select(element.find(".nv-label text")[3]) @@ -1258,7 +1260,7 @@ export default "text-anchor" : "end !imporant", "font-size": "16px", "text-transform" : "uppercase", - "fill" : "#ff5850", + "fill" : colors[3], "src": "url(/static/assets/OpenSans-Regular.ttf)" }); return job_detail_chart; diff --git a/awx/ui/client/src/job-detail/job-detail.block.less b/awx/ui/client/src/job-detail/job-detail.block.less index 854584959d..83671a21da 100644 --- a/awx/ui/client/src/job-detail/job-detail.block.less +++ b/awx/ui/client/src/job-detail/job-detail.block.less @@ -3,7 +3,19 @@ @import '../shared/branding/colors.less'; @import '../shared/branding/colors.default.less'; +.JobDetail{ + display: flex; + flex-direction: row; +} + .JobDetail-leftSide{ + flex: 1 0 auto; + width: 50%; + padding-right: 20px; +} + +.JobDetail-rightSide{ + flex: 1 0 auto; width: 50%; } @@ -49,6 +61,7 @@ display: flex; flex-wrap: wrap; flex-direction: row; + padding-top: 25px; } .JobDetail-resultRow{ @@ -56,6 +69,10 @@ display: flex; } +.JobDetail-resultRowLabel{ + text-transform: uppercase; +} + .JobDetail-resultRow label{ color: @default-interface-txt; font-size: 14px; @@ -64,14 +81,26 @@ } .JobDetail-resultRow--variables{ - width: 90%; - display: block; + width: 100%; + display: flex; + flex-direction: column; + padding-left:15px; +} + +.JobDetail-extraVars{ + text-transform: none; +} + +.JobDetail-extraVarsLabel{ + margin-left:-15px; + padding-bottom: 15px; } .JobDetail-resultRowText{ width: 40%; flex: 1 0 auto; padding:0px; + text-transform: none; } .JobDetail-searchHeaderRow{ @@ -101,7 +130,7 @@ .JobDetail-tableToggle.active{ background-color: @default-link; border: 1px solid @default-link; - color: @toggle-selected-text; + color: @default-bg; } .JobDetail-tableToggle--left{ @@ -127,7 +156,27 @@ padding-left: 10px; } +.JobDetail-tableRow--selected, +.JobDetail-tableRow--selected > :first-child{ + border-left: 5px solid @list-row-select-bord; +} + +.JobDetail-tableRow--selected > :first-child > .JobDetail-statusIcon{ + margin-left: -5px; +} + +.JobDetail-statusIcon--results{ + padding-left: 0px; + padding-right: 10px; +} + .JobDetail-graphSection{ height: 320px; width:100%; } + +.JobDetail-stdoutActionButton--active{ + flex:none; + width:0px; + padding-right: 0px; +} diff --git a/awx/ui/client/src/job-detail/job-detail.controller.js b/awx/ui/client/src/job-detail/job-detail.controller.js index 220424352c..447cec8d8c 100644 --- a/awx/ui/client/src/job-detail/job-detail.controller.js +++ b/awx/ui/client/src/job-detail/job-detail.controller.js @@ -43,6 +43,7 @@ export default scope.plays = []; scope.parseType = 'yaml'; scope.previousTaskFailed = false; + $scope.stdoutFullScreen = false; scope.$watch('job_status', function(job_status) { if (job_status && job_status.explanation && job_status.explanation.split(":")[0] === "Previous Task Failed") { @@ -202,7 +203,7 @@ export default scope.processing = false; scope.lessStatus = false; scope.lessDetail = false; - scope.lessEvents = false; + scope.lessEvents = true; scope.host_summary = {}; scope.host_summary.ok = 0; @@ -557,7 +558,7 @@ export default }); }); if (scope.activeTask && scope.jobData.plays[scope.activePlay] && scope.jobData.plays[scope.activePlay].tasks[scope.activeTask]) { - scope.jobData.plays[scope.activePlay].tasks[scope.activeTask].taskActiveClass = 'List-tableRow--selected'; + scope.jobData.plays[scope.activePlay].tasks[scope.activeTask].taskActiveClass = 'JobDetail-tableRow--selected'; } scope.$emit('LoadHosts'); }) @@ -677,7 +678,7 @@ export default scope.host_summary.failed; }); if (scope.activePlay && scope.jobData.plays[scope.activePlay]) { - scope.jobData.plays[scope.activePlay].playActiveClass = 'List-tableRow--selected'; + scope.jobData.plays[scope.activePlay].playActiveClass = 'JobDetail-tableRow--selected'; } scope.$emit('LoadTasks', events_url); }) @@ -981,11 +982,11 @@ export default scope.toggleLessStatus = function() { if (!scope.lessStatus) { - $('#job-status-form .toggle-show').slideUp(200); + $('#job-status-form').slideUp(200); scope.lessStatus = true; } else { - $('#job-status-form .toggle-show').slideDown(200); + $('#job-status-form').slideDown(200); scope.lessStatus = false; } }; @@ -1009,6 +1010,7 @@ export default else { $('#events-summary').slideDown(200); scope.lessEvents = false; + DrawGraph({scope:scope}); } }; @@ -1432,16 +1434,10 @@ export default $scope.$emit('LoadJob'); }; - scope.editHost = function(id) { - HostsEdit({ - host_scope: scope, - group_scope: null, - host_id: id, - inventory_id: scope.job.inventory, - mode: 'edit', // 'add' or 'edit' - selected_group_id: null - }); - }; + // Click binding for the expand/collapse button on the standard out log + $scope.toggleStdoutFullscreen = function() { + $scope.stdoutFullScreen = !$scope.stdoutFullScreen; + } scope.editSchedule = function() { // We need to get the schedule's ID out of the related links diff --git a/awx/ui/client/src/job-detail/job-detail.partial.html b/awx/ui/client/src/job-detail/job-detail.partial.html index fcdfe87acb..8bbbc4aaaa 100644 --- a/awx/ui/client/src/job-detail/job-detail.partial.html +++ b/awx/ui/client/src/job-detail/job-detail.partial.html @@ -1,238 +1,406 @@
-
-
-
-
-
- -
- - -
+
+ + +
+ + +
+
+ - -
-
- -
{{ job_status.status_label }}
-
-
- -
-
Previous Task Failed - - - - -
-
- -
- -
-
- -
- - -
- -
- -
{{ job_status.started | date:'MM/dd/yy HH:mm:ss' }}
-
- -
- -
{{ job_type }}
-
- -
- -
{{ job_status.finished | date:'MM/dd/yy HH:mm:ss' }}
-
- -
- - -
- -
- -
{{ job_status.elapsed }}
-
- -
- - -
- -
- - -
- -
- - -
- -
- -
{{ job.playbook }}
-
- -
- - -
- -
- - -
- -
- -
{{ job.forks }}
-
- -
- -
{{ job.limit }}
-
- -
- -
{{ verbosity }}
-
- -
- -
{{ job.job_tags }}
-
- -
- - -
- +
+ + +
- -
-
-
- - DETAILS - - - DETAILS +
+
+ +
{{ job_status.status_label }}
+
+ +
-
-
-
-
-
- - - -
-
-
-
- - -
-
-
- - -
- - - - - - - - -
PlaysStartedElapsed
-
-
- - - - - - - - - - - - - - - - - - -
{{ play.name }}{{ play.created | date: 'HH:mm:ss' }}{{ play.elapsed }}
Waiting...
Loading...
No matching plays
-
-
+
+ +
- -
+
+ + +
+
+ +
{{ job_status.started | date:'MM/dd/yy HH:mm:ss' }}
+
+ +
+ +
{{ job_type }}
+
+ +
+ +
{{ job_status.finished | date:'MM/dd/yy HH:mm:ss' }}
+
+ +
+ + +
+ +
+ +
{{ job_status.elapsed }}
+
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ +
{{ job.playbook }}
+
+ +
+ + +
+ +
+ + +
+ +
+ +
{{ job.forks }}
+
+ +
+ +
{{ job.limit }}
+
+ +
+ +
{{ verbosity }}
+
+ +
+ +
{{ job.job_tags }}
+
+ +
+ + +
+ +
+
+ + + +
+ + +
+
+
+
+
+ + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + +
PlaysStartedElapsed
+
+
+ + + + + + + + + + + + + + + + + + +
{{ play.name }}{{ play.created | date: 'HH:mm:ss' }}{{ play.elapsed }}
Waiting...
Loading...
No matching plays
+
+
+ +
+
+ + +
- - + + +
+
+
+
+ + +
+
+
+ +
+ + + + + + + + + +
TasksStartedElapsed
+
+
+ + + + + + + + + + + + + + + + + + + +
{{ task.name }}{{ task.created | date: 'HH:mm:ss' }}{{ task.elapsed }}
Waiting...
Loading...
No matching tasks
+
+
+
+ + +
+
+
+
+ + +
-
+
+ + +
+
+
+
+ + + + + + + + +
HostsItemMessage
+
+ +
+ + + + + + + + + + + + + + + + + +
{{ result.name }}{{ result.name }}{{ result.item }}{{ result.msg }}
Waiting...
Loading...
No matching host events
+
+
+
+ +
+
+ + + +
+ + + +
+ + +
+ + + - -
-
-
- -
- - -
-
-
-
-
- - - -
-
-
-
- - -
-
-
-
- - - - - - - - -
HostsCompleted TasksActions
-
-
+ +
+ +
+
-
- + +
+ +
+
+ +
+ + + +
+
+
STANDARD OUT
+
+ + + +
-
-
-
- + +
- +
+
diff --git a/awx/ui/client/src/shared/branding/colors.default.less b/awx/ui/client/src/shared/branding/colors.default.less index f63c3860f3..dd53943e88 100644 --- a/awx/ui/client/src/shared/branding/colors.default.less +++ b/awx/ui/client/src/shared/branding/colors.default.less @@ -161,9 +161,6 @@ @db-graph-axis: @default-border; @db-graph-axis-label: @default-interface-txt; -//job detail -@toggle-selected-text: #eeeeee; - // panel @panel-bg: @default-bg; @panel-border: @default-border; diff --git a/awx/ui/client/src/standard-out/log/standard-out-log.controller.js b/awx/ui/client/src/standard-out/log/standard-out-log.controller.js index 3316d088a9..ca3bff7947 100644 --- a/awx/ui/client/src/standard-out/log/standard-out-log.controller.js +++ b/awx/ui/client/src/standard-out/log/standard-out-log.controller.js @@ -21,6 +21,15 @@ export default ['$log', '$rootScope', '$scope', '$state', '$stateParams', 'Proce // Open up a socket for events depending on the type of job function openSockets() { + if ($state.current.name == 'jobDetail') { + $log.debug("socket watching on job_events-" + job_id); + $rootScope.event_socket.on("job_events-" + job_id, function() { + $log.debug("socket fired on job_events-" + job_id); + if (api_complete) { + event_queue++; + } + }); + } if ($state.current.name == 'adHocJobStdout') { $log.debug("socket watching on ad_hoc_command_events-" + job_id); $rootScope.adhoc_event_socket.on("ad_hoc_command_events-" + job_id, function() { @@ -108,7 +117,7 @@ export default ['$log', '$rootScope', '$scope', '$state', '$stateParams', 'Proce function getNextSection() { // get the next range of data from the API var start = loaded_sections[loaded_sections.length - 1].end, url; - url = stdout_url + '?format=json&start_line=' + start + '&end_line=' + (start + page_size); + url = $scope.stdoutEndpoint + '?format=json&start_line=' + start + '&end_line=' + (start + page_size); $('#stdoutMoreRowsBottom').fadeIn(); Rest.setUrl(url); Rest.get() From 656f77c0de455bf05f590710316651c22e4053b9 Mon Sep 17 00:00:00 2001 From: Jared Tabor Date: Fri, 4 Mar 2016 07:42:56 -0800 Subject: [PATCH 2/2] clean up stale code --- awx/ui/client/src/helpers/JobDetail.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/awx/ui/client/src/helpers/JobDetail.js b/awx/ui/client/src/helpers/JobDetail.js index 121786de3a..689e7139b5 100644 --- a/awx/ui/client/src/helpers/JobDetail.js +++ b/awx/ui/client/src/helpers/JobDetail.js @@ -1142,7 +1142,6 @@ export default .factory('DrawGraph', ['DonutChart', function(DonutChart) { return function(params) { var scope = params.scope, - resize = params.resize, graph_data = []; // Ready the data @@ -1192,8 +1191,9 @@ export default element = $("#graph-section"), colors, total,job_detail_chart; - // colors = ['#60D66F', '#FF9900','#FF0000','#ff5850']; - colors = _.map(dataset, function(d){return d.color}); + colors = _.map(dataset, function(d){ + return d.color; + }); total = d3.sum(dataset.map(function(d) { return d.value; }));