From a29e60b53364023d9c7c2a82022193597d5cbe6c Mon Sep 17 00:00:00 2001 From: chouseknecht Date: Mon, 3 Jun 2013 18:05:34 -0400 Subject: [PATCH] Tree refresh is working for the Group Add and Group Edit buttons. Tree is refreshed and opened back to the previously selected node and the host view is left in the correct state. --- .../ui/static/js/controllers/Inventories.js | 4 + ansibleworks/ui/static/js/helpers/Groups.js | 60 +++++---------- .../ui/static/js/helpers/inventory.js | 77 +++++++++++++++---- 3 files changed, 88 insertions(+), 53 deletions(-) diff --git a/ansibleworks/ui/static/js/controllers/Inventories.js b/ansibleworks/ui/static/js/controllers/Inventories.js index b0978a445c..52bb8af3a0 100644 --- a/ansibleworks/ui/static/js/controllers/Inventories.js +++ b/ansibleworks/ui/static/js/controllers/Inventories.js @@ -380,9 +380,13 @@ function InventoriesEdit ($scope, $rootScope, $compile, $location, $log, $routeP } scope.$on('NodeSelect', function(e, n) { + + // Respond to user clicking on a tree node + var node = $('li[id="' + n.attr.id + '"]'); var type = node.attr('type'); var url; + scope['selectedNode'] = node; $('#tree-view').jstree('open_node',node); if (type == 'group') { url = node.attr('all'); diff --git a/ansibleworks/ui/static/js/helpers/Groups.js b/ansibleworks/ui/static/js/helpers/Groups.js index fe2d01eeb3..8a570bc560 100644 --- a/ansibleworks/ui/static/js/helpers/Groups.js +++ b/ansibleworks/ui/static/js/helpers/Groups.js @@ -11,12 +11,12 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', 'GroupListDefinition', 'SearchHelper', 'PaginateHelper', 'ListGenerator', 'AuthService', 'GroupsHelper', 'InventoryHelper' - ]) + ]) .factory('GroupsList', ['$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'GroupList', 'GenerateList', 'Prompt', 'SearchInit', 'PaginateInit', 'ProcessErrors', 'GetBasePath', 'GroupsAdd', 'RefreshTree', function($rootScope, $location, $log, $routeParams, Rest, Alert, GroupList, GenerateList, LoadBreadCrumbs, SearchInit, - PaginateInit, ProcessErrors, GetBasePath, GroupsAdd, RefreshTree) { + PaginateInit, ProcessErrors, GetBasePath, GroupsAdd, RefreshTree) { return function(params) { var inventory_id = params.inventory_id; @@ -45,6 +45,7 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', ' } scope.PostRefreshRemove = scope.$on('PostRefresh', function() { $("tr.success").each(function(index) { + // Make sure no rows have a green background var ngc = $(this).attr('ng-class'); scope[ngc] = ""; }); @@ -64,35 +65,6 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', ' PaginateInit({ scope: scope, list: list, url: defaultUrl }); scope.search(list.iterator); - /*LoadBreadCrumbs();*/ - - scope.editGroup = function(id) { - $location.path($location.path() + '/' + id); - } - - scope.deleteGroup = function(id, name) { - - var action = function() { - var url = defaultUrl; - Rest.setUrl(url); - Rest.post({ id: id, disassociate: 1 }) - .success( function(data, status, headers, config) { - $('#prompt-modal').modal('hide'); - scope.search(list.iterator); - }) - .error( function(data, status, headers, config) { - $('#prompt-modal').modal('hide'); - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Call to ' + url + ' failed. DELETE returned status: ' + status }); - }); - }; - - Prompt({ hdr: 'Delete', - body: 'Are you sure you want to remove group' + name + '?', - action: action - }); - } - scope.formModalAction = function() { var url = (group_id) ? GetBasePath('groups') + group_id + '/children/' : GetBasePath('inventory') + inventory_id + '/groups/'; @@ -120,6 +92,7 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', ' } else { $('#form-modal').modal('hide'); + RefreshTree({ scope: scope }); } } }); @@ -173,16 +146,15 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', ' GroupsAdd({ inventory_id: inventory_id, group_id: group_id }); } - } }]) .factory('GroupsAdd', ['$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'GroupForm', 'GenerateForm', - 'Prompt', 'ProcessErrors', 'GetBasePath', + 'Prompt', 'ProcessErrors', 'GetBasePath', 'RefreshTree', function($rootScope, $location, $log, $routeParams, Rest, Alert, GroupForm, GenerateForm, Prompt, ProcessErrors, - GetBasePath) { + GetBasePath, RefreshTree) { return function(params) { var inventory_id = params.inventory_id; @@ -197,7 +169,7 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', ' scope.formModalActionLabel = 'Save' scope.formModalHeader = 'Create Group' generator.reset(); - var master={}; + var master={}; // Save scope.formModalAction = function() { @@ -224,12 +196,17 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', ' Rest.put({data: scope.variables}) .success( function(data, status, headers, config) { $('#form-modal').modal('hide'); + RefreshTree({ scope: scope }); }) .error( function(data, status, headers, config) { ProcessErrors(scope, data, status, form, { hdr: 'Error!', msg: 'Failed to add group varaibles. PUT returned status: ' + status }); }); } + else { + $('#form-modal').modal('hide'); + RefreshTree({ scope: scope }); + } }) .error( function(data, status, headers, config) { ProcessErrors(scope, data, status, form, @@ -251,9 +228,9 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', ' }]) .factory('GroupsEdit', ['$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'GroupForm', 'GenerateForm', - 'Prompt', 'ProcessErrors', 'GetBasePath', + 'Prompt', 'ProcessErrors', 'GetBasePath', 'RefreshTree', function($rootScope, $location, $log, $routeParams, Rest, Alert, GroupForm, GenerateForm, Prompt, ProcessErrors, - GetBasePath) { + GetBasePath, RefreshTree) { return function(params) { var group_id = params.group_id; @@ -343,13 +320,17 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', ' Rest.put({data: scope.variables}) .success( function(data, status, headers, config) { $('#form-modal').modal('hide'); - }) + RefreshTree({ scope: scope }); + }) .error( function(data, status, headers, config) { ProcessErrors(scope, data, status, form, { hdr: 'Error!', msg: 'Failed to update group varaibles. PUT returned status: ' + status }); }); } - $('#form-modal').modal('hide'); + else { + $('#form-modal').modal('hide'); + RefreshTree({ scope: scope }); + } }) .error( function(data, status, headers, config) { ProcessErrors(scope, data, status, form, @@ -389,6 +370,7 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', ' }) .error( function(data, status, headers, config) { $('#prompt-modal').modal('hide'); + RefreshTree({ scope: scope }); ProcessErrors(scope, data, status, null, { hdr: 'Error!', msg: 'Call to ' + url + ' failed. DELETE returned status: ' + status }); }); diff --git a/ansibleworks/ui/static/js/helpers/inventory.js b/ansibleworks/ui/static/js/helpers/inventory.js index b00bb58630..8ecf0a5370 100644 --- a/ansibleworks/ui/static/js/helpers/inventory.js +++ b/ansibleworks/ui/static/js/helpers/inventory.js @@ -163,6 +163,10 @@ angular.module('InventoryHelper', [ 'RestServices', 'Utilities', 'OrganizationLi items: scope.treeController } }); + + $(tree_id).bind("loaded.jstree", function () { + scope.$emit('treeLoaded'); + }); // When user clicks on a group, display the related hosts in the list view $(tree_id).bind("select_node.jstree", function(e, data){ @@ -178,21 +182,9 @@ angular.module('InventoryHelper', [ 'RestServices', 'Utilities', 'OrganizationLi }]) - .factory('RefreshTree', ['Alert', 'Rest', 'Authorization', '$http', 'TreeInit', - function(Alert, Rest, Authorization, $http, TreeInit) { - return function(params) { - - $('#tree-view').jstree('destroy'); - - TreeInit(params); - - } - }]) - - - .factory('LoadInventory', ['$routeParams', 'Alert', 'Rest', 'Authorization', '$http', 'RefreshTree', 'ProcessErrors', + .factory('LoadInventory', ['$routeParams', 'Alert', 'Rest', 'Authorization', '$http', 'ProcessErrors', 'RelatedSearchInit', 'RelatedPaginateInit', 'GetBasePath', 'LoadBreadCrumbs', 'InventoryForm', - function($routeParams, Alert, Rest, Authorization, $http, RefreshTree ,ProcessErrors, RelatedSearchInit, RelatedPaginateInit, + function($routeParams, Alert, Rest, Authorization, $http, ProcessErrors, RelatedSearchInit, RelatedPaginateInit, GetBasePath, LoadBreadCrumbs, InventoryForm) { return function(params) { @@ -240,6 +232,63 @@ angular.module('InventoryHelper', [ 'RestServices', 'Utilities', 'OrganizationLi { hdr: 'Error!', msg: 'Failed to retrieve inventory: ' + $routeParams.id + '. GET status: ' + status }); }); + } + }]) + + + .factory('RefreshTree', ['Alert', 'Rest', 'Authorization', '$http', 'TreeInit', 'LoadInventory', + function(Alert, Rest, Authorization, $http, TreeInit, LoadInventory) { + return function(params) { + + // Call after an Edit or Add to refresh tree data + + var scope = params.scope; + var openId = []; + var selectedId; + + if (scope.treeLoadedRemove) { + scope.treeLoadedRemove(); + } + scope.treeLoadedRemove = scope.$on('treeLoaded', function() { + // Called recursively to pop the next openId node value and open it. + // Opens the list in reverse so that nodes open in parent then child order, + // drilling down to the last selected node. + var id, node; + if (openId.length > 0) { + id = openId.pop(); + node = $('#tree-view li[id="' + id + '"]'); + $.jstree._reference('#tree-view').open_node(node, function(){ scope.$emit('treeLoaded'); }, true); + } + else { + if (selectedId !== null && selectedId !== undefined) { + // Click on the previously selected node + $('#tree-view li[id="' + selectedId + '"] a').first().click(); + } + } + }); + + if (scope.inventoryLoadedRemove) { + scope.inventoryLoadedRemove(); + } + scope.inventoryLoadedRemove = scope.$on('inventoryLoaded', function() { + // Get the list of open tree nodes starting with the current group and going up + // the tree until we hit the inventory or root node. + function findOpenNodes(node) { + if (node.attr('id') != 'inventory-node') { + if (node.prop('tagName') == 'LI' && (node.hasClass('jstree-open') || node.find('.jstree-clicked'))) { + openId.push(node.attr('id')); + } + findOpenNodes(node.parent()); + } + } + selectedId = scope.selectedNode.attr('id'); + findOpenNodes(scope.selectedNode); + $('#tree-view').jstree('destroy'); + TreeInit(scope.TreeParams); + }); + + LoadInventory({ scope: scope }); + } }]);