diff --git a/awx/ui/client/src/dashboard/hosts/dashboard-hosts.list.js b/awx/ui/client/src/dashboard/hosts/dashboard-hosts.list.js index 169ab31c94..e34a051588 100644 --- a/awx/ui/client/src/dashboard/hosts/dashboard-hosts.list.js +++ b/awx/ui/client/src/dashboard/hosts/dashboard-hosts.list.js @@ -31,6 +31,7 @@ export default function(){ awTipPlacement: 'right', dataPlacement: 'right', awPopOver: '{{ host.job_status_html }}', + dataTitle: '{{host.job_status_title}}', ngClick:'viewHost(host.id)', columnClass: 'col-lg-1 col-md-1 col-sm-2 col-xs-2 List-staticColumn--smallStatus' }, diff --git a/awx/ui/client/src/inventories/list/inventory-list.controller.js b/awx/ui/client/src/inventories/list/inventory-list.controller.js index a5d2b00a01..54ed987ec6 100644 --- a/awx/ui/client/src/inventories/list/inventory-list.controller.js +++ b/awx/ui/client/src/inventories/list/inventory-list.controller.js @@ -50,16 +50,9 @@ function InventoriesList($scope, $rootScope, $location, $log, "aw-pop-over": html, "data-popover-title": title, "data-placement": "right" }); + elem.removeAttr('ng-click'); $compile(elem)($scope); - elem.on('shown.bs.popover', function() { - $('.popover').each(function() { - $compile($(this))($scope); //make nested directives work! - }); - $('.popover-content, .popover-title').click(function() { - elem.popover('hide'); - }); - }); - elem.popover('show'); + $scope.triggerPopover(event); } view.inject(InventoryList, { mode: mode, scope: $scope }); @@ -250,44 +243,62 @@ function InventoriesList($scope, $rootScope, $location, $log, }); $scope.showGroupSummary = function(event, id) { - var inventory; - if (!Empty(id)) { - inventory = Find({ list: $scope.inventories, key: 'id', val: id }); - if (inventory.syncStatus !== 'na') { - Wait('start'); - Rest.setUrl(inventory.related.inventory_sources + '?or__source=ec2&or__source=rax&order_by=-last_job_run&page_size=5'); - Rest.get() - .success(function(data) { - $scope.$emit('GroupSummaryReady', event, inventory, data); - }) - .error(function(data, status) { - ProcessErrors( $scope, data, status, null, { hdr: 'Error!', - msg: 'Call to ' + inventory.related.inventory_sources + ' failed. GET returned status: ' + status + try{ + var elem = $(event.target).parent(); + // if the popover is visible already, then exit the function here + if(elem.data()['bs.popover'].tip().hasClass('in')){ + return; + } + } + catch(err){ + var inventory; + if (!Empty(id)) { + inventory = Find({ list: $scope.inventories, key: 'id', val: id }); + if (inventory.syncStatus !== 'na') { + Wait('start'); + Rest.setUrl(inventory.related.inventory_sources + '?or__source=ec2&or__source=rax&order_by=-last_job_run&page_size=5'); + Rest.get() + .success(function(data) { + $scope.$emit('GroupSummaryReady', event, inventory, data); + }) + .error(function(data, status) { + ProcessErrors( $scope, data, status, null, { hdr: 'Error!', + msg: 'Call to ' + inventory.related.inventory_sources + ' failed. GET returned status: ' + status + }); }); - }); + } } } }; $scope.showHostSummary = function(event, id) { - var url, inventory; - if (!Empty(id)) { - inventory = Find({ list: $scope.inventories, key: 'id', val: id }); - if (inventory.total_hosts > 0) { - Wait('start'); - url = GetBasePath('jobs') + "?type=job&inventory=" + id + "&failed="; - url += (inventory.has_active_failures) ? 'true' : "false"; - url += "&order_by=-finished&page_size=5"; - Rest.setUrl(url); - Rest.get() - .success( function(data) { - $scope.$emit('HostSummaryReady', event, data); - }) - .error( function(data, status) { - ProcessErrors( $scope, data, status, null, { hdr: 'Error!', - msg: 'Call to ' + url + ' failed. GET returned: ' + status + try{ + var elem = $(event.target).parent(); + // if the popover is visible already, then exit the function here + if(elem.data()['bs.popover'].tip().hasClass('in')){ + return; + } + } + catch(err){ + var url, inventory; + if (!Empty(id)) { + inventory = Find({ list: $scope.inventories, key: 'id', val: id }); + if (inventory.total_hosts > 0) { + Wait('start'); + url = GetBasePath('jobs') + "?type=job&inventory=" + id + "&failed="; + url += (inventory.has_active_failures) ? 'true' : "false"; + url += "&order_by=-finished&page_size=5"; + Rest.setUrl(url); + Rest.get() + .success( function(data) { + $scope.$emit('HostSummaryReady', event, data); + }) + .error( function(data, status) { + ProcessErrors( $scope, data, status, null, { hdr: 'Error!', + msg: 'Call to ' + url + ' failed. GET returned: ' + status + }); }); - }); + } } } }; diff --git a/awx/ui/client/src/notifications/notification-templates-list/list.controller.js b/awx/ui/client/src/notifications/notification-templates-list/list.controller.js index a84e4c96da..04265f1181 100644 --- a/awx/ui/client/src/notifications/notification-templates-list/list.controller.js +++ b/awx/ui/client/src/notifications/notification-templates-list/list.controller.js @@ -28,6 +28,7 @@ export default Wait('stop'); if (scope.notification_templates) { scope.notification_templates.forEach(function(notification_template, i) { + setStatus(notification_template); scope.notification_type_options.forEach(function(type) { if (type.value === notification_template.notification_type) { scope.notification_templates[i].notification_type = type.label; @@ -74,78 +75,33 @@ export default callback: 'choicesReadyNotifierList' }); - function attachElem(event, html, title) { - var elem = $(event.target).parent(); - try { - elem.tooltip('hide'); - elem.popover('destroy'); - } - catch(err) { - //ignore - } + function setStatus(notification_template) { + var html, recent_notifications = notification_template.summary_fields.recent_notifications; + if (recent_notifications.length > 0) { + html = "
| Status | "; + html += "Time | "; + html += "
|---|---|
| `; + html += " | " + ($filter('longDate')(row.created)).replace(/ /,' ') + " | \n";
+ html += "
No recent notifications.
\n"; + } + notification_template.template_status_html = html; } - scope.showSummary = function(event, id) { - setTimeout(function(){ - if (!Empty(id)) { - var recent_notifications, - html, title = "Recent Notifications"; - - scope.notification_templates.forEach(function(notification_template){ - if(notification_template.id === id){ - recent_notifications = notification_template.summary_fields.recent_notifications; - } - }); - if (recent_notifications.length > 0) { - html = "| Status | "; - html += "Time | "; - html += "
|---|---|
| `; - html += " | " + ($filter('longDate')(row.created)).replace(/ /,' ') + " | \n";
- html += "
No recent notifications.
\n"; - } - attachElem(event, html, title); - } - }, 100); - }; - scope.testNotification = function(){ var name = $filter('sanitize')(this.notification_template.name), pending_retries = 10; diff --git a/awx/ui/client/src/notifications/notificationTemplates.list.js b/awx/ui/client/src/notifications/notificationTemplates.list.js index 7f3780f959..06eb25615f 100644 --- a/awx/ui/client/src/notifications/notificationTemplates.list.js +++ b/awx/ui/client/src/notifications/notificationTemplates.list.js @@ -19,17 +19,14 @@ export default function(){ fields: { status: { label: '', - columnClass: 'List-staticColumn--smallStatus', + iconOnly: true, searchable: false, nosort: true, - ngClick: "null", - iconOnly: true, - excludeModal: true, - icons: [{ - icon: "{{ 'icon-job-' + notification_template.status }}", - ngClick: "showSummary($event, notification_template.id)", - ngClass: "" - }] + icon: 'icon-job-{{ notification_template.status }}', + awPopOver: '{{ notification_template.template_status_html }}', + dataTitle: "Recent Notifications", + dataPlacement: 'right', + columnClass: 'col-lg-1 col-md-1 col-sm-2 col-xs-2 List-staticColumn--smallStatus' }, name: { key: true, diff --git a/awx/ui/client/src/shared/directives.js b/awx/ui/client/src/shared/directives.js index 1d724b315a..289e04b58d 100644 --- a/awx/ui/client/src/shared/directives.js +++ b/awx/ui/client/src/shared/directives.js @@ -576,6 +576,10 @@ angular.module('AWDirectives', ['RestServices', 'Utilities', 'JobsHelper']) template = '