diff --git a/awx/settings/defaults.py b/awx/settings/defaults.py
index b381548668..89d1727188 100644
--- a/awx/settings/defaults.py
+++ b/awx/settings/defaults.py
@@ -168,6 +168,10 @@ STDOUT_MAX_BYTES_DISPLAY = 1048576
# on how many events to display before truncating/hiding
MAX_UI_JOB_EVENTS = 4000
+# Returned in index.html, tells the UI if it should make requests
+# to update job data in response to status changes websocket events
+UI_LIVE_UPDATES_ENABLED = True
+
# The maximum size of the ansible callback event's res data structure
# beyond this limit and the value will be removed
MAX_EVENT_RES_DATA = 700000
diff --git a/awx/ui/client/src/app.js b/awx/ui/client/src/app.js
index 529e5d7abe..fc79e6a015 100644
--- a/awx/ui/client/src/app.js
+++ b/awx/ui/client/src/app.js
@@ -146,7 +146,11 @@ var awApp = angular.module('awApp', [
.constant('AngularScheduler.showUTCField', true)
.constant('$timezones.definitions.location', urlPrefix + 'lib/angular-tz-extensions/tz/data')
.config(['$logProvider', function($logProvider) {
- $logProvider.debugEnabled($ENV['ng-debug'] || false);
+ window.debug = function(){
+ $logProvider.debugEnabled(!$logProvider.debugEnabled());
+ return $logProvider.debugEnabled();
+ };
+ window.debug(false);
}])
.config(['ngToastProvider', function(ngToastProvider) {
ngToastProvider.configure({
diff --git a/awx/ui/client/src/shared/socket/socket.service.js b/awx/ui/client/src/shared/socket/socket.service.js
index f520fbcbe9..7c51298a72 100644
--- a/awx/ui/client/src/shared/socket/socket.service.js
+++ b/awx/ui/client/src/shared/socket/socket.service.js
@@ -8,7 +8,8 @@ export default
['$rootScope', '$location', '$log','$state', '$q', 'i18n',
function ($rootScope, $location, $log, $state, $q, i18n) {
var needsResubscribing = false,
- socketPromise = $q.defer();
+ socketPromise = $q.defer(),
+ needsRefreshAfterBlur;
return {
init: function() {
var self = this,
@@ -24,6 +25,26 @@ export default
}
url = `${protocol}://${host}/websocket/`;
+ // only toggle background tabbed sockets if the
+ // UI_LIVE_UPDATES_ENABLED flag is true in the settings file
+ if(window.liveUpdates){
+ document.addEventListener('visibilitychange', function() {
+ $log.debug(document.visibilityState);
+ if(document.visibilityState === 'hidden'){
+ window.liveUpdates = false;
+ }
+ else if(document.visibilityState === 'visible'){
+ window.liveUpdates = true;
+ if(needsRefreshAfterBlur){
+ $state.go('.', null, {reload: true});
+ needsRefreshAfterBlur = false;
+ }
+
+ }
+ });
+ }
+
+
if (!$rootScope.sessionTimer || ($rootScope.sessionTimer && !$rootScope.sessionTimer.isExpired())) {
$log.debug('Socket connecting to: ' + url);
@@ -75,6 +96,13 @@ export default
$log.debug('Received From Server: ' + e.data);
var data = JSON.parse(e.data), str = "";
+
+ if(!window.liveUpdates && data.group_name !== "control" && $state.current.name !== "jobResult"){
+ $log.debug('Message from server dropped: ' + e.data);
+ needsRefreshAfterBlur = true;
+ return;
+ }
+
if(data.group_name==="jobs" && !('status' in data)){
// we know that this must have been a
// summary complete message b/c status is missing.
diff --git a/awx/ui/conf.py b/awx/ui/conf.py
index 0d626c28f0..df88890faf 100644
--- a/awx/ui/conf.py
+++ b/awx/ui/conf.py
@@ -63,3 +63,13 @@ register(
category=_('UI'),
category_slug='ui',
)
+
+register(
+ 'UI_LIVE_UPDATES_ENABLED',
+ field_class=fields.BooleanField,
+ label=_('Enable Live Updates in the UI'),
+ help_text=_('If disabled, the page will not refresh when events are received. '
+ 'Reloading the page will be required to get the latest details.'),
+ category=_('UI'),
+ category_slug='ui',
+)
diff --git a/awx/ui/templates/ui/index.html b/awx/ui/templates/ui/index.html
index 38bbad9de3..3dae008dc7 100644
--- a/awx/ui/templates/ui/index.html
+++ b/awx/ui/templates/ui/index.html
@@ -12,6 +12,7 @@
diff --git a/awx/ui/views.py b/awx/ui/views.py
index 0a47154615..994da49732 100644
--- a/awx/ui/views.py
+++ b/awx/ui/views.py
@@ -2,6 +2,7 @@
# All Rights Reserved.
from django.views.generic.base import TemplateView, RedirectView
+from django.conf import settings
class IndexView(TemplateView):
@@ -9,6 +10,7 @@ class IndexView(TemplateView):
def get_context_data(self, **kwargs):
context = super(IndexView, self).get_context_data(**kwargs)
+ context['UI_LIVE_UPDATES_ENABLED'] = settings.UI_LIVE_UPDATES_ENABLED
# Add any additional context info here.
return context