mirror of
https://github.com/ansible/awx.git
synced 2026-03-13 23:17:32 -02:30
Job Events collapse/expand now handled using a filter on ng-repeat and setting 'show' attribute in job_events data set. No longer reading child rows from api on expand and throwing them away on collapse. New method is much faster. Added formatJSON() routine back in to transform relevant event_data bits into html form elments and display in list.
This commit is contained in:
@@ -370,6 +370,10 @@
|
||||
color: #5bb75b;
|
||||
}
|
||||
|
||||
.job-changed {
|
||||
color: #FF9900;
|
||||
}
|
||||
|
||||
.job-detail-status {
|
||||
font-size: 15px;
|
||||
font-weight: bold;
|
||||
|
||||
@@ -19,7 +19,7 @@ function JobEventsList ($scope, $rootScope, $location, $log, $routeParams, Rest,
|
||||
var list = JobEventList;
|
||||
list.base = $location.path();
|
||||
|
||||
var defaultUrl = GetBasePath('jobs') + $routeParams.id + '/job_events/?parent__isnull=1';
|
||||
var defaultUrl = GetBasePath('jobs') + $routeParams.id + '/job_events/'; //?parent__isnull=1';
|
||||
|
||||
var view = GenerateList;
|
||||
var base = $location.path().replace(/^\//,'').split('/')[0];
|
||||
@@ -32,6 +32,47 @@ function JobEventsList ($scope, $rootScope, $location, $log, $routeParams, Rest,
|
||||
scope.parentNode = 'parent-event'; // used in ngClass to dynamicall set row level class and control
|
||||
scope.childNode = 'child-event'; // link color and cursor
|
||||
|
||||
function formatJSON(eventData) {
|
||||
//turn JSON event data into an html form
|
||||
var html = '';
|
||||
if (eventData.res) {
|
||||
var found = false;
|
||||
var n, rows;
|
||||
if (typeof eventData.res == 'string') {
|
||||
n = eventData['res'].match(/\n/g);
|
||||
rows = (n) ? n.length : 1;
|
||||
found = true;
|
||||
html += "<label>Traceback:</label>\n";
|
||||
html += "<textarea readonly class=\"input-xxlarge\" rows=\"" + rows + "\">" + eventData.res + "</textarea>\n";
|
||||
}
|
||||
else {
|
||||
for (var fld in eventData.res) {
|
||||
if ( (fld == 'msg' || fld == 'stdout' || fld == 'stderr') &&
|
||||
(eventData.res[fld] !== null && eventData.res[fld] !== '') ) {
|
||||
html += "<label>";
|
||||
switch(fld) {
|
||||
case 'msg':
|
||||
case 'stdout':
|
||||
html += 'Output:';
|
||||
break;
|
||||
case 'stderr':
|
||||
html += 'Error:';
|
||||
break;
|
||||
}
|
||||
html += "</label>\n";
|
||||
n = eventData['res'][fld].match(/\n/g);
|
||||
rows = (n) ? n.length : 1;
|
||||
html += "<textarea readonly class=\"input-xxlarge\" rows=\"" + rows + "\">" + eventData.res[fld] + "</textarea>\n";
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
html = (found) ? "<form class=\"event-detail\">\n" + html + "</form>\n" : '';
|
||||
}
|
||||
html = (html == '' ) ? null : html;
|
||||
return html;
|
||||
}
|
||||
|
||||
if (scope.RemovePostRefresh) {
|
||||
scope.RemovePostRefresh();
|
||||
}
|
||||
@@ -41,62 +82,35 @@ function JobEventsList ($scope, $rootScope, $location, $log, $routeParams, Rest,
|
||||
var cDate;
|
||||
for (var i=0; i < set.length; i++) {
|
||||
set[i].event_display = set[i].event_display.replace(/^\u00a0*/g,'');
|
||||
if (set[i].parent == null && set[i]['ngclick'] === undefined && set[i]['ngicon'] == undefined) {
|
||||
set[i].parent = 0;
|
||||
if (set[i].event_level < 3 ) {
|
||||
set[i]['ngclick'] = "toggleChildren(" + set[i].id + ", \"" + set[i].related.children + "\")";
|
||||
set[i]['ngicon'] = 'icon-expand-alt';
|
||||
set[i]['level'] = 0;
|
||||
set[i]['spaces'] = 0;
|
||||
set[i]['ngicon'] = 'icon-collapse-alt';
|
||||
set[i]['class'] = 'parentNode';
|
||||
}
|
||||
scope.jobevents[i].status = (scope.jobevents[i].failed) ? 'error' : 'success';
|
||||
else {
|
||||
set[i]['class'] = 'childNode';
|
||||
set[i]['event_detail'] = formatJSON(set[i].event_data);
|
||||
}
|
||||
set[i]['show'] = true;
|
||||
set[i]['spaces'] = set[i].event_level * 24;
|
||||
if (scope.jobevents[i].failed) {
|
||||
scope.jobevents[i].status = 'error';
|
||||
}
|
||||
else if (scope.jobevents[i].changed) {
|
||||
scope.jobevents[i].status = 'changed';
|
||||
}
|
||||
else {
|
||||
scope.jobevents[i].status = 'success';
|
||||
}
|
||||
cDate = new Date(set[i].created);
|
||||
set[i].created = FormatDate(cDate);
|
||||
}
|
||||
|
||||
// Expand all parent nodes
|
||||
if (scope.removeSetExpanded) {
|
||||
scope.removeSetExpanded();
|
||||
}
|
||||
scope.removeSetExpanded = scope.$on('setExpanded', function(event) {
|
||||
// After ToggleChildren completes, look for the next parent that needs to be expanded
|
||||
var found = false;
|
||||
for (var i=0; i < set.length && found == false && scope.expand; i++) {
|
||||
if (set[i]['related']['children'] && (set[i]['ngicon'] == undefined || set[i]['ngicon'] == 'icon-expand-alt')) {
|
||||
found = true;
|
||||
ToggleChildren({
|
||||
scope: scope,
|
||||
list: list,
|
||||
id: set[i].id,
|
||||
children: set[i]['related']['children']
|
||||
});
|
||||
}
|
||||
}
|
||||
if (found == false) {
|
||||
// After looping through all the nodes and finding nothing to expand, turn off
|
||||
// auto-expand. From now on user will manually collapse and expand nodes.
|
||||
scope.expand = false;
|
||||
}
|
||||
});
|
||||
// Start the auto expansion
|
||||
set = scope[list.name];
|
||||
for (var i=0; i < set.length; i++) {
|
||||
if (set[i]['related']['children'] && (set[i]['ngicon'] == undefined || set[i]['ngicon'] == 'icon-expand-alt')) {
|
||||
ToggleChildren({
|
||||
scope: scope,
|
||||
list: list,
|
||||
id: set[i].id,
|
||||
children: set[i]['related']['children']
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
SearchInit({ scope: scope, set: 'jobevents', list: list, url: defaultUrl });
|
||||
PaginateInit({ scope: scope, list: list, url: defaultUrl });
|
||||
|
||||
// Called from Inventories tab host failed events link:
|
||||
// Called from Inventories tab, host failed events link:
|
||||
if ($routeParams.host) {
|
||||
scope[list.iterator + 'SearchField'] = 'host';
|
||||
scope[list.iterator + 'SearchValue'] = $routeParams.host;
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
*
|
||||
* ChildrenHelper
|
||||
*
|
||||
* Used in job_events to expand/collapse children
|
||||
* Used in job_events to expand/collapse children by setting the
|
||||
* 'show' attribute of each job_event in the set of job_events.
|
||||
* See the filter in job_events.js list.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -18,37 +20,28 @@ angular.module('ChildrenHelper', ['RestServices', 'Utilities'])
|
||||
var children = params.children;
|
||||
var set = scope[list.name]; // set is now a pointer to scope[list.name]
|
||||
|
||||
function calcSpaces(lvl) {
|
||||
return lvl * 24;
|
||||
function expand(node) {
|
||||
set[node]['ngicon'] = 'icon-collapse-alt';
|
||||
for (var i = node + 1; i < set.length; i++) {
|
||||
if (set[i].parent == set[node].id) {
|
||||
set[i]['show'] = true;
|
||||
if (set[i].related.children) {
|
||||
expand(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function formatJSON(eventData) {
|
||||
//turn JSON event data into an html form
|
||||
var html = '';
|
||||
if (eventData.res) {
|
||||
var found = false;
|
||||
for (var fld in eventData.res) {
|
||||
if ( (fld == 'msg' || fld == 'stdout' || fld == 'stderr') &&
|
||||
(eventData.res[fld] !== null && eventData.res[fld] !== '') ) {
|
||||
html += "<label>";
|
||||
switch(fld) {
|
||||
case 'msg':
|
||||
case 'stdout':
|
||||
html += 'Output:';
|
||||
break;
|
||||
case 'stderr':
|
||||
html += 'Error:';
|
||||
break;
|
||||
}
|
||||
html += "</label>\n";
|
||||
html += "<textarea readonly class=\"input-xxlarge\">" + eventData.res[fld] + "</textarea>\n";
|
||||
found = true;
|
||||
}
|
||||
function collapse(node) {
|
||||
set[node]['ngicon'] = 'icon-expand-alt';
|
||||
for (var i = node + 1; i < set.length; i++) {
|
||||
if (set[i].parent == set[node].id) {
|
||||
set[i]['show'] = false;
|
||||
if (set[i]['related']['children']) {
|
||||
collapse(i);
|
||||
}
|
||||
}
|
||||
html = (found) ? "<form class=\"event-detail\">\n" + html + "</form>\n" : '';
|
||||
}
|
||||
html = (html == '' ) ? null : html;
|
||||
return html;
|
||||
}
|
||||
}
|
||||
|
||||
// Scan the array list and find the clicked element
|
||||
@@ -62,90 +55,11 @@ angular.module('ChildrenHelper', ['RestServices', 'Utilities'])
|
||||
}
|
||||
// Expand or collapse children based on clicked element's icon
|
||||
if (set[clicked]['ngicon'] == 'icon-expand-alt') {
|
||||
// Expand: lookup and display children
|
||||
var url = children;
|
||||
var search = scope[list.iterator + 'SearchParams'].replace(/^\&/,'').replace(/^\?/,'');
|
||||
url += (search) ? '?' + search : "";
|
||||
Rest.setUrl(url);
|
||||
Rest.get()
|
||||
.success( function(data, status, headers, config) {
|
||||
var found = false;
|
||||
var level = (set[clicked].level !== undefined) ? set[clicked].level + 1 : 1;
|
||||
var spaces = calcSpaces(level);
|
||||
set[clicked]['ngicon'] = 'icon-collapse-alt';
|
||||
for (var j=0; j < data.results.length; j++) {
|
||||
data.results[j].level = level;
|
||||
data.results[j].spaces = spaces;
|
||||
data.results[j].status = (data.results[j].failed) ? 'error' : 'success';
|
||||
data.results[j].event_display = data.results[j].event_display.replace(/^\u00a0*/g,'');
|
||||
cDate = new Date(data.results[j].created);
|
||||
data.results[j].created = FormatDate(cDate);
|
||||
if (data.results[j].related.children) {
|
||||
data.results[j]['ngclick'] = "toggleChildren(" + data.results[j].id + ", \"" + data.results[j].related.children + "\")";
|
||||
data.results[j]['ngicon'] = 'icon-expand-alt';
|
||||
data.results[j]['class'] = 'parentNode';
|
||||
}
|
||||
else {
|
||||
data.results[j]['class'] = 'childNode';
|
||||
// For child nodes, include some of the even_data detail, but in a nicer non-JSONy format
|
||||
data.results[j]['event_detail'] = formatJSON(data.results[j]['event_data']);
|
||||
}
|
||||
/*if (data.results[j]['event_data']['res'] && data.results[j]['event_data']['res']['msg']) {
|
||||
// Display the actual result message
|
||||
data.results[j]['event_display'] = data.results[j]['event_data']['res']['msg'];
|
||||
}
|
||||
if (data.results[j]['event'] == 'playbook_on_stats') {
|
||||
data.results[j]['event_display'] = 'Play Recap ****** ';
|
||||
for (var key in data.results[j]['event_data']) {
|
||||
var count = 0;
|
||||
for (var itm in data.results[j]['event_data'][key]) {
|
||||
count += data.results[j]['event_data'][key][itm];
|
||||
}
|
||||
data.results[j]['event_display'] += key + ": " + count + " ";
|
||||
}
|
||||
}
|
||||
*/
|
||||
if (clicked == (set.length - 1)) {
|
||||
set.push(data.results[j]);
|
||||
}
|
||||
else {
|
||||
set.splice(clicked + 1, 0, data.results[j]);
|
||||
}
|
||||
clicked++;
|
||||
}
|
||||
scope.$emit('setExpanded');
|
||||
})
|
||||
.error( function(data, status, headers, config) {
|
||||
ProcessErrors(scope, data, status, null,
|
||||
{ hdr: 'Error!', msg: 'Call to ' + children + ' failed. GET returned status: ' + status });
|
||||
});
|
||||
// Expand: lookup and display children
|
||||
expand(clicked);
|
||||
}
|
||||
else {
|
||||
// Collapse: find and remove children
|
||||
var parents = [];
|
||||
function findChildren(parent, idx) {
|
||||
// recursive look through the tree finding all
|
||||
// parents including and related the clicked element
|
||||
for (var i=idx; i < set.length; i++) {
|
||||
if (set[i].parent == parent) {
|
||||
parents.push(parent);
|
||||
findChildren(set[i].id, i + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
findChildren(id, clicked + 1);
|
||||
// Remove all the children of the clicked element
|
||||
var count;
|
||||
for (var i=0; i < parents.length; i++) {
|
||||
count = 0;
|
||||
for (var j=clicked + 1; j< set.length; j++) {
|
||||
if (set[j].parent == parents[i]) {
|
||||
set.splice(j,1);
|
||||
j=clicked; // start back a the top of the list
|
||||
}
|
||||
}
|
||||
}
|
||||
set[clicked]['ngicon'] = 'icon-expand-alt';
|
||||
collapse(clicked);
|
||||
}
|
||||
}
|
||||
}]);
|
||||
|
||||
@@ -16,6 +16,7 @@ angular.module('JobEventsListDefinition', [])
|
||||
index: false,
|
||||
hover: true,
|
||||
hasChildren: true,
|
||||
filterBy: '\{ show: true \}',
|
||||
|
||||
fields: {
|
||||
created: {
|
||||
|
||||
@@ -193,6 +193,7 @@ angular.module('ListGenerator', ['GeneratorHelpers'])
|
||||
html += (options.mode == 'lookup' || options.mode == 'select') ? "ng-class=\"" + list.iterator + "_\{\{ " + list.iterator + ".id \}\}_class\" " : "";
|
||||
html += "class=\"" + list.iterator + "_class\" ng-repeat=\"" + list.iterator + " in " + list.name;
|
||||
html += (list.orderBy) ? " | orderBy:'" + list.orderBy + "'" : "";
|
||||
html += (list.filterBy) ? " | filter: " + list.filterBy : "";
|
||||
html += "\"";
|
||||
html += (options.mode == 'lookup' || options.mode == 'select') ? " ng-click=\"toggle_" + list.iterator +"({{ " + list.iterator + ".id }})\"" : "";
|
||||
html += ">\n";
|
||||
|
||||
Reference in New Issue
Block a user