mirror of
https://github.com/ansible/awx.git
synced 2026-03-21 10:57:36 -02:30
Latest job detail page changes. Fixed lookup modal horizontal scroll.
This commit is contained in:
@@ -23,6 +23,8 @@ function JobDetailController ($scope, $compile, $routeParams, ClearScope, Breadc
|
|||||||
|
|
||||||
$scope.plays = [];
|
$scope.plays = [];
|
||||||
$scope.tasks = [];
|
$scope.tasks = [];
|
||||||
|
$scope.hosts = [];
|
||||||
|
$scope.hostResults = [];
|
||||||
|
|
||||||
// Apply each event to the view
|
// Apply each event to the view
|
||||||
if ($scope.removeEventsReady) {
|
if ($scope.removeEventsReady) {
|
||||||
|
|||||||
@@ -39,7 +39,8 @@
|
|||||||
|
|
||||||
angular.module('JobDetailHelper', ['Utilities', 'RestServices'])
|
angular.module('JobDetailHelper', ['Utilities', 'RestServices'])
|
||||||
|
|
||||||
.factory('DigestEvents', ['UpdatePlayStatus', 'UpdatePlayNoHostsMatched', function(UpdatePlayStatus, UpdatePlayNoHostsMatched) {
|
.factory('DigestEvents', ['UpdatePlayStatus', 'UpdatePlayNoHostsMatched', 'UpdateHostStatus', 'UpdatePlayChild', 'AddHostResult',
|
||||||
|
function(UpdatePlayStatus, UpdatePlayNoHostsMatched, UpdateHostStatus, UpdatePlayChild, AddHostResult) {
|
||||||
return function(params) {
|
return function(params) {
|
||||||
var scope = params.scope,
|
var scope = params.scope,
|
||||||
events = params.events;
|
events = params.events;
|
||||||
@@ -48,8 +49,22 @@ angular.module('JobDetailHelper', ['Utilities', 'RestServices'])
|
|||||||
scope.plays.push({
|
scope.plays.push({
|
||||||
id: event.id,
|
id: event.id,
|
||||||
name: event.play,
|
name: event.play,
|
||||||
|
status: (event.failed) ? 'failed' : 'successful',
|
||||||
|
children: []
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (event.event === 'playbook_on_setup') {
|
||||||
|
scope.tasks.push({
|
||||||
|
id: event.id,
|
||||||
|
name: event.event_display,
|
||||||
|
play_id: event.parent,
|
||||||
status: (event.failed) ? 'failed' : 'successful'
|
status: (event.failed) ? 'failed' : 'successful'
|
||||||
});
|
});
|
||||||
|
UpdatePlayStatus({
|
||||||
|
scope: scope,
|
||||||
|
play_id: event.parent,
|
||||||
|
failed: event.failed
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if (event.event === 'playbook_on_task_start') {
|
if (event.event === 'playbook_on_task_start') {
|
||||||
scope.tasks.push({
|
scope.tasks.push({
|
||||||
@@ -58,18 +73,68 @@ angular.module('JobDetailHelper', ['Utilities', 'RestServices'])
|
|||||||
play_id: event.parent,
|
play_id: event.parent,
|
||||||
status: (event.failed) ? 'failed' : 'successful'
|
status: (event.failed) ? 'failed' : 'successful'
|
||||||
});
|
});
|
||||||
UpdatePlayStatus({ scope: scope, play_id: event.parent, status: event.status });
|
UpdatePlayStatus({
|
||||||
|
scope: scope,
|
||||||
|
play_id: event.parent,
|
||||||
|
failed: event.failed
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if (event.event === 'playbook_on_no_hosts_matched') {
|
if (event.event === 'playbook_on_no_hosts_matched') {
|
||||||
UpdatePlayNoHostsMatched({ scope: scope, play_id: event.parent });
|
UpdatePlayNoHostsMatched({ scope: scope, play_id: event.parent });
|
||||||
}
|
}
|
||||||
if (event.event === 'runner_on_failed') {
|
if (event.event === 'runner_on_failed') {
|
||||||
|
|
||||||
|
}
|
||||||
|
if (event.event === 'runner_on_ok') {
|
||||||
|
UpdateHostStatus({
|
||||||
|
scope: scope,
|
||||||
|
name: event.event_data.host,
|
||||||
|
host_id: event.host_id,
|
||||||
|
task_id: event.parent,
|
||||||
|
status: (event.changed) ? 'changed' : 'ok',
|
||||||
|
results: (event.res && event.res.results) ? event.res.results : ''
|
||||||
|
});
|
||||||
|
AddHostResult({
|
||||||
|
scope: scope,
|
||||||
|
event: event
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if (event.event === 'playbook_on_stats') {
|
if (event.event === 'playbook_on_stats') {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}])
|
||||||
|
|
||||||
|
.factory('UpdatePlayChild', [ function() {
|
||||||
|
return function(params) {
|
||||||
|
var scope = params.scope,
|
||||||
|
id = params.id,
|
||||||
|
play_id = params.play_id,
|
||||||
|
failed = params.failed,
|
||||||
|
name = params.name,
|
||||||
|
found_child = false;
|
||||||
|
scope.plays.every(function(play, i) {
|
||||||
|
if (play.id === play_id) {
|
||||||
|
scope.plays[i].children.every(function(child, j) {
|
||||||
|
if (child.id === id) {
|
||||||
|
scope.plays[i].children[j].status = (failed) ? 'failed' : 'successful';
|
||||||
|
found_child = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
if (!found_child) {
|
||||||
|
scope.plays[i].children.push({
|
||||||
|
id: id,
|
||||||
|
name: name,
|
||||||
|
status: (failed) ? 'failed' : 'successful'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
scope.plays[i].status = (failed) ? 'failed' : 'successful';
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
}])
|
}])
|
||||||
@@ -78,11 +143,11 @@ angular.module('JobDetailHelper', ['Utilities', 'RestServices'])
|
|||||||
.factory('UpdatePlayStatus', [ function() {
|
.factory('UpdatePlayStatus', [ function() {
|
||||||
return function(params) {
|
return function(params) {
|
||||||
var scope = params.scope,
|
var scope = params.scope,
|
||||||
status = params.status,
|
failed = params.failed,
|
||||||
id = params.play_id;
|
id = params.play_id;
|
||||||
scope.plays.every(function(play,idx) {
|
scope.plays.every(function(play,idx) {
|
||||||
if (play.id === id) {
|
if (play.id === id) {
|
||||||
scope.plays[idx].status = (status) ? 'failed' : 'successful';
|
scope.plays[idx].status = (failed) ? 'failed' : 'successful';
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -90,6 +155,19 @@ angular.module('JobDetailHelper', ['Utilities', 'RestServices'])
|
|||||||
};
|
};
|
||||||
}])
|
}])
|
||||||
|
|
||||||
|
.factory('UpdateTaskStatus', [ function() {
|
||||||
|
return function(params) {
|
||||||
|
var scope = params.scope,
|
||||||
|
task_id = params.task_id,
|
||||||
|
failed = params.failed;
|
||||||
|
scope.tasks.every(function (task, i) {
|
||||||
|
if (task.id === task_id) {
|
||||||
|
scope.tasks[i].status = (failed) ? 'failed' : 'successful';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}])
|
||||||
|
|
||||||
.factory('UpdatePlayNoHostsMatched', [ function() {
|
.factory('UpdatePlayNoHostsMatched', [ function() {
|
||||||
return function(params) {
|
return function(params) {
|
||||||
var scope = params.scope,
|
var scope = params.scope,
|
||||||
@@ -102,6 +180,90 @@ angular.module('JobDetailHelper', ['Utilities', 'RestServices'])
|
|||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
}])
|
||||||
|
|
||||||
|
// Update or add a new host
|
||||||
|
.factory('UpdateHostStatus', ['UpdateTaskStatus', function(UpdateTaskStatus) {
|
||||||
|
return function(params) {
|
||||||
|
var scope = params.scope,
|
||||||
|
status = params.status, // ok, changed, unreachable, failed
|
||||||
|
name = params.name,
|
||||||
|
host_id = params.host_id,
|
||||||
|
task_id = params.task_id,
|
||||||
|
host_found = false;
|
||||||
|
scope.hosts.every(function(host, i) {
|
||||||
|
if (host.id === host_id) {
|
||||||
|
scope.hosts[i].ok += (status === 'ok' || status === 'changed') ? 1 : 0;
|
||||||
|
scope.hosts[i].changed += (status === 'changed') ? 1 : 0;
|
||||||
|
scope.hosts[i].unreachable += (status === 'unreachable') ? 1 : 0;
|
||||||
|
scope.hosts[i].failed += (status === 'failed') ? 1 : 0;
|
||||||
|
host_found = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
if (!host_found) {
|
||||||
|
scope.hosts.push({
|
||||||
|
id: host_id,
|
||||||
|
name: name,
|
||||||
|
ok: (status === 'ok' || status === 'changed') ? 1 : 0,
|
||||||
|
changed: (status === 'changed') ? 1 : 0,
|
||||||
|
unreachable: (status === 'unreachable') ? 1 : 0,
|
||||||
|
failed: (status === 'failed') ? 1 : 0
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark task failed
|
||||||
|
if (status === 'failed') {
|
||||||
|
UpdateTaskStatus({
|
||||||
|
scope: scope,
|
||||||
|
task_id: task_id,
|
||||||
|
failed: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}])
|
||||||
|
|
||||||
|
// Add a new host result
|
||||||
|
.factory('AddHostResult', ['Empty', function(Empty) {
|
||||||
|
return function(params) {
|
||||||
|
var scope = params.scope,
|
||||||
|
event = params.event,
|
||||||
|
id, status, host_id, play_name, task_name, module_name, module_args,
|
||||||
|
results, rc;
|
||||||
|
|
||||||
|
id = event.id;
|
||||||
|
status = (event.failed) ? 'failed' : (event.changed) ? 'changed' : 'successful';
|
||||||
|
host_id = event.host;
|
||||||
|
play_name = event.play;
|
||||||
|
task_name = event.task;
|
||||||
|
if (event.event_data.res && event.event_data.res.invocation) {
|
||||||
|
module_name = event.event_data.res.invocation.module_name;
|
||||||
|
module_args = event.event_data.res.invocation.module_args;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
module_name = '';
|
||||||
|
module_args = '';
|
||||||
|
}
|
||||||
|
if (event.event_data.res && event.event_data.res.results) {
|
||||||
|
results = '';
|
||||||
|
event.event_data.res.results.forEach(function(row) {
|
||||||
|
results += row;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
rc = (event.event_data.res && !Empty(event.event_data.res.rc)) ? event.event_data.res.rc : '';
|
||||||
|
scope.hostResults.push({
|
||||||
|
id: id,
|
||||||
|
status: status,
|
||||||
|
host_id: host_id,
|
||||||
|
play_name: play_name,
|
||||||
|
task_name : task_name,
|
||||||
|
module_name: module_name,
|
||||||
|
module_args: module_args,
|
||||||
|
results: results,
|
||||||
|
rc: rc
|
||||||
|
});
|
||||||
|
};
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -658,9 +658,12 @@ legend {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#lookup-modal-dialog .instructions {
|
#lookup-modal-dialog
|
||||||
margin-top: 0;
|
overflow-x: hidden;
|
||||||
margin-bottom: 20px;
|
.instructions {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.related-footer {
|
.related-footer {
|
||||||
@@ -1576,15 +1579,71 @@ tr td button i {
|
|||||||
|
|
||||||
/* New job detail page */
|
/* New job detail page */
|
||||||
|
|
||||||
.job-detail-tables {
|
.relative-position {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.job-detail-tables, .job_options {
|
||||||
|
.table {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
.table>tbody>tr>td {
|
.table>tbody>tr>td {
|
||||||
border-top-color: #fff;
|
border-top-color: #fff;
|
||||||
|
padding: 0;
|
||||||
}
|
}
|
||||||
.table>thead>tr>th {
|
.table>thead>tr>th {
|
||||||
border-bottom-color: #fff;
|
border-bottom-color: #fff;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
ul {
|
||||||
|
list-style-type: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
li ul {
|
||||||
|
margin-left: 20px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.job_well {
|
||||||
|
padding: 8px;
|
||||||
|
background-color: @well;
|
||||||
|
border: 1px solid @well-border;
|
||||||
|
border-radius: 4px;
|
||||||
|
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);
|
||||||
|
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.job_options {
|
||||||
|
height: 100px;
|
||||||
|
overflow-y: auto;
|
||||||
|
overflow-x: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll-up-indicator {
|
||||||
|
position: absolute;
|
||||||
|
right: 18px;
|
||||||
|
font-size: 14px;
|
||||||
|
bottom: -2px;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll-down-indicator {
|
||||||
|
position: absolute;
|
||||||
|
right: 18px;
|
||||||
|
bottom: -2px;
|
||||||
|
font-size: 14px;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll-up-indicator,
|
||||||
|
.scroll-up-indicator:hover,
|
||||||
|
.scroll-up-indicator:visited,
|
||||||
|
.scroll-down-indicator,
|
||||||
|
.scroll-down-indicator:hover,
|
||||||
|
.scroll-down-indicator:visited {
|
||||||
|
color: @grey;
|
||||||
|
}
|
||||||
|
|
||||||
/* ng-cloak directive */
|
/* ng-cloak directive */
|
||||||
|
|
||||||
|
|||||||
@@ -696,6 +696,51 @@ angular.module('AWDirectives', ['RestServices', 'Utilities', 'AuthService', 'Job
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
}])
|
||||||
|
|
||||||
|
.directive('awScrollDown', [ function() {
|
||||||
|
return function(scope, element, attrs) {
|
||||||
|
var element_to_scroll = attrs.awScrollDown, elem;
|
||||||
|
$(element).on('click', function() {
|
||||||
|
var height = document.getElementById(element_to_scroll).scrollHeight;
|
||||||
|
$(element).hide();
|
||||||
|
$('#' + element_to_scroll).animate({scrollTop:height}, 800);
|
||||||
|
});
|
||||||
|
elem = document.getElementById(element_to_scroll);
|
||||||
|
$('#' + element_to_scroll).on('scroll', function() {
|
||||||
|
if (elem.scrollTop > 0 && $(element).is(':visible')) {
|
||||||
|
$(element).hide();
|
||||||
|
}
|
||||||
|
else if (elem.scrollTop === 0 && !$(element).is(':visible')) {
|
||||||
|
$(element).fadeIn(2500);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (elem.scrollTop > 0 && $(element).is(':visible')) {
|
||||||
|
$(element).hide();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}])
|
||||||
|
|
||||||
|
.directive('awScrollUp', [ function() {
|
||||||
|
return function(scope, element, attrs) {
|
||||||
|
var element_to_scroll = attrs.awScrollUp, elem;
|
||||||
|
$(element).on('click', function() {
|
||||||
|
$(element).hide();
|
||||||
|
$('#' + element_to_scroll).animate({scrollTop:0}, 'slow');
|
||||||
|
});
|
||||||
|
elem = document.getElementById(element_to_scroll);
|
||||||
|
$('#' + element_to_scroll).on('scroll', function() {
|
||||||
|
if (elem.scrollTop === 0 && $(element).is(':visible')) {
|
||||||
|
$(element).hide();
|
||||||
|
}
|
||||||
|
else if (elem.scrollTop > 0 && !$(element).is(':visible')) {
|
||||||
|
$(element).fadeIn(2500);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (elem.scrollTop === 0) {
|
||||||
|
$(element).hide();
|
||||||
|
}
|
||||||
|
};
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<h4>Job Options</h4>
|
<h5>Options</h5>
|
||||||
<div class="job_options">
|
<div class="job_options job_well" id="job_options">
|
||||||
<table class="table table-condensed">
|
<table class="table table-condensed">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr ng-show="job_template_url">
|
<tr ng-show="job_template_url">
|
||||||
@@ -52,29 +52,27 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
<a id="job_options_scroll_down_indicator" href="" aw-scroll-down="job_options" class="scroll-down-indicator">more <i class="fa fa-chevron-circle-down"></i></a>
|
||||||
|
<a id="job_options_scroll_up_indicator" href="" aw-scroll-up="job_options" class="scroll-up-indicator">more <i class="fa fa-chevron-circle-up"></i></a>
|
||||||
</div>
|
</div>
|
||||||
</div><!-- row -->
|
</div><!-- row -->
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-6 job-detail-tables">
|
<div class="col-md-6 job-detail-tables">
|
||||||
|
|
||||||
<h4>Plays</h4>
|
<h5>Plays</h5>
|
||||||
<div class="job_plays">
|
<div class="job_plays job_well">
|
||||||
<table class="table table-condensed job-detail-table">
|
<ul>
|
||||||
<thead>
|
<li ng-repeat="play in plays">
|
||||||
<tr>
|
<i class="fa icon-job-{{ play.status }}"></i> {{play.name }}
|
||||||
<th class="col-md-1">Status</th>
|
<ul ng-show="play.children.length > 0">
|
||||||
<th>Name</th>
|
<li ng-repeat="child in play.children">
|
||||||
</tr>
|
<i class="fa icon-job-{{ child.status }}"></i> {{child.name }}
|
||||||
</thead>
|
</li>
|
||||||
<tbody>
|
</ul>
|
||||||
<tr ng-repeat="play in plays">
|
</li>
|
||||||
<td><i class="fa icon-job-{{ play.status }}"></i></td>
|
</ul>
|
||||||
<td>{{ play.name }}</td>
|
|
||||||
<td>{{ play.state }}</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h4>Tasks</h4>
|
<h4>Tasks</h4>
|
||||||
@@ -90,7 +88,6 @@
|
|||||||
<tr ng-repeat="task in tasks">
|
<tr ng-repeat="task in tasks">
|
||||||
<td><i class="fa icon-job-{{ task.status }}"></i></td>
|
<td><i class="fa icon-job-{{ task.status }}"></i></td>
|
||||||
<td>{{ task.name }}</td>
|
<td>{{ task.name }}</td>
|
||||||
<td>{{ task.state }}</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
@@ -101,22 +98,20 @@
|
|||||||
<table class="table table-condensed job-detail-table">
|
<table class="table table-condensed job-detail-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="col-md-1">Status</th>
|
|
||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
<th>OK</th>
|
<th class="text-center">OK</th>
|
||||||
<th>Changed</th>
|
<th class="text-center">Changed</th>
|
||||||
<th>Unreachable</th>
|
<th class="text-center">Unreachable</th>
|
||||||
<th>Failed</th>
|
<th class="text-center">Failed</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr ng-repeat="host in hosts">
|
<tr ng-repeat="host in hosts">
|
||||||
<td><i class="fa icon-job-{{ task.status }}"></i></td>
|
|
||||||
<td>{{ host.name }}</td>
|
<td>{{ host.name }}</td>
|
||||||
<td>{{ host.ok }}</td>
|
<td class="text-center">{{ host.ok }}</td>
|
||||||
<td>{{ host.changed }}</td>
|
<td class="text-center">{{ host.changed }}</td>
|
||||||
<td>{{ host.unreachable }}</td>
|
<td class="text-center">{{ host.unreachable }}</td>
|
||||||
<td>{{ host.failed }}</td>
|
<td class="text-center">{{ host.failed }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
@@ -127,17 +122,3 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user