Wired up status filter. Redraw graph with resize option on playbook_on_stat event. Removed counts from tooltips, eliminating over watch issue.

This commit is contained in:
chouseknecht
2014-05-16 14:17:17 -04:00
parent 4e1b9760c9
commit e7d58de007
6 changed files with 89 additions and 53 deletions

View File

@@ -403,7 +403,8 @@ function JobDetailController ($scope, $compile, $routeParams, ClearScope, Breadc
if (!scope.auto_scroll && scope.activeTask && scope.hostResults.length) { if (!scope.auto_scroll && scope.activeTask && scope.hostResults.length) {
scope.auto_scroll = true; scope.auto_scroll = true;
url = GetBasePath('jobs') + job_id + '/job_events/?parent=' + scope.activeTask + '&'; url = GetBasePath('jobs') + job_id + '/job_events/?parent=' + scope.activeTask + '&';
url += (scope.task_host_name) ? 'host__name__icontains=' + scope.task_host_name + '&' : ''; url += (scope.search_all_hosts_name) ? 'host__name__icontains=' + scope.search_all_hosts_name + '&' : '';
url += (scope.searchAllStatus === 'failed') ? 'failed=true&' : '';
url += 'host__name__gt=' + scope.hostResults[scope.hostResults.length - 1].name + '&host__isnull=false&page_size=' + (scope.hostTableRows / 3) + '&order_by=host__name'; url += 'host__name__gt=' + scope.hostResults[scope.hostResults.length - 1].name + '&host__isnull=false&page_size=' + (scope.hostTableRows / 3) + '&order_by=host__name';
Wait('start'); Wait('start');
Rest.setUrl(url); Rest.setUrl(url);
@@ -448,7 +449,8 @@ function JobDetailController ($scope, $compile, $routeParams, ClearScope, Breadc
if (!scope.auto_scroll && scope.activeTask && scope.hostResults.length) { if (!scope.auto_scroll && scope.activeTask && scope.hostResults.length) {
scope.auto_scroll = true; scope.auto_scroll = true;
url = GetBasePath('jobs') + job_id + '/job_events/?parent=' + scope.activeTask + '&'; url = GetBasePath('jobs') + job_id + '/job_events/?parent=' + scope.activeTask + '&';
url += (scope.task_host_name) ? 'host__name__icontains=' + scope.task_host_name + '&' : ''; url += (scope.search_all_hosts_name) ? 'host__name__icontains=' + scope.search_all_hosts_name + '&' : '';
url += (scope.searchAllStatus === 'failed') ? 'failed=true&' : '';
url += 'host__name__lt=' + scope.hostResults[0].name + '&host__isnull=false&page_size=' + (scope.hostTableRows / 3) + '&order_by=-host__name'; url += 'host__name__lt=' + scope.hostResults[0].name + '&host__isnull=false&page_size=' + (scope.hostTableRows / 3) + '&order_by=-host__name';
Wait('start'); Wait('start');
Rest.setUrl(url); Rest.setUrl(url);
@@ -490,7 +492,8 @@ function JobDetailController ($scope, $compile, $routeParams, ClearScope, Breadc
var url; var url;
if (!scope.auto_scroll && scope.hosts) { if (!scope.auto_scroll && scope.hosts) {
url = GetBasePath('jobs') + job_id + '/job_host_summaries/?'; url = GetBasePath('jobs') + job_id + '/job_host_summaries/?';
url += (scope.summary_host_name) ? 'host__name__icontains=' + scope.summary_host_name + '&': ''; url += (scope.search_all_hosts_name) ? 'host__name__icontains=' + scope.search_all_hosts_name + '&' : '';
url += (scope.searchAllStatus === 'failed') ? 'failed=true&' : '';
url += 'host__name__gt=' + scope.hosts[scope.hosts.length - 1].name + '&page_size=' + (scope.hostSummaryTableRows / 3) + '&order_by=host__name'; url += 'host__name__gt=' + scope.hosts[scope.hosts.length - 1].name + '&page_size=' + (scope.hostSummaryTableRows / 3) + '&order_by=host__name';
Wait('start'); Wait('start');
Rest.setUrl(url); Rest.setUrl(url);
@@ -533,7 +536,8 @@ function JobDetailController ($scope, $compile, $routeParams, ClearScope, Breadc
var url; var url;
if (!scope.auto_scroll && scope.hosts) { if (!scope.auto_scroll && scope.hosts) {
url = GetBasePath('jobs') + job_id + '/job_host_summaries/?'; url = GetBasePath('jobs') + job_id + '/job_host_summaries/?';
url += (scope.summary_host_name) ? 'host__name__icontains=' + scope.summary_host_name + '&': ''; url += (scope.search_all_hosts_name) ? 'host__name__icontains=' + scope.search_all_hosts_name + '&' : '';
url += (scope.searchAllStatus === 'failed') ? 'failed=true&' : '';
url += 'host__name__lt=' + scope.hosts[0].name + '&page_size=' + (scope.hostSummaryTableRows / 3) + '&order_by=-host__name'; url += 'host__name__lt=' + scope.hosts[0].name + '&page_size=' + (scope.hostSummaryTableRows / 3) + '&order_by=-host__name';
Wait('start'); Wait('start');
Rest.setUrl(url); Rest.setUrl(url);
@@ -578,6 +582,7 @@ function JobDetailController ($scope, $compile, $routeParams, ClearScope, Breadc
scope.hosts = []; scope.hosts = [];
url = GetBasePath('jobs') + $routeParams.id + '/job_host_summaries/?'; url = GetBasePath('jobs') + $routeParams.id + '/job_host_summaries/?';
url += (scope.search_all_hosts_name) ? 'host__name__icontains=' + scope.search_all_hosts_name + '&': ''; url += (scope.search_all_hosts_name) ? 'host__name__icontains=' + scope.search_all_hosts_name + '&': '';
url += (scope.searchAllStatus === 'failed') ? 'failed=true&' : '';
url += 'page_size=' + scope.hostSummaryTableRows + '&order_by=host__name'; url += 'page_size=' + scope.hostSummaryTableRows + '&order_by=host__name';
Rest.setUrl(url); Rest.setUrl(url);
Rest.get() Rest.get()
@@ -626,6 +631,28 @@ function JobDetailController ($scope, $compile, $routeParams, ClearScope, Breadc
scope.searchAllByHost(); scope.searchAllByHost();
} }
}; };
scope.filterByStatus = function(choice) {
var tmp = [];
if (choice === 'Failed') {
scope.searchAllStatus = 'failed';
scope.plays.forEach(function(row) {
if (row.status === 'failed') {
tmp.push(row.id);
}
});
tmp.sort();
scope.activePlay = tmp[tmp.length - 1];
}
else {
scope.searchAllStatus = '';
scope.activePlay = scope.plays[scope.plays.length - 1].id;
}
scope.searchSummaryHosts();
setTimeout(function() {
SelectPlay({ scope: scope, id: scope.activePlay });
}, 500);
};
} }
JobDetailController.$inject = [ '$scope', '$compile', '$routeParams', 'ClearScope', 'Breadcrumbs', 'LoadBreadCrumbs', 'GetBasePath', 'Wait', JobDetailController.$inject = [ '$scope', '$compile', '$routeParams', 'ClearScope', 'Breadcrumbs', 'LoadBreadCrumbs', 'GetBasePath', 'Wait',

View File

@@ -232,7 +232,7 @@ function(UpdatePlayStatus, UpdateHostStatus, UpdatePlayChild, AddHostResult, Sel
scope.job_status.status_class = ""; scope.job_status.status_class = "";
scope.host_summary = {}; scope.host_summary = {};
LoadHostSummary({ scope: scope, data: event.event_data }); LoadHostSummary({ scope: scope, data: event.event_data });
DrawGraph({ scope: scope }); DrawGraph({ scope: scope, resize: true });
} }
}); });
}; };
@@ -735,32 +735,34 @@ function(UpdatePlayStatus, UpdateHostStatus, UpdatePlayChild, AddHostResult, Sel
// is the job done? if so, only select hosts for the last task? // is the job done? if so, only select hosts for the last task?
//Wait('start');
scope.hostResults = []; scope.hostResults = [];
url = GetBasePath('jobs') + $routeParams.id + '/job_events/?parent=' + id + '&'; if (id > 0) {
url += (scope.search_all_hosts_name) ? 'host__name__icontains=' + scope.search_all_hosts_name + '&' : ''; // If we have a selected task, then get the list of hosts
url += 'host__isnull=false&page_size=' + scope.hostTableRows + '&order_by=host__name'; url = GetBasePath('jobs') + $routeParams.id + '/job_events/?parent=' + id + '&';
Rest.setUrl(url); url += (scope.search_all_hosts_name) ? 'host__name__icontains=' + scope.search_all_hosts_name + '&' : '';
Rest.get() url += (scope.searchAllStatus === 'failed') ? 'failed=true&' : '';
.success(function(data) { url += 'host__isnull=false&page_size=' + scope.hostTableRows + '&order_by=host__name';
data.results.forEach(function(row) { Rest.setUrl(url);
scope.hostResults.push({ Rest.get()
id: row.id, .success(function(data) {
status: ( (row.failed) ? 'failed' : (row.changed) ? 'changed' : 'successful' ), data.results.forEach(function(row) {
host_id: row.host, scope.hostResults.push({
task_id: row.parent, id: row.id,
name: row.event_data.host, status: ( (row.failed) ? 'failed' : (row.changed) ? 'changed' : 'successful' ),
created: row.created, host_id: row.host,
msg: ( (row.event_data && row.event_data.res) ? row.event_data.res.msg : '' ) task_id: row.parent,
name: row.event_data.host,
created: row.created,
msg: ( (row.event_data && row.event_data.res) ? row.event_data.res.msg : '' )
});
}); });
SelectHost({ scope: scope });
})
.error(function(data, status) {
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
msg: 'Call to ' + url + '. GET returned: ' + status });
}); });
//Wait('stop'); }
SelectHost({ scope: scope });
})
.error(function(data, status) {
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
msg: 'Call to ' + url + '. GET returned: ' + status });
});
}; };
}]) }])

View File

@@ -439,9 +439,7 @@ function($location, Wait, GetBasePath, LookUpInit, JobTemplateForm, CredentialLi
} }
scope.removePlaybookLaunchFinished = scope.$on('PlaybookLaunchFinished', function() { scope.removePlaybookLaunchFinished = scope.$on('PlaybookLaunchFinished', function() {
var base = $location.path().replace(/^\//, '').split('/')[0]; var base = $location.path().replace(/^\//, '').split('/')[0];
if (base === 'jobs') { if (base !== 'jobs') {
scope.refreshJobs();
} else {
$location.path('/jobs'); $location.path('/jobs');
} }
}); });

View File

@@ -10,7 +10,7 @@
@failed-hosts-color: #DA4D49; @failed-hosts-color: #DA4D49;
@successful-hosts-color: #5bb75b; @successful-hosts-color: #5bb75b;
@changed-hosts-color: #FF9900; @changed-hosts-color: #FF9900;
@skipped-hosts-color: #00BFFF; @skipped-hosts-color: #01BCC5;
@unreachable-hosts-color: #A9A9A9; @unreachable-hosts-color: #A9A9A9;
@@ -303,13 +303,12 @@ label.small-label {
.badge-column a { .badge-column a {
width: 20%; width: 20%;
} }
.legend {
margin: 8px 0;
}
} }
.legend { .legend {
display: inline-block;
font-size: 12px; font-size: 12px;
text-align: center;
i { i {
font-size: 10px; font-size: 10px;
margin-left: 5px; margin-left: 5px;
@@ -329,8 +328,6 @@ label.small-label {
.header { .header {
margin-top: 20px; margin-top: 20px;
.legend { .legend {
text-align: center;
margin: 15px 0 0 0;
i { i {
margin-left: 10px margin-left: 10px
} }
@@ -353,7 +350,8 @@ polyline{
} }
svg text.percent{ svg text.percent{
fill:white; fill:@black;
text-anchor:middle; text-anchor:middle;
font-size:12px; font-size:12px;
font-weight: bold;
} }

View File

@@ -746,6 +746,7 @@ angular.module('AWDirectives', ['RestServices', 'Utilities', 'AuthService', 'Job
.directive('awToggleButton', [ function() { .directive('awToggleButton', [ function() {
return function(scope, element) { return function(scope, element) {
$(element).click(function() { $(element).click(function() {
var next, choice;
$(this).find('.btn').toggleClass('active'); $(this).find('.btn').toggleClass('active');
if ($(this).find('.btn-primary').size()>0) { if ($(this).find('.btn-primary').size()>0) {
$(this).find('.btn').toggleClass('btn-primary'); $(this).find('.btn').toggleClass('btn-primary');
@@ -760,6 +761,19 @@ angular.module('AWDirectives', ['RestServices', 'Utilities', 'AuthService', 'Job
$(this).find('.btn').toggleClass('btn-info'); $(this).find('.btn').toggleClass('btn-info');
} }
$(this).find('.btn').toggleClass('btn-default'); $(this).find('.btn').toggleClass('btn-default');
// Add data-after-toggle="functionName" to the btn-group, and we'll
// execute here. The newly active choice is passed as a parameter.
if ($(this).attr('data-after-toggle')) {
next = $(this).attr('data-after-toggle');
choice = $(this).find('.active').text();
setTimeout(function() {
scope.$apply(function() {
scope[next](choice);
});
});
}
}); });
}; };
}]); }]);

View File

@@ -52,7 +52,9 @@
</div> </div>
</div> </div>
<div id="plays-table-detail" aw-custom-scroll class="table-detail"> <div id="plays-table-detail" aw-custom-scroll class="table-detail">
<div class="row cursor-pointer" ng-repeat="play in plays | FilterById : search_all_plays " ng-class="play.playActiveClass" ng-click="selectPlay(play.id)"> <div class="row cursor-pointer"
ng-repeat="play in plays | FilterById : search_all_plays | filter:{ status : searchAllStatus}"
ng-class="play.playActiveClass" ng-click="selectPlay(play.id)">
<div class="col-lg-1 col-md-1 col-sm-2 hidden-xs">{{ play.created | date: 'HH:mm:ss' }}</div> <div class="col-lg-1 col-md-1 col-sm-2 hidden-xs">{{ play.created | date: 'HH:mm:ss' }}</div>
<div class="col-lg-1 col-md-1 hidden-sm hidden-xs" aw-tool-tip="Completed at {{ play.finished | date:'HH:mm:ss' }}" <div class="col-lg-1 col-md-1 hidden-sm hidden-xs" aw-tool-tip="Completed at {{ play.finished | date:'HH:mm:ss' }}"
data-placement="top">{{ play.elapsed }} data-placement="top">{{ play.elapsed }}
@@ -76,7 +78,7 @@
</div> </div>
</div> </div>
<div id="tasks-table-detail" aw-custom-scroll class="table-detail"> <div id="tasks-table-detail" aw-custom-scroll class="table-detail">
<div class="row cursor-pointer" ng-repeat="task in taskList = (tasks | FilterById : search_all_tasks | filter:{ play_id: activePlay })" ng-class="task.taskActiveClass" <div class="row cursor-pointer" ng-repeat="task in taskList = (tasks | FilterById : search_all_tasks | filter:{ status : searchAllStatus} | filter:{ play_id: activePlay })" ng-class="task.taskActiveClass"
ng-click="selectTask(task.id)"> ng-click="selectTask(task.id)">
<div class="col-lg-1 col-md-1 col-sm-2 hidden-xs">{{ task.created | date: 'HH:mm:ss' }}</div> <div class="col-lg-1 col-md-1 col-sm-2 hidden-xs">{{ task.created | date: 'HH:mm:ss' }}</div>
<div class="col-lg-1 col-md-1 hidden-sm hidden-xs" aw-tool-tip="Completed at {{ task.finished | date:'HH:mm:ss' }}" <div class="col-lg-1 col-md-1 hidden-sm hidden-xs" aw-tool-tip="Completed at {{ task.finished | date:'HH:mm:ss' }}"
@@ -87,7 +89,7 @@
<i class="fa icon-job-{{ task.status }}"></i><span ng-show="hasRoles"> {{ task.role }} </span> {{ task.name }} <i class="fa icon-job-{{ task.status }}"></i><span ng-show="hasRoles"> {{ task.role }} </span> {{ task.name }}
</div> </div>
<div class="col-lg-5 col-md-5 hidden-sm hidden-xs"> <div class="col-lg-5 col-md-5 hidden-sm hidden-xs">
<div class="status-bar"><div class="successful-hosts inner-bar" id="{{ task.id }}-{{ task.play_id }}-successful-bar" aw-tool-tip="{{ task.successfulCount}} hosts OK" aw-tip-watch="task.successfulCount" data-placement="top" ng-style="task.successfulStyle">{{ task.successfulCount }}</div><div class="changed-hosts inner-bar" id="{{ task.id }}-{{ task.play_id }}-changed-bar" aw-tool-tip="{{ task.changedCount}} hosts changed" aw-tip-watch="task.changedCount" data-placement="top" ng-style="task.changedStyle">{{ task.changedCount }}</div><div class="skipped-hosts inner-bar" id="{{ task.id }}-{{ task.play_id }}-skipped-bar" aw-tool-tip="{{ task.skippedCount}} hosts skipped" aw-tip-watch="task.skippedCount" data-placement="top" ng-style="task.skippedStyle">{{ task.skippedCount }}</div><div class="failed-hosts inner-bar" id="{{ task.id }}-{{ task.play_id }}-failed-bar" aw-tool-tip="{{ task.failedCount}} hosts failed" aw-tip-watch="task.failedCount" data-placement="top" ng-style="task.failedStyle">{{ task.failedCount }}</div><div class="no-matching-hosts inner-bar" id="{{ task.id }}-{{ task.play_id }}-no-matching-hosts-bar" aw-tool-tip="No matching hosts were found" data-placement="top" style="width: 100%;" ng-show="task.status === 'no-m atching-hosts'">No matching hosts</div></div> <div class="status-bar"><div class="successful-hosts inner-bar" id="{{ task.id }}-{{ task.play_id }}-successful-bar" aw-tool-tip="Hosts OK" data-placement="top" ng-style="task.successfulStyle">{{ task.successfulCount }}</div><div class="changed-hosts inner-bar" id="{{ task.id }}-{{ task.play_id }}-changed-bar" aw-tool-tip="Hosts Changed" data-placement="top" ng-style="task.changedStyle">{{ task.changedCount }}</div><div class="skipped-hosts inner-bar" id="{{ task.id }}-{{ task.play_id }}-skipped-bar" aw-tool-tip="Hosts Skipped" data-placement="top" ng-style="task.skippedStyle">{{ task.skippedCount }}</div><div class="failed-hosts inner-bar" id="{{ task.id }}-{{ task.play_id }}-failed-bar" aw-tool-tip="Hosts Failed" data-placement="top" ng-style="task.failedStyle">{{ task.failedCount }}</div><div class="no-matching-hosts inner-bar" id="{{ task.id }}-{{ task.play_id }}-no-matching-hosts-bar" aw-tool-tip="No matching hosts were found" data-placement="top" style="width: 100%;" ng-show="task.status === 'no-m atching-hosts'">No matching hosts</div></div>
</div> </div>
</div> </div>
<div class="row" ng-show="taskList.length === 0"> <div class="row" ng-show="taskList.length === 0">
@@ -110,7 +112,7 @@
<div id="hosts-table-detail" aw-custom-scroll data-on-total-scroll="HostDetailOnTotalScroll" <div id="hosts-table-detail" aw-custom-scroll data-on-total-scroll="HostDetailOnTotalScroll"
data-on-total-scroll-back="HostDetailOnTotalScrollBack" class="table-detail"> data-on-total-scroll-back="HostDetailOnTotalScrollBack" class="table-detail">
<div id="hosts-table-detail-inner"> <div id="hosts-table-detail-inner">
<div class="row" ng-repeat="result in results = (hostResults | filter:{ task_id: activeTask })"> <div class="row" ng-repeat="result in results = (hostResults | filter:{ status : searchAllStatus} | filter:{ task_id: activeTask })">
<div class="col-lg-7 col-md-7 col-sm-7 col-xs-7 status-column"> <div class="col-lg-7 col-md-7 col-sm-7 col-xs-7 status-column">
<a href="" ng-click="doSomething()" aw-tool-tip="Event Id: {{ result.id }} Status: {{ result.status }}. Click for details" data-placement="top"><i class="fa icon-job-{{ result.status }}"></i> {{ result.name }}</a> <a href="" ng-click="doSomething()" aw-tool-tip="Event Id: {{ result.id }} Status: {{ result.status }}. Click for details" data-placement="top"><i class="fa icon-job-{{ result.status }}"></i> {{ result.name }}</a>
</div> </div>
@@ -157,9 +159,9 @@
<div class="col-lg-4 col-md-4 col-sm-4 col-xs-4"> <div class="col-lg-4 col-md-4 col-sm-4 col-xs-4">
<div style="padding-top: 5px;"> <div style="padding-top: 5px;">
<label class="small-label">Show</label> <label class="small-label">Show</label>
<div class="btn-group" aw-toggle-button> <div class="btn-group" aw-toggle-button data-after-toggle="filterByStatus">
<button class="btn btn-xs btn-default">All</button> <button class="btn btn-xs btn-primary active">All</button>
<button class="btn btn-xs btn-primary active">Failures</button> <button class="btn btn-xs btn-default">Failed</button>
</div> </div>
</div> </div>
</div> </div>
@@ -169,14 +171,9 @@
<div id="hosts-summary-section" class="section job_summary"> <div id="hosts-summary-section" class="section job_summary">
<div class="header"> <div class="header">
<div class="title">Host Summary</div> <div class="title">Host Summary</div>
<div class="search-field"> <div class="legend pull-right"><i class="fa fa-circle successful-hosts-color"></i> Successful <i class="fa fa-circle changed-hosts-color"></i> Changed
<!-- <input type="text" ng-model="summary_host_name" placeholder="Host Name" ng-keypress="summaryHostNameKeyPress($event)" />
<a class="search-icon" ng-show="searchSummaryHostsEnabled" ng-click="searchSummaryHosts()"><i class="fa fa-search"></i></a>
<a class="search-icon" ng-show="!searchSummaryHostsEnabled" ng-click="summary_host_name=''; searchSummaryHosts()"><i class="fa fa-times"></i></a> -->
</div>
</div>
<div class="legend"><i class="fa fa-circle successful-hosts-color"></i> Successful <i class="fa fa-circle changed-hosts-color"></i> Changed
<i class="fa fa-circle unreachable-hosts-color"></i> Unreachable <i class="fa fa-circle failed-hosts-color"></i> Failed</div> <i class="fa fa-circle unreachable-hosts-color"></i> Unreachable <i class="fa fa-circle failed-hosts-color"></i> Failed</div>
</div>
<div class="table-header"> <div class="table-header">
<div class="row"> <div class="row">
<div class="col-lg-6 col-md-6 col-sm-6 col-xs-6">Host</div> <div class="col-lg-6 col-md-6 col-sm-6 col-xs-6">Host</div>
@@ -209,7 +206,7 @@
<div id="graph-section" class="section"> <div id="graph-section" class="section">
<div class="header"> <div class="header">
<div class="title">Host Status Summary</div> <div class="title">Host Status Summary</div>
<div class="legend" style="display: none;"><i class="fa fa-circle successful-hosts-color"></i> Successful <i class="fa fa-circle changed-hosts-color"></i> Changed <div class="legend pull-right" style="display: none;"><i class="fa fa-circle successful-hosts-color"></i> Successful <i class="fa fa-circle changed-hosts-color"></i> Changed
<i class="fa fa-circle unreachable-hosts-color"></i> Unreachable <i class="fa fa-circle failed-hosts-color"></i> Failed</div> <i class="fa fa-circle unreachable-hosts-color"></i> Unreachable <i class="fa fa-circle failed-hosts-color"></i> Failed</div>
</div> </div>
</div><!-- graph section --> </div><!-- graph section -->