Promise-ify the call to /config and reduce number

of calls to 1 per session. We'll also pull the config/license info from memory instead of local storage
This commit is contained in:
Jared Tabor
2016-05-16 09:24:49 -04:00
parent 05b3920837
commit 8b271c4caf
15 changed files with 388 additions and 100 deletions

View File

@@ -68,6 +68,7 @@ import './shared/directives';
import './shared/filters'; import './shared/filters';
import './shared/Socket'; import './shared/Socket';
import './shared/features/main'; import './shared/features/main';
import config from './shared/config/main';
import './login/authenticationServices/pendo/ng-pendo'; import './login/authenticationServices/pendo/ng-pendo';
import footer from './footer/main'; import footer from './footer/main';
import scheduler from './scheduler/main'; import scheduler from './scheduler/main';
@@ -109,6 +110,7 @@ var tower = angular.module('Tower', [
JobTemplates.name, JobTemplates.name,
portalMode.name, portalMode.name,
search.name, search.name,
config.name,
'ngToast', 'ngToast',
'templates', 'templates',
'Utilities', 'Utilities',
@@ -514,10 +516,15 @@ var tower = angular.module('Tower', [
}]); }]);
}]) }])
.run(['$q', '$compile', '$cookieStore', '$rootScope', '$log', 'CheckLicense', '$location', 'Authorization', 'LoadBasePaths', 'Timer', 'ClearScope', 'Socket', .run(['$q', '$compile', '$cookieStore', '$rootScope', '$log',
'LoadConfig', 'Store', 'ShowSocketHelp', 'pendoService', 'Prompt', 'Rest', 'Wait', 'ProcessErrors', '$state', 'GetBasePath', 'CheckLicense', '$location', 'Authorization', 'LoadBasePaths', 'Timer',
function ($q, $compile, $cookieStore, $rootScope, $log, CheckLicense, $location, Authorization, LoadBasePaths, Timer, ClearScope, Socket, 'ClearScope', 'Socket', 'LoadConfig', 'Store',
LoadConfig, Store, ShowSocketHelp, pendoService, Prompt, Rest, Wait, ProcessErrors, $state, GetBasePath) { 'ShowSocketHelp', 'pendoService', 'Prompt', 'Rest', 'Wait',
'ProcessErrors', '$state', 'GetBasePath', 'ConfigService',
function ($q, $compile, $cookieStore, $rootScope, $log, CheckLicense,
$location, Authorization, LoadBasePaths, Timer, ClearScope, Socket,
LoadConfig, Store, ShowSocketHelp, pendoService, Prompt, Rest, Wait,
ProcessErrors, $state, GetBasePath, ConfigService) {
var sock; var sock;
$rootScope.addPermission = function (scope) { $rootScope.addPermission = function (scope) {
$compile("<add-permissions class='AddPermissions'></add-permissions>")(scope); $compile("<add-permissions class='AddPermissions'></add-permissions>")(scope);
@@ -585,11 +592,11 @@ var tower = angular.module('Tower', [
Prompt({ Prompt({
hdr: `Remove role`, hdr: `Remove role`,
body: ` body: `
<div class="Prompt-bodyQuery"> <div class="Prompt-bodyQuery">
Confirm the removal of the ${roleType} Confirm the removal of the ${roleType}
<span class="Prompt-emphasis"> ${roleName} </span> <span class="Prompt-emphasis"> ${roleName} </span>
role associated with ${userName}. role associated with ${userName}.
</div> </div>
`, `,
action: action, action: action,
actionText: 'REMOVE' actionText: 'REMOVE'
@@ -615,11 +622,11 @@ var tower = angular.module('Tower', [
Prompt({ Prompt({
hdr: `Remove role`, hdr: `Remove role`,
body: ` body: `
<div class="Prompt-bodyQuery"> <div class="Prompt-bodyQuery">
Confirm the removal of the ${roleType} Confirm the removal of the ${roleType}
<span class="Prompt-emphasis"> ${roleName} </span> <span class="Prompt-emphasis"> ${roleName} </span>
role associated with the ${teamName} team. role associated with the ${teamName} team.
</div> </div>
`, `,
action: action, action: action,
actionText: 'REMOVE' actionText: 'REMOVE'
@@ -760,9 +767,7 @@ var tower = angular.module('Tower', [
$rootScope.$on("$stateChangeStart", function (event, next, nextParams, prev) { $rootScope.$on("$stateChangeStart", function (event, next, nextParams, prev) {
if (next.name !== 'signOut'){
CheckLicense.notify();
}
$rootScope.$broadcast("closePermissionsModal"); $rootScope.$broadcast("closePermissionsModal");
$rootScope.$broadcast("closeUsersModal"); $rootScope.$broadcast("closeUsersModal");
// this line removes the query params attached to a route // this line removes the query params attached to a route
@@ -813,15 +818,19 @@ var tower = angular.module('Tower', [
if ($rootScope.current_user === undefined || $rootScope.current_user === null) { if ($rootScope.current_user === undefined || $rootScope.current_user === null) {
Authorization.restoreUserInfo(); //user must have hit browser refresh 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(); activateTab();
}); });
$rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState) { $rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState) {
// catch license expiration notifications immediately after user logs in, redirect // catch license expiration notifications immediately after user logs in, redirect
if (fromState.name === 'signIn'){ // if (fromState.name === 'signIn'){
CheckLicense.notify(); // CheckLicense.notify();
} // }
if(fromState.name === 'license' && toParams.hasOwnProperty('licenseMissing')){ if(fromState.name === 'license' && toParams.hasOwnProperty('licenseMissing')){
$rootScope.licenseMissing = toParams.licenseMissing; $rootScope.licenseMissing = toParams.licenseMissing;
@@ -868,8 +877,10 @@ var tower = angular.module('Tower', [
Timer.init().then(function(timer){ Timer.init().then(function(timer){
$rootScope.sessionTimer = timer; $rootScope.sessionTimer = timer;
$rootScope.$emit('OpenSocket'); $rootScope.$emit('OpenSocket');
pendoService.issuePendoIdentity(); ConfigService.getConfig().then(function(){
CheckLicense.notify(); pendoService.issuePendoIdentity();
CheckLicense.test(event);
});
}); });
} }
} }
@@ -904,7 +915,7 @@ var tower = angular.module('Tower', [
// create a promise that will resolve state $AnsibleConfig is loaded // create a promise that will resolve state $AnsibleConfig is loaded
$rootScope.loginConfig = $q.defer(); $rootScope.loginConfig = $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 //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. // this, set the last path to /portal for instances where portal is visited for the first time.
$rootScope.lastPath = ($location.path() === "/portal") ? 'portal' : undefined; $rootScope.lastPath = ($location.path() === "/portal") ? 'portal' : undefined;

View File

@@ -1,5 +1,5 @@
<div id="bread_crumb" class="BreadCrumb" ng-class="{'is-loggedOut' : !$root.current_user.username}"> <div id="bread_crumb" class="BreadCrumb" ng-class="{'is-loggedOut' : !$root.current_user.username}">
<div ng-if="!licenseMissing" ncy-breadcrumb></div> <div ng-hide="licenseMissing" ncy-breadcrumb></div>
<div class="BreadCrumb-menuLink" <div class="BreadCrumb-menuLink"
id="bread_crumb_activity_stream" id="bread_crumb_activity_stream"
aw-tool-tip="View Activity Stream" aw-tool-tip="View Activity Stream"

View File

@@ -6,21 +6,15 @@
export default export default
['$state', '$rootScope', 'Rest', 'GetBasePath', 'ProcessErrors', '$q', ['$state', '$rootScope', 'Rest', 'GetBasePath', 'ProcessErrors', '$q',
function($state, $rootScope, Rest, GetBasePath, ProcessErrors, $q){ 'Store', 'ConfigService',
function($state, $rootScope, Rest, GetBasePath, ProcessErrors, $q, Store,
ConfigService){
return { return {
get: function() { get: function() {
var defaultUrl = GetBasePath('config'); var config = ConfigService.get();
Rest.setUrl(defaultUrl); return config.license_info;
return Rest.get()
.success(function(res){
$rootScope.license_tested = true;
return res;
})
.error(function(res, status){
ProcessErrors($rootScope, res, status, null, {hdr: 'Error!',
msg: 'Call to '+ defaultUrl + ' failed. Return status: '+ status});
});
}, },
post: function(license, eula){ post: function(license, eula){
var defaultUrl = GetBasePath('config'); var defaultUrl = GetBasePath('config');
Rest.setUrl(defaultUrl); Rest.setUrl(defaultUrl);
@@ -51,27 +45,37 @@ export default
} }
return true; return true;
}, },
notify: function(){ test: function(event){
var deferred = $q.defer(), var //deferred = $q.defer(),
self = this; license = this.get();
if($rootScope.license_tested !== true){ if(license === null || !$rootScope.license_tested){
this.get() if(this.valid(license) === false) {
.then(function(res){ $rootScope.licenseMissing = true;
if(self.valid(res.data.license_info) === false) { if(event){
$rootScope.licenseMissing = true; event.preventDefault();
deferred.resolve(); }
$state.go('license'); $state.go('license');
} // deferred.reject();
else { }
$rootScope.licenseMissing = false; else {
} $rootScope.licenseMissing = false;
}); // deferred.resolve();
}
} }
else{ else if(this.valid(license) === false) {
deferred.resolve(); $rootScope.licenseMissing = true;
$state.transitionTo('license');
if(event){
event.preventDefault();
}
// deferred.reject(license);
} }
else {
return deferred.promise; $rootScope.licenseMissing = false;
// deferred.resolve(license);
}
return;
// return deferred.promise;
} }
}; };

View File

@@ -0,0 +1,201 @@
/*************************************************
* Copyright (c) 2015 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
/**
* @ngdoc function
* @name helpers.function:License
* @description Routines for checking and reporting license status
* CheckLicense.test() is called in app.js, in line 532, which is when the license is checked. The license information is
* stored in local storage using 'Store()'.
*
*
*
*
*/
// import '../forms';
export default
['$q', '$rootScope', '$compile', 'CreateDialog', 'Store',
'GenerateForm', 'TextareaResize', 'ToJSON', 'GetBasePath',
'Rest', 'ProcessErrors', 'Alert', 'IsAdmin', '$state', 'pendoService',
'Authorization', 'Wait',
function($q, $rootScope, $compile, CreateDialog, Store, GenerateForm,
TextareaResize, ToJSON, GetBasePath, Rest, ProcessErrors, Alert, IsAdmin, $state,
pendoService, Authorization, Wait) {
return {
getRemainingDays: function(time_remaining) {
// assumes time_remaining will be in seconds
var tr = parseInt(time_remaining, 10);
return Math.floor(tr / 86400);
},
shouldNotify: function(license) {
if (license && typeof license === 'object' && Object.keys(license).length > 0) {
// we have a license object
if (!license.valid_key) {
// missing valid key
return true;
}
else if (license.free_instances <= 0) {
// host count exceeded
return true;
}
else if (this.getRemainingDays(license.time_remaining) < 15) {
// below 15 days remaining on license
return true;
}
return false;
} else {
// missing license object
return true;
}
},
isAdmin: function() {
return IsAdmin();
},
post: function(license, eula){
var defaultUrl = GetBasePath('config');
Rest.setUrl(defaultUrl);
var data = license;
data.eula_accepted = eula;
return Rest.post(JSON.stringify(data))
.success(function(res){
return res;
})
.error(function(res, status){
ProcessErrors($rootScope, res, status, null, {hdr: 'Error!',
msg: 'Call to '+ defaultUrl + ' failed. Return status: '+ status});
});
},
postLicense: function(license_key, in_scope) {
var url = GetBasePath('config'),
self = this,
json_data, scope;
scope = (in_scope) ? in_scope : self.scope;
json_data = ToJSON('json', license_key);
json_data.eula_accepted = scope.eula_agreement;
if (typeof json_data === 'object' && Object.keys(json_data).length > 0) {
Rest.setUrl(url);
Rest.post(json_data)
.success(function (response) {
response.license_info = response;
Alert('License Accepted', 'The Ansible Tower license was updated. To review or update the license, choose View License from the Setup menu.','alert-info');
$rootScope.features = undefined;
Authorization.getLicense()
.success(function (data) {
Authorization.setLicense(data);
pendoService.issuePendoIdentity();
Wait("stop");
$state.go('home');
})
.error(function () {
Wait('stop');
Alert('Error', 'Failed to access license information. GET returned status: ' + status, 'alert-danger',
$state.go('signOut'));
});
})
.catch(function (response) {
scope.license_json_api_error = "A valid license key in JSON format is required";
ProcessErrors(scope, response.data, response.status, null, { hdr: 'Error!',
msg: 'Failed to update license. POST returned: ' + response.status
});
});
} else {
scope.license_json_api_error = "A valid license key in JSON format is required";
}
},
test: function() {
var license = Store('license'),
self = this;
// scope;
var getLicense = function() {
var deferred = $q.defer();
if (license === null) {
Rest.setUrl(GetBasePath('config'));
return Rest.get()
.then(function (data) {
license = data.data.license_info;
deferred.resolve();
return deferred.promise;
}, function () {
deferred.resolve();
return deferred.promise;
});
} else {
deferred.resolve(license);
return deferred.promise;
}
};
var promise = getLicense();
promise.then(function() {
// self.scope = $rootScope.$new();
// scope = self.scope;
if (license && typeof license === 'object' && Object.keys(license).length > 0) {
// if (license.tested) {
// return true;
// }
license.tested = true;
Store('license',license); //update with tested flag
}
// Don't do anything when the license is valid
if (!self.shouldNotify(license)) {
$rootScope.licenseMissing = false;
return true; // if the license is valid it would exit 'test' here, otherwise it moves on to making the modal for the license
}
$rootScope.licenseMissing = true;
$state.go('license');
});
},
// Checks current license validity
// Intended to for runtime or pre-state checks
// Returns false if invalid
valid: function(license) {
if (!license.valid_key){
return false;
}
else if (license.free_instances <= 0){
return false;
}
// notify if less than 15 days remaining
else if (license.time_remaining / 1000 / 60 / 60 / 24 > 15){
return false;
}
return true;
},
GetLicense: function() {
// Retrieve license detail
var //self = this,
// scope = (inScope) ? inScope : self.scope,
url = GetBasePath('config');
Rest.setUrl(url);
return Rest.get()
.success(function(res){
$rootScope.license_tested = true;
return res;
})
.error(function (data, status) {
ProcessErrors($rootScope, data, status, null, { hdr: 'Error!',
msg: 'Failed to retrieve license. GET status: ' + status
});
});
}
};
}];

View File

@@ -6,7 +6,6 @@
@import "awx/ui/client/src/shared/branding/colors.default.less"; @import "awx/ui/client/src/shared/branding/colors.default.less";
@import "awx/ui/client/src/shared/layouts/one-plus-two.less"; @import "awx/ui/client/src/shared/layouts/one-plus-two.less";
.License-container{ .License-container{
.OnePlusTwo-container; .OnePlusTwo-container;
} }

View File

@@ -74,23 +74,22 @@ export default
var calcExpiresOn = function(days){ var calcExpiresOn = function(days){
// calculate the expiration date of the license // calculate the expiration date of the license
days = parseInt(days);
return moment().add(days, 'days').calendar(); return moment().add(days, 'days').calendar();
}; };
var init = function(){ var init = function(){
$scope.fileName = "No file selected."; $scope.fileName = "No file selected.";
$scope.title = $rootScope.licenseMissing ? "Tower License" : "License Management"; $scope.title = $rootScope.licenseMissing ? "Tower License" : "License Management";
Wait('start'); Wait('start');
CheckLicense.get() var license = CheckLicense.get();
.then(function(res){ //.then(function(res){
$scope.license = res.data; $scope.license = license;
$scope.license.version = res.data.version.split('-')[0]; $scope.license.version = license.version.split('-')[0];
$scope.time = {}; $scope.time = {};
$scope.time.remaining = calcDaysRemaining($scope.license.license_info.time_remaining); $scope.time.remaining = calcDaysRemaining($scope.license.license_info.time_remaining);
$scope.time.expiresOn = calcExpiresOn($scope.time.remaining); $scope.time.expiresOn = calcExpiresOn($scope.time.remaining);
$scope.valid = CheckLicense.valid($scope.license.license_info); $scope.valid = CheckLicense.valid($scope.license.license_info);
Wait('stop'); Wait('stop');
}); // });
}; };
var reset = function(){ var reset = function(){
document.getElementById('License-form').reset(); document.getElementById('License-form').reset();

View File

@@ -1,6 +1,6 @@
<div class="License-container" <div class="License-container"
ng-class="{'License-container--missing': licenseMissing}"> ng-class="{'License-container--missing': licenseMissing}">
<div class="License-details" ng-if="!licenseMissing"> <div class="License-details" ng-hide="licenseMissing">
<div class="Panel"> <div class="Panel">
<div class="License-titleText">Details</div> <div class="License-titleText">Details</div>
<div class="License-fields"> <div class="License-fields">

View File

@@ -16,4 +16,4 @@ export default
.factory('CheckLicense', CheckLicense) .factory('CheckLicense', CheckLicense)
.run(['$stateExtender', function($stateExtender) { .run(['$stateExtender', function($stateExtender) {
$stateExtender.addState(route); $stateExtender.addState(route);
}]); }]);

View File

@@ -98,6 +98,7 @@ export default
$rootScope.license_tested = undefined; $rootScope.license_tested = undefined;
$rootScope.userLoggedIn = false; $rootScope.userLoggedIn = false;
$rootScope.sessionExpired = false; $rootScope.sessionExpired = false;
$rootScope.licenseMissing = true;
$rootScope.token = null; $rootScope.token = null;
$rootScope.token_expires = null; $rootScope.token_expires = null;
$rootScope.login_username = null; $rootScope.login_username = null;
@@ -127,7 +128,7 @@ export default
Store('license', license); Store('license', license);
$rootScope.features = Store('license').features; $rootScope.features = Store('license').features;
}, },
licenseTested: function () { licenseTested: function () {
var license, result; var license, result;
if ($rootScope.license_tested !== undefined) { if ($rootScope.license_tested !== undefined) {

View File

@@ -7,9 +7,9 @@
export default export default
[ '$rootScope', '$pendolytics', 'Rest', 'GetBasePath', 'ProcessErrors', '$q', [ '$rootScope', '$pendolytics', 'Rest', 'GetBasePath', 'ProcessErrors', '$q',
'Store', '$log', 'ConfigService', '$log',
function ($rootScope, $pendolytics, Rest, GetBasePath, ProcessErrors, $q, function ($rootScope, $pendolytics, Rest, GetBasePath, ProcessErrors, $q,
Store, $log) { ConfigService, $log) {
return { return {
setPendoOptions: function (config) { setPendoOptions: function (config) {
var tower_version = config.version.split('-')[0], var tower_version = config.version.split('-')[0],
@@ -93,7 +93,7 @@ export default
}, },
getConfig: function () { getConfig: function () {
var config = Store('license'), var config = ConfigService.get(),
deferred = $q.defer(); deferred = $q.defer();
if(_.isEmpty(config)){ if(_.isEmpty(config)){
var url = GetBasePath('config'); var url = GetBasePath('config');

View File

@@ -2,8 +2,8 @@
<!-- Menu logo item --> <!-- Menu logo item -->
<a id="main_menu_logo" <a id="main_menu_logo"
href="/#/" href="/#/"
class="MainMenu-logo" class="MainMenu-logo ng-cloak"
ng-if="!licenseMissing" ng-hide="licenseMissing"
ng-class="{'is-loggedOut' : !$root.current_user.username}"> ng-class="{'is-loggedOut' : !$root.current_user.username}">
<img class="MainMenu-logoImage" <img class="MainMenu-logoImage"
ng-src="/static/assets/tower-logo-header.svg"> ng-src="/static/assets/tower-logo-header.svg">
@@ -86,10 +86,10 @@
</span> </span>
<!-- Non-mobile menu items --> <!-- Non-mobile menu items -->
<a class="MainMenu-item MainMenu-item--notMobile MainMenu-item--left" <a class="MainMenu-item MainMenu-item--notMobile MainMenu-item--left ng-cloak"
id="main_menu_projects_link" id="main_menu_projects_link"
href="/#/projects" href="/#/projects"
ng-if="!licenseMissing" ng-hide="licenseMissing"
ng-class="{'is-currentRoute' : isCurrentState('projects'), 'is-loggedOut' : !$root.current_user.username}"> ng-class="{'is-currentRoute' : isCurrentState('projects'), 'is-loggedOut' : !$root.current_user.username}">
<span class="MainMenu-itemText"> <span class="MainMenu-itemText">
PROJECTS PROJECTS
@@ -98,7 +98,7 @@
<a class="MainMenu-item MainMenu-item--notMobile MainMenu-item--left" <a class="MainMenu-item MainMenu-item--notMobile MainMenu-item--left"
id="main_menu_inventories_link" id="main_menu_inventories_link"
href="/#/inventories" href="/#/inventories"
ng-if="!licenseMissing" ng-hide="licenseMissing"
ng-class="{'is-currentRoute' : isCurrentState('inventories'), 'is-loggedOut' : !$root.current_user.username}"> ng-class="{'is-currentRoute' : isCurrentState('inventories'), 'is-loggedOut' : !$root.current_user.username}">
<span class="MainMenu-itemText"> <span class="MainMenu-itemText">
INVENTORIES INVENTORIES
@@ -107,7 +107,7 @@
<a class="MainMenu-item MainMenu-item--notMobile MainMenu-item--left" <a class="MainMenu-item MainMenu-item--notMobile MainMenu-item--left"
id="main_menu_job_templates_link" id="main_menu_job_templates_link"
href="/#/job_templates" href="/#/job_templates"
ng-if="!licenseMissing" ng-hide="licenseMissing"
ng-class="{'is-currentRoute' : isCurrentState('jobTemplates'), 'is-loggedOut' : !$root.current_user.username}"> ng-class="{'is-currentRoute' : isCurrentState('jobTemplates'), 'is-loggedOut' : !$root.current_user.username}">
<span class="MainMenu-itemText"> <span class="MainMenu-itemText">
JOB TEMPLATES JOB TEMPLATES
@@ -116,7 +116,7 @@
<a class="MainMenu-item MainMenu-item--notMobile MainMenu-item--left MainMenu-item--lastLeft" <a class="MainMenu-item MainMenu-item--notMobile MainMenu-item--left MainMenu-item--lastLeft"
id="main_menu_jobs_link" id="main_menu_jobs_link"
href="/#/jobs" href="/#/jobs"
ng-if="!licenseMissing" ng-hide="licenseMissing"
ng-class="{'is-currentRoute' : isCurrentState('jobs'), 'is-loggedOut' : !$root.current_user.username}"> ng-class="{'is-currentRoute' : isCurrentState('jobs'), 'is-loggedOut' : !$root.current_user.username}">
<span class="MainMenu-itemText"> <span class="MainMenu-itemText">
JOBS JOBS
@@ -125,7 +125,7 @@
<a class="MainMenu-item MainMenu-item--notMobile MainMenu-item--user MainMenu-item--right" <a class="MainMenu-item MainMenu-item--notMobile MainMenu-item--user MainMenu-item--right"
id="main_menu_current_user_link" id="main_menu_current_user_link"
ng-href="/#/users/{{ $root.current_user.id }}" ng-href="/#/users/{{ $root.current_user.id }}"
ng-if="!licenseMissing" ng-hide="licenseMissing"
ng-class="{'is-currentRoute' : isCurrentState('users.edit'), 'is-loggedOut' : !$root.current_user.username}" ng-class="{'is-currentRoute' : isCurrentState('users.edit'), 'is-loggedOut' : !$root.current_user.username}"
aw-tool-tip="{{currentUserTip}}" aw-tool-tip="{{currentUserTip}}"
aw-tip-watch="currentUserTip" aw-tip-watch="currentUserTip"
@@ -142,7 +142,7 @@
<a class="MainMenu-item MainMenu-item--notMobile MainMenu-item--right" <a class="MainMenu-item MainMenu-item--notMobile MainMenu-item--right"
id="main_menu_setup_link" id="main_menu_setup_link"
ng-href="/#/setup" ng-href="/#/setup"
ng-if="!licenseMissing" ng-hide="licenseMissing"
ng-class="{'is-currentRoute' : isCurrentState('setup'), 'is-loggedOut' : !$root.current_user.username}" ng-class="{'is-currentRoute' : isCurrentState('setup'), 'is-loggedOut' : !$root.current_user.username}"
aw-tool-tip="Settings" aw-tool-tip="Settings"
data-placement="bottom" data-placement="bottom"
@@ -155,7 +155,7 @@
<a class="MainMenu-item MainMenu-item--notMobile MainMenu-item--right" <a class="MainMenu-item MainMenu-item--notMobile MainMenu-item--right"
id="main_menu_portal_link" id="main_menu_portal_link"
ng-href="/#/portal" ng-href="/#/portal"
ng-if="!licenseMissing" ng-hide="licenseMissing"
ng-class="{'is-currentRoute' : isCurrentState('portalMode'), 'is-loggedOut' : !$root.current_user.username}" ng-class="{'is-currentRoute' : isCurrentState('portalMode'), 'is-loggedOut' : !$root.current_user.username}"
aw-tool-tip="My View" aw-tool-tip="My View"
data-placement="bottom" data-placement="bottom"
@@ -168,7 +168,7 @@
<a class="MainMenu-item MainMenu-item--notMobile MainMenu-item--right" <a class="MainMenu-item MainMenu-item--notMobile MainMenu-item--right"
id="main_menu_docs_link" id="main_menu_docs_link"
ng-href="http://docs.ansible.com/ansible-tower/" ng-href="http://docs.ansible.com/ansible-tower/"
ng-if="!licenseMissing" ng-hide="licenseMissing"
ng-class="{'is-loggedOut' : !$root.current_user.username}" ng-class="{'is-loggedOut' : !$root.current_user.username}"
aw-tool-tip="View Documentation" aw-tool-tip="View Documentation"
data-placement="bottom" data-placement="bottom"
@@ -213,7 +213,7 @@
<button <button
id="main_menu_mobile_toggle_button" id="main_menu_mobile_toggle_button"
class="MainMenu-toggle" class="MainMenu-toggle"
ng-if="!licenseMissing" ng-hide="licenseMissing"
ng-class="{'is-active': !isHiddenOnMobile, 'is-loggedOut' : !$root.current_user.username}" ng-class="{'is-active': !isHiddenOnMobile, 'is-loggedOut' : !$root.current_user.username}"
ng-click="toggleMenu()"> ng-click="toggleMenu()">
<i class="fa fa-bars MainMenu-toggleImage"></i> <i class="fa fa-bars MainMenu-toggleImage"></i>

View File

@@ -0,0 +1,52 @@
/*************************************************
* Copyright (c) 2016 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
export default
[ '$rootScope', '$pendolytics', 'Rest', 'GetBasePath', 'ProcessErrors', '$q',
function ($rootScope, $pendolytics, Rest, GetBasePath, ProcessErrors, $q) {
return {
get: function(){
return this.config;
},
set: function(config){
this.config = config;
},
getConfig: function () {
var config = this.get(),
that = this,
deferred = $q.defer();
if(_.isEmpty(config)){
var url = GetBasePath('config');
Rest.setUrl(url);
var promise = Rest.get();
promise.then(function (response) {
var config = response.data;
that.set(config);
deferred.resolve(response.data);
});
promise.catch(function (response) {
ProcessErrors($rootScope, response.data, response.status, null, {
hdr: 'Error!',
msg: 'Failed to get inventory name. GET returned status: ' +
response.status });
deferred.reject('Could not resolve pendo config.');
});
}
else if(config){
this.set(config);
deferred.resolve(config);
}
else {
deferred.reject('Config not found.');
}
return deferred.promise;
}
};
}
];

View File

@@ -0,0 +1,11 @@
/*************************************************
* Copyright (c) 2016 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
import ConfigService from './config.service';
export default
angular.module('config', [])
.service('ConfigService', ConfigService);

View File

@@ -4,26 +4,32 @@
* All Rights Reserved * All Rights Reserved
*************************************************/ *************************************************/
export default ['$rootScope', 'Rest', 'GetBasePath', 'ProcessErrors', '$http', '$q', export default ['$rootScope', 'Rest', 'GetBasePath', 'ProcessErrors', '$http',
function ($rootScope, Rest, GetBasePath, ProcessErrors, $http, $q) { '$q', 'ConfigService',
function ($rootScope, Rest, GetBasePath, ProcessErrors, $http, $q,
ConfigService) {
var license_info; var license_info;
return { return {
getFeatures: function(){ getFeatures: function(){
var promise; var config = ConfigService.get();
Rest.setUrl(GetBasePath('config')); license_info = config.license_info;
promise = Rest.get(); $rootScope.features = config.license_info.features;
return promise.then(function (data) { return $rootScope.features;
license_info = data.data.license_info; // var promise;
$rootScope.features = data.data.license_info.features; // Rest.setUrl(GetBasePath('config'));
return $rootScope.features; // promise = Rest.get();
}).catch(function (response) { // return promise.then(function (data) {
ProcessErrors($rootScope, response.data, response.status, null, { // license_info = data.data.license_info;
hdr: 'Error!', // $rootScope.features = data.data.license_info.features;
msg: 'Failed to get license info. GET returned status: ' + // return $rootScope.features;
response.status // }).catch(function (response) {
}); // ProcessErrors($rootScope, response.data, response.status, null, {
}); // hdr: 'Error!',
// msg: 'Failed to get license info. GET returned status: ' +
// response.status
// });
// });
}, },
get: function(){ get: function(){
if(_.isEmpty($rootScope.features)){ if(_.isEmpty($rootScope.features)){
@@ -41,9 +47,6 @@ function ($rootScope, Rest, GetBasePath, ProcessErrors, $http, $q) {
else { else {
return false; return false;
} }
},
getLicenseInfo: function() {
return license_info;
} }
}; };
}]; }];

View File

@@ -11,10 +11,17 @@ export default function($stateProvider) {
resolve.features = ['FeaturesService', function(FeaturesService) { resolve.features = ['FeaturesService', function(FeaturesService) {
return FeaturesService.get(); return FeaturesService.get();
}]; }];
// resolve.features = ['CheckLicense', 'Store', '$state',
// function(CheckLicense, Store, $state) {
// var license = Store('license');
// if(CheckLicense.valid(license)=== false){
// $state.go('license');
// }
// }];
return resolve; return resolve;
} }
}, },
addState: function(state) { addState: function(state) {
var route = state.route || state.url, var route = state.route || state.url,
resolve = this.getResolves(state); resolve = this.getResolves(state);