Latest inventory tree updates. Now using root_groups to retrieve top-level inventory groups. Ajax group load now works -hosts and subgroups loading. Need to add sorting, but all works.

This commit is contained in:
chouseknecht
2013-05-15 17:24:49 -04:00
parent 01ec33ec8f
commit 1bc85f608c
6 changed files with 135 additions and 74 deletions

View File

@@ -56,35 +56,35 @@ angular.module('ansible', [
// when('/job_templates/:id', { templateUrl: urlPrefix + 'partials/job_templates.html', // when('/job_templates/:id', { templateUrl: urlPrefix + 'partials/job_templates.html',
// controller: JobTemplatesEdit }). // controller: JobTemplatesEdit }).
when('/projects', { templateUrl: urlPrefix + 'partials/projects.html', when('/projects',
controller: ProjectsList }). { templateUrl: urlPrefix + 'partials/projects.html', controller: ProjectsList }).
when('/inventories', { templateUrl: urlPrefix + 'partials/inventories.html', when('/inventories',
controller: InventoriesList }). { templateUrl: urlPrefix + 'partials/inventories.html', controller: InventoriesList }).
when('/inventories/add', { templateUrl: urlPrefix + 'partials/inventories.html', when('/inventories/add',
controller: InventoriesAdd }). { templateUrl: urlPrefix + 'partials/inventories.html', controller: InventoriesAdd }).
when('/inventories/:id', { templateUrl: urlPrefix + 'partials/inventories.html', when('/inventories/:id',
controller: InventoriesEdit }). { templateUrl: urlPrefix + 'partials/inventories.html', controller: InventoriesEdit }).
when('/inventories/:id/hosts', { templateUrl: urlPrefix + 'partials/inventories.html', when('/inventories/:inventory_id/hosts',
controller: HostsList }). { templateUrl: urlPrefix + 'partials/inventories.html', controller: HostsList }).
when('/inventories/:id/hosts/add', { templateUrl: urlPrefix + 'partials/inventories.html', when('/inventories/:inventory_id/hosts/add',
controller: HostsAdd }). { templateUrl: urlPrefix + 'partials/inventories.html', controller: HostsAdd }).
when('/inventories/:inventory_id/hosts/:id', { templateUrl: urlPrefix + 'partials/inventories.html', when('/inventories/:inventory_id/hosts/:host_id',
controller: HostsEdit }). { templateUrl: urlPrefix + 'partials/inventories.html', controller: HostsEdit }).
when('/inventories/:id/groups', { templateUrl: urlPrefix + 'partials/inventories.html', when('/inventories/:inventory_id/groups',
controller: GroupsList }). { templateUrl: urlPrefix + 'partials/inventories.html', controller: GroupsList }).
when('/inventories/:id/groups/add', { templateUrl: urlPrefix + 'partials/inventories.html', when('/inventories/:inventory_id/groups/add',
controller: GroupsAdd }). { templateUrl: urlPrefix + 'partials/inventories.html', controller: GroupsAdd }).
when('/inventories/:inventory_id/groups/:id', { templateUrl: urlPrefix + 'partials/inventories.html', when('/inventories/:inventory_id/groups/:group_id',
controller: GroupsEdit }). { templateUrl: urlPrefix + 'partials/inventories.html', controller: GroupsEdit }).
when('/inventories/:inventory_id/groups/:group_id/children', when('/inventories/:inventory_id/groups/:group_id/children',
{ templateUrl: urlPrefix + 'partials/inventories.html', controller: GroupsList }). { templateUrl: urlPrefix + 'partials/inventories.html', controller: GroupsList }).
@@ -92,7 +92,7 @@ angular.module('ansible', [
when('/inventories/:inventory_id/groups/:group_id/children/add', when('/inventories/:inventory_id/groups/:group_id/children/add',
{ templateUrl: urlPrefix + 'partials/inventories.html', controller: GroupsAdd }). { templateUrl: urlPrefix + 'partials/inventories.html', controller: GroupsAdd }).
when('/inventories/:inventory_id/groups/:group_id/children/:id', when('/inventories/:inventory_id/groups/:group_id/children/:child_id',
{ templateUrl: urlPrefix + 'partials/inventories.html', controller: GroupsEdit }). { templateUrl: urlPrefix + 'partials/inventories.html', controller: GroupsEdit }).
when('/inventories/:inventory_id/groups/:group_id/hosts', when('/inventories/:inventory_id/groups/:group_id/hosts',
@@ -101,7 +101,7 @@ angular.module('ansible', [
when('/inventories/:inventory_id/groups/:group_id/hosts/add', when('/inventories/:inventory_id/groups/:group_id/hosts/add',
{ templateUrl: urlPrefix + 'partials/inventories.html', controller: HostsAdd }). { templateUrl: urlPrefix + 'partials/inventories.html', controller: HostsAdd }).
when('/inventories/:inventory_id/groups/:group_id/hosts/:id', when('/inventories/:inventory_id/groups/:group_id/hosts/:host_id',
{ templateUrl: urlPrefix + 'partials/inventories.html', controller: HostsEdit }). { templateUrl: urlPrefix + 'partials/inventories.html', controller: HostsEdit }).
when('/organizations', { templateUrl: urlPrefix + 'partials/organizations.html', when('/organizations', { templateUrl: urlPrefix + 'partials/organizations.html',

View File

@@ -162,9 +162,9 @@ function GroupsAdd ($scope, $rootScope, $compile, $location, $log, $routeParams,
data[fld] = scope[fld]; data[fld] = scope[fld];
} }
//if ($routeParams.group_id) { if ($routeParams.inventory_id) {
// data['inventory'] = $routeParams.inventory_id; data['inventory'] = $routeParams.inventory_id;
//} }
Rest.post(data) Rest.post(data)
.success( function(data, status, headers, config) { .success( function(data, status, headers, config) {
@@ -197,11 +197,11 @@ function GroupsEdit ($scope, $rootScope, $compile, $location, $log, $routeParams
var generator = GenerateForm; var generator = GenerateForm;
var form = GroupForm; var form = GroupForm;
var defaultUrl = GetBasePath('groups') + $routeParams.id + '/'; var defaultUrl = GetBasePath('groups') + $routeParams.group_id + '/';
var scope = generator.inject(form, {mode: 'edit', related: true}); var scope = generator.inject(form, {mode: 'edit', related: true});
generator.reset(); generator.reset();
var master = {}; var master = {};
var id = $routeParams.id; var id = $routeParams.group_id;
var relatedSets = {}; var relatedSets = {};
// After the Organization is loaded, retrieve each related set // After the Organization is loaded, retrieve each related set
@@ -238,7 +238,7 @@ function GroupsEdit ($scope, $rootScope, $compile, $location, $log, $routeParams
}) })
.error( function(data, status, headers, config) { .error( function(data, status, headers, config) {
ProcessErrors(scope, data, status, form, ProcessErrors(scope, data, status, form,
{ hdr: 'Error!', msg: 'Failed to retrieve group: ' + $routeParams.id + '. GET status: ' + status }); { hdr: 'Error!', msg: 'Failed to retrieve group: ' + id + '. GET status: ' + status });
}); });
// Save changes to the parent // Save changes to the parent
@@ -255,7 +255,7 @@ function GroupsEdit ($scope, $rootScope, $compile, $location, $log, $routeParams
}) })
.error( function(data, status, headers, config) { .error( function(data, status, headers, config) {
ProcessErrors(scope, data, status, form, ProcessErrors(scope, data, status, form,
{ hdr: 'Error!', msg: 'Failed to update group: ' + $routeParams.id + '. PUT status: ' + status }); { hdr: 'Error!', msg: 'Failed to update group: ' + id + '. PUT status: ' + status });
}); });
}; };

View File

@@ -160,11 +160,9 @@ function HostsAdd ($scope, $rootScope, $compile, $location, $log, $routeParams,
for (var fld in form.fields) { for (var fld in form.fields) {
data[fld] = scope[fld]; data[fld] = scope[fld];
} }
if ($routeParams.inventory_id) {
if ($routeParams.group_id) {
data['inventory'] = $routeParams.inventory_id; data['inventory'] = $routeParams.inventory_id;
} }
Rest.post(data) Rest.post(data)
.success( function(data, status, headers, config) { .success( function(data, status, headers, config) {
ReturnToCaller(1); ReturnToCaller(1);
@@ -201,7 +199,7 @@ function HostsEdit ($scope, $rootScope, $compile, $location, $log, $routeParams,
var scope = generator.inject(form, {mode: 'edit', related: true}); var scope = generator.inject(form, {mode: 'edit', related: true});
generator.reset(); generator.reset();
var master = {}; var master = {};
var id = $routeParams.id; var id = $routeParams.host_id;
var relatedSets = {}; var relatedSets = {};
// After form data loads, load related sets and lookups // After form data loads, load related sets and lookups
@@ -235,7 +233,7 @@ function HostsEdit ($scope, $rootScope, $compile, $location, $log, $routeParams,
}) })
.error( function(data, status, headers, config) { .error( function(data, status, headers, config) {
ProcessErrors(scope, data, status, form, ProcessErrors(scope, data, status, form,
{ hdr: 'Error!', msg: 'Failed to retrieve host: ' + $routeParams.id + '. GET status: ' + status }); { hdr: 'Error!', msg: 'Failed to retrieve host: ' + id + '. GET status: ' + status });
}); });
// Save changes to the parent // Save changes to the parent
@@ -251,7 +249,7 @@ function HostsEdit ($scope, $rootScope, $compile, $location, $log, $routeParams,
}) })
.error( function(data, status, headers, config) { .error( function(data, status, headers, config) {
ProcessErrors(scope, data, status, form, ProcessErrors(scope, data, status, form,
{ hdr: 'Error!', msg: 'Failed to update host: ' + $routeParams.id + '. PUT status: ' + status }); { hdr: 'Error!', msg: 'Failed to update host: ' + id + '. PUT status: ' + status });
}); });
}; };

View File

@@ -166,6 +166,9 @@ function InventoriesAdd ($scope, $rootScope, $compile, $location, $log, $routePa
for (var fld in form.fields) { for (var fld in form.fields) {
data[fld] = scope[fld]; data[fld] = scope[fld];
} }
if ($routeParams.inventory_id) {
data.inventory = $routeParams.inventory_id;
}
Rest.post(data) Rest.post(data)
.success( function(data, status, headers, config) { .success( function(data, status, headers, config) {
ReturnToCaller(); ReturnToCaller();

View File

@@ -2,31 +2,123 @@
* Copyright (c) 2013 AnsibleWorks, Inc. * Copyright (c) 2013 AnsibleWorks, Inc.
* *
* InventoryHelper * InventoryHelper
* Routines shared amongst the inventory controllers * Routines for building the tree. Everything related to the tree is here except
* for the menu piece. The routine for building the menu is in InventoriesEdit controller
* (controllers/Inventories.js)
*
*/ */
angular.module('InventoryHelper', [ 'RestServices', 'Utilities', 'OrganizationListDefinition', angular.module('InventoryHelper', [ 'RestServices', 'Utilities', 'OrganizationListDefinition',
'SearchHelper', 'PaginateHelper', 'ListGenerator', 'AuthService' 'SearchHelper', 'PaginateHelper', 'ListGenerator', 'AuthService'
]) ])
.factory('TreeInit', ['Alert', 'Rest', 'Authorization', .factory('TreeInit', ['Alert', 'Rest', 'Authorization', '$http',
function(Alert, Rest, Authorization) { function(Alert, Rest, Authorization, $http) {
return function(params) { return function(params) {
var scope = params.scope; var scope = params.scope;
var inventory = params.inventory; var inventory = params.inventory;
var groups = inventory.related.groups; var groups = inventory.related.root_groups;
var hosts = inventory.related.hosts; var hosts = inventory.related.hosts;
var inventory_name = inventory.name; var inventory_name = inventory.name;
var inventory_url = inventory.url; var inventory_url = inventory.url;
var inventory_id = inventory.id; var inventory_id = inventory.id;
var tree_id = '#tree-view';
var treeData = []; var treeData = [];
// On group expand, fetch and add hosts
if (scope.loadHostsRemove) {
scope.loadHostsRemove();
}
scope.loadHostsRemove = scope.$on('loadHosts', function(){
var node = scope.selected_node;
var url = $(node).attr('hosts');
var children = [];
// Rest and $http refuse to work. Seems we've hit a nesting limit at this point?
$.ajax({
url: url,
dataType: 'json',
headers: { 'Authorization': 'Token ' + Authorization.getToken() }
}).done( function(data) {
for (var i=0; i < data.results.length; i++) {
// Add each host to the group node
$(tree_id).jstree("create_node", node, "inside", {
data: {
title: data.results[i].name,
icon: '/'
},
attr: {
id: data.results[i].id,
type: 'host',
name: data.results[i].name,
description: data.results[i].description,
url: data.results[i].url,
variable_data: data.results[i].varaible_data,
inventory: data.results[i].related.inventory,
job_events: data.results[i].related.job_events
}
});
}
// Open the group node
$(tree_id).jstree("open_node", node);
});
});
// After loading the Inventory top-level data, initialize the tree
if (scope.buildTreeRemove) {
scope.buildTreeRemove();
}
scope.buildTreeRemove = scope.$on('buildTree', function() {
$(tree_id).jstree({
"core": { "initially_open":['inventory-node'] },
"plugins": ['themes', 'json_data', 'ui', 'contextmenu'],
"json_data": {
data: treeData,
ajax: {
url: function(node){
scope.selected_node = node;
return $(node).attr('children');
},
headers: { 'Authorization': 'Token ' + Authorization.getToken() },
success: function(data) {
var response = [];
for (var i=0; i < data.results.length; i++) {
response.push({
data: {
title: data.results[i].name
},
attr: {
id: data.results[i].id,
type: 'group',
name: data.results[i].name,
description: data.results[i].description,
inventory: data.results[i].inventory,
all: data.results[i].related.all_hosts,
children: data.results[i].related.children,
hosts: data.results[i].related.hosts,
variable: data.results[i].related.variable_data
},
state: 'closed'
});
}
scope.$emit('loadHosts');
return response;
}
}
},
"contextmenu": {
items: scope.treeController
}
});
});
// Ater inventory top-level hosts, load top-level groups
if (scope.HostLoadedRemove) { if (scope.HostLoadedRemove) {
scope.HostLoadedRemove(); scope.HostLoadedRemove();
} }
scope.HostLoadedRemove = scope.$on('hostsLoaded', function() { scope.HostLoadedRemove = scope.$on('hostsLoaded', function() {
Rest.setUrl(groups + '?order_by=name'); Rest.setUrl(groups + '?order_by=name');
Rest.get() Rest.get()
@@ -50,45 +142,14 @@ angular.module('InventoryHelper', [ 'RestServices', 'Utilities', 'OrganizationLi
state: 'closed' state: 'closed'
}); });
} }
scope.$emit('buildTree');
var tree_id = '#tree-view';
//.bind("open_node.jstree close_node.jstree", function (e,data) {
// var currentNode = data.args[0];
// if (e.type === "open_node") {
//var tree = $.jstree._reference(tree_id);
//tree.refresh(currentNode);
// }
// })
$(tree_id).jstree({
"core": { "initially_open":['inventory-node'] },
"plugins": ['themes', 'json_data', 'ui', 'contextmenu'],
"json_data": {
data: treeData,
ajax: {
url: function(node){
return $(node).attr('all');
},
headers: { 'Authorization': 'Token ' + Authorization.getToken() },
success: function(data) {
},
error: function() {
if (console) {
console.log('Error accessing node data!');
}
}
}
},
"contextmenu": {
items: scope.treeController
}
});
}) })
.error( function(data, status, headers, config) { .error( function(data, status, headers, config) {
Alert('Error', 'Failed to laod tree data. Url: ' + groups + ' GET status: ' + status); Alert('Error', 'Failed to laod tree data. Url: ' + groups + ' GET status: ' + status);
}); });
}); });
// Load inventory top-level hosts
Rest.setUrl(hosts + '?order_by=name'); Rest.setUrl(hosts + '?order_by=name');
Rest.get() Rest.get()
.success ( function(data, status, headers, config) { .success ( function(data, status, headers, config) {

View File

@@ -4,7 +4,6 @@
<meta charset="utf-8"> <meta charset="utf-8">
<title>Ansible Commander</title> <title>Ansible Commander</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="{{ STATIC_URL }}css/smoothness/jquery-ui-1.10.3.custom.min.css" />
<link rel="stylesheet" href="{{ STATIC_URL }}css/bootstrap.min.css" /> <link rel="stylesheet" href="{{ STATIC_URL }}css/bootstrap.min.css" />
<link rel="stylesheet" href="{{ STATIC_URL }}css/bootstrap-responsive.min.css" /> <link rel="stylesheet" href="{{ STATIC_URL }}css/bootstrap-responsive.min.css" />
<link rel="stylesheet" href="{{ STATIC_URL }}css/font-awesome.min.css" /> <link rel="stylesheet" href="{{ STATIC_URL }}css/font-awesome.min.css" />