diff --git a/awx/ui/client/src/license/license.controller.js b/awx/ui/client/src/license/license.controller.js
index c5b5fcf532..9f160dc9c6 100644
--- a/awx/ui/client/src/license/license.controller.js
+++ b/awx/ui/client/src/license/license.controller.js
@@ -10,34 +10,42 @@ export default
['Wait', '$state', '$scope', '$rootScope',
'ProcessErrors', 'CheckLicense', 'moment','$window',
'ConfigService', 'FeaturesService', 'pendoService', 'i18n', 'config',
- function( Wait, $state, $scope, $rootScope,
- ProcessErrors, CheckLicense, moment, $window, ConfigService,
- FeaturesService, pendoService, i18n, config){
+ function(Wait, $state, $scope, $rootScope, ProcessErrors, CheckLicense, moment,
+ $window, ConfigService, FeaturesService, pendoService, i18n, config) {
- var calcDaysRemaining = function(seconds){
- // calculate the number of days remaining on the license
- var duration = moment.duration(seconds, 'seconds').asDays();
- duration = Math.floor(duration);
- if(duration < 0 ){
- duration = 0;
- }
- duration = (duration!==1) ? `${duration} Days` : `${duration} Day`;
- return duration;
- };
+ var calcDaysRemaining = function(seconds) {
+ // calculate the number of days remaining on the license
+ var duration = moment.duration(seconds, 'seconds').asDays();
- var calcExpiresOn = function(seconds){
+ duration = Math.floor(duration);
+ if(duration < 0){
+ duration = 0;
+ }
+
+ duration = (duration!==1) ? `${duration} Days` : `${duration} Day`;
+
+ return duration;
+ };
+
+ var calcExpiresOn = function(seconds) {
// calculate the expiration date of the license
return moment.unix(seconds).calendar();
};
- var reset = function(){
+ var reset = function() {
document.getElementById('License-form').reset();
};
- var init = function(config){
+ var init = function(config) {
// license/license.partial.html compares fileName
$scope.fileName = N_("No file selected.");
- $scope.title = $rootScope.licenseMissing ? ($rootScope.BRAND_NAME + i18n._(" License")) : i18n._("License Management");
+
+ if ($rootScope.licenseMissing) {
+ $scope.title = $rootScope.BRAND_NAME + i18n._(" License");
+ } else {
+ $scope.title = i18n._("License Management")
+ }
+
$scope.license = config;
$scope.license.version = config.version.split('-')[0];
$scope.time = {};
@@ -45,71 +53,80 @@ export default
$scope.time.expiresOn = calcExpiresOn($scope.license.license_info.license_date);
$scope.valid = CheckLicense.valid($scope.license.license_info);
$scope.compliant = $scope.license.license_info.compliant;
+ $scope.newLicense = {};
+
+ $scope.newLicense.pendo = true;
};
init(config);
- $scope.getKey = function(event){
+ $scope.getKey = function(event) {
// Mimic HTML5 spec, show filename
$scope.fileName = event.target.files[0].name;
// Grab the key from the raw license file
var raw = new FileReader();
// readAsFoo runs async
- raw.onload = function(){
+ raw.onload = function() {
try {
$scope.newLicense.file = JSON.parse(raw.result);
- }
- catch(err) {
- ProcessErrors($rootScope, null, null, null, {msg: i18n._('Invalid file format. Please upload valid JSON.')});
+ } catch(err) {
+ ProcessErrors($rootScope, null, null, null,
+ {msg: i18n._('Invalid file format. Please upload valid JSON.')});
}
};
+
try {
raw.readAsText(event.target.files[0]);
- }
- catch(err) {
- ProcessErrors($rootScope, null, null, null, {msg: i18n._('Invalid file format. Please upload valid JSON.')});
+ } catch(err) {
+ ProcessErrors($rootScope, null, null, null,
+ {msg: i18n._('Invalid file format. Please upload valid JSON.')});
}
};
+
// HTML5 spec doesn't provide a way to customize file input css
// So we hide the default input, show our own, and simulate clicks to the hidden input
- $scope.fakeClick = function(){
+ $scope.fakeClick = function() {
if($scope.user_is_superuser) {
$('#License-file').click();
}
};
- $scope.downloadLicense = function(){
+ $scope.downloadLicense = function() {
$window.open('https://www.ansible.com/license', '_blank');
};
- $scope.newLicense = {};
- $scope.submit = function(){
- Wait('start');
- CheckLicense.post($scope.newLicense.file, $scope.newLicense.eula)
- .then(() => {
- reset();
+ $scope.submit = function() {
+ Wait('start');
+ CheckLicense.post($scope.newLicense.file, $scope.newLicense.eula)
+ .then(() => {
+ reset();
+
ConfigService.delete();
- ConfigService.getConfig().then(function(config){
- delete($rootScope.features);
- FeaturesService.get();
- pendoService.issuePendoIdentity();
- if($rootScope.licenseMissing === true){
- $state.go('dashboard', {
- licenseMissing: false
- });
- }
- else{
- init(config);
- $scope.success = true;
- $rootScope.licenseMissing = false;
- // for animation purposes
- var successTimeout = setTimeout(function(){
- $scope.success = false;
- clearTimeout(successTimeout);
- }, 4000);
- }
- });
- });
- };
- }
-];
+ ConfigService.getConfig()
+ .then(function(config) {
+ delete($rootScope.features);
+ FeaturesService.get();
+
+ if ($scope.newLicense.pendo) {
+ pendoService.updatePendoTrackingState('detailed');
+ pendoService.issuePendoIdentity();
+ }
+
+ if ($rootScope.licenseMissing === true) {
+ $state.go('dashboard', {
+ licenseMissing: false
+ });
+ } else {
+ init(config);
+ $scope.success = true;
+ $rootScope.licenseMissing = false;
+ // for animation purposes
+ var successTimeout = setTimeout(function() {
+ $scope.success = false;
+ clearTimeout(successTimeout);
+ }, 4000);
+ }
+ });
+ });
+ };
+}];
diff --git a/awx/ui/client/src/license/license.partial.html b/awx/ui/client/src/license/license.partial.html
index 7b8bfe3499..dd3e8dad32 100644
--- a/awx/ui/client/src/license/license.partial.html
+++ b/awx/ui/client/src/license/license.partial.html
@@ -122,6 +122,19 @@
+
Save successful!
diff --git a/awx/ui/client/src/login/authenticationServices/pendo.service.js b/awx/ui/client/src/login/authenticationServices/pendo.service.js
index 977fddc15c..77eba980ce 100644
--- a/awx/ui/client/src/login/authenticationServices/pendo.service.js
+++ b/awx/ui/client/src/login/authenticationServices/pendo.service.js
@@ -5,87 +5,78 @@
*************************************************/
-export default
- [ '$rootScope', 'Rest', 'GetBasePath', 'ProcessErrors', '$q',
- 'ConfigService', '$log', 'AppStrings',
- function ($rootScope, Rest, GetBasePath, ProcessErrors, $q,
- ConfigService, $log, AppStrings) {
- return {
+export default ['$rootScope', 'Rest', 'GetBasePath', 'ProcessErrors', '$q', 'ConfigService', '$log',
+ 'AppStrings',
+ function ($rootScope, Rest, GetBasePath, ProcessErrors, $q, ConfigService, $log, AppStrings) {
+ return {
setPendoOptions: function (config) {
- var tower_version = config.version.split('-')[0],
- trial = (config.trial) ? config.trial : false,
- options = {
+ const tower_version = config.version.split('-')[0];
+ const trial = (config.trial) ? config.trial : false;
+ let options = {
apiKey: AppStrings.get('PENDO_API_KEY'),
visitor: {
- id: null,
- role: null,
+ id: null,
+ role: null,
},
account: {
- id: null,
- planLevel: config.license_type,
- planPrice: config.instance_count,
- creationDate: config.license_date,
- trial: trial,
- tower_version: tower_version,
- ansible_version: config.ansible_version
+ id: null,
+ planLevel: config.license_type,
+ planPrice: config.instance_count,
+ creationDate: config.license_date,
+ trial: trial,
+ tower_version: tower_version,
+ ansible_version: config.ansible_version
}
};
- if(config.analytics_status === 'detailed'){
+
+ if (config.analytics_status === 'detailed') {
this.setDetailed(options, config);
- }
- else if(config.analytics_status === 'anonymous'){
+ } else if (config.analytics_status === 'anonymous') {
this.setAnonymous(options);
}
- return options;
+ return options;
},
setDetailed: function(options, config) {
- // Detailed mode
- // VisitorId: userid+hash of license_key
- // AccountId: hash of license_key from license
-
+ // config.deployment_id is a hash of the tower license_key
options.visitor.id = $rootScope.current_user.id + '@' + config.deployment_id;
options.account.id = config.deployment_id;
},
setAnonymous: function (options) {
- //Anonymous mode
- // VisitorId:
- // AccountId:
-
options.visitor.id = 0;
options.account.id = "tower.ansible.com";
},
setRole: function(options) {
var deferred = $q.defer();
- if($rootScope.current_user.is_superuser === true){
+
+ if ($rootScope.current_user.is_superuser === true) {
options.visitor.role = 'admin';
deferred.resolve(options);
+ } else {
+ Rest.setUrl(GetBasePath('users') + $rootScope.current_user.id +
+ '/admin_of_organizations/');
+ Rest.get()
+ .then(function (response) {
+ if (response.data.count > 0) {
+ options.visitor.role = "orgadmin";
+ deferred.resolve(options);
+ } else {
+ options.visitor.role = "user";
+ deferred.resolve(options);
+ }
+ })
+ .catch(function (response) {
+ ProcessErrors($rootScope, response.data, response.status, null, {
+ hdr: 'Error!',
+ msg: 'Failed to get admin of org user list. GET returned status: ' +
+ response.status });
+ deferred.reject('Could not resolve pendo role.');
+ });
}
- else{
- var url = GetBasePath('users') + $rootScope.current_user.id + '/admin_of_organizations/';
- Rest.setUrl(url);
- var promise = Rest.get();
- promise.then(function (response) {
- if(response.data.count > 0 ) {
- options.visitor.role = "orgadmin";
- deferred.resolve(options);
- }
- else {
- options.visitor.role = "user";
- deferred.resolve(options);
- }
- });
- 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 role.');
- });
- }
+
return deferred.promise;
},
@@ -107,24 +98,44 @@ export default
config.analytics_status = c.analytics_status;
config.version = c.version;
config.ansible_version = c.ansible_version;
- if(config.analytics_status === 'detailed' || config.analytics_status === 'anonymous'){
- this.bootstrap();
- options = this.setPendoOptions(config);
- this.setRole(options).then(function(options){
- $log.debug('Pendo status is '+ config.analytics_status + '. Object below:');
- $log.debug(options);
- /* jshint ignore:start */
- pendo.initialize(options);
- /* jshint ignore:end */
- }, function(reason){
- // reject function for setRole
- $log.debug(reason);
- });
- }
- else {
+
+ if (config.analytics_status === 'detailed' ||
+ config.analytics_status === 'anonymous') {
+ this.bootstrap();
+ options = this.setPendoOptions(config);
+ this.setRole(options)
+ .then(function(options){
+ $log.debug('Pendo status is '+ config.analytics_status +
+ '. Object below:');
+ $log.debug(options);
+
+ /* jshint ignore:start */
+ pendo.initialize(options);
+ /* jshint ignore:end */
+ }, function(reason){
+ // reject function for setRole
+ $log.debug(reason);
+ });
+ } else {
$log.debug('Pendo is turned off.');
}
- }
+ },
+
+ updatePendoTrackingState: function(tracking_type) {
+ if (tracking_type === 'off' || tracking_type === 'anonymous' ||
+ tracking_type === 'detailed') {
+ Rest.setUrl(`${GetBasePath('settings')}ui`);
+ Rest.patch({ PENDO_TRACKING_STATE: tracking_type })
+ .catch(function ({data, status}) {
+ ProcessErrors($rootScope, data, status, null, {
+ hdr: 'Error!',
+ msg: 'Failed to patch PENDO_TRACKING_STATE in settings: ' +
+ status });
+ });
+ } else {
+ throw new Error(`Can't update pendo tracking state in settings to
+ "${tracking_type}"`);
+ }
+ }
};
- }
-];
+ }];