mirror of
https://github.com/ansible/awx.git
synced 2026-03-21 02:47:35 -02:30
Job stdout refactor
More infinite scrolling. Mostly seems to be working. However, we're not removing content, just continually adding as user scrolls back up.
This commit is contained in:
@@ -474,6 +474,10 @@ angular.module('Tower', [
|
|||||||
window.clearInterval($rootScope.jobDetailInterval);
|
window.clearInterval($rootScope.jobDetailInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($rootScope.jobStdOutInterval) {
|
||||||
|
window.clearInterval($rootScope.jobStdOutInterval);
|
||||||
|
}
|
||||||
|
|
||||||
// On each navigation request, check that the user is logged in
|
// On each navigation request, check that the user is logged in
|
||||||
if (!/^\/(login|logout)/.test($location.path())) {
|
if (!/^\/(login|logout)/.test($location.path())) {
|
||||||
// capture most recent URL, excluding login/logout
|
// capture most recent URL, excluding login/logout
|
||||||
|
|||||||
@@ -16,7 +16,12 @@ function JobStdoutController ($log, $rootScope, $scope, $compile, $routeParams,
|
|||||||
stdout_url,
|
stdout_url,
|
||||||
current_range,
|
current_range,
|
||||||
event_socket,
|
event_socket,
|
||||||
first_time=0;
|
first_time=0,
|
||||||
|
loaded_sections = [],
|
||||||
|
event_queue = 0,
|
||||||
|
auto_scroll_down=true,
|
||||||
|
live_event_processing = true,
|
||||||
|
page_size = 500;
|
||||||
|
|
||||||
event_socket = Socket({
|
event_socket = Socket({
|
||||||
scope: $scope,
|
scope: $scope,
|
||||||
@@ -29,25 +34,67 @@ function JobStdoutController ($log, $rootScope, $scope, $compile, $routeParams,
|
|||||||
|
|
||||||
event_socket.on("job_events-" + job_id, function() {
|
event_socket.on("job_events-" + job_id, function() {
|
||||||
if (api_complete) {
|
if (api_complete) {
|
||||||
$scope.$emit('LoadStdout');
|
event_queue++;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if ($rootScope.removeJobStatusChange) {
|
||||||
|
$rootScope.removeJobStatusChange();
|
||||||
|
}
|
||||||
|
$rootScope.removeJobStatusChange = $rootScope.$on('JobStatusChange', function(e, data) {
|
||||||
|
// if we receive a status change event for the current job indicating the job
|
||||||
|
// is finished, stop event queue processing and reload
|
||||||
|
if (parseInt(data.unified_job_id, 10) === parseInt(job_id,10)) {
|
||||||
|
$scope.job.status = data.status;
|
||||||
|
if (data.status === 'failed' || data.status === 'canceled' ||
|
||||||
|
data.status === 'error' || data.status === 'successful') {
|
||||||
|
if ($rootScope.jobStdOutInterval) {
|
||||||
|
window.clearInterval($rootScope.jobStdOutInterval);
|
||||||
|
}
|
||||||
|
if (live_event_processing) {
|
||||||
|
getNextSection();
|
||||||
|
}
|
||||||
|
live_event_processing = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$rootScope.jobStdOutInterval = setInterval( function() {
|
||||||
|
// limit the scrolling to every 5 seconds
|
||||||
|
$log.debug('checking for stdout...');
|
||||||
|
if (event_queue > 15) {
|
||||||
|
if (loaded_sections.length === 0) {
|
||||||
|
$log.debug('calling LoadStdout');
|
||||||
|
$scope.$emit('LoadStdout');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$log.debug('calling getNextSection');
|
||||||
|
getNextSection();
|
||||||
|
}
|
||||||
|
event_queue = 0;
|
||||||
|
}
|
||||||
|
}, 5000);
|
||||||
|
|
||||||
if ($scope.removeLoadStdout) {
|
if ($scope.removeLoadStdout) {
|
||||||
$scope.removeLoadStdout();
|
$scope.removeLoadStdout();
|
||||||
}
|
}
|
||||||
$scope.removeLoadStdout = $scope.$on('LoadStdout', function() {
|
$scope.removeLoadStdout = $scope.$on('LoadStdout', function() {
|
||||||
Rest.setUrl(stdout_url + '?format=json&start_line=-500');
|
Rest.setUrl(stdout_url + '?format=json&start_line=-' + page_size);
|
||||||
Rest.get()
|
Rest.get()
|
||||||
.success(function(data) {
|
.success(function(data) {
|
||||||
api_complete = true;
|
|
||||||
Wait('stop');
|
Wait('stop');
|
||||||
$('#pre-container-content').html(data.content);
|
if (data.content) {
|
||||||
current_range = data.range;
|
api_complete = true;
|
||||||
//$('#pre-container').mCustomScrollbar("update");
|
$('#pre-container-content').html(data.content);
|
||||||
setTimeout(function() {
|
current_range = data.range;
|
||||||
$('#pre-container').mCustomScrollbar("scrollTo", 'bottom');
|
loaded_sections.push(data.range.start);
|
||||||
}, 300);
|
setTimeout(function() {
|
||||||
|
$('#pre-container').mCustomScrollbar("scrollTo", "bottom");
|
||||||
|
}, 300);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
api_complete = true;
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.error(function(data, status) {
|
.error(function(data, status) {
|
||||||
ProcessErrors($scope, data, status, null, { hdr: 'Error!',
|
ProcessErrors($scope, data, status, null, { hdr: 'Error!',
|
||||||
@@ -56,7 +103,7 @@ function JobStdoutController ($log, $rootScope, $scope, $compile, $routeParams,
|
|||||||
});
|
});
|
||||||
|
|
||||||
function resizeToFit() {
|
function resizeToFit() {
|
||||||
available_height = $(window).height() - $('#main-menu-container .navbar').outerHeight() -
|
available_height = $(window).height() - $('#main-menu-container .navbar').outerHeight() - $('#job-status').outerHeight() -
|
||||||
$('#breadcrumb-container').outerHeight() - 20;
|
$('#breadcrumb-container').outerHeight() - 20;
|
||||||
$('#pre-container').height(available_height);
|
$('#pre-container').height(available_height);
|
||||||
$('#pre-container').mCustomScrollbar("update");
|
$('#pre-container').mCustomScrollbar("update");
|
||||||
@@ -72,6 +119,9 @@ function JobStdoutController ($log, $rootScope, $scope, $compile, $routeParams,
|
|||||||
.success(function(data) {
|
.success(function(data) {
|
||||||
$scope.job = data;
|
$scope.job = data;
|
||||||
stdout_url = data.related.stdout;
|
stdout_url = data.related.stdout;
|
||||||
|
if (data.status === 'successful' || data.status === 'failed' || data.status === 'error' || data.status === 'canceled') {
|
||||||
|
live_event_processing = false;
|
||||||
|
}
|
||||||
$scope.$emit('LoadStdout');
|
$scope.$emit('LoadStdout');
|
||||||
})
|
})
|
||||||
.error(function(data, status) {
|
.error(function(data, status) {
|
||||||
@@ -81,14 +131,39 @@ function JobStdoutController ($log, $rootScope, $scope, $compile, $routeParams,
|
|||||||
|
|
||||||
|
|
||||||
$scope.onTotalScroll = function() {
|
$scope.onTotalScroll = function() {
|
||||||
$log.debug('Total scroll!');
|
// scroll forward or into the future toward the end of the file
|
||||||
|
var start = current_range.end + 1, url;
|
||||||
|
if ((!live_event_processing) && (!auto_scroll_down) && loaded_sections.indexOf(start) < 0) {
|
||||||
|
url = stdout_url + '?format=json&start_line=' + start + '&end_line=' + (current_range.start + page_size);
|
||||||
|
first_time++;
|
||||||
|
Wait('start');
|
||||||
|
Rest.setUrl(url);
|
||||||
|
Rest.get()
|
||||||
|
.success( function(data) {
|
||||||
|
Wait('stop');
|
||||||
|
if (data.content) {
|
||||||
|
$('#pre-container-content').append(data.content);
|
||||||
|
loaded_sections.push(data.range.start);
|
||||||
|
current_range = data.range;
|
||||||
|
}
|
||||||
|
//$("#pre-container").mCustomScrollbar("scrollTo", "bottom", {scrollInertia:0});
|
||||||
|
//$('#pre-container').mCustomScrollbar("update");
|
||||||
|
})
|
||||||
|
.error(function(data, status) {
|
||||||
|
ProcessErrors($scope, data, status, null, { hdr: 'Error!',
|
||||||
|
msg: 'Failed to retrieve stdout for job: ' + job_id + '. GET returned: ' + status });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
auto_scroll_down = false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.onTotalScrollBack = function() {
|
$scope.onTotalScrollBack = function() {
|
||||||
// scroll up or back in time toward the beginning of the file
|
// scroll up or back in time toward the beginning of the file
|
||||||
if (current_range.start > 0) {
|
if ((!live_event_processing) && current_range.start > 0) {
|
||||||
//we haven't hit the top yet
|
//we haven't hit the top yet
|
||||||
var start = (current_range.start < 500) ? 0 : current_range.start - 500,
|
var start = (current_range.start < page_size) ? 0 : current_range.start - page_size,
|
||||||
url = stdout_url + '?format=json&start_line=' + start + '&end_line=' + (current_range.start - 1);
|
url = stdout_url + '?format=json&start_line=' + start + '&end_line=' + (current_range.start - 1);
|
||||||
first_time++;
|
first_time++;
|
||||||
Wait('start');
|
Wait('start');
|
||||||
@@ -99,6 +174,7 @@ function JobStdoutController ($log, $rootScope, $scope, $compile, $routeParams,
|
|||||||
var oldContentHeight, heightDiff;
|
var oldContentHeight, heightDiff;
|
||||||
oldContentHeight=$("#pre-container .mCSB_container").innerHeight();
|
oldContentHeight=$("#pre-container .mCSB_container").innerHeight();
|
||||||
$('#pre-container-content').prepend(data.content);
|
$('#pre-container-content').prepend(data.content);
|
||||||
|
loaded_sections.unshift(data.range.start);
|
||||||
current_range = data.range;
|
current_range = data.range;
|
||||||
heightDiff=$("#pre-container .mCSB_container").innerHeight() - oldContentHeight;
|
heightDiff=$("#pre-container .mCSB_container").innerHeight() - oldContentHeight;
|
||||||
if (first_time === 1) {
|
if (first_time === 1) {
|
||||||
@@ -113,6 +189,28 @@ function JobStdoutController ($log, $rootScope, $scope, $compile, $routeParams,
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function getNextSection() {
|
||||||
|
var start = current_range.end + 1, url;
|
||||||
|
if (loaded_sections.indexOf(start) < 0) {
|
||||||
|
url = stdout_url + '?format=json&start_line=' + start + '&end_line=' + (current_range.start + page_size);
|
||||||
|
Wait('start');
|
||||||
|
Rest.setUrl(url);
|
||||||
|
Rest.get()
|
||||||
|
.success( function(data) {
|
||||||
|
Wait('stop');
|
||||||
|
$('#pre-container-content').append(data.content);
|
||||||
|
loaded_sections.push(data.range.start);
|
||||||
|
current_range = data.range;
|
||||||
|
$("#pre-container").mCustomScrollbar("scrollTo", "bottom", {scrollInertia:0});
|
||||||
|
})
|
||||||
|
.error(function(data, status) {
|
||||||
|
ProcessErrors($scope, data, status, null, { hdr: 'Error!',
|
||||||
|
msg: 'Failed to retrieve stdout for job: ' + job_id + '. GET returned: ' + status });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JobStdoutController.$inject = [ '$log', '$rootScope', '$scope', '$compile', '$routeParams', 'ClearScope', 'GetBasePath', 'Wait', 'Rest', 'ProcessErrors',
|
JobStdoutController.$inject = [ '$log', '$rootScope', '$scope', '$compile', '$routeParams', 'ClearScope', 'GetBasePath', 'Wait', 'Rest', 'ProcessErrors',
|
||||||
|
|||||||
@@ -5,6 +5,15 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#jobs-stdout {
|
||||||
|
#job-status {
|
||||||
|
label {
|
||||||
|
margin-right: 15px;
|
||||||
|
}
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.body_foreground { color: #AAAAAA; }
|
.body_foreground { color: #AAAAAA; }
|
||||||
.body_background { background-color: @black; }
|
.body_background { background-color: @black; }
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
|
<div id="job-status"><label>Job Status</label> <i class="fa icon-job-{{ job.status }}"></i> {{ job.status }}</div>
|
||||||
<div id="pre-container" class="body_background body_foreground pre mono-space" aw-custom-scroll data-scroll-theme="light-thin"
|
<div id="pre-container" class="body_background body_foreground pre mono-space" aw-custom-scroll data-scroll-theme="light-thin"
|
||||||
data-scroll-inertia="500" data-on-total-scroll="onTotalScroll" data-on-total-scroll-back="onTotalScrollBack"
|
data-scroll-inertia="500" data-on-total-scroll="onTotalScroll" data-on-total-scroll-back="onTotalScrollBack"
|
||||||
data-on-total-scroll-back-offset="100">
|
data-on-total-scroll-back-offset="100">
|
||||||
|
|||||||
Reference in New Issue
Block a user