diff --git a/awx/ui/client/src/job-results/event-queue.service.js b/awx/ui/client/src/job-results/event-queue.service.js index 929c5dc9a8..b8796c361e 100644 --- a/awx/ui/client/src/job-results/event-queue.service.js +++ b/awx/ui/client/src/job-results/event-queue.service.js @@ -175,6 +175,12 @@ export default ['jobResultsService', 'parseStdoutService', '$q', function(jobRes val.populateDefers[event.counter] = $q.defer(); } + if (val.queue[event.counter] && + val.queue[event.counter].processed) { + val.populateDefers.reject("duplicate event: " + + event); + } + if (!val.queue[event.counter]) { var resolvePopulation = function(event) { // to resolve, put the event on the queue and diff --git a/awx/ui/client/src/job-results/job-results-stdout/job-results-stdout.block.less b/awx/ui/client/src/job-results/job-results-stdout/job-results-stdout.block.less index a669d2b5a0..be005bb7b2 100644 --- a/awx/ui/client/src/job-results/job-results-stdout/job-results-stdout.block.less +++ b/awx/ui/client/src/job-results/job-results-stdout/job-results-stdout.block.less @@ -1,19 +1,128 @@ @import '../../shared/branding/colors.default.less'; -.JobResultsStdOut{ +.JobResultsStdOut { height: 100%; - margin-top: 15px; - background-color: @default-no-items-bord; - border-radius: 5px; - margin-bottom: 10px; } -.JobResultsStdOut-aLineOfStdOut, -.JobResultsStdOut-expandLine { +.JobResultsStdOut-toolbar { display: flex; + height: 38px; + margin-top: 15px; + border: 1px solid @default-list-header-bg; + border-bottom: 0px; + border-radius: 5px; + border-bottom-left-radius: 0px; + border-bottom-right-radius: 0px; + user-select: none; + -moz-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; } -.JobResultsStdOut-lineNumberColumn{ +.JobResultsStdOut-toolbarNumberColumn { + background-color: @default-list-header-bg; + color: @b7grey; + flex: initial; + display: flex; + justify-content: space-between; + width: 70px; + padding-bottom: 0px; + padding-left: 8px; + padding-right: 8px; + padding-top: 10px; + border-top-left-radius: 5px; +} + +.JobResultsStdOut-expandAllButton { + height: 18px; + width: 18px; + padding-left: 4px; + padding-top: 1px; + border-radius: 50%; + background-color: @default-bg; + font-size: 12px; + cursor: pointer; +} + +.JobResultsStdOut-expandAllButton:hover .JobResultsStdOut-expandAllIcon, +.JobResultsStdOut-expandAllIcon:hover { + color: @default-data-txt; +} + +.JobResultsStdOut-toolbarStdoutColumn { + white-space: normal; + flex: 1; + display: flex; + justify-content: flex-end; + padding-right: 10px; + background-color: @default-no-items-bord; +} + +.JobResultsStdOut-followButton { + cursor: pointer; + width: 18px; + height: 18px; + width: 18px; + padding-left: 3.8px; + border-radius: 50%; + margin-top: 10px; + font-size: 12px; + background-color: @default-icon; + color: @default-border; +} + +.JobResultsStdOut-followIcon { + color: @default-border; +} + +.JobResultsStdOut-followButton:hover { + background-color: @default-icon-hov; +} + +.JobResultsStdOut-followButton:hover .JobResultsStdOut-followIcon, +.JobResultsStdOut-followIcon:hover { + color: @default-interface-txt; +} + +.JobResultsStdOut-stdoutContainer { + height: ~"calc(100% - 108px)"; + background-color: @default-no-items-bord; + border: 1px solid @default-list-header-bg; + border-top: 0px; + border-radius: 5px; + border-top-left-radius: 0px; + border-top-right-radius: 0px; + margin-bottom: 10px; + overflow: scroll; +} + +.JobResultsStdOut-numberColumnPreload { + background-color: #EBEBEB; + width: 70px; + position: fixed; +} + +.JobResultsStdOut-aLineOfStdOut { + display: flex; + font-family: Monaco, Menlo, Consolas, "Courier New", monospace; +} + +.JobResultsStdOut-lineExpander { + text-align: left; + padding-left: 11px; + margin-right: auto; +} + +.JobResultsStdOut-lineExpanderIcon { + font-size: 19px; + cursor: pointer; +} + +.JobResultsStdOut-lineExpanderIcon:hover { + color: @default-data-txt; +} + +.JobResultsStdOut-lineNumberColumn { display: flex; background-color: @default-list-header-bg; text-align: right; @@ -22,28 +131,16 @@ padding-bottom: 2px; color: @b7grey; width: 75px; + flex: initial; white-space: pre-line; user-select: none; -moz-user-select: none; -webkit-user-select: none; -ms-user-select: none; + z-index: 1; } -.JobResultsStdOut-lineExpander { - text-align: left; - padding-left: 10px; - margin-right: auto; -} - -.JobResultsStdOut-lineNumberColumn--first{ - text-align: left; - padding: 0px; - padding-left: 11px; - padding-top: 10px; - white-space: normal; -} - -.JobResultsStdOut-stdoutColumn{ +.JobResultsStdOut-stdoutColumn { padding-left: 20px; padding-top: 2px; padding-bottom: 2px; @@ -54,6 +151,8 @@ width:100%; } -.JobResultsStdOut-stdoutColumn--first{ - padding-top:0px; + +// TODO: needs to be set based on height of browser window +.JobResultsStdOut-numberColumnPreload { + height: 720px; } diff --git a/awx/ui/client/src/job-results/job-results-stdout/job-results-stdout.directive.js b/awx/ui/client/src/job-results/job-results-stdout/job-results-stdout.directive.js index e6bdefe91d..dd7366fc11 100644 --- a/awx/ui/client/src/job-results/job-results-stdout/job-results-stdout.directive.js +++ b/awx/ui/client/src/job-results/job-results-stdout/job-results-stdout.directive.js @@ -5,15 +5,75 @@ *************************************************/ // import hostStatusBarController from './host-status-bar.controller'; -export default [ 'templateUrl', - function(templateUrl) { +export default [ 'templateUrl', '$timeout', + function(templateUrl, $timeout) { return { - scope: true, + scope: false, templateUrl: templateUrl('job-results/job-results-stdout/job-results-stdout'), restrict: 'E', - // controller: jobResultsStdOutController, - link: function(scope) { + link: function(scope, element, attrs) { + scope.toggleAllStdout = function(type) { + var expandClass; + if (type === 'expand') { + expandClass = "fa-caret-right"; + } else { + expandClass = "fa-caret-down"; + } + element.find(".expanderizer--task."+expandClass) + .each((i, val) => { + $timeout(function(){ + angular.element(val).trigger('click'); + }); + }); + + element.find(".expanderizer--play."+expandClass) + .each((i, val) => { + if(angular.element("." + + angular.element(val).attr("data-uuid")) + .find(".expanderizer--task") + .length === 0 || + type !== 'collapse') { + + $timeout(function(){ + angular.element(val) + .trigger('click'); + }); + } + }); + }; + + scope.toggleLine = function($event, id) { + if ($($event.currentTarget).hasClass("fa-caret-down")) { + $(id).hide(); + $($event.currentTarget) + .removeClass("fa-caret-down"); + $($event.currentTarget) + .addClass("fa-caret-right"); + } else { + $(id).show(); + $($event.currentTarget) + .removeClass("fa-caret-right"); + $($event.currentTarget) + .addClass("fa-caret-down"); + + if ($($event.currentTarget) + .hasClass("expanderizer--play")) { + $("." + $($event.currentTarget) + .attr("data-uuid")) + .find(".expanderizer--task") + .each((i, val) => { + if ($(val) + .hasClass("fa-caret-right")) { + $timeout(function(){ + angular.element(val) + .trigger('click'); + }); + } + }); + } + } + }; } }; }]; diff --git a/awx/ui/client/src/job-results/job-results-stdout/job-results-stdout.partial.html b/awx/ui/client/src/job-results/job-results-stdout/job-results-stdout.partial.html index 283a80a502..152429c7d4 100644 --- a/awx/ui/client/src/job-results/job-results-stdout/job-results-stdout.partial.html +++ b/awx/ui/client/src/job-results/job-results-stdout/job-results-stdout.partial.html @@ -1,11 +1,31 @@