From f0a2ce2c676e5d46bc2e91bfe82ddde946b3c1c1 Mon Sep 17 00:00:00 2001
From: John Mitchell
Date: Mon, 2 Feb 2015 23:31:14 -0500
Subject: [PATCH 1/3] initial commit of the click-off popOver bug
---
awx/ui/static/lib/ansible/directives.js | 49 ++++++++++++++++++++++---
1 file changed, 43 insertions(+), 6 deletions(-)
diff --git a/awx/ui/static/lib/ansible/directives.js b/awx/ui/static/lib/ansible/directives.js
index ebda3089d7..3a811e8442 100644
--- a/awx/ui/static/lib/ansible/directives.js
+++ b/awx/ui/static/lib/ansible/directives.js
@@ -488,7 +488,9 @@ angular.module('AWDirectives', ['RestServices', 'Utilities', 'AuthService', 'Job
title = (attrs.title) ? attrs.title : (attrs.popoverTitle) ? attrs.popoverTitle : 'Help',
container = (attrs.container !== undefined) ? attrs.container : false,
trigger = (attrs.trigger !== undefined) ? attrs.trigger : 'manual',
- template = '';
+ template = '',
+ id_to_close = "",
+ body_click_count;
if (element[0].id) {
template = '';
@@ -522,15 +524,20 @@ angular.module('AWDirectives', ['RestServices', 'Utilities', 'AuthService', 'Job
$(element).attr('tabindex',-1);
$(element).click(function() {
var self = $(this);
+
+ // remove tool-tip
try {
- self.tooltip('hide');
+ element.tooltip('hide');
}
catch(e) {
// ignore
}
+
+ // this is called on the help-link (over and over again)
$('.help-link, .help-link-white').each( function() {
if (self.attr('id') !== $(this).attr('id')) {
try {
+ // not sure what this does different than the method above
$(this).popover('hide');
}
catch(e) {
@@ -543,16 +550,46 @@ angular.module('AWDirectives', ['RestServices', 'Utilities', 'AuthService', 'Job
$(this).remove();
});
$('.tooltip').each( function() {
- // close any lingering tool tipss
+ // close any lingering tool tips
$(this).hide();
});
+
+ // set id_to_close of the actual open element
+ id_to_close = "#" + $(element).attr('id') + "_popover_container";
+
+ // set the number of times the body has been clicked since the popover has been opened
+ body_click_count = 0;
+
+ if ($._data(document.body, "events")) {
+ // in the case that the popOver is retriggered (ie: you click the question mark
+ // again for that popover. tread this as a toggle and do not bind another
+ // click event.
+ // PROBLEM NOTE: if things are bound to the body this might break.
+ $('body').off('click');
+ } else {
+ $('body').on('click', function(e) {
+ if ($(e.target).parents(id_to_close).length === 0) {
+ // if you click outside the popover
+ // increment the body click counter
+ body_click_count++;
+ if (body_click_count === 2) {
+ // if that counter was incremented to 2
+ // note this value is 2 because an initial fire
+ // needs to be taken into account when the modal opens...
+ // toggle the tooltip because this is actually
+ // the first click outside of the popOver since it has been open
+ $(element).popover('toggle');
+ $('body').off('click');
+ }
+ }
+ });
+ }
+
$(this).popover('toggle');
+
$('.popover').each(function() {
$compile($(this))(scope); //make nested directives work!
});
- $('.popover-content, .popover-title').click(function() {
- $(self).popover('hide');
- });
});
$(document).bind('keydown', function(e) {
From cef0d0bb000b4c05b880d7eef549653a93cbf15d Mon Sep 17 00:00:00 2001
From: John Mitchell
Date: Wed, 4 Feb 2015 14:30:32 -0500
Subject: [PATCH 2/3] removed bottom right pop-over directions.
---
awx/ui/static/js/controllers/Home.js | 5 +---
awx/ui/static/js/controllers/Inventories.js | 5 +---
awx/ui/static/js/controllers/JobDetail.js | 4 +--
awx/ui/static/js/helpers/Credentials.js | 6 ++---
awx/ui/static/js/helpers/Groups.js | 4 +--
awx/ui/static/js/helpers/Hosts.js | 4 +--
awx/ui/static/js/helpers/JobSubmission.js | 3 +--
awx/ui/static/js/helpers/JobTemplates.js | 3 +--
awx/ui/static/js/lists/Credentials.js | 3 +--
awx/ui/static/js/lists/CustomInventory.js | 3 ---
awx/ui/static/js/lists/Organizations.js | 2 +-
awx/ui/static/js/lists/Projects.js | 25 +------------------
awx/ui/static/js/lists/Users.js | 2 +-
.../static/lib/ansible/generator-helpers.js | 2 +-
14 files changed, 15 insertions(+), 56 deletions(-)
diff --git a/awx/ui/static/js/controllers/Home.js b/awx/ui/static/js/controllers/Home.js
index 820ef907c9..4173c278e4 100644
--- a/awx/ui/static/js/controllers/Home.js
+++ b/awx/ui/static/js/controllers/Home.js
@@ -513,11 +513,9 @@ function HomeGroups($log, $scope, $filter, $compile, $location, $routeParams, Lo
});
html += "\n";
html += "\n";
- html += "\n";
}
else {
- html = "No recent job data available for this inventory.
\n" +
- "\n";
+ html = "No recent job data available for this inventory.
\n";
}
attachElem(event, html, title);
});
@@ -549,7 +547,6 @@ function HomeGroups($log, $scope, $filter, $compile, $location, $routeParams, Lo
});
html += "\n";
html += "\n";
- html += "\n";
title = "Sync Status";
attachElem(event, html, title);
});
diff --git a/awx/ui/static/js/controllers/Inventories.js b/awx/ui/static/js/controllers/Inventories.js
index 98161dcba6..b8bbb36c1a 100644
--- a/awx/ui/static/js/controllers/Inventories.js
+++ b/awx/ui/static/js/controllers/Inventories.js
@@ -205,11 +205,9 @@ function InventoriesList($scope, $rootScope, $location, $log, $routeParams, $com
});
html += "\n";
html += "\n";
- html += "\n";
}
else {
- html = "No recent job data available for this inventory.
\n" +
- "\n";
+ html = "No recent job data available for this inventory.
\n";
}
attachElem(event, html, title);
});
@@ -250,7 +248,6 @@ function InventoriesList($scope, $rootScope, $location, $log, $routeParams, $com
});
html += "\n";
html += "\n";
- html += "\n";
title = "Sync Status";
attachElem(event, html, title);
});
diff --git a/awx/ui/static/js/controllers/JobDetail.js b/awx/ui/static/js/controllers/JobDetail.js
index a1a8a9e6de..d2b3d6393a 100644
--- a/awx/ui/static/js/controllers/JobDetail.js
+++ b/awx/ui/static/js/controllers/JobDetail.js
@@ -90,9 +90,7 @@ function JobDetailController ($location, $rootScope, $scope, $compile, $routePar
scope.eventsHelpText = " Successful
\n" +
" Changed
\n" +
" Unreachable
\n" +
- " Failed
\n" +
- "\n";
-
+ " Failed
\n";
function openSocket() {
event_socket = Socket({
scope: scope,
diff --git a/awx/ui/static/js/helpers/Credentials.js b/awx/ui/static/js/helpers/Credentials.js
index 31ac14b160..43bd723f26 100644
--- a/awx/ui/static/js/helpers/Credentials.js
+++ b/awx/ui/static/js/helpers/Credentials.js
@@ -40,7 +40,7 @@ angular.module('CredentialsHelper', ['Utilities'])
scope.key_required = false; // JT -- doing the same for key and project
scope.project_required = false;
scope.subscription_required = false;
- scope.key_description = "Paste the contents of the SSH private key file.";
+ scope.key_description = "Paste the contents of the SSH private key file.";
scope.key_hint= "drag and drop an SSH private key file on the field below";
scope.host_required = false;
scope.password_required = false;
@@ -68,7 +68,7 @@ angular.module('CredentialsHelper', ['Utilities'])
scope.email_required = true;
scope.key_required = true;
scope.project_required = true;
- scope.key_description = 'Paste the contents of the PEM file associated with the service account email. ';
+ scope.key_description = 'Paste the contents of the PEM file associated with the service account email.';
scope.key_hint= "drag and drop a private key file on the field below";
break;
case 'azure':
@@ -76,7 +76,7 @@ angular.module('CredentialsHelper', ['Utilities'])
scope.sshKeyDataLabel = 'Management Certificate';
scope.subscription_required = true;
scope.key_required = true;
- scope.key_description = "Paste the contents of the PEM file that corresponds to the certificate you uploaded in the Microsoft Azure console.";
+ scope.key_description = "Paste the contents of the PEM file that corresponds to the certificate you uploaded in the Microsoft Azure console.";
scope.key_hint= "drag and drop a management certificate file on the field below";
break;
case 'vmware':
diff --git a/awx/ui/static/js/helpers/Groups.js b/awx/ui/static/js/helpers/Groups.js
index 6c240530b6..3f09a09546 100644
--- a/awx/ui/static/js/helpers/Groups.js
+++ b/awx/ui/static/js/helpers/Groups.js
@@ -1439,9 +1439,7 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
"the associated groups and hosts will no longer appear in the inventory.\n" +
"PromoteGroups and hosts associated with the group being removed will be " +
"promoted one level. Note: groups already associated with other groups cannot be promoted to the top level of the " +
- "tree.\n" +
- "";
-
+ "tree.\n";
buttonSet = [{
label: "Cancel",
onClick: function() {
diff --git a/awx/ui/static/js/helpers/Hosts.js b/awx/ui/static/js/helpers/Hosts.js
index d1004c6134..af3467d8f3 100644
--- a/awx/ui/static/js/helpers/Hosts.js
+++ b/awx/ui/static/js/helpers/Hosts.js
@@ -77,8 +77,7 @@ angular.module('HostsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', 'H
function noRecentJobs() {
title = 'No job data';
- html = "No recent job data available for this host.
\n" +
- "\n";
+ html = "No recent job data available for this host.
\n";
}
function setMsg(host) {
@@ -129,7 +128,6 @@ angular.module('HostsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', 'H
}
html += "\n";
html += "\n";
- html += "\n";
}
else {
noRecentJobs();
diff --git a/awx/ui/static/js/helpers/JobSubmission.js b/awx/ui/static/js/helpers/JobSubmission.js
index 5b65178856..7b911d1166 100644
--- a/awx/ui/static/js/helpers/JobSubmission.js
+++ b/awx/ui/static/js/helpers/JobSubmission.js
@@ -453,8 +453,7 @@ function($location, Wait, GetBasePath, LookUpInit, JobTemplateForm, CredentialLi
"JSON:
\n" +
"{
\"somevar\": \"somevalue\",
\"password\": \"magic\"
}
\n" +
"YAML:
\n" +
- "---
somevar: somevalue
password: magic
\n" +
- "\n";
+ "---
somevar: somevalue
password: magic
\n";
scope.extra_vars = ParseVariableString(extra_vars);
scope.parseType = 'yaml';
diff --git a/awx/ui/static/js/helpers/JobTemplates.js b/awx/ui/static/js/helpers/JobTemplates.js
index 5c7d3c483e..734facff1f 100644
--- a/awx/ui/static/js/helpers/JobTemplates.js
+++ b/awx/ui/static/js/helpers/JobTemplates.js
@@ -47,8 +47,7 @@ angular.module('JobTemplatesHelper', ['Utilities'])
scope.callback_server_path + GetBasePath('job_templates') + scope.example_template_id + "/callback/\n" +
"Note the requesting host must be defined in the inventory associated with the job template. If Tower fails to " +
"locate the host, the request will be denied.
" +
- "Successful requests create an entry on the Jobs page, where results and history can be viewed.
" +
- "";
+ "Successful requests create an entry on the Jobs page, where results and history can be viewed.
";
};
// The md5 helper emits NewMD5Generated whenever a new key is available
diff --git a/awx/ui/static/js/lists/Credentials.js b/awx/ui/static/js/lists/Credentials.js
index c485f83986..419d383e60 100644
--- a/awx/ui/static/js/lists/Credentials.js
+++ b/awx/ui/static/js/lists/Credentials.js
@@ -17,8 +17,7 @@ angular.module('CredentialsListDefinition', [])
selectTitle: 'Add Credentials',
editTitle: 'Credentials',
selectInstructions: "Select existing credentials by clicking each credential or checking the related checkbox. When " +
- "finished, click the blue Select button, located bottom right.
Create a brand new credential by clicking " +
- "the button.
",
+ "finished, click the blue Select button, located bottom right.
Create a brand new credential by clicking ",
index: false,
hover: true,
diff --git a/awx/ui/static/js/lists/CustomInventory.js b/awx/ui/static/js/lists/CustomInventory.js
index 3765d53115..15b80b0f51 100644
--- a/awx/ui/static/js/lists/CustomInventory.js
+++ b/awx/ui/static/js/lists/CustomInventory.js
@@ -16,9 +16,6 @@ angular.module('CustomInventoryListDefinition', [])
iterator: 'source_script', //'custom_inventory',
selectTitle: 'Add custom inventory',
editTitle: 'Custom Inventories',
- // selectInstructions: "
Select existing credentials by clicking each credential or checking the related checkbox. When " +
- // "finished, click the blue Select button, located bottom right.
Create a brand new credential by clicking " +
- // "the button.
",
index: false,
hover: false,
diff --git a/awx/ui/static/js/lists/Organizations.js b/awx/ui/static/js/lists/Organizations.js
index d81d497b08..307c874945 100644
--- a/awx/ui/static/js/lists/Organizations.js
+++ b/awx/ui/static/js/lists/Organizations.js
@@ -17,7 +17,7 @@ angular.module('OrganizationListDefinition', [])
selectTitle: 'Add Organizations',
selectInstructions: 'Select existing organizations by clicking each organization or checking the related checkbox. When finished, ' +
'click the blue Select button, located bottom right.
Create a new organization by clicking the ' +
- ' button.
',
+ ' button.',
editTitle: 'Organizations',
hover: true,
index: false,
diff --git a/awx/ui/static/js/lists/Projects.js b/awx/ui/static/js/lists/Projects.js
index b875cc50f7..5772c50804 100644
--- a/awx/ui/static/js/lists/Projects.js
+++ b/awx/ui/static/js/lists/Projects.js
@@ -17,8 +17,7 @@ angular.module('ProjectsListDefinition', [])
selectTitle: 'Add Project',
editTitle: 'Projects',
selectInstructions: 'Select existing projects by clicking each project or checking the related checkbox. When finished, click the blue ' +
- 'Select button, located bottom right.
Create a new project by clicking the button.
'+
- '',
+ 'Select button, located bottom right.Create a new project by clicking the button.
',
index: false,
hover: true,
@@ -66,34 +65,12 @@ angular.module('ProjectsListDefinition', [])
ngClick: 'addProject()',
awToolTip: 'Create a new project'
},
- /*help: {
- awPopOver: "\n- Updating
- A source control update is in progress.
\n" +
- "- Never Updated
- This project has not yet been updated from source control.
\n" +
- "- Failed
- An error occurred during the most recent source control update, click the status " +
- "text for more information.
\n" +
- "- Successful
- TThe latest source control update completed successfully.
\n" +
- "- Missing
- The previously configured local project directory is missing.
\n" +
- "- N/A
- The project is not linked to source control, so updates are not applicable.
\n" +
- "
\n",
- dataPlacement: 'left',
- dataContainer: 'body',
- mode: 'edit',
- awToolTip: 'Click for help',
- awTipPlacement: 'top'
- },*/
refresh: {
mode: 'all',
awToolTip: "Refresh the page",
ngClick: "refresh()",
ngShow: "socketStatus == 'error'"
},
- /*socket: {
- mode: 'all',
- iconClass: "{{ 'fa fa-power-off fa-lg socket-' + socketStatus }}",
- awToolTip: "{{ socketTip }}",
- dataTipWatch: "socketTip",
- ngClick: "socketToggle()",
- },*/
stream: {
ngClick: "showActivity()",
awToolTip: "View Activity Stream",
diff --git a/awx/ui/static/js/lists/Users.js b/awx/ui/static/js/lists/Users.js
index 8b31713dc1..32a35bd955 100644
--- a/awx/ui/static/js/lists/Users.js
+++ b/awx/ui/static/js/lists/Users.js
@@ -17,7 +17,7 @@ angular.module('UserListDefinition', [])
editTitle: 'Users',
selectInstructions: 'Select existing users by clicking each user or checking the related checkbox. When finished, click the blue ' +
'Select button, located bottom right.
When available, a brand new user can be created by clicking the ' +
- ' button.
',
+ ' button.',
index: false,
hover: true,
diff --git a/awx/ui/static/lib/ansible/generator-helpers.js b/awx/ui/static/lib/ansible/generator-helpers.js
index 47d13cff5e..cd0e09b47e 100644
--- a/awx/ui/static/lib/ansible/generator-helpers.js
+++ b/awx/ui/static/lib/ansible/generator-helpers.js
@@ -42,7 +42,7 @@ angular.module('GeneratorHelpers', [])
break;
case 'awPopOver':
// construct the entire help link
- result = "
Date: Tue, 3 Feb 2015 17:12:25 -0500
Subject: [PATCH 3/3] Cleanup the hack
---
awx/ui/static/lib/ansible/directives.js | 73 +++++++++++++------------
1 file changed, 39 insertions(+), 34 deletions(-)
diff --git a/awx/ui/static/lib/ansible/directives.js b/awx/ui/static/lib/ansible/directives.js
index 3a811e8442..4b1abf2845 100644
--- a/awx/ui/static/lib/ansible/directives.js
+++ b/awx/ui/static/lib/ansible/directives.js
@@ -489,8 +489,7 @@ angular.module('AWDirectives', ['RestServices', 'Utilities', 'AuthService', 'Job
container = (attrs.container !== undefined) ? attrs.container : false,
trigger = (attrs.trigger !== undefined) ? attrs.trigger : 'manual',
template = '',
- id_to_close = "",
- body_click_count;
+ id_to_close = "";
if (element[0].id) {
template = '';
@@ -522,7 +521,32 @@ angular.module('AWDirectives', ['RestServices', 'Utilities', 'AuthService', 'Job
});
}
$(element).attr('tabindex',-1);
- $(element).click(function() {
+
+ $(element).one('click', showPopover);
+
+ $(element).on('shown.bs.popover', function() {
+ $('body').one('click.popover' + id_to_close, function(e) {
+ if ($(e.target).parents(id_to_close).length === 0) {
+ $(element).popover('hide');
+ }
+ });
+
+ $(document).on('keydown.popover', dismissOnEsc);
+
+ });
+
+ $(element).on('hidden.bs.popover', function() {
+ $(element).off('click', dismissPopover);
+ $(element).off('click', showPopover);
+ $('body').off('click.popover.' + id_to_close);
+ $(element).one('click', showPopover);
+ $(document).off('keydown.popover', dismissOnEsc);
+ });
+
+ function showPopover(e) {
+ console.log(element);
+ e.stopPropagation();
+
var self = $(this);
// remove tool-tip
@@ -545,6 +569,7 @@ angular.module('AWDirectives', ['RestServices', 'Utilities', 'AuthService', 'Job
}
}
});
+
$('.popover').each(function() {
// remove lingering popover . Seems to be a bug in TB3 RC1
$(this).remove();
@@ -557,50 +582,30 @@ angular.module('AWDirectives', ['RestServices', 'Utilities', 'AuthService', 'Job
// set id_to_close of the actual open element
id_to_close = "#" + $(element).attr('id') + "_popover_container";
- // set the number of times the body has been clicked since the popover has been opened
- body_click_count = 0;
-
- if ($._data(document.body, "events")) {
- // in the case that the popOver is retriggered (ie: you click the question mark
- // again for that popover. tread this as a toggle and do not bind another
- // click event.
- // PROBLEM NOTE: if things are bound to the body this might break.
- $('body').off('click');
- } else {
- $('body').on('click', function(e) {
- if ($(e.target).parents(id_to_close).length === 0) {
- // if you click outside the popover
- // increment the body click counter
- body_click_count++;
- if (body_click_count === 2) {
- // if that counter was incremented to 2
- // note this value is 2 because an initial fire
- // needs to be taken into account when the modal opens...
- // toggle the tooltip because this is actually
- // the first click outside of the popOver since it has been open
- $(element).popover('toggle');
- $('body').off('click');
- }
- }
- });
- }
+ // $(element).one('click', dismissPopover);
$(this).popover('toggle');
$('.popover').each(function() {
$compile($(this))(scope); //make nested directives work!
});
- });
+ }
- $(document).bind('keydown', function(e) {
+ function dismissPopover(e) {
+ e.stopPropagation();
+ $(element).popover('hide');
+ }
+
+ function dismissOnEsc(e) {
if (e.keyCode === 27) {
$(element).popover('hide');
$('.popover').each(function() {
// remove lingering popover
. Seems to be a bug in TB3 RC1
- $(this).remove();
+ // $(this).remove();
});
}
- });
+ }
+
};
}])