AC-725 Added tower version to app footer and license dialog. Refactored license dialog to use tabs rather than accordions. Fixed conflict between angular routes and TB tabs.

This commit is contained in:
Chris Houseknecht
2014-02-13 19:01:17 +00:00
parent 9aea64eb3f
commit c77db691eb
9 changed files with 66 additions and 46 deletions

View File

@@ -446,8 +446,11 @@ angular.module('ansible', [
}; };
$rootScope.viewLicense = function () { $rootScope.viewLicense = function () {
//$location.path('/license');
ViewLicense(); ViewLicense();
}; };
$rootScope.toggleTab = function(e, tab, tabs) {
e.preventDefault();
$('#' + tabs + ' #' + tab).tab('show');
};
} }
]); ]);

View File

@@ -104,7 +104,7 @@ function Authenticate($cookieStore, $window, $scope, $rootScope, $location, Auth
$rootScope.user_is_superuser = data.results[0].is_superuser; $rootScope.user_is_superuser = data.results[0].is_superuser;
Authorization.getLicense() Authorization.getLicense()
.success(function (data) { .success(function (data) {
Authorization.setLicense(data.license_info); Authorization.setLicense(data);
if (lastPath()) { if (lastPath()) {
// Go back to most recent navigation path // Go back to most recent navigation path
$location.path(lastPath()); $location.path(lastPath());
@@ -114,12 +114,12 @@ function Authenticate($cookieStore, $window, $scope, $rootScope, $location, Auth
}) })
.error(function () { .error(function () {
Wait('stop'); Wait('stop');
Alert('Error', 'Failed to access user information. GET returned status: ' + status, 'alert-danger', setLoginFocus); Alert('Error', 'Failed to access license information. GET returned status: ' + status, 'alert-danger', setLoginFocus);
}); });
}) })
.error(function (data, status) { .error(function (data, status) {
Wait('stop'); Wait('stop');
Alert('Error', 'Failed to access license information. GET returned status: ' + status, 'alert-danger', setLoginFocus); Alert('Error', 'Failed to access user information. GET returned status: ' + status, 'alert-danger', setLoginFocus);
}); });
}) })
.error(function (data, status) { .error(function (data, status) {

View File

@@ -13,7 +13,17 @@ angular.module('LicenseFormDefinition', [])
name: 'license', name: 'license',
well: false, well: false,
forceListeners: true,
tabs: [{
name: 'license',
label: 'License'
}, {
name: 'managed',
label: 'Managed Hosts'
},{
name: 'contact',
label: 'Contact Info'
}],
fields: { fields: {
license_status: { license_status: {
@@ -21,64 +31,64 @@ angular.module('LicenseFormDefinition', [])
control: "<div class=\"license-status\" ng-class=\"status_color\"><i class=\"fa fa-circle\"></i> " + control: "<div class=\"license-status\" ng-class=\"status_color\"><i class=\"fa fa-circle\"></i> " +
"{{ license_status }}</span></div>", "{{ license_status }}</span></div>",
readonly: true, readonly: true,
section: 'License' tab: 'license'
}, },
license_key: { license_key: {
label: 'Key', label: 'Key',
type: 'textarea', type: 'textarea',
'class': 'modal-input-xlarge', 'class': 'modal-input-xlarge',
readonly: true, readonly: true,
section: 'License' tab: 'license'
}, },
license_date: { license_date: {
label: 'Expires On', label: 'Expires On',
type: 'text', type: 'text',
readonly: true, readonly: true,
section: 'License' tab: 'license'
}, },
time_remaining: { time_remaining: {
label: 'Time Left', label: 'Time Left',
type: 'text', type: 'text',
readonly: true, readonly: true,
section: 'License' tab: 'license'
}, },
available_instances: { available_instances: {
label: 'Available', label: 'Available',
type: 'text', type: 'text',
readonly: true, readonly: true,
section: 'Managed Hosts' tab: 'managed'
}, },
current_instances: { current_instances: {
label: 'Used', label: 'Used',
type: 'text', type: 'text',
readonly: true, readonly: true,
section: 'Managed Hosts' tab: 'managed'
}, },
free_instances: { free_instances: {
label: 'Remaining', label: 'Remaining',
type: 'text', type: 'text',
readonly: true, readonly: true,
section: 'Managed Hosts',
controlNGClass: 'free_instances_class', controlNGClass: 'free_instances_class',
labelNGClass: 'free_instances_class' labelNGClass: 'free_instances_class',
tab: 'managed'
}, },
company_name: { company_name: {
label: 'Company', label: 'Company',
type: 'text', type: 'text',
readonly: true, readonly: true,
section: 'Contact Info' tab: 'contact'
}, },
contact_name: { contact_name: {
label: 'Contact', label: 'Contact',
type: 'text', type: 'text',
readonly: true, readonly: true,
section: 'Contact Info' tab: 'contact'
}, },
contact_email: { contact_email: {
label: 'Contact Email', label: 'Contact Email',
type: 'text', type: 'text',
readonly: true, readonly: true,
section: 'Contact Info' tab: 'contact'
} }
} }
}); });

View File

@@ -48,13 +48,13 @@ angular.module('AccessHelper', ['RestServices', 'Utilities', 'ngCookies'])
} }
]) ])
.factory('CheckLicense', ['$rootScope', '$cookieStore', 'Alert', '$location', 'Authorization', .factory('CheckLicense', ['$rootScope', 'Store', 'Alert', '$location', 'Authorization',
function ($rootScope, $cookieStore, Alert, $location, Authorization) { function ($rootScope, Store, Alert, $location, Authorization) {
return function () { return function () {
// Check license status and alert the user, if needed // Check license status and alert the user, if needed
var status = 'success', var status = 'success',
hdr, msg, hdr, msg,
license = $cookieStore.get('license'), license = Store('license'),
purchase_msg = '<p>To purchase a license or extend an existing license ' + purchase_msg = '<p>To purchase a license or extend an existing license ' +
'<a href="http://www.ansible.com/ansible-pricing" target="_blank"><strong>visit the Ansible online store</strong></a>, ' + '<a href="http://www.ansible.com/ansible-pricing" target="_blank"><strong>visit the Ansible online store</strong></a>, ' +
'or visit <strong><a href="https://support.ansible.com" target="_blank">support.ansible.com</a></strong> for assistance.</p>'; 'or visit <strong><a href="https://support.ansible.com" target="_blank">support.ansible.com</a></strong> for assistance.</p>';
@@ -62,9 +62,9 @@ angular.module('AccessHelper', ['RestServices', 'Utilities', 'ngCookies'])
if (license && !Authorization.licenseTested()) { if (license && !Authorization.licenseTested()) {
// This is our first time evaluating the license // This is our first time evaluating the license
license.tested = true; license.tested = true;
$cookieStore.remove('license'); Store('license',license); //update with tested flag
$cookieStore.put('license', license);
$rootScope.license_tested = true; $rootScope.license_tested = true;
$rootScope.version = license.version;
if (license.valid_key !== undefined && license.valid_key === false) { if (license.valid_key !== undefined && license.valid_key === false) {
// The license is invalid. Stop the user from logging in. // The license is invalid. Stop the user from logging in.
status = 'alert-danger'; status = 'alert-danger';

View File

@@ -185,6 +185,11 @@ textarea {
font-size: 16px; font-size: 16px;
} }
.license-version {
font-size: 18px;
color: @grey-txt;
}
.modal-dialog .ui-accordion .ui-accordion-content { .modal-dialog .ui-accordion .ui-accordion-content {
overflow: hidden; overflow: hidden;
} }
@@ -454,7 +459,7 @@ dd {
} }
.copyright { .copyright {
padding-top: 18px; padding-top: 6px;
font-weight: normal; font-weight: normal;
text-align: center; text-align: center;
} }

View File

@@ -11,8 +11,8 @@
angular.module('AuthService', ['ngCookies', 'Utilities']) angular.module('AuthService', ['ngCookies', 'Utilities'])
.factory('Authorization', ['$http', '$rootScope', '$location', '$cookieStore', 'GetBasePath', .factory('Authorization', ['$http', '$rootScope', '$location', '$cookieStore', 'GetBasePath', 'Store',
function ($http, $rootScope, $location, $cookieStore, GetBasePath) { function ($http, $rootScope, $location, $cookieStore, GetBasePath, Store) {
return { return {
setToken: function (token, expires) { setToken: function (token, expires) {
// set the session cookie // set the session cookie
@@ -63,7 +63,6 @@ angular.module('AuthService', ['ngCookies', 'Utilities'])
$cookieStore.remove('token_expires'); $cookieStore.remove('token_expires');
$cookieStore.remove('current_user'); $cookieStore.remove('current_user');
$cookieStore.remove('lastPath'); $cookieStore.remove('lastPath');
$cookieStore.remove('license');
$cookieStore.put('userLoggedIn', false); $cookieStore.put('userLoggedIn', false);
$cookieStore.put('sessionExpired', false); $cookieStore.put('sessionExpired', false);
$cookieStore.remove('lastPath', '/home'); $cookieStore.remove('lastPath', '/home');
@@ -86,9 +85,11 @@ angular.module('AuthService', ['ngCookies', 'Utilities'])
}); });
}, },
setLicense: function (license) { setLicense: function (data) {
var license = data.license_info;
license.version = data.version;
license.tested = false; license.tested = false;
$cookieStore.put('license', license); Store('license', license);
}, },
licenseTested: function () { licenseTested: function () {
@@ -96,7 +97,9 @@ angular.module('AuthService', ['ngCookies', 'Utilities'])
if ($rootScope.license_tested !== undefined) { if ($rootScope.license_tested !== undefined) {
result = $rootScope.license_tested; result = $rootScope.license_tested;
} else { } else {
license = $cookieStore.get('license'); // User may have hit browser refresh
license = Store('license');
$rootScope.version = license.version;
if (license && license.tested !== undefined) { if (license && license.tested !== undefined) {
result = license.tested; result = license.tested;
} else { } else {

View File

@@ -1161,7 +1161,9 @@ angular.module('FormGenerator', ['GeneratorHelpers', 'ngCookies', 'Utilities'])
if (i === 0) { if (i === 0) {
html += " class=\"active\""; html += " class=\"active\"";
} }
html += "><a href=\"#" + tab.name + "\" data-toggle=\"tab\">" + tab.label + "</a></li>\n"; html += "><a id=\"" + tab.name + "_link\" ng-click=\"toggleTab($event, '" + tab.name + "_link', '" +
this.form.name + "_tabs')\" href=\"#" + tab.name + "\"" +
tab.name + "\" data-toggle=\"tab\">" + tab.label + "</a></li>\n";
} }
html += "</ul>\n"; html += "</ul>\n";
html += "<div class=\"tab-content\">\n"; html += "<div class=\"tab-content\">\n";

View File

@@ -51,11 +51,7 @@ angular.module('License', ['RestServices', 'Utilities', 'FormGenerator', 'Prompt
scope.formModalActionLabel = 'OK'; scope.formModalActionLabel = 'OK';
scope.formModalCancelShow = false; scope.formModalCancelShow = false;
scope.formModalInfo = 'Purchase/Extend License'; scope.formModalInfo = 'Purchase/Extend License';
scope.formModalHeader = 'Tower License'; scope.formModalHeader = "Ansible Tower <span class=\"license-version\">v." + data.version + "</span>";
//$('#form-modal .btn-success').removeClass('btn-success').addClass('btn-none');
//$('#form-modal').addClass('skinny-modal');
// Respond to license button // Respond to license button
scope.formModalInfoAction = function () { scope.formModalInfoAction = function () {
@@ -126,7 +122,7 @@ angular.module('License', ['RestServices', 'Utilities', 'FormGenerator', 'Prompt
}) })
.error(function (data, status) { .error(function (data, status) {
ProcessErrors($rootScope, data, status, form, { hdr: 'Error!', ProcessErrors($rootScope, data, status, null, { hdr: 'Error!',
msg: 'Failed to retrieve license. GET status: ' + status msg: 'Failed to retrieve license. GET status: ' + status
}); });
}); });

View File

@@ -164,15 +164,15 @@
<div class="row"> <div class="row">
<div class="col-lg-12"> <div class="col-lg-12">
<ul class="nav nav-tabs" id="main_tabs"> <ul class="nav nav-tabs" id="main_tabs">
<li class="active"><a href="#home" id="main_home_tab" data-toggle="tab">Home</a></li> <li class="active"><a href="#home" id="main_home_tab" data-toggle="tab" class="main-tab-link">Home</a></li>
<li><a href="#organizations" id="main_organizations_tab" data-toggle="tab">Organizations</a></li> <li><a href="#organizations" id="main_organizations_tab" class="main-tab-link" data-toggle="tab">Organizations</a></li>
<li><a href="#users" id="main_users_tab" data-toggle="tab">Users</a></li> <li><a href="#users" id="main_users_tab" data-toggle="tab" class="main-tab-link">Users</a></li>
<li><a href="#teams" id="main_teams_tab" data-toggle="tab">Teams</a></li> <li><a href="#teams" id="main_teams_tab" data-toggle="tab" class="main-tab-link">Teams</a></li>
<li><a href="#credentials" id="main_credentials_tab" data-toggle="tab">Credentials</a></li> <li><a href="#credentials" id="main_credentials_tab" data-toggle="tab" class="main-tab-link">Credentials</a></li>
<li><a href="#projects" id="main_projects_tab" data-toggle="tab">Projects</a></li> <li><a href="#projects" id="main_projects_tab" data-toggle="tab" class="main-tab-link">Projects</a></li>
<li><a href="#inventories" id="main_inventories_tab" data-toggle="tab">Inventories</a></li> <li><a href="#inventories" id="main_inventories_tab" data-toggle="tab" class="main-tab-link">Inventories</a></li>
<li><a href="#job_templates" id="main_job_templates_tab" data-toggle="tab">Job Templates</a></li> <li><a href="#job_templates" id="main_job_templates_tab" data-toggle="tab" class="main-tab-link">Job Templates</a></li>
<li><a href="#jobs" id="main_jobs_tab" data-toggle="tab">Jobs</a></li> <li><a href="#jobs" id="main_jobs_tab" data-toggle="tab" class="main-tab-link">Jobs</a></li>
</ul> </ul>
<div class="tab-content" id="tab-content-container"> <div class="tab-content" id="tab-content-container">
@@ -374,7 +374,7 @@
target="_blank"><i class="fa fa-question-circle"></i> Contact Support</a> target="_blank"><i class="fa fa-question-circle"></i> Contact Support</a>
</div> </div>
<div class="col-lg-6 text-center copyright"> <div class="col-lg-6 text-center copyright">
<a href="http://www.ansible.com">Copyright &copy; 2014 AnsibleWorks, Inc. All rights reserved.</a> <a href="http://www.ansible.com">Ansible Tower <span ng-bind="version"></span><br />Copyright &copy; 2014 Ansible, Inc. All rights reserved.</a>
</div> </div>
<div class="col-lg-3"> <div class="col-lg-3">
<div class="logo"> <div class="logo">
@@ -391,6 +391,7 @@
<script src="{{ STATIC_URL }}lib/jqueryui/ui/minified/jquery-ui.min.js"></script> <script src="{{ STATIC_URL }}lib/jqueryui/ui/minified/jquery-ui.min.js"></script>
<script> <script>
// When user clicks on main tab, fire the matching Angular route
$('a[data-toggle="tab"]').on('show.bs.tab', function (e) { $('a[data-toggle="tab"]').on('show.bs.tab', function (e) {
var url = $(e.target).text(); var url = $(e.target).text();
var regx = new RegExp('/\#\/' + url.toLowerCase().replace(/ /g,'_') + '/'); var regx = new RegExp('/\#\/' + url.toLowerCase().replace(/ /g,'_') + '/');
@@ -398,7 +399,7 @@
if (! regx.test(loc)) { if (! regx.test(loc)) {
window.location = '#/' + url.toLowerCase().replace(/ /g,'_'); window.location = '#/' + url.toLowerCase().replace(/ /g,'_');
} }
}); });
</script> </script>
</body> </body>