RESULTS
@@ -77,17 +77,19 @@
diff --git a/awx/ui/client/src/standard-out/scm-update/standard-out-scm-update.route.js b/awx/ui/client/src/standard-out/scm-update/standard-out-scm-update.route.js
index 294518cd7b..15cddbb5b4 100644
--- a/awx/ui/client/src/standard-out/scm-update/standard-out-scm-update.route.js
+++ b/awx/ui/client/src/standard-out/scm-update/standard-out-scm-update.route.js
@@ -24,18 +24,8 @@ export default {
features: ['FeaturesService', function(FeaturesService) {
return FeaturesService.get();
}],
- adhocEventsSocket: ['Socket', '$rootScope', function(Socket, $rootScope) {
- // if (!$rootScope.adhoc_event_socket) {
- // $rootScope.adhoc_event_socket = Socket({
- // scope: $rootScope,
- // endpoint: "ad_hoc_command_events"
- // });
- // $rootScope.adhoc_event_socket.init();
- // return true;
- // } else {
- // return true;
- // }
-
+ scmUpdateSocket: ['Socket', '$rootScope', function(Socket, $rootScope) {
+ // TODO: determine whether or not we have socket support for scm update standard out
return true;
}]
}
diff --git a/awx/ui/client/src/standard-out/standard-out.block.less b/awx/ui/client/src/standard-out/standard-out.block.less
index 654439b6ed..8d0e8a0219 100644
--- a/awx/ui/client/src/standard-out/standard-out.block.less
+++ b/awx/ui/client/src/standard-out/standard-out.block.less
@@ -10,19 +10,19 @@
.StandardOut-leftPanel {
flex: 0 0 400px;
+ margin-right: 20px;
}
.StandardOut-rightPanel {
flex: 1 0;
- margin-left: 20px;
}
.StandardOut-panelHeader {
color: @default-interface-txt;
font-size: 14px;
font-weight: bold;
- margin-right: 10px;
text-transform: uppercase;
+ display: flex;
}
.StandardOut-consoleOutput {
@@ -30,6 +30,8 @@
min-height: 200px;
background-color: @default-secondary-bg;
border-radius: 5px;
+ height: 300px;
+ overflow: scroll;
}
.StandardOut-details {
@@ -63,13 +65,54 @@
text-transform: capitalize;
}
+.StandardOut-preContainer {
+ height: 300px;
+}
+
+.StandardOut-panelHeaderText {
+ align-items: center;
+ flex: 1 0 auto;
+ display: flex;
+}
+
+.StandardOut-panelHeaderActions {
+ justify-content: flex-end;
+ display: flex;
+ margin-left: 10px;
+ font-size: 20px;
+}
+
+.StandardOut-actionButton {
+ font-size: 16px;
+ height: 30px;
+ min-width: 30px;
+ color: #b7b7b7;
+ background-color: inherit;
+ border: none;
+ border-radius: 50%;
+}
+
+.StandardOut-actionButton:hover {
+ background-color: @list-actn-bg-hov !important;
+ color: @list-actn-icn-hov;
+}
+
+.StandardOut-actionButton--active {
+ background-color: @list-actn-bg-hov !important;
+ color: @list-actn-icn-hov;
+}
+
+.StandardOut-actionButton + a {
+ margin-left: 15px;
+}
+
@standardout-breakpoint: 900px;
@media screen and (max-width: @standardout-breakpoint) {
.StandardOut {
flex-direction: column;
}
- .StandardOut-rightPanel {
- margin-left: 0px;
+ .StandardOut-leftPanel {
+ margin-right: 0px;
}
}
diff --git a/awx/ui/client/src/standard-out/standard-out.controller.js b/awx/ui/client/src/standard-out/standard-out.controller.js
index 1b9233a248..152d2a8a5d 100644
--- a/awx/ui/client/src/standard-out/standard-out.controller.js
+++ b/awx/ui/client/src/standard-out/standard-out.controller.js
@@ -11,153 +11,34 @@
*/
-export function JobStdoutController ($location, $log, $rootScope, $scope, $compile, $state, $stateParams, ClearScope, GetBasePath, Wait, Rest, ProcessErrors, ModelToBasePathKey, Empty, GetChoices, LookUpName) {
+export function JobStdoutController ($rootScope, $scope, $state, $stateParams, ClearScope, GetBasePath, Rest, ProcessErrors, Empty, GetChoices, LookUpName) {
ClearScope();
var job_id = $stateParams.id,
- jobType = $state.current.data.jobType,
- api_complete = false,
- stdout_url,
- current_range,
- loaded_sections = [],
- event_queue = 0,
- auto_scroll_down=true, // programmatic scroll to bottom
- live_event_processing = true,
- should_apply_live_events = true,
- page_size = 500,
- lastScrollTop = 0,
- st,
- direction;
+ jobType = $state.current.data.jobType;
- $scope.isClosed = true;
+ // This scope variable controls whether or not the left panel is shown and the right panel
+ // is expanded to take up the full screen
+ $scope.stdoutFullScreen = false;
-
- // function openSockets() {
- // if (/\/jobs\/(\d)+\/stdout/.test($location.$$url)) {
- // $log.debug("socket watching on job_events-" + job_id);
- // $rootScope.event_socket.on("job_events-" + job_id, function() {
- // $log.debug("socket fired on job_events-" + job_id);
- // if (api_complete) {
- // event_queue++;
- // }
- // });
- // } else if (/\/ad_hoc_commands\/(\d)+/.test($location.$$url)) {
- // $log.debug("socket watching on ad_hoc_command_events-" + job_id);
- // $rootScope.adhoc_event_socket.on("ad_hoc_command_events-" + job_id, function() {
- // $log.debug("socket fired on ad_hoc_command_events-" + job_id);
- // if (api_complete) {
- // event_queue++;
- // }
- // });
- // }
- // }
- //
- // openSockets();
-
- if ($rootScope.removeJobStatusChange) {
- $rootScope.removeJobStatusChange();
+ // Listen for job status updates that may come across via sockets. We need to check the payload
+ // to see whethere the updated job is the one that we're currently looking at.
+ if ($scope.removeJobStatusChange) {
+ $scope.removeJobStatusChange();
}
- $rootScope.removeJobStatusChange = $rootScope.$on('JobStatusChange-jobStdout', function(e, data) {
+ $scope.removeJobStatusChange = $rootScope.$on('JobStatusChange-jobStdout', function(e, data) {
if (parseInt(data.unified_job_id, 10) === parseInt(job_id,10) && $scope.job) {
$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) {
- if (loaded_sections.length === 0) {
- $scope.$emit('LoadStdout');
- }
- else {
- getNextSection();
- }
- }
- live_event_processing = false;
- }
}
+
+ // TODO: when the job completes we should refresh the job data so that we pull in the finish
+ // timestamp as well as the run time.
});
- $rootScope.jobStdOutInterval = setInterval( function() {
- if (event_queue > 0) {
- // events happened since the last check
- $log.debug('checking for stdout...');
- if (loaded_sections.length === 0) { ////this if statement for refresh
- $log.debug('calling LoadStdout');
- $scope.$emit('LoadStdout');
- }
- else if (live_event_processing) {
- $log.debug('calling getNextSection');
- getNextSection();
- }
- event_queue = 0;
- }
- }, 2000);
-
- if ($scope.removeLoadStdout) {
- $scope.removeLoadStdout();
- }
- $scope.removeLoadStdout = $scope.$on('LoadStdout', function() {
- Rest.setUrl(stdout_url + '?format=json&start_line=-' + page_size);
- Rest.get()
- .success(function(data) {
- Wait('stop');
- if (data.content) {
- api_complete = true;
- $('#pre-container-content').html(data.content);
- current_range = data.range;
- if (data.content !== "Waiting for results...") {
- loaded_sections.push({
- start: (data.range.start < 0) ? 0 : data.range.start,
- end: data.range.end
- });
- }
-
- $('#pre-container').scrollTop($('#pre-container').prop("scrollHeight"));
- }
- else {
- api_complete = true;
- }
- })
- .error(function(data, status) {
- ProcessErrors($scope, data, status, null, { hdr: 'Error!',
- msg: 'Failed to retrieve stdout for job: ' + job_id + '. GET returned: ' + status });
- });
- });
-
- function detectDirection() {
- st = $('#pre-container').scrollTop();
- if (st > lastScrollTop) {
- direction = "down";
- } else {
- direction = "up";
- }
- lastScrollTop = st;
- return direction;
- }
-
- $('#pre-container').bind('scroll', function() {
- if (detectDirection() === "up") {
- should_apply_live_events = false;
- }
-
- if ($(this).scrollTop() + $(this).height() === $(this).prop("scrollHeight")) {
- should_apply_live_events = true;
- }
- });
-
- $scope.toggleClosedStatus = function() {
- if (!$scope.isClosed) {
- $('.StandardOutDetails-detailRow--closable').slideUp(200);
- $scope.isClosed = true;
- }
- else {
- $('.StandardOutDetails-detailRow--closable').slideDown(200);
- $scope.isClosed = false;
- }
- };
-
+ // Go out and get the job details based on the job type. jobType gets defined
+ // in the data block of the route declaration for each of the different types
+ // of stdout jobs.
Rest.setUrl(GetBasePath('base') + jobType + '/' + job_id + '/');
Rest.get()
.success(function(data) {
@@ -179,7 +60,6 @@ export function JobStdoutController ($location, $log, $rootScope, $scope, $compi
$scope.limit = data.limit;
$scope.verbosity = data.verbosity;
$scope.job_tags = data.job_tags;
- stdout_url = data.related.stdout;
// If we have a source then we have to go get the source choices from the server
if (!Empty(data.source)) {
@@ -252,14 +132,12 @@ export function JobStdoutController ($location, $log, $rootScope, $scope, $compi
});
}
- // if (data.status === 'successful' || data.status === 'failed' || data.status === 'error' || data.status === 'canceled') {
- // live_event_processing = false;
- // if ($rootScope.jobStdOutInterval) {
- // window.clearInterval($rootScope.jobStdOutInterval);
- // }
- // }
- if(stdout_url) {
- $scope.$emit('LoadStdout');
+ // If the job isn't running we want to clear out the interval that goes out and checks for stdout updates.
+ // This interval is defined in the standard out log directive controller.
+ if (data.status === 'successful' || data.status === 'failed' || data.status === 'error' || data.status === 'canceled') {
+ if ($rootScope.jobStdOutInterval) {
+ window.clearInterval($rootScope.jobStdOutInterval);
+ }
}
})
.error(function(data, status) {
@@ -267,88 +145,17 @@ export function JobStdoutController ($location, $log, $rootScope, $scope, $compi
msg: 'Failed to retrieve job: ' + job_id + '. GET returned: ' + status });
});
+ // TODO: this is currently not used but is necessary for cases where sockets
+ // are not available and a manual refresh trigger is needed.
$scope.refresh = function(){
- if (loaded_sections.length === 0) { ////this if statement for refresh
- $scope.$emit('LoadStdout');
- }
- else if (live_event_processing) {
- getNextSection();
- }
+ $scope.$emit('LoadStdout');
};
- $scope.stdOutScrollToTop = function() {
- // scroll up or back in time toward the beginning of the file
- var start, end, url;
- if (loaded_sections.length > 0 && loaded_sections[0].start > 0) {
- start = (loaded_sections[0].start - page_size > 0) ? loaded_sections[0].start - page_size : 0;
- end = loaded_sections[0].start - 1;
- }
- else if (loaded_sections.length === 0) {
- start = 0;
- end = page_size;
- }
- if (start !== undefined && end !== undefined) {
- $('#stdoutMoreRowsTop').fadeIn();
- url = stdout_url + '?format=json&start_line=' + start + '&end_line=' + end;
- Rest.setUrl(url);
- Rest.get()
- .success( function(data) {
- //var currentPos = $('#pre-container').scrollTop();
- var newSH, oldSH = $('#pre-container').prop('scrollHeight'),
- st = $('#pre-container').scrollTop();
-
- $('#pre-container-content').prepend(data.content);
-
- newSH = $('#pre-container').prop('scrollHeight');
- $('#pre-container').scrollTop(newSH - oldSH + st);
-
- loaded_sections.unshift({
- start: (data.range.start < 0) ? 0 : data.range.start,
- end: data.range.end
- });
- current_range = data.range;
- $('#stdoutMoreRowsTop').fadeOut(400);
- })
- .error(function(data, status) {
- ProcessErrors($scope, data, status, null, { hdr: 'Error!',
- msg: 'Failed to retrieve stdout for job: ' + job_id + '. GET returned: ' + status });
- });
- }
- };
-
- function getNextSection() {
- // get the next range of data from the API
- var start = loaded_sections[loaded_sections.length - 1].end, url;
- url = stdout_url + '?format=json&start_line=' + start + '&end_line=' + (start + page_size);
- $('#stdoutMoreRowsBottom').fadeIn();
- Rest.setUrl(url);
- Rest.get()
- .success( function(data) {
- if ($('#pre-container-content').html() === "Waiting for results...") {
- $('#pre-container-content').html(data.content);
- } else {
- $('#pre-container-content').append(data.content);
- }
- loaded_sections.push({
- start: (data.range.start < 0) ? 0 : data.range.start,
- end: data.range.end
- });
- //console.log('loaded start: ' + data.range.start + ' end: ' + data.range.end);
- //console.log(data.content);
- if (should_apply_live_events) {
- // if user has not disabled live event view by scrolling upward, then scroll down to the new content
- current_range = data.range;
- auto_scroll_down = true; // prevent auto load from happening
- $('#pre-container').scrollTop($('#pre-container').prop("scrollHeight"));
- }
- $('#stdoutMoreRowsBottom').fadeOut(400);
- })
- .error(function(data, status) {
- ProcessErrors($scope, data, status, null, { hdr: 'Error!',
- msg: 'Failed to retrieve stdout for job: ' + job_id + '. GET returned: ' + status });
- });
+ // Click binding for the expand/collapse button on the standard out log
+ $scope.toggleStdoutFullscreen = function() {
+ $scope.stdoutFullScreen = !$scope.stdoutFullScreen;
}
}
-JobStdoutController.$inject = [ '$location', '$log', '$rootScope', '$scope', '$compile', '$state', '$stateParams', 'ClearScope', 'GetBasePath', 'Wait', 'Rest', 'ProcessErrors', 'ModelToBasePathKey', 'Empty', 'GetChoices', 'LookUpName'];
+JobStdoutController.$inject = [ '$rootScope', '$scope', '$state', '$stateParams', 'ClearScope', 'GetBasePath', 'Rest', 'ProcessErrors', 'Empty', 'GetChoices', 'LookUpName'];