diff --git a/awx/ui/static/js/app.js b/awx/ui/static/js/app.js index cb32841562..65d62bf5a4 100644 --- a/awx/ui/static/js/app.js +++ b/awx/ui/static/js/app.js @@ -77,7 +77,8 @@ angular.module('ansible', [ 'JobsHelper', 'InventoryStatusDefinition', 'InventorySummaryHelpDefinition', - 'InventoryHostsHelpDefinition' + 'InventoryHostsHelpDefinition', + 'TreeSelector' ]) .config(['$routeProvider', function($routeProvider) { $routeProvider. diff --git a/awx/ui/static/js/controllers/Groups.js b/awx/ui/static/js/controllers/Groups.js index 18f293c461..618909cf01 100644 --- a/awx/ui/static/js/controllers/Groups.js +++ b/awx/ui/static/js/controllers/Groups.js @@ -9,7 +9,7 @@ function InventoryGroups ($scope, $rootScope, $compile, $location, $log, $routeParams, InventoryGroupsForm, GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, ReturnToCaller, ClearScope, Prompt, - TreeInit, GetBasePath, GroupsList, GroupsAdd, GroupsEdit, LoadInventory, + BuildTree, GetBasePath, GroupsList, GroupsAdd, GroupsEdit, LoadInventory, GroupsDelete, RefreshGroupName, EditInventory, InventoryStatus) { ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior @@ -33,7 +33,13 @@ function InventoryGroups ($scope, $rootScope, $compile, $location, $log, $routeP } scope.inventoryLoadedRemove = scope.$on('inventoryLoaded', function() { LoadBreadCrumbs({ path: '/inventories/' + id, title: scope.inventory_name }); - TreeInit(scope.TreeParams); + //TreeInit(scope.TreeParams); + BuildTree({ + scope: scope, + inventory_id: id, + emit_on_select: 'NodeSelect', + target_id: 'search-tree-container' + }); if (!scope.$$phase) { scope.$digest(); } @@ -119,61 +125,59 @@ function InventoryGroups ($scope, $rootScope, $compile, $location, $log, $routeP } } - scope.$on('NodeSelect', function(e, n) { + scope.$on('NodeSelect', function(e, id, group_id, name) { // Respond to user clicking on a tree node - var node = $('li[id="' + n.attr.id + '"]'); + var node = $('#' + id); var parent = node.parent().parent(); - var type = node.attr('type'); + var type = (group_id == null) ? 'inventory' : 'group'; var url; - if ($rootScope.timer) { + /*if ($rootScope.timer) { // Kill any lingering timers from the inventory summary page clearInterval($rootScope.timer); $rootScope.timer = null; - } + }*/ - scope['nodeSelectValue'] = n; scope['selectedNode'] = node; - scope['selectedNodeName'] = node.attr('name'); + scope['selectedNodeName'] = name scope['grpBtnDisable'] = false; scope['flashMessage'] = null; scope['groupUpdateHide'] = true; - $('#tree-view').jstree('open_node',node); + //$('#tree-view').jstree('open_node',node); if (type == 'group') { - url = node.attr('all'); + //url = node.attr('all'); scope.groupAddHide = false; scope.groupCreateHide = false; scope.groupEditHide = false; scope.inventoryEditHide = true; scope.groupDeleteHide = false; scope.createButtonShow = true; - scope.group_id = node.attr('group_id'); - - scope.addGroupHelp = "Copy an existing group into " + node.attr('name'); - scope.createGroupHelp = "Create a new group, adding it to " + node.attr('name'); - scope.updateGroupHelp = "Start the inventory update process, refreshing " + node.attr('name'); - if (parent.attr('id') == 'inventory-node') { - scope.deleteGroupHelp = "Remove " + node.attr('name') + " from " + parent.attr('name') + + scope.group_id = group_id; + scope.addGroupHelp = "Copy an existing group into " + name; + scope.createGroupHelp = "Create a new group, adding it to " + name; + scope.updateGroupHelp = "Start the inventory update process, refreshing " + name; + if (parent.attr('id') == 'inventory-root-node') { + scope.deleteGroupHelp = "Remove " + name + " from " + parent.attr('data-name') + " Inventory. Any hosts will still be available in All Hosts."; } else { - scope.deleteGroupHelp = "Remove " + node.attr('name') + " from " + parent.attr('name') + + scope.deleteGroupHelp = "Remove " + name + " from " + parent.attr('data-name') + ". Any hosts will still be available in " + parent.attr('name') + " and All Hosts."; } // Load the form - GroupsEdit({ "inventory_id": id, group_id: scope.group_id }); + GroupsEdit({ "inventory_id": scope['inventory_id'], group_id: scope['group_id'] }); // Slide in the group properties form $('#tree-form').show(); $('input:first').focus(); } else if (type == 'inventory') { - url = node.attr('hosts'); + //url = node.attr('hosts'); scope.groupAddHide = true; scope.groupCreateHide = false; scope.groupEditHide =true; @@ -181,7 +185,7 @@ function InventoryGroups ($scope, $rootScope, $compile, $location, $log, $routeP scope.groupDeleteHide = true; scope.createButtonShow = false; scope.group_id = null; - scope.inventory_name = node.attr('name'); + scope.inventory_name = name; InventoryStatus({ scope: scope }); $('#tree-form').show(); } @@ -240,7 +244,7 @@ function InventoryGroups ($scope, $rootScope, $compile, $location, $log, $routeP InventoryGroups.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'InventoryGroupsForm', 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'ReturnToCaller', 'ClearScope', 'Prompt', - 'TreeInit', 'GetBasePath', 'GroupsList', 'GroupsAdd', 'GroupsEdit', 'LoadInventory', + 'BuildTree', 'GetBasePath', 'GroupsList', 'GroupsAdd', 'GroupsEdit', 'LoadInventory', 'GroupsDelete', 'RefreshGroupName', 'EditInventory', 'InventoryStatus' ]; \ No newline at end of file diff --git a/awx/ui/static/js/helpers/Hosts.js b/awx/ui/static/js/helpers/Hosts.js index c8e7bcc4a4..9dae2331ba 100644 --- a/awx/ui/static/js/helpers/Hosts.js +++ b/awx/ui/static/js/helpers/Hosts.js @@ -513,225 +513,6 @@ angular.module('HostsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', 'H } }]) - - .factory('LoadSearchTree', ['Rest', 'GetBasePath', 'ProcessErrors', '$compile', '$rootScope', 'Wait', 'SortNodes', - function(Rest, GetBasePath, ProcessErrors, $compile, $rootScope, Wait, SortNodes) { - return function(params) { - - var scope = params.scope; - var inventory_id = params.inventory_id; - var html = ''; - var toolTip = 'Hosts have failed jobs?'; - - function buildHTML(tree_data) { - var sorted = SortNodes(tree_data); - html += (sorted.length > 0) ? "\n"; - } - - function refresh(parent) { - var group, title; - if (parent.attr('data-group-id')) { - group = parent.attr('data-group-id'); - title = parent.attr('data-name'); - //title += (parent.attr('data-description') !== "") ? '

' + parent.attr('data-description') + '

' : ''; - } - else { - group = null; - title = 'All Hosts' - } - // The following will trigger the host list to load. See Inventory.js controller. - scope.$emit('refreshHost', group, title); - } - - function activate(e) { - /* Set the clicked node as active */ - var elm = angular.element(e.target); // - var parent = angular.element(e.target.parentNode.parentNode); //
  • - $('.search-tree .active').removeClass('active'); - elm.addClass('active'); - refresh(parent); - } - - function toggle(e) { - var id, parent, elm, icon; - - if (e.target.tagName == 'I') { - id = e.target.parentNode.parentNode.parentNode.attributes.id.value; - parent = angular.element(e.target.parentNode.parentNode.parentNode); //
  • - elm = angular.element(e.target.parentNode); // - } - else { - id = e.target.parentNode.parentNode.attributes.id.value; - parent = angular.element(e.target.parentNode.parentNode); - elm = angular.element(e.target); - } - - var sibling = angular.element(parent.children()[2]); // - var state = parent.attr('data-state'); - var icon = angular.element(elm.children()[0]); - - if (state == 'closed') { - // expand the elment - var childlists = parent.find('ul'); - if (childlists && childlists.length > 0) { - // has childen - for (var i=0; i < childlists.length; i++) { - var listChild = angular.element(childlists[i]); - var listParent = angular.element(listChild.parent()); - if (listParent.attr('id') == id) { - angular.element(childlists[i]).removeClass('hidden'); - } - } - } - parent.attr('data-state','open'); - icon.removeClass('icon-caret-right').addClass('icon-caret-down'); - } - else { - // close the element - parent.attr('data-state','closed'); - icon.removeClass('icon-caret-down').addClass('icon-caret-right'); - var childlists = parent.find('ul'); - if (childlists && childlists.length > 0) { - // has childen - for (var i=0; i < childlists.length; i++) { - angular.element(childlists[i]).addClass('hidden'); - } - } - /* When the active node's parent is closed, activate the parent*/ - if ($(parent).find('.active').length > 0) { - $(parent).find('.active').removeClass('active'); - sibling.addClass('active'); - refresh(parent); - } - } - } - - // Responds to searchTreeReady, thrown from Hosts.js helper when the inventory tree - // is ready - if (scope.searchTreeReadyRemove) { - scope.searchTreeReadyRemove(); - } - scope.searchTreeReadyRemove = scope.$on('searchTreeReady', function(e, html) { - var container = angular.element(document.getElementById('search-tree-container')); - container.empty(); - var compiled = $compile(html)(scope); - container.append(compiled); - var links = container.find('a'); - for (var i=0; i < links.length; i++) { - var link = angular.element(links[i]); - if (link.hasClass('expand')) { - link.unbind('click', toggle); - link.bind('click', toggle); - } - if (link.hasClass('activate')) { - link.unbind('click', activate); - link.bind('click', activate); - } - } - - // Attempt to stop the title from dropping to the next - // line - $(container).find('.title-container').each(function(idx) { - var parent = $(this).parent(); - if ($(this).width() >= parent.width()) { - $(this).css('width','80%'); - } - }); - - Wait('stop'); - }); - - if (scope.buildAllGroupsRemove) { - scope.buildAllGroupsRemove(); - } - scope.buildAllGroupsRemove = scope.$on('buildAllGroups', function(e, inventory_name, inventory_tree) { - Rest.setUrl(inventory_tree); - Rest.get() - .success( function(data, status, headers, config) { - buildHTML(data); - scope.$emit('searchTreeReady', html + "
  • \n\n"); - }) - .error( function(data, status, headers, config) { - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Failed to get inventory tree for: ' + inventory_id + '. GET returned: ' + status }); - }); - }); - - - if (scope.buildGroupListRemove) { - scope.buildGroupListRemove(); - } - scope.buildGroupListRemove = scope.$on('buildAllGroups', function(e, inventory_name, inventory_tree, groups_url) { - scope.inventory_groups = []; - Rest.setUrl(groups_url); - Rest.get() - .success( function(data, status, headers, config) { - var groups = []; - for (var i=0; i < data.results.length; i++) { - groups.push({ - id: data.results[i].id, - description: data.results[i].description, - name: data.results[i].name }); - } - scope.inventory_groups = SortNodes(groups); - }) - .error( function(data, status, headers, config) { - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Failed to get groups for inventory: ' + inventory_id + '. GET returned: ' + status }); - }); - }); - - - Wait('start'); - - // Load the inventory root node - Rest.setUrl (GetBasePath('inventory') + inventory_id + '/'); - Rest.get() - .success( function(data, status, headers, config) { - html += "
    Group Selector:
    \n" + - "
    \n"); + }) + .error( function(data, status, headers, config) { + ProcessErrors(scope, data, status, null, + { hdr: 'Error!', msg: 'Failed to get inventory tree for: ' + inventory_id + '. GET returned: ' + status }); + }); + }); + + // Builds scope.inventory_groups, used by the group picker on Hosts view to build the list of potential groups + // that can be added to a host. <<<< Should probably be moved to /helpers/Hosts.js + if (scope.buildGroupListRemove) { + scope.buildGroupListRemove(); + } + scope.buildGroupListRemove = scope.$on('buildAllGroups', function(e, inventory_name, inventory_tree, groups_url) { + scope.inventory_groups = []; + Rest.setUrl(groups_url); + Rest.get() + .success( function(data, status, headers, config) { + var groups = []; + for (var i=0; i < data.results.length; i++) { + groups.push({ + id: data.results[i].id, + description: data.results[i].description, + name: data.results[i].name }); + } + scope.inventory_groups = SortNodes(groups); + }) + .error( function(data, status, headers, config) { + ProcessErrors(scope, data, status, null, + { hdr: 'Error!', msg: 'Failed to get groups for inventory: ' + inventory_id + '. GET returned: ' + status }); + }); + }); + + Wait('start'); + + // Load the inventory root node + Rest.setUrl (GetBasePath('inventory') + inventory_id + '/'); + Rest.get() + .success( function(data, status, headers, config) { + html += "
    Group Selector:
    \n" + + "