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 += "
esc or click to close
\n"; } else { - html = "

No recent job data available for this inventory.

\n" + - "
esc or click to close
\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 += "
esc or click to close
\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 += "
esc or click to close
\n"; } else { - html = "

No recent job data available for this inventory.

\n" + - "
esc or click to close
\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 += "
esc or click to close
\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" + - "
esc or click to close
\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.
esc or click to close
"; + 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.
esc or click to close
'; + 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.
esc or click to close
"; + 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" + "
Promote
Groups 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" + - "
esc or click to close
"; - + "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" + - "
esc or click to close
\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 += "
esc or click to close
\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" + - "
esc or click to close
\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.

" + - "
esc or click to close
"; + "

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.

esc or click to close
", + "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.

esc or click to close
", 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.

esc or click to close
', + ' 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.

'+ - '
esc or click to close
', + '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.

esc or click to close
', + ' 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 = "esc or click to close\' "; + 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(); }); } - }); + } + }; }])