Merge pull request #1246 from leigh-johnson/JobDetailService

Add JobDetailService, remove REST calls from JobDetail controller
This commit is contained in:
Leigh
2016-03-15 11:39:07 -04:00
5 changed files with 160 additions and 59 deletions

View File

@@ -1,5 +1,5 @@
/************************************************* /*************************************************
* Copyright (c) 2015 Ansible, Inc. * Copyright (c) 2016 Ansible, Inc.
* *
* All Rights Reserved * All Rights Reserved
*************************************************/ *************************************************/
@@ -12,23 +12,22 @@
export default export default
[ '$location', '$rootScope', '$filter', '$scope', '$compile', [ '$location', '$rootScope', '$filter', '$scope', '$compile',
'$stateParams', '$log', 'ClearScope', 'GetBasePath', 'Wait', 'Rest', '$stateParams', '$log', 'ClearScope', 'GetBasePath', 'Wait',
'ProcessErrors', 'SelectPlay', 'SelectTask', 'Socket', 'GetElapsed', 'ProcessErrors', 'SelectPlay', 'SelectTask', 'Socket', 'GetElapsed',
'DrawGraph', 'LoadHostSummary', 'ReloadHostSummaryList', 'DrawGraph', 'LoadHostSummary', 'ReloadHostSummaryList',
'JobIsFinished', 'SetTaskStyles', 'DigestEvent', 'UpdateDOM', 'JobIsFinished', 'SetTaskStyles', 'DigestEvent', 'UpdateDOM', 'DeleteJob', 'PlaybookRun', 'HostEventsViewer',
'EventViewer', 'DeleteJob', 'PlaybookRun', 'HostEventsViewer',
'LoadPlays', 'LoadTasks', 'LoadHosts', 'HostsEdit', 'LoadPlays', 'LoadTasks', 'LoadHosts', 'HostsEdit',
'ParseVariableString', 'GetChoices', 'fieldChoices', 'fieldLabels', 'ParseVariableString', 'GetChoices', 'fieldChoices', 'fieldLabels',
'EditSchedule', 'ParseTypeChange', 'EditSchedule', 'ParseTypeChange', 'JobDetailService', 'EventViewer',
function( function(
$location, $rootScope, $filter, $scope, $compile, $stateParams, $location, $rootScope, $filter, $scope, $compile, $stateParams,
$log, ClearScope, GetBasePath, Wait, Rest, ProcessErrors, $log, ClearScope, GetBasePath, Wait, ProcessErrors,
SelectPlay, SelectTask, Socket, GetElapsed, DrawGraph, SelectPlay, SelectTask, Socket, GetElapsed, DrawGraph,
LoadHostSummary, ReloadHostSummaryList, JobIsFinished, LoadHostSummary, ReloadHostSummaryList, JobIsFinished,
SetTaskStyles, DigestEvent, UpdateDOM, EventViewer, DeleteJob, SetTaskStyles, DigestEvent, UpdateDOM, DeleteJob,
PlaybookRun, HostEventsViewer, LoadPlays, LoadTasks, LoadHosts, PlaybookRun, HostEventsViewer, LoadPlays, LoadTasks, LoadHosts,
HostsEdit, ParseVariableString, GetChoices, fieldChoices, HostsEdit, ParseVariableString, GetChoices, fieldChoices,
fieldLabels, EditSchedule, ParseTypeChange fieldLabels, EditSchedule, ParseTypeChange, JobDetailService, EventViewer
) { ) {
ClearScope(); ClearScope();
@@ -283,15 +282,15 @@ export default
scope.removeInitialLoadComplete(); scope.removeInitialLoadComplete();
} }
scope.removeInitialLoadComplete = scope.$on('InitialLoadComplete', function() { scope.removeInitialLoadComplete = scope.$on('InitialLoadComplete', function() {
var url;
Wait('stop'); Wait('stop');
if (JobIsFinished(scope)) { if (JobIsFinished(scope)) {
scope.liveEventProcessing = false; // signal that event processing is over and endless scroll scope.liveEventProcessing = false; // signal that event processing is over and endless scroll
scope.pauseLiveEvents = false; // should be enabled scope.pauseLiveEvents = false; // should be enabled
url = scope.job.related.job_events + '?event=playbook_on_stats'; var params = {
Rest.setUrl(url); event: 'playbook_on_stats'
Rest.get() };
JobDetailService.getRelatedJobEvents(scope.job.id, params)
.success(function(data) { .success(function(data) {
if (data.results.length > 0) { if (data.results.length > 0) {
LoadHostSummary({ LoadHostSummary({
@@ -327,11 +326,11 @@ export default
} }
scope.removeHostSummaries = scope.$on('LoadHostSummaries', function() { scope.removeHostSummaries = scope.$on('LoadHostSummaries', function() {
if(scope.job){ if(scope.job){
var url = scope.job.related.job_host_summaries + '?'; var params = {
url += '&page_size=' + scope.hostSummariesMaxRows + '&order=host_name'; page_size: scope.hostSummariesMaxRows,
order: 'host_name'
Rest.setUrl(url); };
Rest.get() JobDetailService.getJobHostSummaries(scope.job.id, params)
.success(function(data) { .success(function(data) {
scope.next_host_summaries = data.next; scope.next_host_summaries = data.next;
if (data.results.length > 0) { if (data.results.length > 0) {
@@ -357,10 +356,6 @@ export default
}; };
}); });
scope.$emit('InitialLoadComplete'); scope.$emit('InitialLoadComplete');
})
.error(function(data, status) {
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
msg: 'Call to ' + url + '. GET returned: ' + status });
}); });
} }
@@ -373,17 +368,17 @@ export default
if (scope.activeTask) { if (scope.activeTask) {
var play = scope.jobData.plays[scope.activePlay], var play = scope.jobData.plays[scope.activePlay],
task, // = play.tasks[scope.activeTask], task;
url;
if(play){ if(play){
task = play.tasks[scope.activeTask]; task = play.tasks[scope.activeTask];
} }
if (play && task) { if (play && task) {
url = scope.job.related.job_events + '?parent=' + task.id + '&'; var params = {
url += 'event__startswith=runner&page_size=' + scope.hostResultsMaxRows + '&order=host_name,counter'; parent: task.id,
event__startswith: 'runner',
Rest.setUrl(url); page_size: scope.hostResultsMaxRows
Rest.get() };
JobDetailService.getRelatedJobEvents(scope.job.id, params)
.success(function(data) { .success(function(data) {
var idx, event, status, status_text, item, msg; var idx, event, status, status_text, item, msg;
if (data.results.length > 0) { if (data.results.length > 0) {
@@ -450,10 +445,6 @@ export default
} }
} }
scope.$emit('LoadHostSummaries'); scope.$emit('LoadHostSummaries');
})
.error(function(data, status) {
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
msg: 'Call to ' + url + '. GET returned: ' + status });
}); });
} else { } else {
scope.$emit('LoadHostSummaries'); scope.$emit('LoadHostSummaries');
@@ -468,14 +459,15 @@ export default
} }
scope.removeLoadTasks = scope.$on('LoadTasks', function() { scope.removeLoadTasks = scope.$on('LoadTasks', function() {
if (scope.activePlay) { if (scope.activePlay) {
var play = scope.jobData.plays[scope.activePlay], url; var play = scope.jobData.plays[scope.activePlay];
if (play) { if (play) {
url = scope.job.url + 'job_tasks/?event_id=' + play.id; var params = {
url += '&page_size=' + scope.tasksMaxRows + '&order=id'; event_id: play.id,
page_size: scope.tasksMaxRows,
Rest.setUrl(url); order: 'id'
Rest.get() }
JobDetailService.getJobTasks(scope.job.id, params)
.success(function(data) { .success(function(data) {
scope.next_tasks = data.next; scope.next_tasks = data.next;
if (data.results.length > 0) { if (data.results.length > 0) {
@@ -585,12 +577,10 @@ export default
scope.host_summary.failed = 0; scope.host_summary.failed = 0;
scope.host_summary.total = 0; scope.host_summary.total = 0;
scope.jobData.plays = {}; scope.jobData.plays = {};
var params = {
var url = scope.job.url + 'job_plays/?order_by=id'; order_by: 'id'
url += '&page_size=' + scope.playsMaxRows + '&order_by=id'; };
JobDetailService.getJobPlays(scope.job.id, params)
Rest.setUrl(url);
Rest.get()
.success( function(data) { .success( function(data) {
scope.next_plays = data.next; scope.next_plays = data.next;
if (data.results.length > 0) { if (data.results.length > 0) {
@@ -681,10 +671,6 @@ export default
scope.jobData.plays[scope.activePlay].playActiveClass = 'JobDetail-tableRow--selected'; scope.jobData.plays[scope.activePlay].playActiveClass = 'JobDetail-tableRow--selected';
} }
scope.$emit('LoadTasks', events_url); scope.$emit('LoadTasks', events_url);
})
.error( function(data, status) {
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
msg: 'Call to ' + url + '. GET returned: ' + status });
}); });
}); });
@@ -702,8 +688,7 @@ export default
scope.LoadHostSummaries = true; scope.LoadHostSummaries = true;
// Load the job record // Load the job record
Rest.setUrl(GetBasePath('jobs') + job_id + '/'); JobDetailService.getJob(job_id)
Rest.get()
.success(function(data) { .success(function(data) {
var i; var i;
scope.job = data; scope.job = data;
@@ -1177,8 +1162,7 @@ export default
if (((!scope.liveEventProcessing) || (scope.liveEventProcessing && scope.pauseLiveEvents)) && scope.next_plays) { if (((!scope.liveEventProcessing) || (scope.liveEventProcessing && scope.pauseLiveEvents)) && scope.next_plays) {
$('#playsMoreRows').fadeIn(); $('#playsMoreRows').fadeIn();
scope.playsLoading = true; scope.playsLoading = true;
Rest.setUrl(scope.next_plays); JobDetailService.getNextPage(scope.next_plays)
Rest.get()
.success( function(data) { .success( function(data) {
scope.next_plays = data.next; scope.next_plays = data.next;
data.results.forEach(function(event, idx) { data.results.forEach(function(event, idx) {
@@ -1243,8 +1227,7 @@ export default
if (((!scope.liveEventProcessing) || (scope.liveEventProcessing && scope.pauseLiveEvents)) && scope.next_tasks) { if (((!scope.liveEventProcessing) || (scope.liveEventProcessing && scope.pauseLiveEvents)) && scope.next_tasks) {
$('#tasksMoreRows').fadeIn(); $('#tasksMoreRows').fadeIn();
scope.tasksLoading = true; scope.tasksLoading = true;
Rest.setUrl(scope.next_tasks); JobDetailService.getNextPage(scope.next_tasks)
Rest.get()
.success(function(data) { .success(function(data) {
scope.next_tasks = data.next; scope.next_tasks = data.next;
data.results.forEach(function(event, idx) { data.results.forEach(function(event, idx) {
@@ -1315,8 +1298,7 @@ export default
if (((!scope.liveEventProcessing) || (scope.liveEventProcessing && scope.pauseLiveEvents)) && scope.next_host_results) { if (((!scope.liveEventProcessing) || (scope.liveEventProcessing && scope.pauseLiveEvents)) && scope.next_host_results) {
$('#hostResultsMoreRows').fadeIn(); $('#hostResultsMoreRows').fadeIn();
scope.hostResultsLoading = true; scope.hostResultsLoading = true;
Rest.setUrl(scope.next_host_results); JobDetailService.getNextPage(scope.next_host_results)
Rest.get()
.success(function(data) { .success(function(data) {
scope.next_host_results = data.next; scope.next_host_results = data.next;
data.results.forEach(function(row) { data.results.forEach(function(row) {
@@ -1387,8 +1369,7 @@ export default
// check for more hosts when user scrolls to bottom of host summaries list... // check for more hosts when user scrolls to bottom of host summaries list...
if (((!scope.liveEventProcessing) || (scope.liveEventProcessing && scope.pauseLiveEvents)) && scope.next_host_summaries) { if (((!scope.liveEventProcessing) || (scope.liveEventProcessing && scope.pauseLiveEvents)) && scope.next_host_summaries) {
scope.hostSummariesLoading = true; scope.hostSummariesLoading = true;
Rest.setUrl(scope.next_host_summaries); JobDetailService.getNextPage(scope.next_host_summaries)
Rest.get()
.success(function(data) { .success(function(data) {
scope.next_host_summaries = data.next; scope.next_host_summaries = data.next;
data.results.forEach(function(row) { data.results.forEach(function(row) {

View File

@@ -344,7 +344,7 @@
<table class="table"> <table class="table">
<tbody> <tbody>
<tr class="List-tableRow cursor-pointer" ng-class-odd="'List-tableRow--oddRow'" ng-class-even="'List-tableRow--evenRow'" ng-repeat="result in results = (hostResults) track by $index"> <tr class="List-tableRow cursor-pointer" ng-class-odd="'List-tableRow--oddRow'" ng-class-even="'List-tableRow--evenRow'" ng-repeat="result in results = (hostResults) track by $index">
<td class="List-tableCell col-lg-4 col-md-3 col-sm-3 col-xs-3 status-column"><a href="" ng-click="viewHostResults(result.id)" aw-tool-tip="Event ID: {{ result.id }}<br \>Status: {{ result.status_text }}. Click for details" data-placement="top"><i ng-show="result.status_text != 'Unreachable'" class="JobDetail-statusIcon fa icon-job-{{ result.status }}"></i><span ng-show="result.status_text != 'Unreachable'">{{ result.name }}</span><i ng-show="result.status_text == 'Unreachable'" class="JobDetail-statusIcon fa icon-job-unreachable"></i><span ng-show="result.status_text == 'Unreachable'">{{ result.name }}</span></a></td> <td class="List-tableCell col-lg-4 col-md-3 col-sm-3 col-xs-3 status-column"><a ng-click="viewHostResults(result.id)" aw-tool-tip="Event ID: {{ result.id }}<br \>Status: {{ result.status_text }}. Click for details" data-placement="top"><i ng-show="result.status_text != 'Unreachable'" class="JobDetail-statusIcon fa icon-job-{{ result.status }}"></i><span ng-show="result.status_text != 'Unreachable'">{{ result.name }}</span><i ng-show="result.status_text == 'Unreachable'" class="JobDetail-statusIcon fa icon-job-unreachable"></i><span ng-show="result.status_text == 'Unreachable'">{{ result.name }}</span></a></td>
<td class="List-tableCell col-lg-3 col-md-4 col-sm-3 col-xs-3 item-column">{{ result.item }}</td> <td class="List-tableCell col-lg-3 col-md-4 col-sm-3 col-xs-3 item-column">{{ result.item }}</td>
<td class="List-tableCell col-lg-3 col-md-4 col-sm-3 col-xs-3">{{ result.msg }}</td> <td class="List-tableCell col-lg-3 col-md-4 col-sm-3 col-xs-3">{{ result.msg }}</td>
</tr> </tr>

View File

@@ -0,0 +1,118 @@
export default
['$rootScope', 'Rest', 'GetBasePath', 'ProcessErrors', function($rootScope, Rest, GetBasePath, ProcessErrors){
return {
/*
For ES6
it might be useful to set some default params here, e.g.
getJobHostSummaries: function(id, page_size=200, order='host_name'){}
without ES6, we'd have to supply defaults like this:
this.page_size = params.page_size ? params.page_size : 200;
*/
// GET events related to a job run
// e.g.
// ?event=playbook_on_stats
// ?parent=206&event__startswith=runner&page_size=200&order=host_name,counter
getRelatedJobEvents: function(id, params){
var url = GetBasePath('jobs');
url = url + id + '/job_events/?';
Object.keys(params).forEach(function(key, index) {
// the API is tolerant of extra ampersands
// ?&event=playbook_on_start == ?event=playbook_on_stats
url = url + '&' + key + '=' + params[key];
});
Rest.setUrl(url);
return Rest.get()
.success(function(data){
return data
})
.error(function(data, status) {
ProcessErrors($rootScope, data, status, null, { hdr: 'Error!',
msg: 'Call to ' + url + '. GET returned: ' + status });
});
},
// GET job host summaries related to a job run
// e.g. ?page_size=200&order=host_name
getJobHostSummaries: function(id, params){
var url = GetBasePath('jobs');
url = url + id + '/job_host_summaries/?'
Object.keys(params).forEach(function(key, index) {
// the API is tolerant of extra ampersands
url = url + '&' + key + '=' + params[key];
});
Rest.setUrl(url);
return Rest.get()
.success(function(data){
return data
})
.error(function(data, status) {
ProcessErrors($rootScope, data, status, null, { hdr: 'Error!',
msg: 'Call to ' + url + '. GET returned: ' + status });
});
},
// GET job plays related to a job run
// e.g. ?page_size=200
getJobPlays: function(id, params){
var url = GetBasePath('jobs');
url = url + id + '/job_plays/?';
Object.keys(params).forEach(function(key, index) {
// the API is tolerant of extra ampersands
url = url + '&' + key + '=' + params[key];
});
Rest.setUrl(url);
return Rest.get()
.success(function(data){
return data
})
.error(function(data, status) {
ProcessErrors($rootScope, data, status, null, { hdr: 'Error!',
msg: 'Call to ' + url + '. GET returned: ' + status });
});
},
getJobTasks: function(id, params){
var url = GetBasePath('jobs');
url = url + id + '/job_tasks/?';
Object.keys(params).forEach(function(key, index) {
// the API is tolerant of extra ampersands
url = url + '&' + key + '=' + params[key];
});
Rest.setUrl(url);
return Rest.get()
.success(function(data){
return data
})
.error(function(data, status) {
ProcessErrors($rootScope, data, status, null, { hdr: 'Error!',
msg: 'Call to ' + url + '. GET returned: ' + status });
});
},
getJob: function(id){
var url = GetBasePath('jobs');
url = url + id;
Rest.setUrl(url);
return Rest.get()
.success(function(data){
return data
})
.error(function(data, status) {
ProcessErrors($rootScope, data, status, null, { hdr: 'Error!',
msg: 'Call to ' + url + '. GET returned: ' + status });
});
},
// GET next set of paginated results
// expects 'next' param returned by the API e.g.
// "/api/v1/jobs/51/job_plays/?order_by=id&page=2&page_size=1"
getNextPage: function(url){
return Rest.get()
.success(function(data){
return data
})
.error(function(data, status) {
ProcessErrors($rootScope, data, status, null, { hdr: 'Error!',
msg: 'Call to ' + url + '. GET returned: ' + status });
});
}
}
}
];

View File

@@ -6,10 +6,12 @@
import route from './job-detail.route'; import route from './job-detail.route';
import controller from './job-detail.controller'; import controller from './job-detail.controller';
import service from './job-detail.service';
export default export default
angular.module('jobDetail', []) angular.module('jobDetail', [])
.controller('JobDetailController', controller) .controller('JobDetailController', controller)
.service('JobDetailService', service)
.run(['$stateExtender', function($stateExtender) { .run(['$stateExtender', function($stateExtender) {
$stateExtender.addState(route); $stateExtender.addState(route);
}]); }]);