From 44d9d12e4d0a452a22e5b9b9b1595bac1add9448 Mon Sep 17 00:00:00 2001
From: chris Houseknecht
Date: Thu, 23 Jan 2014 16:38:39 -0500
Subject: [PATCH] AC-966,AC-967,AC-968,AC-973,AC-972: fixed links, titles,
texts referencing AWX and ansibleworks. Fixed AC-941 issues also for
Credentials and Projects tab. Upgraded projects status to use jquery dialog,
allowing user to expand and move.
---
awx/ui/static/js/controllers/Credentials.js | 6 +-
awx/ui/static/js/controllers/Projects.js | 12 ++-
awx/ui/static/js/forms/Groups.js | 8 +-
awx/ui/static/js/forms/Hosts.js | 2 +-
awx/ui/static/js/forms/Inventories.js | 2 +-
awx/ui/static/js/forms/JobTemplates.js | 15 ++--
awx/ui/static/js/forms/Jobs.js | 6 +-
awx/ui/static/js/forms/ProjectStatus.js | 2 +
awx/ui/static/js/forms/Projects.js | 6 +-
awx/ui/static/js/helpers/Access.js | 39 ++++----
awx/ui/static/js/helpers/Groups.js | 3 +-
awx/ui/static/js/helpers/Jobs.js | 14 ++-
awx/ui/static/js/helpers/Projects.js | 93 +++++++++++++++----
awx/ui/static/js/lists/Jobs.js | 2 +-
awx/ui/static/lib/ansible/form-generator.js | 99 ++++++++++++++-------
awx/ui/static/lib/ansible/license.js | 16 ++--
awx/ui/static/partials/projects.html | 1 +
awx/ui/templates/ui/index.html | 6 +-
18 files changed, 220 insertions(+), 112 deletions(-)
diff --git a/awx/ui/static/js/controllers/Credentials.js b/awx/ui/static/js/controllers/Credentials.js
index 299f785724..21404ec788 100644
--- a/awx/ui/static/js/controllers/Credentials.js
+++ b/awx/ui/static/js/controllers/Credentials.js
@@ -14,9 +14,10 @@ function CredentialsList ($scope, $rootScope, $location, $log, $routeParams, Res
GenerateList, LoadBreadCrumbs, Prompt, SearchInit, PaginateInit, ReturnToCaller,
ClearScope, ProcessErrors, GetBasePath, SelectionInit, GetChoices, Wait, Stream)
{
- ClearScope('tree-form');
ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior
- //scope.
+ //scope.
+ Wait('start');
+
var list = CredentialList;
var defaultUrl = GetBasePath('credentials');
var view = GenerateList;
@@ -24,6 +25,7 @@ function CredentialsList ($scope, $rootScope, $location, $log, $routeParams, Res
var mode = (base == 'credentials') ? 'edit' : 'select'; // if base path 'credentials', we're here to add/edit
var scope = view.inject(list, { mode: mode }); // Inject our view
scope.selected = [];
+ scope.credentialLoading = true;
var url = GetBasePath(base);
url += (base == 'users') ? $routeParams.user_id + '/credentials/' : $routeParams.team_id + '/credentials/';
diff --git a/awx/ui/static/js/controllers/Projects.js b/awx/ui/static/js/controllers/Projects.js
index ac5e99bc56..e23623d3f7 100644
--- a/awx/ui/static/js/controllers/Projects.js
+++ b/awx/ui/static/js/controllers/Projects.js
@@ -15,17 +15,20 @@ function ProjectsList ($scope, $rootScope, $location, $log, $routeParams, Rest,
ClearScope, ProcessErrors, GetBasePath, SelectionInit, ProjectUpdate, ProjectStatus,
FormatDate, Refresh, Wait, Stream, GetChoices)
{
- ClearScope('tree-form');
ClearScope('htmlTemplate');
+ Wait('start');
+
var list = ProjectList;
var defaultUrl = GetBasePath('projects');
var view = GenerateList;
var base = $location.path().replace(/^\//,'').split('/')[0];
var mode = (base == 'projects') ? 'edit' : 'select';
var scope = view.inject(list, { mode: mode });
- $rootScope.flashMessage = null;
+ $rootScope.flashMessage = null;
+ scope.projectLoading = true;
+
var url = (base == 'teams') ? GetBasePath('teams') + $routeParams.team_id + '/projects/' : defaultUrl;
if (mode == 'select') {
@@ -179,9 +182,11 @@ function ProjectsList ($scope, $rootScope, $location, $log, $routeParams, Rest,
}
if (project.scm_type !== null) {
if (project.related.current_update) {
+ Wait('start');
ProjectStatus({ project_id: id, last_update: project.related.current_update });
}
else if (project.related.last_update) {
+ Wait('start');
ProjectStatus({ project_id: id, last_update: project.related.last_update });
}
else {
@@ -197,8 +202,7 @@ function ProjectsList ($scope, $rootScope, $location, $log, $routeParams, Rest,
});
// Refresh the project list so we're looking at the latest data
- scope.search(list.iterator);
-
+ scope.search(list.iterator, null, false, true);
}
scope.deleteProject = function(id, name) {
diff --git a/awx/ui/static/js/forms/Groups.js b/awx/ui/static/js/forms/Groups.js
index a24b8f8933..1a9691dee9 100644
--- a/awx/ui/static/js/forms/Groups.js
+++ b/awx/ui/static/js/forms/Groups.js
@@ -56,7 +56,7 @@ angular.module('GroupFormDefinition', [])
"YAML:
\n" +
"---
somevar: somevalue
password: magic
\n" +
'View JSON examples at www.json.org
' +
- 'View YAML examples at ansibleworks.com
',
+ 'View YAML examples at docs.ansible.com
',
dataContainer: 'body',
tab: 'properties'
},
@@ -98,7 +98,7 @@ angular.module('GroupFormDefinition', [])
dataTitle: 'Source Regions',
dataPlacement: 'right',
awPopOver: "Click on the regions field to see a list of regions for your cloud provider. You can select multiple regions, " +
- "or choose All to include all regions. AWX will only be updated with Hosts associated with the selected regions." +
+ "or choose All to include all regions. Tower will only be updated with Hosts associated with the selected regions." +
"
",
dataContainer: 'body',
tab: 'source'
@@ -123,7 +123,7 @@ angular.module('GroupFormDefinition', [])
"YAML:
\n" +
"---
somevar: somevalue
password: magic
\n" +
'View JSON examples at www.json.org
' +
- 'View YAML examples at ansibleworks.com
',
+ 'View YAML examples at docs.ansible.com
',
dataContainer: 'body',
tab: 'source'
},
@@ -137,7 +137,7 @@ angular.module('GroupFormDefinition', [])
'default': { label: 'none', value: 0 },
dataTitle: 'Update Interval',
dataPlacement: 'left',
- awPopOver: "Instruct the AWX server to automatically run the inventory update process the selected number of minutes from " +
+ awPopOver: "
Automatically run the inventory update process the selected number of minutes from " +
"the last run.
With a value set, task manager will periodically compare the amount of elapsed time from the last run. If enough time " +
"has elapsed, it will go ahead and start an inventory update process.
",
dataContainer: 'body'
diff --git a/awx/ui/static/js/forms/Hosts.js b/awx/ui/static/js/forms/Hosts.js
index 391bd2ab0d..4431c992ed 100644
--- a/awx/ui/static/js/forms/Hosts.js
+++ b/awx/ui/static/js/forms/Hosts.js
@@ -66,7 +66,7 @@ angular.module('HostFormDefinition', [])
"YAML:
\n" +
"---
somevar: somevalue
password: magic
\n" +
'View JSON examples at www.json.org
' +
- 'View YAML examples at ansibleworks.com
',
+ 'View YAML examples at docs.ansible.com
',
dataTitle: 'Host Variables',
dataPlacement: 'right',
dataContainer: '#form-modal .modal-content'
diff --git a/awx/ui/static/js/forms/Inventories.js b/awx/ui/static/js/forms/Inventories.js
index 11134facba..d30e52b9a6 100644
--- a/awx/ui/static/js/forms/Inventories.js
+++ b/awx/ui/static/js/forms/Inventories.js
@@ -68,7 +68,7 @@ angular.module('InventoryFormDefinition', [])
"YAML:
\n" +
"---
somevar: somevalue
password: magic
\n" +
'View JSON examples at www.json.org
' +
- 'View YAML examples at ansibleworks.com
',
+ 'View YAML examples at docs.ansible.com
',
dataTitle: 'Inventory Variables',
dataPlacement: 'right',
dataContainer: 'body'
diff --git a/awx/ui/static/js/forms/JobTemplates.js b/awx/ui/static/js/forms/JobTemplates.js
index ef7776334c..274a4a0d13 100644
--- a/awx/ui/static/js/forms/JobTemplates.js
+++ b/awx/ui/static/js/forms/JobTemplates.js
@@ -139,7 +139,9 @@ angular.module('JobTemplateFormDefinition', [])
editRequired: false,
'class': "input-small",
column: 1,
- awPopOver: "The number of parallel or simultaneous processes to use while executing the playbook.
",
+ awPopOver: 'The number of parallel or simultaneous processes to use while executing the playbook. 0 signifies ' +
+ 'the default value from the ansible configuration file.
',
dataTitle: 'Forks',
dataPlacement: 'right',
dataContainer: "body"
@@ -151,9 +153,8 @@ angular.module('JobTemplateFormDefinition', [])
editRequired: false,
column: 1,
awPopOver: "Provide a host pattern to further constrain the list of hosts that will be managed or affected by the playbook. " +
- "Multiple patterns can be separated by ; : or ,
For more information and examples see the " +
- "Selecting Targets section under Inventory and Patterns " +
- " in the Ansible documentation.
",
+ "Multiple patterns can be separated by ; : or ,
For more information and examples see " +
+ "the Patters top at docs.ansible.com.
",
dataTitle: 'Limit',
dataPlacement: 'right',
dataContainer: "body"
@@ -218,7 +219,7 @@ angular.module('JobTemplateFormDefinition', [])
falseValue: 'false',
ngChange: "toggleCallback('host_config_key')",
column: 2,
- awPopOver: "Create a callback URL a host can use to contact the AWX server and request a configuration update " +
+ awPopOver: "
Create a callback URL a host can use to contact Tower and request a configuration update " +
"using the job template. The URL will look like the following:
\n" +
"http://your.server.com:999/api/v1/job_templates/1/callback/
" +
"The request from the host must be a POST. Here is an example using curl:
\n" +
@@ -240,7 +241,7 @@ angular.module('JobTemplateFormDefinition', [])
column: 2,
required: false,
'class': 'span12',
- awPopOver: "Using this URL a host can contact the AWX server and request a configuration update using the job " +
+ awPopOver: "
Using this URL a host can contact Tower and request a configuration update using the job " +
"template. The request from the host must be a POST. Here is an example using curl:
\n" +
"curl --data \"host_config_key=5a8ec154832b780b9bdef1061764ae5a\" " +
"http://your.server.com:999/api/v1/job_templates/1/callback/
\n" +
@@ -257,7 +258,7 @@ angular.module('JobTemplateFormDefinition', [])
ngShow: "allow_callbacks",
genMD5: true,
column: 2,
- awPopOver: "When contacting the AWX server using the callback URL, the calling host must authenticate by including " +
+ awPopOver: "
When contacting the Tower server using the callback URL, the calling host must authenticate by including " +
"this key in the POST data of the request. Here's an example using curl:
\n" +
"curl --data \"host_config_key=5a8ec154832b780b9bdef1061764ae5a\" " +
"http://your.server.com:999/api/v1/job_templates/1/callback/
\n",
diff --git a/awx/ui/static/js/forms/Jobs.js b/awx/ui/static/js/forms/Jobs.js
index b17f5bd402..6b60223d78 100644
--- a/awx/ui/static/js/forms/Jobs.js
+++ b/awx/ui/static/js/forms/Jobs.js
@@ -233,7 +233,7 @@ angular.module('JobFormDefinition', [])
ngChange: "toggleCallback('host_config_key')",
"class": "span12",
column: 2,
- awPopOver: "Create a callback URL a host can use to contact the AWX server and request a configuration update " +
+ awPopOver: "
Create a callback URL a host can use to contact Tower and request a configuration update " +
"using the job template. The URL will look like the following:
\n" +
"http://your.server.com:999/api/v1/job_templates/1/callback/
" +
"The request from the host must be a POST. Here is an example using curl:
\n" +
@@ -255,7 +255,7 @@ angular.module('JobFormDefinition', [])
column: 2,
required: false,
'class': 'span12',
- awPopOver: "Using this URL a host can contact the AWX server and request a configuration update using the job " +
+ awPopOver: "
Using this URL a host can contact Tower and request a configuration update using the job " +
"template. The request from the host must be a POST. Here is an example using curl:
\n" +
"curl --data \"host_config_key=5a8ec154832b780b9bdef1061764ae5a\" " +
"http://your.server.com:999/api/v1/job_templates/1/callback/
\n" +
@@ -272,7 +272,7 @@ angular.module('JobFormDefinition', [])
ngShow: "allow_callbacks",
genMD5: true,
column: 2,
- awPopOver: "When contacting the AWX server using the callback URL, the calling host must authenticate by including " +
+ awPopOver: "
When contacting Tower using the callback URL, the calling host must authenticate by including " +
"this key in the POST data of the request. Here's an example using curl:
\n" +
"curl --data \"host_config_key=5a8ec154832b780b9bdef1061764ae5a\" " +
"http://your.server.com:999/api/v1/job_templates/1/callback/
\n",
diff --git a/awx/ui/static/js/forms/ProjectStatus.js b/awx/ui/static/js/forms/ProjectStatus.js
index 3d965369bd..8de59fbcc4 100644
--- a/awx/ui/static/js/forms/ProjectStatus.js
+++ b/awx/ui/static/js/forms/ProjectStatus.js
@@ -30,6 +30,7 @@ angular.module('ProjectStatusDefinition', [])
label: 'Std Out',
type: 'textarea',
ngShow: "result_stdout",
+ 'class': 'mono-space',
readonly: true,
rows: 15
},
@@ -37,6 +38,7 @@ angular.module('ProjectStatusDefinition', [])
label: 'Traceback',
type: 'textarea',
ngShow: "result_traceback",
+ 'class': 'mono-space',
readonly: true,
rows: 15
}
diff --git a/awx/ui/static/js/forms/Projects.js b/awx/ui/static/js/forms/Projects.js
index fec21f36c5..3727c46ed6 100644
--- a/awx/ui/static/js/forms/Projects.js
+++ b/awx/ui/static/js/forms/Projects.js
@@ -76,8 +76,8 @@ angular.module('ProjectFormDefinition', [])
ngShow: 'showMissingPlaybooksAlert && !scm_type',
alertTxt: 'WARNING: There are no unassigned playbook directories in the base project path {{ base_dir }}. Either the projects ' +
'directory is empty, or all of the contents are already assigned to other projects. New projects can be checked out from source control by ' +
- 'changing the SCM type option rather than specifying checkout paths manually. To continue with manual setup, log into the AWX server and ' +
- 'ensure content is present in a subdirectory under {{ base_dir }}. Run "chown -R awx" on the content directory to ensure awx can read the ' +
+ 'changing the SCM type option rather than specifying checkout paths manually. To continue with manual setup, log into the Tower host and ' +
+ 'ensure content is present in a subdirectory under {{ base_dir }}. Run "chown -R awx" on the content directory to ensure Tower can read the ' +
'playbooks.
'
},
base_dir: {
@@ -256,4 +256,4 @@ angular.module('ProjectFormDefinition', [])
}); // Form
-
\ No newline at end of file
+
diff --git a/awx/ui/static/js/helpers/Access.js b/awx/ui/static/js/helpers/Access.js
index 74a5a6ce8f..26202a48e9 100644
--- a/awx/ui/static/js/helpers/Access.js
+++ b/awx/ui/static/js/helpers/Access.js
@@ -48,6 +48,11 @@ angular.module('AccessHelper', ['RestServices', 'Utilities', 'ngCookies'])
var status = 'success';
var hdr, msg;
var license = $cookieStore.get('license');
+
+ var purchase_msg = 'To purchase a license or extend an existing license ' +
+ 'visit the Ansible online store, ' +
+ 'or visit support.ansible.com for assistance.
';
+
if (license && !Authorization.licenseTested()) {
// This is our first time evaluating the license
license['tested'] = true;
@@ -58,47 +63,37 @@ angular.module('AccessHelper', ['RestServices', 'Utilities', 'ngCookies'])
// The license is invalid. Stop the user from logging in.
status = 'alert-danger';
hdr = 'License Error';
- msg = 'Something is wrong with your /etc/awx/license file on this server. ' +
- 'Please contact info@ansibleworks.com for assistance.';
- //action = function() { window.location = '#/logout'; };
+ msg = 'There is a problem with the /etc/awx/license file on your Tower server. Check to make sure Tower can access ' +
+ 'the file.
' + purchase_msg;
Alert(hdr, msg, status, null, false, true);
}
else if (license['demo'] !== undefined && license['demo'] == true) {
// demo
status = 'alert-info';
- hdr = 'AWX Demo';
- msg = 'Thank you for trying AnsibleWorks AWX. You can use this edition to manage up to 10 hosts free. ' +
- 'Should you wish to acquire a license for additional servers, please ' +
- 'visit the AnsibleWorks online store, or ' +
- 'contact info@ansibleworks.com for assistance.';
+ hdr = 'Tower Demo';
+ msg = '
Thank you for trying Ansible Tower. You can use this edition to manage up to 10 hosts free.
' +
+ purchase_msg;
Alert(hdr, msg, status);
}
if (license['date_expired'] !== undefined && license['date_expired'] == true) {
// expired
status = 'alert-info';
- hdr = 'AWX License Expired';
- msg = 'Your AnsibleWorks AWX License has expired and is no longer compliant. ' +
- 'You can continue, but you will be unable to add any additional hosts. Please ' +
- 'visit the AnsibleWorks online store ' +
- 'for license and renewal information, or contact info@ansibleworks.com ' +
- 'for assistance.';
+ hdr = 'License Expired';
+ msg = '
Your Ansible Tower License has expired and is no longer compliant. You can continue, but you will be ' +
+ 'unable to add any additional hosts.
' + purchase_msg;
Alert(hdr, msg, status);
}
else if (license['date_warning'] !== undefined && license['date_warning'] == true) {
status = 'alert-info';
- hdr = 'AWX License Warning';
- msg = 'Your AnsibleWorks AWX License is about to expire. To extend your license, please ' +
- 'visit the AnsibleWorks online store, or ' +
- 'contact info@ansibleworks.com for more information.';
+ hdr = 'License Warning';
+ msg = '
Your Ansible Tower license is about to expire!
' + purchase_msg;
Alert(hdr, msg, status);
}
if (license['free_instances'] !== undefined && parseInt(license['free_instances']) <= 0) {
status = 'alert-info';
hdr = 'License Warning';
- msg = 'Your AnsibleWorks AWX License has reached capacity for the number of managed ' +
- 'hosts allowed. You will not be able to add any additional hosts. To extend your license, please ' +
- 'visit the AnsibleWorks online store, or ' +
- 'contact info@ansibleworks.com for more information.';
+ msg = 'Your Ansible Tower license has reached capacity for the number of managed ' +
+ 'hosts allowed. You will not be able to add any additional hosts.
' + purchase_msg;
Alert(hdr, msg, status, null, true);
}
}
diff --git a/awx/ui/static/js/helpers/Groups.js b/awx/ui/static/js/helpers/Groups.js
index f62ea7398a..2da171e82a 100644
--- a/awx/ui/static/js/helpers/Groups.js
+++ b/awx/ui/static/js/helpers/Groups.js
@@ -238,6 +238,7 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
//$('#s2id_group_source_regions').select2('data', []);
$('#s2id_group_source_regions').select2('data', [{ id: 'all', text: 'All' }]);
}
+ else
var kind = (scope.source.value == 'rax') ? 'rax' : 'aws';
var url = GetBasePath('credentials') + '?cloud=true&kind=' + kind;
LookUpInit({
@@ -1102,8 +1103,6 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
generator.reset();
scope.formModalAction = function() {
- console.log('tree_id: ' + tree_id);
- console.log('selected_tree_id: ' + parent_scope.selected_tree_id);
$('#form-modal').modal("hide");
if (parent_scope && parent_scope.showHosts && !Empty(tree_id)) {
if (parent_scope.selected_tree_id !== tree_id)
diff --git a/awx/ui/static/js/helpers/Jobs.js b/awx/ui/static/js/helpers/Jobs.js
index ae89d1e45d..af723d1868 100644
--- a/awx/ui/static/js/helpers/Jobs.js
+++ b/awx/ui/static/js/helpers/Jobs.js
@@ -51,7 +51,9 @@ angular.module('JobsHelper', ['Utilities', 'FormGenerator', 'JobSummaryDefinitio
var form = JobSummary;
// Using jquery dialog for its expandable property
+
var html = "\n";
+
$('#inventory-modal-container').empty().append(html);
var scope = generator.inject(form, { mode: 'edit', id: 'form-container', breadCrumbs: false, related: false });
@@ -97,8 +99,19 @@ angular.module('JobsHelper', ['Utilities', 'FormGenerator', 'JobSummaryDefinitio
},
close: function(e, ui) {
// Destroy on close
+ $('.tooltip').each( function(index) {
+ // Remove any lingering tooltip elements
+ $(this).remove();
+ });
+ $('.popover').each(function(index) {
+ // remove lingering popover
elements
+ $(this).remove();
+ });
$('#status-modal-dialog').dialog('destroy');
$('#inventory-modal-container').empty();
+ },
+ open: function(e, ui) {
+ Wait('stop');
}
});
@@ -122,7 +135,6 @@ angular.module('JobsHelper', ['Utilities', 'FormGenerator', 'JobSummaryDefinitio
scope['traceback_rows'] = calcRows(scope['result_traceback']);
var cDate = new Date(data.created);
scope.created = FormatDate(cDate);
- Wait('stop');
$('#status-modal-dialog').dialog('open');
})
.error( function(data, status, headers, config) {
diff --git a/awx/ui/static/js/helpers/Projects.js b/awx/ui/static/js/helpers/Projects.js
index afcb4562ff..a551ef2f90 100644
--- a/awx/ui/static/js/helpers/Projects.js
+++ b/awx/ui/static/js/helpers/Projects.js
@@ -12,24 +12,89 @@
angular.module('ProjectsHelper', ['RestServices', 'Utilities', 'ProjectStatusDefinition', 'ProjectFormDefinition'])
.factory('ProjectStatus', ['$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'GenerateForm',
- 'Prompt', 'ProcessErrors', 'GetBasePath', 'FormatDate', 'ProjectStatusForm',
+ 'Prompt', 'ProcessErrors', 'GetBasePath', 'FormatDate', 'ProjectStatusForm', 'Wait',
function($rootScope, $location, $log, $routeParams, Rest, Alert, GenerateForm, Prompt, ProcessErrors, GetBasePath,
- FormatDate, ProjectStatusForm) {
+ FormatDate, ProjectStatusForm, Wait) {
return function(params) {
var project_id = params.project_id;
var last_update = params.last_update;
+
var generator = GenerateForm;
var form = ProjectStatusForm;
- var scope;
+
+ Wait('start');
+
+ // Using jquery dialog for its expandable property
+ var html = "
\n";
+ $('#projects-modal-container').empty().append(html);
+
+ var scope = generator.inject(form, { mode: 'edit', id: 'form-container', related: false, breadCrumbs: false });
+ generator.reset();
+
+ // Set modal dimensions based on viewport width
+ var ww = $(document).width();
+ var wh = $('body').height();
+ var x, y, maxrows;
+ if (ww > 1199) {
+ // desktop
+ x = 675;
+ y = (750 > wh) ? wh - 20 : 750;
+ maxrows = 20;
+ }
+ else if (ww <= 1199 && ww >= 768) {
+ x = 550;
+ y = (620 > wh) ? wh - 15 : 620;
+ maxrows = 15;
+ }
+ else {
+ x = (ww - 20);
+ y = (500 > wh) ? wh : 500;
+ maxrows = 10;
+ }
+ // Create the modal
+ $('#status-modal-dialog').dialog({
+ buttons: { "OK": function() { $( this ).dialog( "close" ); } },
+ modal: true,
+ width: x,
+ height: y,
+ autoOpen: false,
+ create: function (e, ui) {
+ // fix the close button
+ $('.ui-dialog[aria-describedby="status-modal-dialog"]').find('.ui-dialog-titlebar button').empty().attr({ 'class': 'close' }).text('x');
+ // fix the OK button
+ $('.ui-dialog[aria-describedby="status-modal-dialog"]').find('.ui-dialog-buttonset button:first')
+ .attr({ 'class': 'btn btn-primary' });
+ },
+ resizeStop: function(e, ui) {
+ // for some reason, after resizing dialog the form and fields (the content) doesn't expand to 100%
+ var dialog = $('.ui-dialog[aria-describedby="status-modal-dialog"]');
+ var content = dialog.find('#status-modal-dialog');
+ content.width( dialog.width() - 28 );
+ },
+ close: function(e, ui) {
+ // Destroy on close
+ // Destroy on close
+ $('.tooltip').each( function(index) {
+ // Remove any lingering tooltip
elements
+ $(this).remove();
+ });
+ $('.popover').each(function(index) {
+ // remove lingering popover
elements
+ $(this).remove();
+ });
+ $('#status-modal-dialog').dialog('destroy');
+ $('#projects-modal-container').empty();
+ },
+ open: function(e, ui) {
+ Wait('stop');
+ }
+ });
// Retrieve detail record and prepopulate the form
Rest.setUrl(last_update);
Rest.get()
.success( function(data, status, headers, config) {
- // load up the form
- scope = generator.inject(form, { mode: 'edit', modal: true, related: false});
- generator.reset();
var results = data;
for (var fld in form.fields) {
if (results[fld]) {
@@ -46,18 +111,10 @@ angular.module('ProjectsHelper', ['RestServices', 'Utilities', 'ProjectStatusDef
}
}
}
- scope.formModalAction = function() {
- $('#form-modal').modal("hide");
- }
- scope.formModalActionLabel = 'OK';
- scope.formModalCancelShow = false;
- scope.formModalInfo = false;
- scope.formModalHeader = results.summary_fields.project.name + '
- SCM Status';
- $('#form-modal .btn-success').removeClass('btn-success').addClass('btn-none');
- $('#form-modal').addClass('skinny-modal');
- if (!scope.$$phase) {
- scope.$digest();
- }
+ $('#status-modal-dialog')
+ .dialog({ title: results.summary_fields.project.name + ' Status'})
+ .dialog('open');
+
})
.error( function(data, status, headers, config) {
$('#form-modal').modal("hide");
diff --git a/awx/ui/static/js/lists/Jobs.js b/awx/ui/static/js/lists/Jobs.js
index a56a2328b8..29a40309d0 100644
--- a/awx/ui/static/js/lists/Jobs.js
+++ b/awx/ui/static/js/lists/Jobs.js
@@ -84,7 +84,7 @@ angular.module('JobsListDefinition', [])
fieldActions: {
submit: {
- label: 'Launch',
+ label: 'Relaunch',
icon: 'icon-rocket',
mode: 'all',
ngClick: "submitJob(\{\{ job.id \}\}, '\{\{ job.summary_fields.job_template.name \}\}' )",
diff --git a/awx/ui/static/lib/ansible/form-generator.js b/awx/ui/static/lib/ansible/form-generator.js
index e87bfcf02c..3817f34686 100644
--- a/awx/ui/static/lib/ansible/form-generator.js
+++ b/awx/ui/static/lib/ansible/form-generator.js
@@ -142,19 +142,39 @@ angular.module('FormGenerator', ['GeneratorHelpers', 'ngCookies', 'Utilities'])
}
}
if (options.modal_selector) {
- $(options.modal_selector).modal({ show: true, backdrop: 'static', keyboard: true });
- $(options.modal_selector).on('shown.bs.modal', function() {
- $(options.modal_select + ' input:first').focus();
- });
- $(options.modal_selector).unbind('hidden.bs.modal');
+ $(options.modal_selector).modal({ show: true, backdrop: 'static', keyboard: true });
+ $(options.modal_selector).on('shown.bs.modal', function() {
+ $(options.modal_select + ' input:first').focus();
+ });
+ $(options.modal_selector).on('hidden.bs.modal', function() {
+ $('.tooltip').each( function(index) {
+ // Remove any lingering tooltip and popover
elements
+ $(this).remove();
+ });
+
+ $('.popover').each(function(index) {
+ // remove lingering popover
. Seems to be a bug in TB3 RC1
+ $(this).remove();
+ });
+ });
}
else {
- var show = (options.show_modal == false) ? false : true;
- $('#form-modal').modal({ show: show, backdrop: 'static', keyboard: true });
- $('#form-modal').on('shown.bs.modal', function() {
- $('#form-modal input:first').focus();
- });
- $('#form-modal').off('hidden.bs.modal');
+ var show = (options.show_modal == false) ? false : true;
+ $('#form-modal').modal({ show: show, backdrop: 'static', keyboard: true });
+ $('#form-modal').on('shown.bs.modal', function() {
+ $('#form-modal input:first').focus();
+ });
+ $('#form-modal').on('hidden.bs.modal', function() {
+ $('.tooltip').each( function(index) {
+ // Remove any lingering tooltip and popover
elements
+ $(this).remove();
+ });
+
+ $('.popover').each(function(index) {
+ // remove lingering popover
. Seems to be a bug in TB3 RC1
+ $(this).remove();
+ });
+ });
}
$(document).bind('keydown', function(e) {
if (e.keyCode === 27) {
@@ -194,38 +214,51 @@ angular.module('FormGenerator', ['GeneratorHelpers', 'ngCookies', 'Utilities'])
if (this.scope[this.form.name + '_form']) {
this.scope[this.form.name + '_form'].$setPristine();
}
+
+ var scope = this.scope;
+ var form = this.form;
- for (var fld in this.form.fields) {
- if (this.form.fields[fld].type == 'checkbox_group') {
- for (var i=0; i < this.form.fields[fld].fields.length; i++) {
- this.scope[this.form.fields[fld].fields[i].name] = '';
- this.scope[this.form.fields[fld].fields[i].name + '_api_error'] = '';
- }
+ function resetField(f, fld) {
+ // f is the field object, fld is the key
+
+ if (f.type == 'checkbox_group') {
+ for (var i=0; i < f.fields.length; i++) {
+ scope[f.name] = '';
+ scope[f.name + '_api_error'] = '';
+ }
}
else {
- this.scope[fld] = '';
- this.scope[fld + '_api_error'] = '';
+ scope[fld] = '';
+ scope[fld + '_api_error'] = '';
}
- if (this.form.fields[fld].sourceModel) {
- this.scope[this.form.fields[fld].sourceModel + '_' + this.form.fields[fld].sourceField] = '';
- this.scope[this.form.fields[fld].sourceModel + '_' + this.form.fields[fld].sourceField + '_api_error'] = '';
+ if (f.sourceModel) {
+ scope[f.sourceModel + '_' + f.sourceField] = '';
+ scope[f.sourceModel + '_' + f.sourceField + '_api_error'] = '';
}
- if ( this.form.fields[fld].type == 'lookup' &&
- this.scope[this.form.name + '_form'][this.form.fields[fld].sourceModel + '_' + this.form.fields[fld].sourceField] ) {
- this.scope[this.form.name + '_form'][this.form.fields[fld].sourceModel + '_' + this.form.fields[fld].sourceField].$setPristine();
+ if (f.type == 'lookup' && scope[form.name + '_form'][f.sourceModel + '_' + f.sourceField]) {
+ scope[form.name + '_form'][f.sourceModel + '_' + f.sourceField].$setPristine();
}
- if (this.scope[this.form.name + '_form'][fld]) {
- this.scope[this.form.name + '_form'][fld].$setPristine();
+ if (scope[form.name + '_form'][fld]) {
+ scope[form.name + '_form'][fld].$setPristine();
}
- if (this.form.fields[fld].chkPass && this.scope[this.form.name + '_form'][fld]) {
- this.scope[this.form.name + '_form'][fld].$setValidity('complexity', true);
+ if (f.chkPass && scope[form.name + '_form'][fld]) {
+ scope[form.name + '_form'][fld].$setValidity('complexity', true);
$('#progbar').css({ width: 0 });
}
- if (this.form.fields[fld].awPassMatch && this.scope[this.form.name + '_form'][fld]) {
- this.scope[this.form.name + '_form'][fld].$setValidity('awpassmatch', true);
+ if (f.awPassMatch && scope[form.name + '_form'][fld]) {
+ scope[form.name + '_form'][fld].$setValidity('awpassmatch', true);
}
- if (this.form.fields[fld].ask) {
- this.scope[fld + '_ask'] = false;
+ if (f.ask) {
+ scope[fld + '_ask'] = false;
+ }
+ }
+
+ for (var fld in form.fields) {
+ resetField(form.fields[fld], fld);
+ }
+ if (form.statusFields) {
+ for (var fld in form.statusFields) {
+ resetField(form.statusFields[fld], fld);
}
}
if (this.mode == 'add') {
diff --git a/awx/ui/static/lib/ansible/license.js b/awx/ui/static/lib/ansible/license.js
index b247cf1ffa..cacba6b0ce 100644
--- a/awx/ui/static/lib/ansible/license.js
+++ b/awx/ui/static/lib/ansible/license.js
@@ -1,7 +1,9 @@
-/*****************************************
+/*********************************************
+ * Copyright (c) 2014 AnsibleWorks, Inc.
+ *
* License.js
*
- * View license info: /api/vi/config/
+ * View license info found in /api/vi/config/
*
*****************************************/
@@ -118,7 +120,7 @@ angular.module('License', ['RestServices', 'Utilities', 'FormGenerator', 'Prompt
scope.formModalActionLabel = 'OK';
scope.formModalCancelShow = false;
scope.formModalInfo = 'Purchase/Extend License';
- scope.formModalHeader = 'AWX License';
+ scope.formModalHeader = 'Tower License';
//$('#form-modal .btn-success').removeClass('btn-success').addClass('btn-none');
//$('#form-modal').addClass('skinny-modal');
@@ -127,10 +129,10 @@ angular.module('License', ['RestServices', 'Utilities', 'FormGenerator', 'Prompt
// Respond to license button
scope.formModalInfoAction = function() {
Prompt({
- hdr: 'AWX Licensing',
- body: "
AWX licenses can be purchased or extended by visiting " +
- "the AnsibleWorks online store. Would you like to purchase or extend your license now?
",
+ hdr: 'Tower Licensing',
+ body: "
Ansible Tower licenses can be purchased or extended by visiting " +
+ "the Ansible online store. Would you like to purchase or extend your license now?
",
'class': 'btn-primary',
action: function() {
var href = $('#license-link').attr('href');
diff --git a/awx/ui/static/partials/projects.html b/awx/ui/static/partials/projects.html
index 4b57efbd87..a034df92bc 100644
--- a/awx/ui/static/partials/projects.html
+++ b/awx/ui/static/partials/projects.html
@@ -1,3 +1,4 @@
\ No newline at end of file
diff --git a/awx/ui/templates/ui/index.html b/awx/ui/templates/ui/index.html
index 51e5e3cc18..478f1e9c69 100644
--- a/awx/ui/templates/ui/index.html
+++ b/awx/ui/templates/ui/index.html
@@ -369,14 +369,14 @@
-

+