diff --git a/awx/ui/static/js/controllers/Inventories.js b/awx/ui/static/js/controllers/Inventories.js index 44208ce494..e976465537 100644 --- a/awx/ui/static/js/controllers/Inventories.js +++ b/awx/ui/static/js/controllers/Inventories.js @@ -521,10 +521,26 @@ function InventoriesEdit ($scope, $location, $routeParams, $compile, GenerateLis } $scope.showGroupActivity = function() { - var url = GetBasePath('activity_stream') + '?group__inventory__id=' + $scope.inventory_id; - Stream({ scope: $scope, inventory_name: $scope.inventory_name, url: url }); + var url, title, group; + if ($scope.selected_group_id) { + group = Find({ list: $scope.groups, key: 'id', val: $scope.selected_tree_id }); + url = GetBasePath('activity_stream') + '?group__id=' + $scope.selected_group_id; + title = 'Showing all activities for group ' + group.name; + } + else { + title = 'Showing all activities for all ' + $scope.inventory_name + ' groups'; + url = GetBasePath('activity_stream') + '?group__inventory__id=' + $scope.inventory_id; + } + Stream({ scope: $scope, inventory_name: $scope.inventory_name, url: url, title: title }); } + $scope.showHostActivity = function() { + var url, title; + title = 'Showing all activities for all ' + $scope.inventory_name + ' hosts'; + url = GetBasePath('activity_stream') + '?host__inventory__id=' + $scope.inventory_id; + Stream({ scope: $scope, inventory_name: $scope.inventory_name, url: url, title: title }); + } + $scope.showJobSummary = function(job_id) { ShowJobSummary({ job_id: job_id }); } diff --git a/awx/ui/static/js/lists/InventoryHosts.js b/awx/ui/static/js/lists/InventoryHosts.js index 3efae93e01..b40cd9ea6b 100644 --- a/awx/ui/static/js/lists/InventoryHosts.js +++ b/awx/ui/static/js/lists/InventoryHosts.js @@ -100,7 +100,13 @@ angular.module('InventoryHostsDefinition', []) ngHide: 'selected_tree_id == 1', //disable when 'All Hosts' selected awToolTip: "Create a new host" }, - help: { + stream: { + ngClick: "showHostActivity()", + awToolTip: "View Activity Stream", + mode: 'all', + ngShow: "user_is_superuser" + }, + help: { mode: 'all', awToolTip: //"
" + diff --git a/awx/ui/static/js/widgets/Stream.js b/awx/ui/static/js/widgets/Stream.js index 7bef535ed8..25baf67b82 100644 --- a/awx/ui/static/js/widgets/Stream.js +++ b/awx/ui/static/js/widgets/Stream.js @@ -189,14 +189,17 @@ angular.module('StreamWidget', ['RestServices', 'Utilities', 'StreamListDefiniti } else if (obj1) { name = ''; + var name_nolink = ''; // find the name in changes, if needed if ( !(obj1_obj && obj1_obj.name) || obj1_obj && obj1_obj.name && /^_delete/.test(obj1_obj.name) ) { if (activity.changes && activity.changes.name) { if (typeof activity.changes.name == 'string') { name = ' ' + activity.changes.name; + name_nolink = name; } else if (typeof activity.changes.name == 'object' && Array.isArray(activity.changes.name)) { - name = ' ' + activity.changes.name[0] + name = ' ' + activity.changes.name[0]; + name_nolink = name; } } else if (obj1 == 'job' && obj1_obj && activity.changes && activity.changes.job_template) { @@ -204,9 +207,11 @@ angular.module('StreamWidget', ['RestServices', 'Utilities', 'StreamListDefiniti if (activity.operation != 'delete') { obj1_obj['base'] = obj1; name = ' ' + ''+ obj1_obj.id + ' ' + activity.changes.job_template + ''; + name_nolink = ' ' + obj1_obj.id + ' ' + activity.changes.job_template; } else { name = ' ' + obj1_obj.id + ' ' + activity.changes.job_template; + name_nolink = name; } } else if (obj1 == 'job' && obj1_obj) { @@ -214,17 +219,20 @@ angular.module('StreamWidget', ['RestServices', 'Utilities', 'StreamListDefiniti if (activity.operation != 'delete') { obj1_obj['base'] = obj1; name = ' ' + '' + obj1_obj.id + ''; + name_nolink = ' ' + obj1_obj.id; } else { name = ' ' + obj1_obj.id; + name_nolink = name; } } } else if (obj1_obj && obj1_obj.name) { name = ' ' + stripDeleted(obj1_obj.name); + name_nolink = name; } descr += obj1 + name; - descr_nolink += obj1 + name; + descr_nolink += obj1 + name_nolink; } activity['description'] = descr; activity['description_nolink'] = descr_nolink; @@ -301,10 +309,10 @@ angular.module('StreamWidget', ['RestServices', 'Utilities', 'StreamListDefiniti var PreviousSearchParams = Store('CurrentSearchParams'); // pass in an inventory name to fix breadcrumb display - var inventory_name = (params) ? params.inventory_name : null; + var inventory_name = (params && params.inventory_name) ? params.inventory_name : null; // url will override the attempt to compute an activity_stream query - var url = (params) ? params.url : null; + var url = (params && params.url) ? params.url : null; $rootScope.flashMessage = null; @@ -357,6 +365,9 @@ angular.module('StreamWidget', ['RestServices', 'Utilities', 'StreamListDefiniti secondWidget: true, activityStream: true }); + + // descriptive title describing what AS is showing + scope.streamTitle = (params && params.title) ? params.title : null; scope.closeStream = function(inUrl) { HideStream(); diff --git a/awx/ui/static/less/ansible-ui.less b/awx/ui/static/less/ansible-ui.less index 80c1e8a33a..6774c9db81 100644 --- a/awx/ui/static/less/ansible-ui.less +++ b/awx/ui/static/less/ansible-ui.less @@ -1382,6 +1382,11 @@ tr td button i { border: 1px solid @grey; border-radius: 8px; padding: 8px; + + h5 { + margin-top: 0; + margin-bottom: 20px; + } } /* diff --git a/awx/ui/static/lib/ansible/list-generator.js b/awx/ui/static/lib/ansible/list-generator.js index bc0951eafa..5c84c2be82 100644 --- a/awx/ui/static/lib/ansible/list-generator.js +++ b/awx/ui/static/lib/ansible/list-generator.js @@ -147,6 +147,15 @@ angular.module('ListGenerator', ['GeneratorHelpers']) html += "
\n"; } + if (options.activityStream) { + // Add a title row + html += "
\n"; + html += "
\n"; + html += "
{{ streamTitle }}
\n"; + html += "
\n"; + html += "
\n"; + } + html += "
\n"; if (list.name != 'groups') {