diff --git a/awx/ui/static/js/controllers/JobDetail.js b/awx/ui/static/js/controllers/JobDetail.js index 023d5670b7..f9756e461d 100644 --- a/awx/ui/static/js/controllers/JobDetail.js +++ b/awx/ui/static/js/controllers/JobDetail.js @@ -8,7 +8,7 @@ 'use strict'; function JobDetailController ($scope, $compile, $routeParams, ClearScope, Breadcrumbs, LoadBreadCrumbs, GetBasePath, Wait, Rest, ProcessErrors, DigestEvents, - SelectPlay, SelectTask, Socket, GetElapsed, SelectHost) { + SelectPlay, SelectTask, Socket, GetElapsed, SelectHost, FilterAllByHostName) { ClearScope(); @@ -23,6 +23,8 @@ function JobDetailController ($scope, $compile, $routeParams, ClearScope, Breadc scope.plays = []; scope.tasks = []; scope.hosts = []; + scope.search_all_tasks = []; + scope.search_all_plays = []; scope.hostResults = []; scope.job_status = {}; scope.job_id = job_id; @@ -457,7 +459,7 @@ function JobDetailController ($scope, $compile, $routeParams, ClearScope, Breadc // Called when user scrolls down (or forward in time). Using _.debounce var url, mcs = arguments[0]; scope.$apply(function() { - if (!scope.auto_scroll && scope.activeTask && scope.hostResults) { + if (!scope.auto_scroll && scope.activeTask && scope.hostResults.length) { scope.auto_scroll = true; url = GetBasePath('jobs') + job_id + '/job_events/?parent=' + scope.activeTask + '&'; url += (scope.task_host_name) ? 'host__name__icontains=' + scope.task_host_name + '&' : ''; @@ -502,7 +504,7 @@ function JobDetailController ($scope, $compile, $routeParams, ClearScope, Breadc // Called when user scrolls up (or back in time) var url, mcs = arguments[0]; scope.$apply(function() { - if (!scope.auto_scroll && scope.activeTask && scope.hostResults) { + if (!scope.auto_scroll && scope.activeTask && scope.hostResults.length) { scope.auto_scroll = true; url = GetBasePath('jobs') + job_id + '/job_events/?parent=' + scope.activeTask + '&'; url += (scope.task_host_name) ? 'host__name__icontains=' + scope.task_host_name + '&' : ''; @@ -716,8 +718,33 @@ function JobDetailController ($scope, $compile, $routeParams, ClearScope, Breadc scope.searchSummaryHosts(); } }; + + scope.searchAllByHost = function() { + if (scope.search_all_hosts_name) { + FilterAllByHostName({ + scope: scope, + host: scope.search_all_hosts_name + }); + scope.searchAllHostsEnabled = false; + } + else { + scope.search_all_tasks = []; + scope.search_all_plays = []; + scope.searchAllHostsEnabled = true; + } + scope.task_host_name = scope.search_all_hosts_name; + scope.searchTaskHosts(); + scope.summary_host_name = scope.search_all_hosts_name; + scope.searchSummaryHosts(); + }; + + scope.allHostNameKeyPress = function(e) { + if (e.keyCode === 13) { + scope.searchAllByHost(); + } + }; } JobDetailController.$inject = [ '$scope', '$compile', '$routeParams', 'ClearScope', 'Breadcrumbs', 'LoadBreadCrumbs', 'GetBasePath', 'Wait', - 'Rest', 'ProcessErrors', 'DigestEvents', 'SelectPlay', 'SelectTask', 'Socket', 'GetElapsed', 'SelectHost' + 'Rest', 'ProcessErrors', 'DigestEvents', 'SelectPlay', 'SelectTask', 'Socket', 'GetElapsed', 'SelectHost', 'FilterAllByHostName' ]; diff --git a/awx/ui/static/js/helpers/JobDetail.js b/awx/ui/static/js/helpers/JobDetail.js index 9988a4f8a7..3ab92bbd30 100644 --- a/awx/ui/static/js/helpers/JobDetail.js +++ b/awx/ui/static/js/helpers/JobDetail.js @@ -229,8 +229,6 @@ function(UpdatePlayStatus, UpdateHostStatus, UpdatePlayChild, AddHostResult, Sel }); scope.job_status.status = (event.failed) ? 'failed' : 'successful'; scope.job_status.status_class = ""; - scope.liveEventsEnabled = true; // Show the stop button - scope.liveEventToggleDisabled = true; //Disable clicking on the button, the job is over } }); }; @@ -697,8 +695,8 @@ function(UpdatePlayStatus, UpdateHostStatus, UpdatePlayChild, AddHostResult, Sel }; }]) -.factory('SelectTask', ['SelectHost', 'GetBasePath', '$routeParams', 'Rest', 'ProcessErrors', 'Wait', - function(SelectHost, GetBasePath, $routeParams, Rest, ProcessErrors, Wait) { +.factory('SelectTask', ['SelectHost', 'GetBasePath', '$routeParams', 'Rest', 'ProcessErrors', + function(SelectHost, GetBasePath, $routeParams, Rest, ProcessErrors) { return function(params) { var scope = params.scope, id = params.id, @@ -730,7 +728,7 @@ function(UpdatePlayStatus, UpdateHostStatus, UpdatePlayChild, AddHostResult, Sel // is the job done? if so, only select hosts for the last task? - Wait('start'); + //Wait('start'); scope.hostResults = []; url = GetBasePath('jobs') + $routeParams.id + '/job_events/?parent=' + id + '&'; url += (scope.task_host_name) ? 'host__name__icontains=' + scope.task_host_name + '&' : ''; @@ -749,7 +747,7 @@ function(UpdatePlayStatus, UpdateHostStatus, UpdatePlayChild, AddHostResult, Sel msg: ( (row.event_data && row.event_data.res) ? row.event_data.res.msg : '' ) }); }); - Wait('stop'); + //Wait('stop'); SelectHost({ scope: scope }); }) .error(function(data, status) { @@ -782,6 +780,75 @@ function(UpdatePlayStatus, UpdateHostStatus, UpdatePlayChild, AddHostResult, Sel {label:"Skipped", color:"#D4D4D4"}, {label:"Unreachable", color:""} ];*/ +}]) + +.factory('FilterAllByHostName', ['Rest', 'GetBasePath', 'ProcessErrors', 'SelectPlay', function(Rest, GetBasePath, ProcessErrors, SelectPlay) { + return function(params) { + var scope = params.scope, + host = params.host, + job_id = scope.job_id, + url = GetBasePath('jobs') + job_id + '/job_events/?event__icontains=runner&host_name__icontains=' + host; + + scope.search_all_tasks = []; + scope.search_all_plays = []; + + if (scope.removeAllPlaysReady) { + scope.removeAllPlaysReady(); + } + scope.removeAllPlaysReady = scope.$on('AllPlaysReady', function() { + if (scope.activePlay) { + setTimeout(function() { + SelectPlay({ scope: scope, id: scope.activePlay }); + }, 500); + } + }); + + if (scope.removeAllTasksReady) { + scope.removeAllTasksReady(); + } + scope.removeAllTasksReady = scope.$on('AllTasksReady', function() { + url = GetBasePath('jobs') + job_id + '/job_events/?id__in=' + scope.search_all_tasks.join(); + Rest.setUrl(url); + Rest.get() + .success(function(data) { + data.results.forEach(function(row) { + if (row.parent) { + scope.search_all_plays.push(row.parent); + } + }); + if (scope.search_all_plays.length > 0) { + scope.search_all_plays.sort(); + scope.activePlay = scope.search_all_plays[scope.search_all_plays.length - 1]; + } + else { + scope.activePlay = null; + } + scope.$emit('AllPlaysReady'); + }) + .error(function(data, status) { + ProcessErrors(scope, data, status, null, { hdr: 'Error!', + msg: 'Call to ' + url + '. GET returned: ' + status }); + }); + }); + + Rest.setUrl(url); + Rest.get() + .success(function(data) { + data.results.forEach(function(row) { + if (row.parent) { + scope.search_all_tasks.push(row.parent); + } + }); + if (scope.search_all_tasks.length > 0) { + scope.search_all_tasks.sort(); + } + scope.$emit('AllTasksReady'); + }) + .error(function(data, status) { + ProcessErrors(scope, data, status, null, { hdr: 'Error!', + msg: 'Call to ' + url + '. GET returned: ' + status }); + }); + }; }]); diff --git a/awx/ui/static/lib/ansible/filters.js b/awx/ui/static/lib/ansible/filters.js index f8eb69af6a..e8d8a9ad08 100644 --- a/awx/ui/static/lib/ansible/filters.js +++ b/awx/ui/static/lib/ansible/filters.js @@ -12,18 +12,43 @@ angular.module('AWFilters', []) // // capitalize -capitalize the first letter of each word // - .filter('capitalize', [ - function () { - return function (input) { - var values, result, i; - if (input) { - values = input.replace(/\_/g, ' ').split(" "); - result = ""; - for (i = 0; i < values.length; i++) { - result += values[i].charAt(0).toUpperCase() + values[i].substr(1) + ' '; - } - return result.trim(); + .filter('capitalize', [ function () { + return function (input) { + var values, result, i; + if (input) { + values = input.replace(/\_/g, ' ').split(" "); + result = ""; + for (i = 0; i < values.length; i++) { + result += values[i].charAt(0).toUpperCase() + values[i].substr(1) + ' '; } - }; - } - ]); \ No newline at end of file + return result.trim(); + } + }; + }]) + + // + // Filter a list of objects by id using an array of id values + // Created specifically for Filter Events on job detail page. + // + .filter('FilterById', [ function() { + return function(input, list) { + var found, results = []; + if (list.length > 0) { + input.forEach(function(row) { + found = false; + list.every(function(id) { + if (row.id === id) { + found = true; + return false; + } + return true; + }); + if (found) { + results.push(row); + } + }); + return results; + } + return input; + }; + }]); \ No newline at end of file diff --git a/awx/ui/static/partials/job_detail.html b/awx/ui/static/partials/job_detail.html index 9172494da2..57d6ad0178 100644 --- a/awx/ui/static/partials/job_detail.html +++ b/awx/ui/static/partials/job_detail.html @@ -20,7 +20,7 @@