AC-503 cloud inventory- first attempt at summary information on Inventory-> Groups page. Fixed compilation bugs.

This commit is contained in:
chouseknecht
2013-10-02 02:08:04 -04:00
parent 32d3914270
commit 77e79d9917
10 changed files with 176 additions and 56 deletions

View File

@@ -32,6 +32,7 @@ angular.module('ansible', [
'InventoryHelper', 'InventoryHelper',
'InventoryHostsFormDefinition', 'InventoryHostsFormDefinition',
'InventoryGroupsFormDefinition', 'InventoryGroupsFormDefinition',
'InventorySummaryDefinition',
'AWFilters', 'AWFilters',
'HostFormDefinition', 'HostFormDefinition',
'HostListDefinition', 'HostListDefinition',

View File

@@ -10,7 +10,7 @@
function InventoryGroups ($scope, $rootScope, $compile, $location, $log, $routeParams, InventoryGroupsForm, function InventoryGroups ($scope, $rootScope, $compile, $location, $log, $routeParams, InventoryGroupsForm,
GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, ReturnToCaller, ClearScope, Prompt, GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, ReturnToCaller, ClearScope, Prompt,
TreeInit, GetBasePath, GroupsList, GroupsAdd, GroupsEdit, LoadInventory, TreeInit, GetBasePath, GroupsList, GroupsAdd, GroupsEdit, LoadInventory,
GroupsDelete, RefreshGroupName, EditInventory, SetShowGroupHelp) GroupsDelete, RefreshGroupName, EditInventory, SetShowGroupHelp, InventoryStatus)
{ {
ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior
//scope. //scope.
@@ -155,7 +155,6 @@ function InventoryGroups ($scope, $rootScope, $compile, $location, $log, $routeP
$('input:first').focus(); $('input:first').focus();
} }
else if (type == 'inventory') { else if (type == 'inventory') {
$('#tree-form').hide().empty();
url = node.attr('hosts'); url = node.attr('hosts');
scope.groupAddHide = true; scope.groupAddHide = true;
scope.groupCreateHide = false; scope.groupCreateHide = false;
@@ -164,6 +163,8 @@ function InventoryGroups ($scope, $rootScope, $compile, $location, $log, $routeP
scope.groupDeleteHide = true; scope.groupDeleteHide = true;
scope.createButtonShow = false; scope.createButtonShow = false;
scope.group_id = null; scope.group_id = null;
InventoryStatus();
$('#tree-form').show();
} }
if (!scope.$$phase) { if (!scope.$$phase) {
@@ -221,6 +222,6 @@ function InventoryGroups ($scope, $rootScope, $compile, $location, $log, $routeP
InventoryGroups.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'InventoryGroupsForm', InventoryGroups.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'InventoryGroupsForm',
'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'ReturnToCaller', 'ClearScope', 'Prompt', 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'ReturnToCaller', 'ClearScope', 'Prompt',
'TreeInit', 'GetBasePath', 'GroupsList', 'GroupsAdd', 'GroupsEdit', 'LoadInventory', 'TreeInit', 'GetBasePath', 'GroupsList', 'GroupsAdd', 'GroupsEdit', 'LoadInventory',
'GroupsDelete', 'RefreshGroupName', 'EditInventory', 'SetShowGroupHelp' 'GroupsDelete', 'RefreshGroupName', 'EditInventory', 'SetShowGroupHelp', 'InventoryStatus'
]; ];

View File

@@ -91,7 +91,7 @@ function OrganizationsAdd ($scope, $rootScope, $compile, $location, $log, $route
// Save // Save
scope.formSave = function() { scope.formSave = function() {
form.clearApiErrors();s form.clearApiErrors();
var url = GetBasePath(base); var url = GetBasePath(base);
url += (base != 'organizations') ? $routeParams['project_id'] + '/organizations/' : ''; url += (base != 'organizations') ? $routeParams['project_id'] + '/organizations/' : '';
Rest.setUrl(url); Rest.setUrl(url);

View File

@@ -232,7 +232,6 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
} }
}]) }])
.factory('GroupsEdit', ['$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'GroupForm', 'GenerateForm', .factory('GroupsEdit', ['$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'GroupForm', 'GenerateForm',
'Prompt', 'ProcessErrors', 'GetBasePath', 'RefreshGroupName', 'ParseTypeChange', 'getSourceTypeOptions', 'Prompt', 'ProcessErrors', 'GetBasePath', 'RefreshGroupName', 'ParseTypeChange', 'getSourceTypeOptions',
function($rootScope, $location, $log, $routeParams, Rest, Alert, GroupForm, GenerateForm, Prompt, ProcessErrors, function($rootScope, $location, $log, $routeParams, Rest, Alert, GroupForm, GenerateForm, Prompt, ProcessErrors,
@@ -488,6 +487,7 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
{ hdr: 'Error!', msg: 'Failed to update group varaibles. PUT status: ' + status }); { hdr: 'Error!', msg: 'Failed to update group varaibles. PUT status: ' + status });
}); });
} }
RefreshGroupName(scope['selectedNode'], data.name, data.description);
scope.$emit('formSaveSuccess', data.id); scope.$emit('formSaveSuccess', data.id);
}) })
.error( function(data, status, headers, config) { .error( function(data, status, headers, config) {

View File

@@ -11,7 +11,7 @@
angular.module('InventoryHelper', [ 'RestServices', 'Utilities', 'OrganizationListDefinition', angular.module('InventoryHelper', [ 'RestServices', 'Utilities', 'OrganizationListDefinition',
'SearchHelper', 'PaginateHelper', 'ListGenerator', 'AuthService', 'SearchHelper', 'PaginateHelper', 'ListGenerator', 'AuthService',
'InventoryHelper', 'RelatedSearchHelper', 'RelatedPaginateHelper', 'InventoryHelper', 'RelatedSearchHelper', 'RelatedPaginateHelper',
'InventoryFormDefinition', 'ParseHelper' 'InventoryFormDefinition', 'ParseHelper', 'InventorySummaryDefinition'
]) ])
.factory('LoadTreeData', ['Alert', 'Rest', 'Authorization', '$http', 'Wait', 'SortNodes', .factory('LoadTreeData', ['Alert', 'Rest', 'Authorization', '$http', 'Wait', 'SortNodes',
@@ -160,6 +160,7 @@ angular.module('InventoryHelper', [ 'RestServices', 'Utilities', 'OrganizationLi
$(tree_id).bind("loaded.jstree", function () { $(tree_id).bind("loaded.jstree", function () {
scope['treeLoading'] = false; scope['treeLoading'] = false;
Wait('stop'); Wait('stop');
$(tree_id).prepend('<div class=\"title\"><i class=\"icon-sitemap\"></i> Group Selector</div>');
scope.$emit('treeLoaded'); scope.$emit('treeLoaded');
}); });
@@ -666,5 +667,65 @@ angular.module('InventoryHelper', [ 'RestServices', 'Utilities', 'OrganizationLi
} }
return newData; return newData;
} }
}])
.factory('InventoryStatus', [ 'Rest', 'Alert', 'ProcessErrors', 'GetBasePath', 'FormatDate', 'InventorySummary', 'GenerateList',
function(Rest, Aler, ProcessErrors, GetBasePath, FormatDate, InventorySummary, GenerateList) {
return function(params) {
//Build a summary of a given inventory
$('#tree-form').hide().empty();
var view = GenerateList;
var scope = view.inject(InventorySummary, { mode: 'summary', id: 'tree-form', breadCrumbs: false });
scope['groups'] = [];
function checkSource(url) {
Rest.setUrl(url);
Rest.get()
.success( function(data, status, headers, config) {
//console.log(data);
var last_update = (data.last_updated == null) ? 'n/a' : FormatDate(new Date(data.last_updated));
var source = 'Manual';
switch(data.source) {
case 'file':
source = 'File';
break;
case 'ec2':
source = 'Amazon EC2';
break;
case 'rackspace':
source = 'Rackspace';
break;
}
scope['groups'].push({
name: data.summary_fields.group.name,
description: data.summary_fields.group.description,
failures: data.summary_fields.group.hosts_with_active_failures,
source: source,
last_update: last_update,
status: data.status
});
})
.error( function(data, status, headers, config) {
ProcessErrors(scope, data, status, null,
{ hdr: 'Error!', msg: 'Call to ' + url + ' failed. POST status: ' + status });
});
}
var url = GetBasePath('inventory') + scope['inventory_id'] + '/groups/';
Rest.setUrl(url);
Rest.get()
.success( function(data, status, headers, config) {
for (var i=0; i < data.results.length; i++) {
if (data.results[i].related.inventory_source) {
checkSource(data.results[i].related.inventory_source);
}
}
})
.error( function(data, status, headers, config) {
ProcessErrors(scope, data, status, null,
{ hdr: 'Error!', msg: 'Call to ' + url + ' failed. POST status: ' + status });
});
}
}]); }]);

View File

@@ -0,0 +1,44 @@
/*********************************************
* Copyright (c) 2013 AnsibleWorks, Inc.
*
* InventorySummary.js
*
* Summary of groups contained within an inventory
*
*/
angular.module('InventorySummaryDefinition', [])
.value(
'InventorySummary', {
name: 'groups',
iterator: 'group',
editTitle: 'Inventory Summary',
index: false,
hover: true,
fields: {
name: {
key: true,
label: 'Name'
},
failures: {
label: 'Hosts Failures'
},
source: {
label: 'Source'
},
last_update: {
label: 'Last Update'
},
status: {
label: 'Update Status'
}
},
actions: {
},
fieldActions: {
}
});

View File

@@ -771,8 +771,15 @@ select.field-mini-height {
border-radius: 6px; border-radius: 6px;
background-color: #e3e3e3; background-color: #e3e3e3;
padding-top: 10px; padding-top: 10px;
margin-top: 10px; padding-left: 10px;
padding-bottom: 10px;
min-height: 100px; min-height: 100px;
.title {
color: #888;
padding-bottom: 5px;
margin-left: 5px;
}
} }
/* /*
@@ -792,13 +799,13 @@ select.field-mini-height {
#tree-form { #tree-form {
display: none; display: none;
padding: 15px 10px 0 10px; padding: 15px 10px 0 10px;
margin-top: 10px; margin-top: 5px;
border: 1px solid #e3e3e3; border: 1px solid #e3e3e3;
background-color: #e3e3e3; background-color: #e3e3e3;
border-radius: 6px; border-radius: 6px;
.form-title { .form-title {
color: #999; color: #888;
padding-left: 10px; padding-left: 10px;
} }
@@ -1102,7 +1109,7 @@ tr td button i {
#tree-view { #tree-view {
margin-left: 10px; margin-left: 10px;
margin-top: 10px; margin-top: 5px;
} }
.label-text { .label-text {

View File

@@ -1230,7 +1230,9 @@ angular.module('FormGenerator', ['GeneratorHelpers', 'ngCookies'])
html += "</div><!-- tree controls -->\n"; html += "</div><!-- tree controls -->\n";
html += "<hr class=\"tree-control-divider\">\n"; html += "<hr class=\"tree-control-divider\">\n";
html += "<div class=\"row\">\n"; html += "<div class=\"row\">\n";
html += "<div class=\"col-lg-4\"><div id=\"tree-view\"></div></div>\n"; html += "<div class=\"col-lg-4\">\n" +
"<div id=\"tree-view\"></div>\n" +
"</div>\n";
html += "<div class=\"col-lg-8 tree-form-container\">\n<div id=\"tree-form\">\n</div>\n</div>\n"; html += "<div class=\"col-lg-8 tree-form-container\">\n<div id=\"tree-form\">\n</div>\n</div>\n";
html += "</div>\n"; html += "</div>\n";
html += "</div><!-- well -->\n"; html += "</div><!-- well -->\n";

View File

@@ -170,54 +170,57 @@ angular.module('ListGenerator', ['GeneratorHelpers'])
html += "<div class=\"well\">\n"; html += "<div class=\"well\">\n";
} }
if (options.mode == 'lookup' || options.id != undefined) { if (options.mode !== 'summary') {
html += SearchWidget({ iterator: list.iterator, template: list, mini: true , size: 'col-lg-8' });
}
else {
html += SearchWidget({ iterator: list.iterator, template: list, mini: true });
}
if (options.mode != 'lookup') { if ( options.mode == 'lookup' || options.id != undefined ) {
//actions html += SearchWidget({ iterator: list.iterator, template: list, mini: true , size: 'col-lg-8' });
var base = $location.path().replace(/^\//,'').split('/')[0]; }
html += "<div class=\"list-actions "; else {
html += (options.id != undefined) ? "col-lg-3" : "col-lg-7 col-md-5"; html += SearchWidget({ iterator: list.iterator, template: list, mini: true });
html += "\">\n"; }
for (action in list.actions) {
if (list.actions[action].mode == 'all' || list.actions[action].mode == options.mode) { if (options.mode != 'lookup') {
if ( (list.actions[action].basePaths == undefined) || //actions
(list.actions[action].basePaths && list.actions[action].basePaths.indexOf(base) > -1) ) { var base = $location.path().replace(/^\//,'').split('/')[0];
html += this.button(list.actions[action], action); html += "<div class=\"list-actions ";
html += (options.id != undefined) ? "col-lg-3" : "col-lg-7 col-md-5";
html += "\">\n";
for (action in list.actions) {
if (list.actions[action].mode == 'all' || list.actions[action].mode == options.mode) {
if ( (list.actions[action].basePaths == undefined) ||
(list.actions[action].basePaths && list.actions[action].basePaths.indexOf(base) > -1) ) {
html += this.button(list.actions[action], action);
}
} }
} }
}
if (list.name == 'inventories' && options.mode !== 'select') { if (list.name == 'inventories' && options.mode !== 'select') {
html += "<label class=\"checkbox-inline pull-right\"><input type=\"checkbox\" ng-model=\"inventoryFailureFilter\" " + html += "<label class=\"checkbox-inline pull-right\"><input type=\"checkbox\" ng-model=\"inventoryFailureFilter\" " +
"ng-change=\"search('inventory')\" id=\"failed_jobs_chbox\"> Show only inventories with failed jobs</label>\n"; "ng-change=\"search('inventory')\" id=\"failed_jobs_chbox\"> Show only inventories with failed jobs</label>\n";
} }
//select instructions //select instructions
if (options.mode == 'select' && list.selectInstructions) { if (options.mode == 'select' && list.selectInstructions) {
var btn = { var btn = {
awPopOver: list.selectInstructions, awPopOver: list.selectInstructions,
dataPlacement: 'left', dataPlacement: 'left',
dataContainer: 'body', dataContainer: 'body',
icon: "icon-question-sign", icon: "icon-question-sign",
'class': 'btn-sm btn-help btn-info', 'class': 'btn-sm btn-help btn-info',
awToolTip: 'Click for help', awToolTip: 'Click for help',
dataTitle: 'Help', dataTitle: 'Help',
iconSize: 'large' iconSize: 'large'
}; };
html += this.button(btn, 'select'); html += this.button(btn, 'select');
} }
}
else {
html += "<div class=\"col-lg-7\"></div>\n";
}
html += "</div>\n";
html += "</div><!-- row -->\n";
} }
else {
html += "<div class=\"col-lg-7\"></div>\n";
}
html += "</div>\n";
html += "</div><!-- row -->\n";
// table header row // table header row
html += "<table id=\"" + list.name + "_table\" "; html += "<table id=\"" + list.name + "_table\" ";

View File

@@ -76,6 +76,7 @@
<script src="{{ STATIC_URL }}js/lists/Inventories.js"></script> <script src="{{ STATIC_URL }}js/lists/Inventories.js"></script>
<script src="{{ STATIC_URL }}js/lists/Teams.js"></script> <script src="{{ STATIC_URL }}js/lists/Teams.js"></script>
<script src="{{ STATIC_URL }}js/lists/Hosts.js"></script> <script src="{{ STATIC_URL }}js/lists/Hosts.js"></script>
<script src="{{ STATIC_URL }}js/lists/InventorySummary.js"></script>
<script src="{{ STATIC_URL }}js/lists/Groups.js"></script> <script src="{{ STATIC_URL }}js/lists/Groups.js"></script>
<script src="{{ STATIC_URL }}js/lists/Credentials.js"></script> <script src="{{ STATIC_URL }}js/lists/Credentials.js"></script>
<script src="{{ STATIC_URL }}js/lists/JobTemplates.js"></script> <script src="{{ STATIC_URL }}js/lists/JobTemplates.js"></script>