diff --git a/awx/ui/client/src/activity-stream/activitystream.route.js b/awx/ui/client/src/activity-stream/activitystream.route.js
index a7e1da313f..06977c591d 100644
--- a/awx/ui/client/src/activity-stream/activitystream.route.js
+++ b/awx/ui/client/src/activity-stream/activitystream.route.js
@@ -18,25 +18,26 @@ export default {
label: "ACTIVITY STREAM"
},
resolve: {
- features: ['FeaturesService', 'ProcessErrors', '$state', function(FeaturesService, ProcessErrors, $state) {
- FeaturesService.get()
- .then(function(features) {
+ features: ['FeaturesService', 'ProcessErrors', '$state', '$rootScope',
+ function(FeaturesService, ProcessErrors, $state, $rootScope) {
+ var features = FeaturesService.get();
+ if(features){
if(FeaturesService.featureEnabled('activity_streams')) {
- // Good to go - pass the features along to the controller.
return features;
}
else {
- // The activity stream feature isn't enabled. Take the user
- // back to the dashboard
$state.go('dashboard');
}
- })
- .catch(function (response) {
- ProcessErrors(null, response.data, response.status, null, {
- hdr: 'Error!',
- msg: 'Failed to get feature info. GET returned status: ' +
- response.status
- });
+ }
+ $rootScope.featuresConfigured.promise.then(function(features){
+ if(features){
+ if(FeaturesService.featureEnabled('activity_streams')) {
+ return features;
+ }
+ else {
+ $state.go('dashboard');
+ }
+ }
});
}],
subTitle:
diff --git a/awx/ui/client/src/app.js b/awx/ui/client/src/app.js
index 4fd0f98fc4..af5e3b8858 100644
--- a/awx/ui/client/src/app.js
+++ b/awx/ui/client/src/app.js
@@ -68,6 +68,7 @@ import './shared/directives';
import './shared/filters';
import './shared/Socket';
import './shared/features/main';
+import config from './shared/config/main';
import './login/authenticationServices/pendo/ng-pendo';
import footer from './footer/main';
import scheduler from './scheduler/main';
@@ -109,6 +110,7 @@ var tower = angular.module('Tower', [
JobTemplates.name,
portalMode.name,
search.name,
+ config.name,
'ngToast',
'templates',
'Utilities',
@@ -212,8 +214,10 @@ var tower = angular.module('Tower', [
timeout: 4000
});
}])
- .config(['$stateProvider', '$urlRouterProvider', '$breadcrumbProvider', '$urlMatcherFactoryProvider',
- function ($stateProvider, $urlRouterProvider, $breadcrumbProvider, $urlMatcherFactoryProvider) {
+ .config(['$stateProvider', '$urlRouterProvider', '$breadcrumbProvider',
+ '$urlMatcherFactoryProvider',
+ function ($stateProvider, $urlRouterProvider, $breadcrumbProvider,
+ $urlMatcherFactoryProvider) {
$urlMatcherFactoryProvider.strictMode(false);
$breadcrumbProvider.setOptions({
templateUrl: urlPrefix + 'partials/breadcrumb.html'
@@ -241,10 +245,9 @@ var tower = angular.module('Tower', [
label: "DASHBOARD"
},
resolve: {
- graphData: ['$q', 'jobStatusGraphData', 'FeaturesService', function($q, jobStatusGraphData, FeaturesService) {
+ graphData: ['$q', 'jobStatusGraphData', function($q, jobStatusGraphData) {
return $q.all({
jobStatus: jobStatusGraphData.get("month", "all"),
- features: FeaturesService.get()
});
}]
}
@@ -514,10 +517,16 @@ var tower = angular.module('Tower', [
}]);
}])
- .run(['$q', '$compile', '$cookieStore', '$rootScope', '$log', 'CheckLicense', '$location', 'Authorization', 'LoadBasePaths', 'Timer', 'ClearScope', 'Socket',
- 'LoadConfig', 'Store', 'ShowSocketHelp', 'pendoService', 'Prompt', 'Rest', 'Wait', 'ProcessErrors', '$state', 'GetBasePath',
- function ($q, $compile, $cookieStore, $rootScope, $log, CheckLicense, $location, Authorization, LoadBasePaths, Timer, ClearScope, Socket,
- LoadConfig, Store, ShowSocketHelp, pendoService, Prompt, Rest, Wait, ProcessErrors, $state, GetBasePath) {
+ .run(['$q', '$compile', '$cookieStore', '$rootScope', '$log',
+ 'CheckLicense', '$location', 'Authorization', 'LoadBasePaths', 'Timer',
+ 'ClearScope', 'Socket', 'LoadConfig', 'Store',
+ 'ShowSocketHelp', 'pendoService', 'Prompt', 'Rest', 'Wait',
+ 'ProcessErrors', '$state', 'GetBasePath', 'ConfigService',
+ 'FeaturesService',
+ function ($q, $compile, $cookieStore, $rootScope, $log, CheckLicense,
+ $location, Authorization, LoadBasePaths, Timer, ClearScope, Socket,
+ LoadConfig, Store, ShowSocketHelp, pendoService, Prompt, Rest, Wait,
+ ProcessErrors, $state, GetBasePath, ConfigService, FeaturesService) {
var sock;
$rootScope.addPermission = function (scope) {
$compile("")(scope);
@@ -585,11 +594,11 @@ var tower = angular.module('Tower', [
Prompt({
hdr: `Remove role`,
body: `
-
- Confirm the removal of the ${roleType}
- ${roleName}
- role associated with ${userName}.
-
+
+ Confirm the removal of the ${roleType}
+ ${roleName}
+ role associated with ${userName}.
+
`,
action: action,
actionText: 'REMOVE'
@@ -615,11 +624,11 @@ var tower = angular.module('Tower', [
Prompt({
hdr: `Remove role`,
body: `
-
- Confirm the removal of the ${roleType}
- ${roleName}
- role associated with the ${teamName} team.
-
+
+ Confirm the removal of the ${roleType}
+ ${roleName}
+ role associated with the ${teamName} team.
+
`,
action: action,
actionText: 'REMOVE'
@@ -745,7 +754,7 @@ var tower = angular.module('Tower', [
control_socket.on("limit_reached", function(data) {
$log.debug(data.reason);
$rootScope.sessionTimer.expireSession('session_limit');
- $location.url('/login');
+ $state.go('signOut');
});
}
openSocket();
@@ -760,9 +769,7 @@ var tower = angular.module('Tower', [
$rootScope.$on("$stateChangeStart", function (event, next, nextParams, prev) {
- if (next.name !== 'signOut'){
- CheckLicense.notify();
- }
+
$rootScope.$broadcast("closePermissionsModal");
$rootScope.$broadcast("closeUsersModal");
// this line removes the query params attached to a route
@@ -813,15 +820,15 @@ var tower = angular.module('Tower', [
if ($rootScope.current_user === undefined || $rootScope.current_user === null) {
Authorization.restoreUserInfo(); //user must have hit browser refresh
}
+ if (next && (next.name !== "signIn" && next.name !== "signOut" && next.name !== "license")) {
+ // if not headed to /login or /logout, then check the license
+ CheckLicense.test(event);
+ }
}
activateTab();
});
$rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState) {
- // catch license expiration notifications immediately after user logs in, redirect
- if (fromState.name === 'signIn'){
- CheckLicense.notify();
- }
if(fromState.name === 'license' && toParams.hasOwnProperty('licenseMissing')){
$rootScope.licenseMissing = toParams.licenseMissing;
@@ -865,11 +872,20 @@ var tower = angular.module('Tower', [
$rootScope.user_is_superuser = Authorization.getUserInfo('is_superuser');
// state the user refreshes we want to open the socket, except if the user is on the login page, which should happen after the user logs in (see the AuthService module for that call to OpenSocket)
if(!_.contains($location.$$url, '/login')){
- Timer.init().then(function(timer){
- $rootScope.sessionTimer = timer;
- $rootScope.$emit('OpenSocket');
- pendoService.issuePendoIdentity();
- CheckLicense.notify();
+ ConfigService.getConfig().then(function(){
+ Timer.init().then(function(timer){
+ $rootScope.sessionTimer = timer;
+ $rootScope.$emit('OpenSocket');
+ pendoService.issuePendoIdentity();
+ CheckLicense.test();
+ FeaturesService.get();
+ if($location.$$path === "/home" && $state.current && $state.current.name === ""){
+ $state.go('dashboard');
+ }
+ else if($location.$$path === "/portal" && $state.current && $state.current.name === ""){
+ $state.go('portalMode');
+ }
+ });
});
}
}
@@ -904,7 +920,11 @@ var tower = angular.module('Tower', [
// create a promise that will resolve state $AnsibleConfig is loaded
$rootScope.loginConfig = $q.defer();
}
-
+ if (!$rootScope.featuresConfigured) {
+ // create a promise that will resolve when features are loaded
+ $rootScope.featuresConfigured = $q.defer();
+ }
+ $rootScope.licenseMissing = true;
//the authorization controller redirects to the home page automatcially if there is no last path defined. in order to override
// this, set the last path to /portal for instances where portal is visited for the first time.
$rootScope.lastPath = ($location.path() === "/portal") ? 'portal' : undefined;
diff --git a/awx/ui/client/src/bread-crumb/bread-crumb.directive.js b/awx/ui/client/src/bread-crumb/bread-crumb.directive.js
index e74ccfaaf3..c45321c7e5 100644
--- a/awx/ui/client/src/bread-crumb/bread-crumb.directive.js
+++ b/awx/ui/client/src/bread-crumb/bread-crumb.directive.js
@@ -1,5 +1,6 @@
export default
- [ 'templateUrl', '$state', 'FeaturesService', 'ProcessErrors', 'Store', 'Empty', '$log', function(templateUrl, $state, FeaturesService, ProcessErrors, Store, Empty, $log) {
+ ['templateUrl', '$state', 'FeaturesService', 'ProcessErrors','$rootScope',
+ function(templateUrl, $state, FeaturesService, ProcessErrors, $rootScope) {
return {
restrict: 'E',
templateUrl: templateUrl('bread-crumb/bread-crumb'),
@@ -12,49 +13,21 @@ export default
scope.toggleActivityStream = function() {
- // If the user is not already on the activity stream then they want to navigate to it
- if(!scope.activityStreamActive) {
- var stateGoParams = {};
+ var stateGoParams = {};
- if(streamConfig && streamConfig.activityStream) {
- if(streamConfig.activityStreamTarget) {
- stateGoParams.target = streamConfig.activityStreamTarget;
- }
- if(streamConfig.activityStreamId) {
- stateGoParams.id = $state.params[streamConfig.activityStreamId];
- }
+ if(streamConfig && streamConfig.activityStream) {
+ if(streamConfig.activityStreamTarget) {
+ stateGoParams.target = streamConfig.activityStreamTarget;
}
-
- $state.go('activityStream', stateGoParams);
- }
- // The user is navigating away from the activity stream - take them back from whence they came
- else {
- // Pull the previous state out of local storage
- var previousState = Store('previous_state');
-
- if(previousState && !Empty(previousState.name)) {
- $state.go(previousState.name, previousState.fromParams);
+ if(streamConfig.activityStreamId) {
+ stateGoParams.id = $state.params[streamConfig.activityStreamId];
}
- else {
- // If for some reason something went wrong (like local storage was wiped, etc) take the
- // user back to the dashboard
- $state.go('dashboard');
- }
-
}
+ $state.go('activityStream', stateGoParams);
};
- scope.$on("$stateChangeSuccess", function updateActivityStreamButton(event, toState, toParams, fromState, fromParams) {
-
- if(fromState && !Empty(fromState.name)) {
- // Go ahead and attach the from params to the state object so that it can all be stored together
- fromState.fromParams = fromParams ? fromParams : {};
-
- // Store the state that we're coming from in local storage to be accessed when navigating away from the
- // activity stream
- Store('previous_state', fromState);
- }
+ scope.$on("$stateChangeStart", function updateActivityStreamButton(event, toState) {
streamConfig = (toState && toState.data) ? toState.data : {};
@@ -65,27 +38,12 @@ export default
// point. We use the get() function call here just in case the features aren't available.
// The get() function will only fire off the server call if the features aren't already
// attached to the $rootScope.
-
- FeaturesService.get()
- .then(function() {
+ var features = FeaturesService.get();
+ if(features){
scope.loadingLicense = false;
scope.activityStreamActive = (toState.name === 'activityStream') ? true : false;
- scope.showActivityStreamButton = (FeaturesService.featureEnabled('activity_streams') || toState.name === 'activityStream') ? true : false;
- var licenseInfo = FeaturesService.getLicenseInfo();
- scope.licenseType = licenseInfo ? licenseInfo.license_type : null;
- if (!licenseInfo) {
- console.warn("License info not loaded correctly"); // jshint ignore:line
- $log.error("License info not loaded correctly");
- }
- })
- .catch(function (response) {
- ProcessErrors(null, response.data, response.status, null, {
- hdr: 'Error!',
- msg: 'Failed to get feature info. GET returned status: ' +
- response.status
- });
- });
-
+ scope.showActivityStreamButton = (FeaturesService.featureEnabled('activity_streams') || toState.name ==='activityStream') ? true : false;
+ }
}
else {
@@ -94,6 +52,15 @@ export default
}
});
+ // scope.$on('featuresLoaded', function(){
+ $rootScope.featuresConfigured.promise.then(function(features){
+ // var features = FeaturesService.get();
+ if(features){
+ scope.loadingLicense = false;
+ scope.activityStreamActive = ($state.name === 'activityStream') ? true : false;
+ scope.showActivityStreamButton = (FeaturesService.featureEnabled('activity_streams') || $state.name ==='activityStream') ? true : false;
+ }
+ });
}
};
}];
diff --git a/awx/ui/client/src/bread-crumb/bread-crumb.partial.html b/awx/ui/client/src/bread-crumb/bread-crumb.partial.html
index 4d51219070..734de68414 100644
--- a/awx/ui/client/src/bread-crumb/bread-crumb.partial.html
+++ b/awx/ui/client/src/bread-crumb/bread-crumb.partial.html
@@ -1,5 +1,5 @@