diff --git a/awx/ui/client/src/inventories/related-hosts/main.js b/awx/ui/client/src/inventories/related-hosts/main.js index 2f892270b3..4b0e63c43d 100644 --- a/awx/ui/client/src/inventories/related-hosts/main.js +++ b/awx/ui/client/src/inventories/related-hosts/main.js @@ -9,12 +9,14 @@ import relatedHostList from './list/main'; import relatedHostsListDefinition from './related-host.list'; import relatedHostsFormDefinition from './related-host.form'; + import relatedGroupsLabels from './related-groups-labels/main'; export default angular.module('relatedHost', [ relatedHostAdd.name, relatedHostEdit.name, - relatedHostList.name + relatedHostList.name, + relatedGroupsLabels.name ]) .factory('RelatedHostsFormDefinition', relatedHostsFormDefinition) .value('RelatedHostsListDefinition', relatedHostsListDefinition); diff --git a/awx/ui/client/src/inventories/related-hosts/related-groups-labels/main.js b/awx/ui/client/src/inventories/related-hosts/related-groups-labels/main.js new file mode 100644 index 0000000000..a3be739b8a --- /dev/null +++ b/awx/ui/client/src/inventories/related-hosts/related-groups-labels/main.js @@ -0,0 +1,11 @@ +/************************************************* + * Copyright (c) 2015 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ + +import relatedGroupsabelsList from './relatedGroupsLabelsList.directive'; + +export default + angular.module('relatedGroupsLabels', []) + .directive('relatedGroupsLabelsList', relatedGroupsabelsList); diff --git a/awx/ui/client/src/inventories/related-hosts/related-groups-labels/relatedGroupsLabelsList.block.less b/awx/ui/client/src/inventories/related-hosts/related-groups-labels/relatedGroupsLabelsList.block.less new file mode 100644 index 0000000000..56cbee8b09 --- /dev/null +++ b/awx/ui/client/src/inventories/related-hosts/related-groups-labels/relatedGroupsLabelsList.block.less @@ -0,0 +1,6 @@ +/** @define LabelList */ +// @import "./client/src/shared/branding/colors.default.less"; + +.RelatedGroupsLabelsCell{ + width:100%; +} diff --git a/awx/ui/client/src/inventories/related-hosts/related-groups-labels/relatedGroupsLabelsList.directive.js b/awx/ui/client/src/inventories/related-hosts/related-groups-labels/relatedGroupsLabelsList.directive.js new file mode 100644 index 0000000000..f8638403d9 --- /dev/null +++ b/awx/ui/client/src/inventories/related-hosts/related-groups-labels/relatedGroupsLabelsList.directive.js @@ -0,0 +1,103 @@ +/* jshint unused: vars */ +export default + [ 'templateUrl', + 'Wait', + 'Rest', + 'GetBasePath', + 'ProcessErrors', + 'Prompt', + '$q', + '$filter', + '$state', + function(templateUrl, Wait, Rest, GetBasePath, ProcessErrors, Prompt, $q, $filter, $state) { + return { + restrict: 'E', + scope: false, + templateUrl: templateUrl('inventories/related-hosts/related-groups-labels/relatedGroupsLabelsList'), + link: function(scope, element, attrs) { + scope.showDelete = attrs.showDelete === 'true'; + scope.seeMoreInactive = true; + + var getNext = function(data, arr, resolve) { + Rest.setUrl(data.next); + Rest.get() + .success(function (data) { + if (data.next) { + getNext(data, arr.concat(data.results), resolve); + } else { + resolve.resolve(arr.concat(data.results)); + } + }); + }; + + scope.seeMore = function () { + var seeMoreResolve = $q.defer(); + Rest.setUrl(scope[scope.$parent.list.iterator].related.groups); + Rest.get() + .success(function(data) { + if (data.next) { + getNext(data, data.results, seeMoreResolve); + } else { + seeMoreResolve.resolve(data.results); + } + }); + + seeMoreResolve.promise.then(function (groups) { + scope.related_groups = groups; + scope.seeMoreInactive = false; + }); + }; + + scope.seeLess = function() { + // Trim the groups array back down to 10 items + scope.related_groups = scope.related_groups.slice(0, 5); + // Re-set the seeMoreInteractive flag so that the "See More" will be displayed + scope.seeMoreInactive = true; + }; + + scope.deleteLabel = function(host, group) { + var action = function () { + $('#prompt-modal').modal('hide'); + scope.seeMoreInactive = true; + Wait('start'); + let url = `${GetBasePath('groups')}${group.id}/hosts`; + if(url) { + Rest.setUrl(url); + Rest.post({"disassociate": true, "id": host.id}) + .success(function () { + Wait('stop'); + $state.go('.', null, {reload: true}); + }) + .error(function (data, status) { + Wait('stop'); + ProcessErrors(scope, data, status, null, { hdr: 'Error!', + msg: 'Could not disassociate host from group. Call to ' + url + ' failed. DELETE returned status: ' + status }); + }); + } + }; + + Prompt({ + hdr: 'Remove host from ' + group.name , + body: '
Confirm the removal of the ' + $filter('sanitize')(host.name) + ' from the ' + $filter('sanitize')(group.name) + ' group.
', + action: action, + actionText: 'REMOVE' + }); + }; + + scope.$watchCollection(scope.$parent.list.iterator, function() { + // To keep the array of groups fresh, we need to set up a watcher - otherwise, the + // array will get set initially and then never be updated as groups are removed + if (scope[scope.$parent.list.iterator].summary_fields.groups){ + scope.related_groups = scope[scope.$parent.list.iterator].summary_fields.groups.results; + scope.count = scope[scope.$parent.list.iterator].summary_fields.groups.count; + } + else{ + scope.related_groups = null; + scope.count = null; + } + }); + + } + }; + } + ]; diff --git a/awx/ui/client/src/inventories/related-hosts/related-groups-labels/relatedGroupsLabelsList.partial.html b/awx/ui/client/src/inventories/related-hosts/related-groups-labels/relatedGroupsLabelsList.partial.html new file mode 100644 index 0000000000..ae6448212b --- /dev/null +++ b/awx/ui/client/src/inventories/related-hosts/related-groups-labels/relatedGroupsLabelsList.partial.html @@ -0,0 +1,14 @@ +
+
+ +
+
+ {{ related_group.name }} +
+
+
View More
+
View Less
diff --git a/awx/ui/client/src/inventories/related-hosts/related-host.list.js b/awx/ui/client/src/inventories/related-hosts/related-host.list.js index 698d1cd853..13c389043d 100644 --- a/awx/ui/client/src/inventories/related-hosts/related-host.list.js +++ b/awx/ui/client/src/inventories/related-hosts/related-host.list.js @@ -44,6 +44,20 @@ export default { dataHostId: "{{ host.id }}", dataType: "host", class: 'InventoryManage-breakWord' + }, + groups: { + label: "Related Groups", + type: 'related_groups', + nosort: true, + showDelete: true, + columnClass: 'RelatedGroupsLabelsCell List-tableCell col-lg-2 col-md-3 hidden-sm hidden-xs' + // ngBind: 'host.summary_fields.groups', + // ngClass: "{ 'host-disabled-label': !host.enabled }", + // columnClass: 'col-lg-6 col-md-8 col-sm-8 col-xs-7', + // dataHostId: "{{ host.id }}", + // dataType: "host", + // class: 'InventoryManage-breakWord' + } }, diff --git a/awx/ui/client/src/shared/generator-helpers.js b/awx/ui/client/src/shared/generator-helpers.js index 25186a2e5e..a30f847d76 100644 --- a/awx/ui/client/src/shared/generator-helpers.js +++ b/awx/ui/client/src/shared/generator-helpers.js @@ -491,13 +491,23 @@ angular.module('GeneratorHelpers', [systemStatus.name]) `; } else if (field.type === 'labels') { - var showDelete = field.showDelete === undefined ? true : field.showDelete; + let showDelete = field.showDelete === undefined ? true : field.showDelete; classList = (field.columnClass) ? Attr(field, 'columnClass') : ""; html += ` + + `; + } else if (field.type === 'related_groups') { + let showDelete = field.showDelete === undefined ? true : field.showDelete; + classList = (field.columnClass) ? + Attr(field, 'columnClass') : ""; + html += ` + + + `; } else if (field.type === 'owners') {