Inventory refactor: Add host works. Click on a row level action on the groups list now shows the row as selected and refreshes the host list. Edit inventory properties now works. Add and Edit dialog boxes are now displayed at the last minute after all data is loaded- accomplished with new list-generator show_modal parameter.

This commit is contained in:
Chris Houseknecht
2014-01-10 20:32:52 +00:00
parent 0d2417e4ae
commit 3d5a09e39e
11 changed files with 303 additions and 589 deletions

View File

@@ -318,7 +318,8 @@ InventoriesAdd.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$lo
function InventoriesEdit ($scope, $location, $routeParams, $compile, GenerateList, ClearScope, InventoryGroups, InventoryHosts, BuildTree, Wait, function InventoriesEdit ($scope, $location, $routeParams, $compile, GenerateList, ClearScope, InventoryGroups, InventoryHosts, BuildTree, Wait,
GetSyncStatusMsg, InjectHosts, HostsReload, GroupsAdd, GroupsEdit, GroupsDelete, Breadcrumbs, LoadBreadCrumbs, Empty, GetSyncStatusMsg, InjectHosts, HostsReload, GroupsAdd, GroupsEdit, GroupsDelete, Breadcrumbs, LoadBreadCrumbs, Empty,
Rest, ProcessErrors, InventoryUpdate, Alert, ToggleChildren, ViewUpdateStatus, GroupsCancelUpdate) Rest, ProcessErrors, InventoryUpdate, Alert, ToggleChildren, ViewUpdateStatus, GroupsCancelUpdate, Find,
HostsCreate, EditInventoryProperties)
{ {
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.
@@ -329,12 +330,12 @@ function InventoriesEdit ($scope, $location, $routeParams, $compile, GenerateLis
$scope.inventory_id = $routeParams.inventory_id; $scope.inventory_id = $routeParams.inventory_id;
LoadBreadCrumbs(); LoadBreadCrumbs({ path: $location.path(), title: '{{ inventory_name }}' });
if ($scope.removeGroupTreeLoaded) { if ($scope.removeGroupTreeLoaded) {
$scope.removeGroupTreeLoaded(); $scope.removeGroupTreeLoaded();
} }
$scope.removeGroupTreeLoaded = $scope.$on('groupTreeLoaded', function(e, inventory_name, groups) { $scope.removeGroupTreeLoaded = $scope.$on('GroupTreeLoaded', function(e, inventory_name, groups) {
// After the tree data loads, generate the groups list // After the tree data loads, generate the groups list
// Add breadcrumbs // Add breadcrumbs
var e = angular.element(document.getElementById('breadcrumbs')); var e = angular.element(document.getElementById('breadcrumbs'));
@@ -367,21 +368,23 @@ function InventoriesEdit ($scope, $location, $routeParams, $compile, GenerateLis
if ($scope.removeGroupTreeRefreshed) { if ($scope.removeGroupTreeRefreshed) {
$scope.removeGroupTreeRefreshed(); $scope.removeGroupTreeRefreshed();
} }
$scope.removeGroupTreeRefreshed = $scope.$on('groupTreeRefreshed', function(e, inventory_name, groups, emit) { $scope.removeGroupTreeRefreshed = $scope.$on('GroupTreeRefreshed', function(e, inventory_name, groups) {
// Called after tree data is reloaded on refresh button click. // Called after tree data is reloaded on refresh button click.
// Reselect the preveiously selected group node, causing host view to refresh. // Reselect the preveiously selected group node, causing host view to refresh.
$scope.showHosts($scope.selected_tree_id, $scope.selected_group_id, false, emit); $scope.showHosts($scope.selected_tree_id, $scope.selected_group_id, false);
}); });
if ($scope.removeGroupDeleteCompleted) { if ($scope.removeGroupDeleteCompleted) {
$scope.removeGroupDeleteCompleted(); $scope.removeGroupDeleteCompleted();
} }
$scope.removeGroupDeleteCompleted = $scope.$on('groupDeleteCompleted', function(e) { $scope.removeGroupDeleteCompleted = $scope.$on('GroupDeleteCompleted', function(e) {
// Group was deleted. Now we need to refresh the group view. // Group was deleted. Now we need to refresh the group view.
$scope.selected_tree_id = 1;
$scope.selected_group_id = null;
BuildTree({ scope: $scope, inventory_id: $scope.inventory_id, refresh: true }); BuildTree({ scope: $scope, inventory_id: $scope.inventory_id, refresh: true });
}); });
$scope.showHosts = function(tree_id, group_id, show_failures, emit) { $scope.showHosts = function(tree_id, group_id, show_failures) {
// Clicked on group // Clicked on group
if (tree_id !== null) { if (tree_id !== null) {
Wait('start'); Wait('start');
@@ -400,7 +403,10 @@ function InventoriesEdit ($scope, $location, $routeParams, $compile, GenerateLis
$scope.groups[i].active_class = ''; $scope.groups[i].active_class = '';
} }
} }
HostsReload({ scope: $scope, group_id: group_id, tree_id: tree_id, inventory_id: $scope.inventory_id, emit: emit }); HostsReload({ scope: $scope, group_id: group_id, tree_id: tree_id, inventory_id: $scope.inventory_id });
}
else {
Wait('stop');
} }
} }
@@ -408,47 +414,47 @@ function InventoriesEdit ($scope, $location, $routeParams, $compile, GenerateLis
GroupsAdd({ scope: $scope, inventory_id: $scope.inventory_id, group_id: $scope.selected_group_id }); GroupsAdd({ scope: $scope, inventory_id: $scope.inventory_id, group_id: $scope.selected_group_id });
} }
$scope.editGroup = function(group_id) { $scope.editGroup = function(group_id, tree_id) {
GroupsEdit({ scope: $scope, inventory_id: $scope.inventory_id, group_id: group_id }); GroupsEdit({ scope: $scope, inventory_id: $scope.inventory_id, group_id: group_id, tree_id: tree_id });
} }
// Launch inventory sync // Launch inventory sync
$scope.updateGroup = function(id) { $scope.updateGroup = function(id) {
for (var i=0; i < $scope.groups.length; i++) { var group = Find({ list: $scope.groups, key: 'id', val: id});
if ($scope.groups[i].id == id) { if (group) {
if (Empty($scope.groups[i].source)) { if (Empty(group.source)) {
// if no source, do nothing. // if no source, do nothing.
} }
else if ($scope.groups[i].status == 'updating') { else if (group.status == 'updating') {
Alert('Update in Progress', 'The inventory update process is currently running for group <em>' + Alert('Update in Progress', 'The inventory update process is currently running for group <em>' +
$scope.groups[i].name + '</em>. Use the Refresh button to monitor the status.', 'alert-info'); $scope.groups[i].name + '</em>. Use the Refresh button to monitor the status.', 'alert-info');
} }
else { else {
Wait('start'); Wait('start');
Rest.setUrl($scope.groups[i].related.inventory_source); Rest.setUrl(group.related.inventory_source);
Rest.get() Rest.get()
.success( function(data, status, headers, config) { .success( function(data, status, headers, config) {
InventoryUpdate({ InventoryUpdate({
scope: $scope, scope: $scope,
url: data.related.update, url: data.related.update,
group_name: data.summary_fields.group.name, group_name: data.summary_fields.group.name,
group_source: data.source group_source: data.source,
}); tree_id: group.id,
}) group_id: group.group_id
.error( function(data, status, headers, config) {
Wait('stop');
ProcessErrors(scope, data, status, form,
{ hdr: 'Error!', msg: 'Failed to retrieve inventory source: ' + $scope.groups[i].related.inventory_source +
' POST returned status: ' + status });
}); });
} })
break; .error( function(data, status, headers, config) {
Wait('stop');
ProcessErrors(scope, data, status, form,
{ hdr: 'Error!', msg: 'Failed to retrieve inventory source: ' + group.related.inventory_source +
' POST returned status: ' + status });
});
} }
} }
} }
$scope.cancelUpdate = function(id) { $scope.cancelUpdate = function(id) {
GroupsCancelUpdate({ scope: $scope, id: id }); GroupsCancelUpdate({ scope: $scope, tree_id: id });
} }
$scope.toggle = function(id) { $scope.toggle = function(id) {
@@ -456,20 +462,31 @@ function InventoriesEdit ($scope, $location, $routeParams, $compile, GenerateLis
ToggleChildren({ scope: $scope, list: list, id: id }); ToggleChildren({ scope: $scope, list: list, id: id });
} }
$scope.refreshGroups = function(emit) { $scope.refreshGroups = function(tree_id, group_id) {
// Refresh the tree data when refresh button cicked // Refresh the tree data when refresh button cicked
// Pass a string label value, if you want to attach scope.$on() to the completion of the refresh if (tree_id) {
BuildTree({ scope: $scope, inventory_id: $scope.inventory_id, refresh: true, emit: emit }); $scope.selected_tree_id = tree_id;
$scope.selected_group_id = group_id;
}
BuildTree({ scope: $scope, inventory_id: $scope.inventory_id, refresh: true });
} }
$scope.viewUpdateStatus = function(id) { $scope.viewUpdateStatus = function(tree_id, group_id) {
ViewUpdateStatus({ scope: $scope, tree_id: id }); ViewUpdateStatus({ scope: $scope, tree_id: tree_id, group_id: group_id });
} }
$scope.deleteGroup = function(id) { $scope.deleteGroup = function(tree_id, group_id) {
GroupsDelete({ scope: $scope, tree_id: id, inventory_id: $scope.inventory_id }); GroupsDelete({ scope: $scope, tree_id: tree_id, group_id: group_id, inventory_id: $scope.inventory_id });
}
$scope.createHost = function() {
HostsCreate({ scope: $scope });
} }
$scope.editInventoryProperties = function() {
EditInventoryProperties({ scope: $scope, inventory_id: $scope.inventory_id });
}
//Load tree data for the first time //Load tree data for the first time
BuildTree({ scope: $scope, inventory_id: $scope.inventory_id, refresh: false }); BuildTree({ scope: $scope, inventory_id: $scope.inventory_id, refresh: false });
@@ -478,6 +495,6 @@ function InventoriesEdit ($scope, $location, $routeParams, $compile, GenerateLis
InventoriesEdit.$inject = [ '$scope', '$location', '$routeParams', '$compile', 'GenerateList', 'ClearScope', 'InventoryGroups', 'InventoryHosts', InventoriesEdit.$inject = [ '$scope', '$location', '$routeParams', '$compile', 'GenerateList', 'ClearScope', 'InventoryGroups', 'InventoryHosts',
'BuildTree', 'Wait', 'GetSyncStatusMsg', 'InjectHosts', 'HostsReload', 'GroupsAdd', 'GroupsEdit', 'GroupsDelete', 'BuildTree', 'Wait', 'GetSyncStatusMsg', 'InjectHosts', 'HostsReload', 'GroupsAdd', 'GroupsEdit', 'GroupsDelete',
'Breadcrumbs', 'LoadBreadCrumbs', 'Empty', 'Rest', 'ProcessErrors', 'InventoryUpdate', 'Alert', 'ToggleChildren', 'Breadcrumbs', 'LoadBreadCrumbs', 'Empty', 'Rest', 'ProcessErrors', 'InventoryUpdate', 'Alert', 'ToggleChildren',
'ViewUpdateStatus', 'GroupsCancelUpdate' 'ViewUpdateStatus', 'GroupsCancelUpdate', 'Find', 'HostsCreate', 'EditInventoryProperties'
]; ];

View File

@@ -79,7 +79,7 @@ angular.module('InventoryFormDefinition', [])
addRequired: false, addRequired: false,
editRequird: false, editRequird: false,
parseTypeName: 'inventoryParseType', parseTypeName: 'inventoryParseType',
rows: 10, rows: 6,
"default": "---", "default": "---",
awPopOver: "<p>Enter inventory variables using either JSON or YAML syntax. Use the radio button to toggle between the two.</p>" + awPopOver: "<p>Enter inventory variables using either JSON or YAML syntax. Use the radio button to toggle between the two.</p>" +
"JSON:<br />\n" + "JSON:<br />\n" +
@@ -89,7 +89,7 @@ angular.module('InventoryFormDefinition', [])
'<p>View JSON examples at <a href="http://www.json.org" target="_blank">www.json.org</a></p>' + '<p>View JSON examples at <a href="http://www.json.org" target="_blank">www.json.org</a></p>' +
'<p>View YAML examples at <a href="http://www.ansibleworks.com/docs/YAMLSyntax.html" target="_blank">ansibleworks.com</a></p>', '<p>View YAML examples at <a href="http://www.ansibleworks.com/docs/YAMLSyntax.html" target="_blank">ansibleworks.com</a></p>',
dataTitle: 'Inventory Variables', dataTitle: 'Inventory Variables',
dataPlacement: 'left', dataPlacement: 'right',
dataContainer: 'body' dataContainer: 'body'
} }
}, },

View File

@@ -82,21 +82,19 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
} }
}]) }])
.factory('ViewUpdateStatus', [ 'Rest', 'ProcessErrors', 'GetBasePath', 'ShowUpdateStatus', 'Alert', 'Wait', 'Empty', .factory('ViewUpdateStatus', [ 'Rest', 'ProcessErrors', 'GetBasePath', 'ShowUpdateStatus', 'Alert', 'Wait', 'Empty', 'Find',
function(Rest, ProcessErrors, GetBasePath, ShowUpdateStatus, Alert, Wait, Empty) { function(Rest, ProcessErrors, GetBasePath, ShowUpdateStatus, Alert, Wait, Empty, Find) {
return function(params) { return function(params) {
var scope = params.scope; var scope = params.scope;
var id = params.tree_id; var tree_id = params.tree_id;
var group_id = params.group_id;
var found = false; var found = false;
var group; var group = Find({ list: scope.group, key: 'id', val: tree_id });
for (var i=0; i < scope.groups.length; i++) {
if (scope.groups[i].id == id) { scope.showHosts(tree_id, group_id, false);
found = true;
group = scope.groups[i]; if (group) {
}
}
if (found) {
if (Empty(group.source)) { if (Empty(group.source)) {
Alert('Missing Configuration', 'The selected group is not configured for inventory sync. ' + Alert('Missing Configuration', 'The selected group is not configured for inventory sync. ' +
'You must first edit the group, provide Source settings, and then run the sync process.', 'alert-info'); 'You must first edit the group, provide Source settings, and then run the sync process.', 'alert-info');
@@ -323,196 +321,6 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
} }
}]) }])
.factory('InventoryStatus', [ '$rootScope', '$routeParams', 'Rest', 'Alert', 'ProcessErrors', 'GetBasePath', 'FormatDate', 'InventorySummary',
'GenerateList', 'ClearScope', 'SearchInit', 'PaginateInit', 'Refresh', 'InventoryUpdate', 'GroupsEdit', 'HelpDialog',
'InventorySummaryHelp', 'ClickNode', 'GetHostsStatusMsg', 'GetSyncStatusMsg', 'ViewUpdateStatus', 'Wait',
function($rootScope, $routeParams, Rest, Alert, ProcessErrors, GetBasePath, FormatDate, InventorySummary, GenerateList, ClearScope,
SearchInit, PaginateInit, Refresh, InventoryUpdate, GroupsEdit, HelpDialog, InventorySummaryHelp, ClickNode,
GetHostsStatusMsg, GetSyncStatusMsg, ViewUpdateStatus, Wait) {
return function(params) {
//Build a summary of a given inventory
ClearScope('tree-form');
$('#tree-form').hide().empty();
var view = GenerateList;
var list = InventorySummary;
var scope = view.inject(InventorySummary, { mode: 'summary', id: 'tree-form', breadCrumbs: false });
var defaultUrl = GetBasePath('inventory') + scope['inventory_id'] + '/groups/';
//?group__isnull=false';
var msg, update_status;
if (scope.PostRefreshRemove) {
scope.PostRefreshRemove();
}
scope.PostRefreshRemove = scope.$on('PostRefresh', function() {
for (var i=0; i < scope.groups.length; i++) {
var last_update = (scope.groups[i].summary_fields.inventory_source.last_updated == null) ? null :
FormatDate(new Date(scope.groups[i].summary_fields.inventory_source.last_updated));
// Set values for Failed Hosts column
scope.groups[i].failed_hosts = scope.groups[i].hosts_with_active_failures + ' / ' + scope.groups[i].total_hosts;
msg = GetHostsStatusMsg({
active_failures: scope.groups[i].hosts_with_active_failures,
total_hosts: scope.groups[i].total_hosts,
inventory_id: scope['inventory_id'],
group_id: scope['groups'][i]['id']
});
update_status = GetSyncStatusMsg({ status: scope.groups[i].summary_fields.inventory_source.status });
scope.groups[i].failed_hosts_tip = msg['tooltip'];
scope.groups[i].failed_hosts_link = msg['url'];
scope.groups[i].failed_hosts_class = msg['class'];
scope.groups[i].status = update_status['status'];
scope.groups[i].source = scope.groups[i].summary_fields.inventory_source.source;
scope.groups[i].last_updated = last_update;
scope.groups[i].status_badge_class = update_status['class'];
scope.groups[i].status_badge_tooltip = update_status['tooltip'];
// Set cancel button attributes
if (scope.groups[i].summary_fields.inventory_source.status == 'updating' ||
scope.groups[i].summary_fields.inventory_source.status == 'updating') {
scope.groups[i].cancel_tooltip = "Cancel the update process";
scope.groups[i].cancel_class = "";
}
else {
scope.groups[i].cancel_tooltip = "Update process is not running";
scope.groups[i].cancel_class = "btn-disabled";
}
// Set update button attributes
if (scope.groups[i].summary_fields.inventory_source.source == "" ||
scope.groups[i].summary_fields.inventory_source.source == null) {
scope.groups[i].update_tooltip = "No external source. Does not require an update.";
scope.groups[i].update_class = "btn-disabled";
}
else {
scope.groups[i].update_tooltip = "Start the inventory update process";
scope.groups[i].update_class = "";
}
}
if (scope.groups.length == 0) {
// Force display for help tooltip when no groups exist
$('#inventory-summary-help').focus();
}
});
SearchInit({ scope: scope, set: 'groups', list: list, url: defaultUrl });
PaginateInit({ scope: scope, list: list, url: defaultUrl });
if (scope['inventorySummaryGroup'] || $routeParams['name']) {
scope[list.iterator + 'SearchField'] = 'name';
scope[list.iterator + 'SearchType'] = 'iexact';
scope[list.iterator + 'SearchValue'] = (scope['inventorySummaryGroup']) ?
scope['inventorySummaryGroup'] : $routeParams['name'];
scope[list.iterator + 'SearchFieldLabel'] = list.fields['name'].label;
}
else if ($routeParams['has_external_source']) {
scope[list.iterator + 'SearchField'] = 'has_external_source';
scope[list.iterator + 'SearchValue'] = list.fields['has_external_source'].searchValue;
scope[list.iterator + 'InputDisable'] = true;
scope[list.iterator + 'SearchType'] = 'in';
scope[list.iterator + 'SearchFieldLabel'] = list.fields['has_external_source'].label;
}
else if ($routeParams['status']) {
// with status param, called post update-submit
scope[list.iterator + 'SearchField'] = 'status';
scope[list.iterator + 'SelectShow'] = true;
scope[list.iterator + 'SearchSelectOpts'] = list.fields['status'].searchOptions;
scope[list.iterator + 'SearchFieldLabel'] = list.fields['status'].label.replace(/\<br\>/g,' ');
for (var opt in list.fields['status'].searchOptions) {
if (list.fields['status'].searchOptions[opt].value == $routeParams['status']) {
scope[list.iterator + 'SearchSelectValue'] = list.fields['status'].searchOptions[opt];
break;
}
}
}
scope.search(list.iterator, false, true);
scope.showHelp = function() {
// Display help dialog
$('.btn').blur(); //remove focus from the help button and all buttons
//this stops the tooltip from continually displaying
HelpDialog({ defn: InventorySummaryHelp });
}
scope.viewUpdateStatus = function(group_id) { ViewUpdateStatus({ scope: scope, group_id: group_id }) };
// Click on group name
scope.GroupsEdit = function(group_id) {
// On the tree, select the first occurrance of the requested group
ClickNode({ selector: '#inventory-tree li[data-group-id="' + group_id + '"]' });
}
// Respond to refresh button
scope.refresh = function() {
/*scope.search(list.iterator, false, true);
BuildTree({
scope: scope,
inventory_id: scope['inventory_id'],
emit_on_select: 'NodeSelect',
target_id: 'search-tree-container',
refresh: true,
moveable: true
});*/
}
// Start the update process
scope.updateGroup = function(id) {
for (var i=0; i < scope.groups.length; i++) {
if (scope.groups[i].id == id) {
if (scope.groups[i].summary_fields.inventory_source.source == "" || scope.groups[i].summary_fields.inventory_source.source == null) {
//Alert('Missing Configuration', 'The selected group is not configured for updates. You must first edit the group and provide ' +
// 'external Source settings before attempting an update.', 'alert-info');
// Do nothing. Act as though button is disabled.
}
else if (scope.groups[i].summary_fields.inventory_source.status == 'updating') {
Alert('Update in Progress', 'The inventory update process is currently running for group <em>' +
scope.groups[i].name + '</em>. Use the Refresh button to monitor the status.', 'alert-info');
}
else {
/*if (scope.groups[i].summary_fields.inventory_source.source == 'ec2') {
scope.sourceUsernameLabel = 'Access Key ID';
scope.sourcePasswordLabel = 'Secret Access Key';
scope.sourcePasswordConfirmLabel = 'Confirm Secret Access Key';
}
else {
scope.sourceUsernameLabel = 'Username';
scope.sourcePasswordLabel = 'Password';
scope.sourcePasswordConfirmLabel = 'Confirm Password';
}*/
Wait('start');
Rest.setUrl(scope.groups[i].related.inventory_source);
Rest.get()
.success( function(data, status, headers, config) {
InventoryUpdate({
scope: scope,
group_id: id,
url: data.related.update,
group_name: data.summary_fields.group.name,
group_source: data.source
});
})
.error( function(data, status, headers, config) {
Wait('stop');
ProcessErrors(scope, data, status, form,
{ hdr: 'Error!', msg: 'Failed to retrieve inventory source: ' + scope.groups[i].related.inventory_source +
' POST returned status: ' + status });
});
}
break;
}
}
}
}
}])
.factory('SourceChange', [ 'GetBasePath', 'CredentialList', 'LookUpInit', .factory('SourceChange', [ 'GetBasePath', 'CredentialList', 'LookUpInit',
function(GetBasePath, CredentialList, LookUpInit){ function(GetBasePath, CredentialList, LookUpInit){
return function(params) { return function(params) {
@@ -607,6 +415,9 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
// Cancel the update process // Cancel the update process
var group = Find({ list: scope.groups, key: 'id', val: id }); var group = Find({ list: scope.groups, key: 'id', val: id });
scope.selected_tree_id = group.id;
scope.selected_group_id = group.group_id;
if (group && (group.status == 'updating' || group.status == 'pending')) { if (group && (group.status == 'updating' || group.status == 'pending')) {
// We found the group, and there is a running update // We found the group, and there is a running update
Wait('start'); Wait('start');
@@ -630,10 +441,10 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
}]) }])
.factory('GroupsAdd', ['$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'GroupForm', 'GenerateForm', .factory('GroupsAdd', ['$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'GroupForm', 'GenerateForm',
'Prompt', 'ProcessErrors', 'GetBasePath', 'ParseTypeChange', 'GroupsEdit', 'ClickNode', 'Wait', 'GetChoices', 'Prompt', 'ProcessErrors', 'GetBasePath', 'ParseTypeChange', 'GroupsEdit', 'Wait', 'GetChoices',
'GetSourceTypeOptions', 'LookUpInit', 'BuildTree', 'SourceChange', 'GetSourceTypeOptions', 'LookUpInit', 'BuildTree', 'SourceChange',
function($rootScope, $location, $log, $routeParams, Rest, Alert, GroupForm, GenerateForm, Prompt, ProcessErrors, function($rootScope, $location, $log, $routeParams, Rest, Alert, GroupForm, GenerateForm, Prompt, ProcessErrors,
GetBasePath, ParseTypeChange, GroupsEdit, ClickNode, Wait, GetChoices, GetSourceTypeOptions, LookUpInit, BuildTree, GetBasePath, ParseTypeChange, GroupsEdit, Wait, GetChoices, GetSourceTypeOptions, LookUpInit, BuildTree,
SourceChange) { SourceChange) {
return function(params) { return function(params) {
@@ -646,7 +457,7 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
GetBasePath('inventory') + inventory_id + '/groups/'; GetBasePath('inventory') + inventory_id + '/groups/';
var form = GroupForm; var form = GroupForm;
var generator = GenerateForm; var generator = GenerateForm;
var scope = generator.inject(form, {mode: 'add', modal: true, related: false}); var scope = generator.inject(form, { mode: 'add', modal: true, related: false, show_modal: false });
var groupCreated = false; var groupCreated = false;
scope.formModalActionLabel = 'Save'; scope.formModalActionLabel = 'Save';
@@ -656,11 +467,6 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
ParseTypeChange(scope); ParseTypeChange(scope);
$('#form-modal .btn-none').removeClass('btn-none').addClass('btn-success'); $('#form-modal .btn-none').removeClass('btn-none').addClass('btn-success');
$('#form-modal').on('hidden.bs.modal', function () {
//if (!groupCreated) {
// ClickNode({ selector: '#' + scope['selectedNode'].attr('id') });
//}
});
generator.reset(); generator.reset();
var master={}; var master={};
@@ -668,7 +474,7 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
if (scope.removeAddTreeRefreshed) { if (scope.removeAddTreeRefreshed) {
scope.removeAddTreeRefreshed(); scope.removeAddTreeRefreshed();
} }
scope.removeAddTreeRefreshed = scope.$on('groupTreeRefreshed', function(e) { scope.removeAddTreeRefreshed = scope.$on('GroupTreeRefreshed', function(e) {
Wait('stop'); Wait('stop');
$('#form-modal').modal('hide'); $('#form-modal').modal('hide');
scope.removeAddTreeRefreshed(); scope.removeAddTreeRefreshed();
@@ -677,11 +483,11 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
if (scope.removeSaveComplete) { if (scope.removeSaveComplete) {
scope.removeSaveComplete(); scope.removeSaveComplete();
} }
scope.removeSaveComplete = scope.$on('SaveComplete', function(e, error) { scope.removeSaveComplete = scope.$on('SaveComplete', function(e, group_id, error) {
if (!error) { if (!error) {
scope.formModalActionDisabled = false; scope.formModalActionDisabled = false;
scope.showGroupHelp = false; //get rid of the Hint scope.showGroupHelp = false; //get rid of the Hint
BuildTree({ scope: inventory_scope, inventory_id: inventory_id, refresh: true }); BuildTree({ scope: inventory_scope, inventory_id: inventory_id, refresh: true, new_group_id: group_id });
} }
}); });
@@ -754,10 +560,10 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
Rest.setUrl(url) Rest.setUrl(url)
Rest.put(data) Rest.put(data)
.success( function(data, status, headers, config) { .success( function(data, status, headers, config) {
scope.$emit('SaveComplete', false); scope.$emit('SaveComplete', group_id, false);
}) })
.error( function(data, status, headers, config) { .error( function(data, status, headers, config) {
scope.$emit('SaveComplete', true); scope.$emit('SaveComplete', group_id, true);
ProcessErrors(scope, data, status, form, ProcessErrors(scope, data, status, form,
{ hdr: 'Error!', msg: 'Failed to update group inventory source. PUT status: ' + status }); { hdr: 'Error!', msg: 'Failed to update group inventory source. PUT status: ' + status });
}); });
@@ -765,7 +571,7 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
} }
else { else {
// No source value // No source value
scope.$emit('SaveComplete', false); scope.$emit('SaveComplete', group_id, false);
} }
}); });
@@ -845,6 +651,7 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
scope.removeChoicesReady = scope.$on('choicesReadyGroup', function() { scope.removeChoicesReady = scope.$on('choicesReadyGroup', function() {
choicesReady++; choicesReady++;
if (choicesReady == 2) { if (choicesReady == 2) {
$('#form-modal').modal('show');
Wait('stop'); Wait('stop');
} }
}); });
@@ -877,42 +684,46 @@ 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', 'SetNodeName', 'ParseTypeChange', 'GetSourceTypeOptions', 'InventoryUpdate', 'Prompt', 'ProcessErrors', 'GetBasePath', 'SetNodeName', 'ParseTypeChange', 'GetSourceTypeOptions', 'InventoryUpdate',
'GetUpdateIntervalOptions', 'ClickNode', 'LookUpInit', 'Empty', 'Wait', 'GetChoices', 'UpdateGroup', 'SourceChange', 'GetUpdateIntervalOptions', 'LookUpInit', 'Empty', 'Wait', 'GetChoices', 'UpdateGroup', 'SourceChange',
function($rootScope, $location, $log, $routeParams, Rest, Alert, GroupForm, GenerateForm, Prompt, ProcessErrors, function($rootScope, $location, $log, $routeParams, Rest, Alert, GroupForm, GenerateForm, Prompt, ProcessErrors,
GetBasePath, SetNodeName, ParseTypeChange, GetSourceTypeOptions, InventoryUpdate, GetUpdateIntervalOptions, ClickNode, GetBasePath, SetNodeName, ParseTypeChange, GetSourceTypeOptions, InventoryUpdate, GetUpdateIntervalOptions,
LookUpInit, Empty, Wait, GetChoices, UpdateGroup, SourceChange) { LookUpInit, Empty, Wait, GetChoices, UpdateGroup, SourceChange) {
return function(params) { return function(params) {
var parent_scope = params.scope;
var group_id = params.group_id; var group_id = params.group_id;
var tree_id = params.tree_id;
var inventory_id = params.inventory_id; var inventory_id = params.inventory_id;
var generator = GenerateForm; var generator = GenerateForm;
var form = GroupForm; var form = GroupForm;
var defaultUrl = GetBasePath('groups') + group_id + '/'; var defaultUrl = GetBasePath('groups') + group_id + '/';
var groups_scope = params.scope;
//var scope =
var scope = generator.inject(form, { mode: 'edit', modal: true, related: false });
generator.reset();
var master = {}; var master = {};
var relatedSets = {}; var relatedSets = {};
// Load the modal form
var scope = generator.inject(form, { mode: 'edit', modal: true, related: false, show_modal: false });
generator.reset();
// Change the selected group
parent_scope.showHosts(tree_id, group_id, false);
GetSourceTypeOptions({ scope: scope, variable: 'source_type_options' }); GetSourceTypeOptions({ scope: scope, variable: 'source_type_options' });
//scope.update_interval_options = GetUpdateIntervalOptions();
scope.formModalActionLabel = 'Save'; scope.formModalActionLabel = 'Save';
scope.formModalHeader = 'Group';
scope.formModalCancelShow = true; scope.formModalCancelShow = true;
scope.source = form.fields.source['default']; scope.source = form.fields.source['default'];
scope.parseType = 'yaml'; scope.parseType = 'yaml';
scope[form.fields['source_vars'].parseTypeName] = 'yaml'; scope[form.fields['source_vars'].parseTypeName] = 'yaml';
scope.sourcePathRequired = false; scope.sourcePathRequired = false;
ParseTypeChange(scope); ParseTypeChange(scope);
ParseTypeChange(scope, 'source_vars', form.fields['source_vars'].parseTypeName); ParseTypeChange(scope, 'source_vars', form.fields['source_vars'].parseTypeName);
// After the group record is loaded, retrieve related data // After the group record is loaded, retrieve related data
if (scope.groupLoadedRemove) { if (scope.groupLoadedRemove) {
scope.groupLoadedRemove(); scope.groupLoadedRemove();
} }
scope.groupLoadedRemove = scope.$on('groupLoaded', function() { scope.groupLoadedRemove = scope.$on('groupLoaded', function() {
for (var set in relatedSets) { for (var set in relatedSets) {
@@ -1046,11 +857,10 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
} }
}); });
if (scope.removeChoicesComplete) { if (scope.removeChoicesComplete) {
scope.removeChoicesComplete(); scope.removeChoicesComplete();
} }
scope.removeChoicesComplete = scope.$on('choicesCompleteGroup', function() { scope.removeChoicesComplete = scope.$on('choicesCompleteGroup', function() {
// Retrieve detail record and prepopulate the form // Retrieve detail record and prepopulate the form
Rest.setUrl(defaultUrl); Rest.setUrl(defaultUrl);
Rest.get() Rest.get()
@@ -1069,6 +879,7 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
} }
scope.variable_url = data.related.variable_data; scope.variable_url = data.related.variable_data;
scope.source_url = data.related.inventory_source; scope.source_url = data.related.inventory_source;
$('#form-modal').modal('show');
scope.$emit('groupLoaded'); scope.$emit('groupLoaded');
}) })
.error( function(data, status, headers, config) { .error( function(data, status, headers, config) {
@@ -1110,17 +921,13 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
Wait('start'); Wait('start');
//if (!scope.$$phase) {
// scope.$digest();
//}
if (scope.removeSaveComplete) { if (scope.removeSaveComplete) {
scope.removeSaveComplete(); scope.removeSaveComplete();
} }
scope.removeSaveComplete = scope.$on('SaveComplete', function(e, error) { scope.removeSaveComplete = scope.$on('SaveComplete', function(e, error) {
if (!error) { if (!error) {
UpdateGroup({ UpdateGroup({
scope: groups_scope, scope: parent_scope,
group_id: group_id, group_id: group_id,
properties: { properties: {
name: scope.name, name: scope.name,
@@ -1136,7 +943,7 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
}); });
if (scope.removeFormSaveSuccess) { if (scope.removeFormSaveSuccess) {
scope.removeFormSaveSuccess(); scope.removeFormSaveSuccess();
} }
scope.removeFormSaveSuccess = scope.$on('formSaveSuccess', function(e, group_id) { scope.removeFormSaveSuccess = scope.$on('formSaveSuccess', function(e, group_id) {
@@ -1152,14 +959,14 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
if (scope.source.value !== null && scope.source.value !== '') { if (scope.source.value !== null && scope.source.value !== '') {
var data = { group: group_id, var data = { group: group_id,
source: scope['source'].value, source: scope['source'].value,
source_path: scope['source_path'], source_path: scope['source_path'],
credential: scope['credential'], credential: scope['credential'],
overwrite: scope['overwrite'], overwrite: scope['overwrite'],
overwrite_vars: scope['overwrite_vars'], overwrite_vars: scope['overwrite_vars'],
update_on_launch: scope['update_on_launch'] update_on_launch: scope['update_on_launch']
//update_interval: scope['update_interval'].value //update_interval: scope['update_interval'].value
}; };
// Create a string out of selected list of regions // Create a string out of selected list of regions
var regions = $('#s2id_group_source_regions').select2("data"); var regions = $('#s2id_group_source_regions').select2("data");
@@ -1248,15 +1055,20 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
Rest.put(data) Rest.put(data)
.success( function(data, status, headers, config) { .success( function(data, status, headers, config) {
if (scope.variables) { if (scope.variables) {
//update group variables //update group variables
Rest.setUrl(scope.variable_url); Rest.setUrl(scope.variable_url);
Rest.put(json_data) Rest.put(json_data)
.error( function(data, status, headers, config) { .success( function(data, status, headers, config) {
ProcessErrors(scope, data, status, form, scope.$emit('formSaveSuccess', data.id);
{ hdr: 'Error!', msg: 'Failed to update group variables. PUT status: ' + status }); })
}); .error( function(data, status, headers, config) {
ProcessErrors(scope, data, status, form,
{ hdr: 'Error!', msg: 'Failed to update group variables. PUT status: ' + status });
});
}
else {
scope.$emit('formSaveSuccess', data.id);
} }
scope.$emit('formSaveSuccess', data.id);
}) })
.error( function(data, status, headers, config) { .error( function(data, status, headers, config) {
Wait('stop'); Wait('stop');
@@ -1324,41 +1136,22 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
.factory('GroupsDelete', ['$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'GroupForm', 'GenerateForm', .factory('GroupsDelete', ['$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'GroupForm', 'GenerateForm',
'Prompt', 'ProcessErrors', 'GetBasePath', 'Wait', 'ClickNode', 'BuildTree', 'Prompt', 'ProcessErrors', 'GetBasePath', 'Wait', 'BuildTree', 'Find',
function($rootScope, $location, $log, $routeParams, Rest, Alert, GroupForm, GenerateForm, Prompt, ProcessErrors, function($rootScope, $location, $log, $routeParams, Rest, Alert, GroupForm, GenerateForm, Prompt, ProcessErrors,
GetBasePath, Wait, ClickNode, BuildTree) { GetBasePath, Wait, BuildTree, Find) {
return function(params) { return function(params) {
// Delete the selected group node. Disassociates it from its parent. // Delete the selected group node. Disassociates it from its parent.
var scope = params.scope; var scope = params.scope;
var tree_id = params.tree_id; var tree_id = params.tree_id;
var group_id = params.group_id;
var inventory_id = params.inventory_id; var inventory_id = params.inventory_id;
var node, parent, url, parent_name; var node = Find({ list: scope.groups, key: 'id', val: tree_id });
var url = GetBasePath('inventory') + inventory_id + '/groups/';
for (var i=0; i < scope.groups.length; i++) {
if (scope.groups[i].id == tree_id) {
node = scope.groups[i];
}
}
//if (node.parent != 0) {
// for (var i=0; i < scope.groups.length; i++) {
// if (scope.groups[i].id == node.parent) {
// parent = scope.groups[i];
// parent_name = scope.groups[i].name;
// }
// }
// }
// else {
// parent_name = scope.inventory_name;
// }
//if (parent) { scope.showHosts(tree_id, group_id, false);
// url = GetBasePath('base') + 'groups/' + parent.group_id + '/children/';
//}
//else {
url = GetBasePath('inventory') + inventory_id + '/groups/';
//}
var action_to_take = function() { var action_to_take = function() {
$('#prompt-modal').on('hidden.bs.modal', function(){ Wait('start'); }); $('#prompt-modal').on('hidden.bs.modal', function(){ Wait('start'); });
$('#prompt-modal').modal('hide'); $('#prompt-modal').modal('hide');
@@ -1366,7 +1159,7 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
Rest.post({ id: node.group_id, disassociate: 1 }) Rest.post({ id: node.group_id, disassociate: 1 })
.success( function(data, status, headers, config) { .success( function(data, status, headers, config) {
$('#prompt-modal').off(); $('#prompt-modal').off();
scope.$emit('groupDeleteCompleted'); // Signal a group refresh to start scope.$emit('GroupDeleteCompleted'); // Signal a group refresh to start
}) })
.error( function(data, status, headers, config) { .error( function(data, status, headers, config) {
Wait('stop'); Wait('stop');
@@ -1377,19 +1170,6 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
Prompt({ hdr: 'Delete Group', body: '<p>Are you sure you want to delete group <em>' + node.name + '?</p>', Prompt({ hdr: 'Delete Group', body: '<p>Are you sure you want to delete group <em>' + node.name + '?</p>',
action: action_to_take, 'class': 'btn-danger' }); action: action_to_take, 'class': 'btn-danger' });
//'</em> from <em>' + parent_name + '</em>
//Force binds to work. Not working usual way.
//$('#prompt-header').text('Delete Group');
//$('#prompt-body').html('<p>Are you sure you want to remove group <em>' + $(obj).attr('data-name') + '</em> from group <em>' +
// parent.attr('data-name') + '</em>?</p>');
//$('#prompt-action-btn').addClass('btn-danger');
//scope.promptAction = action_to_take; // for some reason this binds?
//('#prompt-modal').modal({
// backdrop: 'static',
// keyboard: true,
// show: true
// });
} }
}]) }])

View File

@@ -22,8 +22,7 @@ angular.module('HostsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', 'H
var group_id = params.group_id; var group_id = params.group_id;
var tree_id = params.tree_id var tree_id = params.tree_id
var inventory_id = params.inventory_id; var inventory_id = params.inventory_id;
var emit = params.emit;
var url = ( !Empty(group_id) ) ? GetBasePath('groups') + group_id + '/all_hosts/' : var url = ( !Empty(group_id) ) ? GetBasePath('groups') + group_id + '/all_hosts/' :
GetBasePath('inventory') + inventory_id + '/hosts/'; GetBasePath('inventory') + inventory_id + '/hosts/';
@@ -34,9 +33,7 @@ angular.module('HostsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', 'H
} }
scope.removePostRefresh = scope.$on('PostRefresh', function(e) { scope.removePostRefresh = scope.$on('PostRefresh', function(e) {
Wait('stop'); Wait('stop');
if (emit) { scope.$emit('HostReloadComplete');
scope.$emit(emit);
}
}); });
SearchInit({ scope: scope, set: 'hosts', list: InventoryHosts, url: url }); SearchInit({ scope: scope, set: 'hosts', list: InventoryHosts, url: url });
@@ -53,14 +50,13 @@ angular.module('HostsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', 'H
var inventory_id = params.inventory_id; var inventory_id = params.inventory_id;
var group_id = params.group_id; var group_id = params.group_id;
var tree_id = params.tree_id; var tree_id = params.tree_id;
var emit = params.emit;
// Inject the list html // Inject the list html
var generator = GenerateList; var generator = GenerateList;
generator.inject(InventoryHosts, { scope: scope, mode: 'edit', id: 'hosts-container', breadCrumbs: false, searchSize: 'col-lg-6 col-md-6 col-sm-6' }); generator.inject(InventoryHosts, { scope: scope, mode: 'edit', id: 'hosts-container', breadCrumbs: false, searchSize: 'col-lg-6 col-md-6 col-sm-6' });
// Load data // Load data
HostsReload({ scope: scope, group_id: group_id, tree_id: tree_id, inventory_id: inventory_id, emit: emit }); HostsReload({ scope: scope, group_id: group_id, tree_id: tree_id, inventory_id: inventory_id });
} }
}]) }])
@@ -214,9 +210,10 @@ angular.module('HostsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', 'H
function($rootScope, $location, $log, $routeParams, Rest, Alert, HostForm, GenerateForm, Prompt, ProcessErrors, function($rootScope, $location, $log, $routeParams, Rest, Alert, HostForm, GenerateForm, Prompt, ProcessErrors,
GetBasePath, HostsReload, ParseTypeChange, Wait) { GetBasePath, HostsReload, ParseTypeChange, Wait) {
return function(params) { return function(params) {
var inventory_id = params.inventory_id; var parent_scope = params.scope;
var group_id = (params.group_id !== undefined) ? params.group_id : null; var inventory_id = parent_scope.inventory_id;
var group_id = parent_scope.selected_group_id;
// Inject dynamic view // Inject dynamic view
var defaultUrl = GetBasePath('groups') + group_id + '/hosts/'; var defaultUrl = GetBasePath('groups') + group_id + '/hosts/';
@@ -247,19 +244,26 @@ angular.module('HostsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', 'H
if (!scope.$$phase) { if (!scope.$$phase) {
scope.$digest(); scope.$digest();
} }
if (scope.removeHostSaveComplete) {
scope.removeHostSaveComplete();
}
scope.removeHostSaveComplete = scope.$on('HostSaveComplete', function() {
Wait('stop');
$('#form-modal').modal('hide');
HostsReload({
scope: parent_scope,
group_id: parent_scope.selected_group_id,
tree_id: parent_scope.selected_tree_id,
inventory_id: parent_scope.inventory_id });
});
// Save // Save
scope.formModalAction = function() { scope.formModalAction = function() {
Wait('start'); Wait('start');
function finished() { try {
$('#form-modal').modal('hide');
scope.$emit('hostsReload');
}
try {
scope.formModalActionDisabled = true; scope.formModalActionDisabled = true;
// Make sure we have valid variable data // Make sure we have valid variable data
@@ -294,8 +298,7 @@ angular.module('HostsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', 'H
Rest.setUrl(defaultUrl); Rest.setUrl(defaultUrl);
Rest.post(data) Rest.post(data)
.success( function(data, status, headers, config) { .success( function(data, status, headers, config) {
Wait('stop'); scope.$emit('HostSaveComplete');
finished();
}) })
.error( function(data, status, headers, config) { .error( function(data, status, headers, config) {
Wait('stop'); Wait('stop');

View File

@@ -413,14 +413,17 @@ angular.module('JobSubmissionHelper', [ 'RestServices', 'Utilities', 'Credential
var url = params.url; var url = params.url;
var group_name = params.group_name; var group_name = params.group_name;
var group_source = params.group_source; var group_source = params.group_source;
var group_id = params.group_id;
var tree_id = params.tree_id;
if (scope.removeSubmitRefreshCompleted) { if (scope.removeHostReloadComplete) {
scope.removeSubmitRefreshCompleted(); scope.removeHostReloadComplete();
} }
scope.removeSubmitRefreshCompleted = scope.$on('SubmitRefreshCompleted', function(e) { scope.removeHostReloadComplete = scope.$on('HostReloadComplete', function(e) {
Wait('stop'); Wait('stop');
Alert('Update Started', 'The request to start the inventory update process was submitted. Monitor progress of the update process ' + Alert('Update Started', 'The request to start the inventory update process was submitted. Monitor progress of the update process ' +
'by clicking the <i class="fa fa-refresh fa-lg"></i> button.', 'alert-info'); 'by clicking the <i class="fa fa-refresh fa-lg"></i> button.', 'alert-info');
scope.removeHostReloadComplete();
}); });
if (scope.removeUpdateSubmitted) { if (scope.removeUpdateSubmitted) {
@@ -428,7 +431,10 @@ angular.module('JobSubmissionHelper', [ 'RestServices', 'Utilities', 'Credential
} }
scope.removeUpdateSubmitted = scope.$on('UpdateSubmitted', function(e, action) { scope.removeUpdateSubmitted = scope.$on('UpdateSubmitted', function(e, action) {
if (action == 'started') { if (action == 'started') {
scope.refreshGroups('SubmitRefreshComplete'); // Cancel the update process
scope.selected_tree_id = tree_id;
scope.selected_group_id = group_id;
scope.refreshGroups();
} }
}); });

View File

@@ -14,101 +14,9 @@ angular.module('InventoryHelper', [ 'RestServices', 'Utilities', 'OrganizationLi
'InventoryFormDefinition', 'ParseHelper' 'InventoryFormDefinition', 'ParseHelper'
]) ])
.factory('LoadRootGroups', ['Rest', 'ProcessErrors', function(Rest, ProcessErrors) {
return function(params) {
// Build an array of root group IDs. We'll need this when copying IDs.
var scope = params.scope;
Rest.setUrl(scope.inventoryRootGroupsUrl);
Rest.get()
.success( function(data, status, headers, config) {
scope.inventoryRootGroups = [];
for (var i=0; i < data.results.length; i++){
scope.inventoryRootGroups.push(data.results[i].id);
}
})
.error( function(data, status, headers, config) {
ProcessErrors(scope, data, status, null,
{ hdr: 'Error!', msg: 'Failed to retrieve root groups for inventory: ' +
scope.inventory_id + '. GET status: ' + status });
});
}
}])
.factory('LoadInventory', ['$routeParams', 'Alert', 'Rest', 'Authorization', '$http', 'ProcessErrors',
'RelatedSearchInit', 'RelatedPaginateInit', 'GetBasePath', 'LoadBreadCrumbs', 'InventoryForm', 'LoadRootGroups',
function($routeParams, Alert, Rest, Authorization, $http, ProcessErrors, RelatedSearchInit, RelatedPaginateInit,
GetBasePath, LoadBreadCrumbs, InventoryForm, LoadRootGroups) {
return function(params) {
// Load inventory detail record
var scope = params.scope;
var form = InventoryForm;
scope.relatedSets = [];
scope.master = {};
if (scope.removeLevelOneGroups) {
scope.removeLevelOneGroups();
}
scope.removeLevelOneGroups = scope.$on('inventoryLoaded', function() {
LoadRootGroups({ scope: scope });
});
Rest.setUrl(GetBasePath('inventory') + scope['inventory_id'] + '/');
Rest.get()
.success( function(data, status, headers, config) {
LoadBreadCrumbs({ path: '/inventories/' + $routeParams.id, title: data.name });
for (var fld in form.fields) {
if (form.fields[fld].realName) {
if (data[form.fields[fld].realName]) {
scope[fld] = data[form.fields[fld].realName];
scope.master[fld] = scope[fld];
}
}
else {
if (data[fld]) {
scope[fld] = data[fld];
scope.master[fld] = scope[fld];
}
}
if (form.fields[fld].type == 'lookup' && data.summary_fields[form.fields[fld].sourceModel]) {
scope[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField] =
data.summary_fields[form.fields[fld].sourceModel][form.fields[fld].sourceField];
scope.master[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField] =
scope[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField];
}
}
scope.inventoryGroupsUrl = data.related.groups;
scope.inventoryRootGroupsUrl = data.related.root_groups;
scope.TreeParams = { scope: scope, inventory: data };
scope.variable_url = data.related.variable_data;
scope.relatedSets['hosts'] = { url: data.related.hosts, iterator: 'host' };
scope.treeData = data.related.tree;
// Load the tree view
if (params.doPostSteps) {
RelatedSearchInit({ scope: scope, form: form, relatedSets: scope.relatedSets });
RelatedPaginateInit({ scope: scope, relatedSets: scope.relatedSets });
}
scope.$emit('inventoryLoaded');
})
.error( function(data, status, headers, config) {
ProcessErrors(scope, data, status, null,
{ hdr: 'Error!', msg: 'Failed to retrieve inventory: ' + $routeParams.id + '. GET status: ' + status });
});
}
}])
.factory('SaveInventory', ['InventoryForm', 'Rest', 'Alert', 'ProcessErrors', 'LookUpInit', 'OrganizationList', .factory('SaveInventory', ['InventoryForm', 'Rest', 'Alert', 'ProcessErrors', 'LookUpInit', 'OrganizationList',
'GetBasePath', 'ParseTypeChange', 'LoadInventory', 'Wait', 'GetBasePath', 'ParseTypeChange', 'Wait',
function(InventoryForm, Rest, Alert, ProcessErrors, LookUpInit, OrganizationList, GetBasePath, ParseTypeChange, function(InventoryForm, Rest, Alert, ProcessErrors, LookUpInit, OrganizationList, GetBasePath, ParseTypeChange, Wait) {
LoadInventory, Wait) {
return function(params) { return function(params) {
// Save inventory property modifications // Save inventory property modifications
@@ -153,7 +61,7 @@ angular.module('InventoryHelper', [ 'RestServices', 'Utilities', 'OrganizationLi
Rest.put(json_data) Rest.put(json_data)
.success( function(data, status, headers, config) { .success( function(data, status, headers, config) {
Wait('stop'); Wait('stop');
scope.$emit('inventorySaved'); scope.$emit('InventorySaved');
}) })
.error( function(data, status, headers, config) { .error( function(data, status, headers, config) {
ProcessErrors(scope, data, status, form, ProcessErrors(scope, data, status, form,
@@ -161,7 +69,7 @@ angular.module('InventoryHelper', [ 'RestServices', 'Utilities', 'OrganizationLi
}); });
} }
else { else {
scope.$emit('inventorySaved'); scope.$emit('InventorySaved');
} }
}) })
.error( function(data, status, headers, config) { .error( function(data, status, headers, config) {
@@ -177,104 +85,111 @@ angular.module('InventoryHelper', [ 'RestServices', 'Utilities', 'OrganizationLi
} }
}]) }])
.factory('PostLoadInventory', ['InventoryForm', 'Rest', 'Alert', 'ProcessErrors', 'LookUpInit', 'OrganizationList', 'GetBasePath',
function(InventoryForm, Rest, Alert, ProcessErrors, LookUpInit, OrganizationList, GetBasePath) {
return function(params) {
var scope = params.scope;
LookUpInit({
scope: scope,
form: InventoryForm,
current_item: (scope.organization !== undefined) ? scope.organization : null,
list: OrganizationList,
field: 'organization'
});
if (scope.variable_url) { .factory('EditInventoryProperties', ['InventoryForm', 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LookUpInit', 'OrganizationList',
Rest.setUrl(scope.variable_url); 'GetBasePath', 'ParseTypeChange', 'SaveInventory', 'Wait',
Rest.get() function(InventoryForm, GenerateForm, Rest, Alert, ProcessErrors, LookUpInit, OrganizationList, GetBasePath, ParseTypeChange, SaveInventory,
.success( function(data, status, headers, config) { Wait) {
if ($.isEmptyObject(data)) {
scope.inventory_variables = "---";
}
else {
scope.inventory_variables = jsyaml.safeDump(data);
}
scope.master.inventory_variables = scope.inventory_variables;
})
.error( function(data, status, headers, config) {
scope.inventory_variables = null;
ProcessErrors(scope, data, status, form,
{ hdr: 'Error!', msg: 'Failed to retrieve inventory variables. GET returned status: ' + status });
});
}
else {
scope.inventory_variables = "---";
}
if (!scope.$$phase) {
scope.$digest();
}
}
}])
.factory('EditInventory', ['InventoryForm', 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LookUpInit', 'OrganizationList',
'GetBasePath', 'ParseTypeChange', 'LoadInventory', 'SaveInventory', 'PostLoadInventory',
function(InventoryForm, GenerateForm, Rest, Alert, ProcessErrors, LookUpInit, OrganizationList, GetBasePath, ParseTypeChange,
LoadInventory, SaveInventory, PostLoadInventory) {
return function(params) { return function(params) {
var parent_scope = params.scope
var inventory_id = params.inventory_id;
var generator = GenerateForm; var generator = GenerateForm;
var form = InventoryForm; var form = InventoryForm;
var defaultUrl=GetBasePath('inventory'); var defaultUrl=GetBasePath('inventory');
var scope = params.scope var master = {};
form.well = false; form.well = false;
form.formLabelSize = 'col-lg-3'; //form.formLabelSize = 'col-lg-3';
form.formFieldSize = 'col-lg-9'; //form.formFieldSize = 'col-lg-9';
generator.inject(form, {mode: 'edit', modal: true, related: false}); var scope = generator.inject(form, {mode: 'edit', modal: true, related: false, modal_show: false });
/* Reset form properties. Otherwise it screws up future requests of the Inventories detail page */ /* Reset form properties. Otherwise it screws up future requests of the Inventories detail page */
form.well = true; form.well = true;
delete form.formLabelSize; //delete form.formLabelSize;
delete form.formFieldSize; //delete form.formFieldSize;
ParseTypeChange(scope,'inventory_variables', 'inventoryParseType'); ParseTypeChange(scope,'inventory_variables', 'inventoryParseType');
scope.inventoryParseType = 'yaml'; scope.inventoryParseType = 'yaml';
scope['inventory_id'] = params['inventory_id'];
scope.formModalActionLabel = 'Save'; scope.formModalActionLabel = 'Save';
scope.formModalCancelShow = true; scope.formModalCancelShow = true;
scope.formModalInfo = false; scope.formModalInfo = false;
$('#form-modal .btn-success').removeClass('btn-none').addClass('btn-success');
scope.formModalHeader = 'Inventory Properties'; scope.formModalHeader = 'Inventory Properties';
// Retrieve each related set and any lookups $('#form-modal .btn-success').removeClass('btn-none').addClass('btn-success');
if (scope.inventoryLoadedRemove) {
scope.inventoryLoadedRemove();
}
scope.inventoryLoadedRemove = scope.$on('inventoryLoaded', function() {
PostLoadInventory({ scope: scope });
});
LoadInventory({ scope: scope, doPostSteps: false });
if (!scope.$$phase) { Wait('start');
scope.$digest(); Rest.setUrl(GetBasePath('inventory') + inventory_id + '/');
} Rest.get()
.success( function(data, status, headers, config) {
for (var fld in form.fields) {
if (fld == 'inventory_variables') {
// Parse variables, converting to YAML.
if ($.isEmptyObject(data.variables) || data.variables == "\{\}" ||
data.variables == "null" || data.data_variables == "") {
scope.inventory_variables = "---";
}
else {
var json_obj = JSON.parse(data.variables);
scope.inventory_variables = jsyaml.safeDump(json_obj);
}
master.inventory_variables = scope.variables;
}
else if (fld == 'inventory_name') {
scope[fld] = data.name;
master[fld] = scope[fld];
}
else if (fld == 'inventory_description') {
scope[fld] = data.description;
master[fld] = scope[fld];
}
else if (data[fld]) {
scope[fld] = data[fld];
master[fld] = scope[fld];
}
if (form.fields[fld].sourceModel && data.summary_fields &&
data.summary_fields[form.fields[fld].sourceModel]) {
scope[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField] =
data.summary_fields[form.fields[fld].sourceModel][form.fields[fld].sourceField];
master[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField] =
data.summary_fields[form.fields[fld].sourceModel][form.fields[fld].sourceField];
}
}
LookUpInit({
scope: scope,
form: form,
current_item: scope.organization,
list: OrganizationList,
field: 'organization'
});
Wait('stop');
$('#form-modal').modal('show');
})
.error( function(data, status, headers, config) {
Wait('stop');
ProcessErrors(scope, data, status, null,
{ hdr: 'Error!', msg: 'Failed to get inventory: ' + inventory_id + '. GET returned: ' + status });
});
if (scope.removeInventorySaved) { if (scope.removeInventorySaved) {
scope.removeInventorySaved(); scope.removeInventorySaved();
} }
scope.removeInventorySaved = scope.$on('inventorySaved', function() { scope.removeInventorySaved = scope.$on('InventorySaved', function() {
$('#form-modal').modal('hide'); $('#form-modal').modal('hide');
}); });
scope.formModalAction = function() { scope.formModalAction = function() {
scope.inventory_id = inventory_id;
parent_scope.inventory_name = scope.inventory_name;
console.log('set inventory_name to: ' + parent_scope.inventory_name);
SaveInventory({ scope: scope }); SaveInventory({ scope: scope });
} }
} }
}]); }]);

View File

@@ -75,12 +75,12 @@ angular.module('InventoryGroupsDefinition', [])
create: { create: {
mode: 'all', mode: 'all',
ngClick: "createGroup()", ngClick: "createGroup()",
ngHide: 'selected_tree_id == 1', //disable when 'All Hosts' selected
awToolTip: "Create a new group" awToolTip: "Create a new group"
}, },
properties: { properties: {
mode: 'all', mode: 'all',
awToolTip: "Edit inventory properties" awToolTip: "Edit inventory properties",
ngClick: 'editInventoryProperties()'
}, },
refresh: { refresh: {
mode: 'all', mode: 'all',
@@ -107,7 +107,7 @@ angular.module('InventoryGroupsDefinition', [])
fieldActions: { fieldActions: {
sync_status: { sync_status: {
mode: 'all', mode: 'all',
ngClick: "viewUpdateStatus(\{\{ group.id \}\})", ngClick: "viewUpdateStatus(\{\{ group.id + ',' + group.group_id \}\})",
ngShow: "group.id > 1", // hide for all hosts ngShow: "group.id > 1", // hide for all hosts
awToolTip: "\{\{ group.status_tooltip \}\}", awToolTip: "\{\{ group.status_tooltip \}\}",
ngClass: "group.status_class", ngClass: "group.status_class",
@@ -142,7 +142,7 @@ angular.module('InventoryGroupsDefinition', [])
edit: { edit: {
//label: 'Edit', //label: 'Edit',
mode: 'all', mode: 'all',
ngClick: "editGroup(\{\{ group.group_id \}\})", ngClick: "editGroup(\{\{ group.group_id + ',' + group.id \}\})",
awToolTip: 'Edit group', awToolTip: 'Edit group',
ngShow: "group.id > 1", // hide for all hosts ngShow: "group.id > 1", // hide for all hosts
dataPlacement: "top" dataPlacement: "top"
@@ -150,7 +150,7 @@ angular.module('InventoryGroupsDefinition', [])
"delete": { "delete": {
//label: 'Delete', //label: 'Delete',
mode: 'all', mode: 'all',
ngClick: "deleteGroup(\{\{ group.id \}\})", ngClick: "deleteGroup(\{\{ group.id + ',' + group.group_id \}\})",
awToolTip: 'Delete group', awToolTip: 'Delete group',
ngShow: "group.id != 1", // hide for all hosts ngShow: "group.id != 1", // hide for all hosts
dataPlacement: "top" dataPlacement: "top"

View File

@@ -27,19 +27,6 @@ angular.module('InventoryHostsDefinition', [])
ngClick: "editHost(\{\{ host.id \}\}, '\{\{ host.name \}\}')", ngClick: "editHost(\{\{ host.id \}\}, '\{\{ host.name \}\}')",
searchPlaceholder: "search_place_holder" searchPlaceholder: "search_place_holder"
}, },
active_failures: {
label: 'Job Status',
ngHref: "\{\{ host.activeFailuresLink \}\}",
awToolTip: "\{\{ host.badgeToolTip \}\}",
dataPlacement: 'top',
badgeNgHref: '\{\{ host.activeFailuresLink \}\}',
badgeIcon: "\{\{ 'fa icon-failures-' + host.has_active_failures \}\}",
badgePlacement: 'left',
badgeToolTip: "\{\{ host.badgeToolTip \}\}",
badgeTipPlacement: 'top',
searchable: false,
nosort: true
},
enabled_flag: { enabled_flag: {
label: 'Enabled', label: 'Enabled',
badgeIcon: "\{\{ 'fa icon-enabled-' + host.enabled \}\}", badgeIcon: "\{\{ 'fa icon-enabled-' + host.enabled \}\}",
@@ -84,6 +71,20 @@ angular.module('InventoryHostsDefinition', [])
}, },
fieldActions: { fieldActions: {
active_failures: {
//label: 'Job Status',
awToolTip: "\{\{ host.badgeToolTip \}\}",
dataPlacement: 'top',
badgeNgHref: '\{\{ host.activeFailuresLink \}\}',
iconClass: "\{\{ 'fa icon-failures-' + host.has_active_failures \}\}",
badgePlacement: 'left',
badgeToolTip: "\{\{ host.badgeToolTip \}\}",
badgeTipPlacement: 'top'
},
edit: { edit: {
//label: 'Edit', //label: 'Edit',
ngClick: "editGroup(\{\{ host.id \}\})", ngClick: "editGroup(\{\{ host.id \}\})",
@@ -104,7 +105,7 @@ angular.module('InventoryHostsDefinition', [])
create: { create: {
mode: 'all', mode: 'all',
ngClick: "createHost()", ngClick: "createHost()",
ngHide: "!selected_tree_id", ngHide: 'selected_tree_id == 1', //disable when 'All Hosts' selected
awToolTip: "Create a new host" awToolTip: "Create a new host"
}, },
stream: { stream: {

View File

@@ -178,7 +178,8 @@ angular.module('InventoryTree', ['Utilities', 'RestServices', 'GroupsHelper'])
var inventory_id = params.inventory_id; var inventory_id = params.inventory_id;
var scope = params.scope; var scope = params.scope;
var refresh = params.refresh; var refresh = params.refresh;
var emit = params.emit; var emit = params.emit;
var new_group_id = params.new_group_id;
//var selected_id = params. //var selected_id = params.
@@ -235,6 +236,11 @@ angular.module('InventoryTree', ['Utilities', 'RestServices', 'GroupsHelper'])
show: true show: true
} }
groups.push(group); groups.push(group);
if (new_group_id && group.group_id == new_group_id) {
// For new group
scope.selected_tree_id = id;
scope.selected_group_id = group.group_id;
}
if (sorted[i].children.length > 0) { if (sorted[i].children.length > 0) {
buildGroups(sorted[i].children, id, level + 1); buildGroups(sorted[i].children, id, level + 1);
} }
@@ -243,7 +249,7 @@ angular.module('InventoryTree', ['Utilities', 'RestServices', 'GroupsHelper'])
// Build the HTML for our tree // Build the HTML for our tree
if (scope.buildAllGroupsRemove) { if (scope.buildAllGroupsRemove) {
scope.buildAllGroupsRemove(); scope.buildAllGroupsRemove();
} }
scope.buildAllGroupsRemove = scope.$on('buildAllGroups', function(e, inventory_name, inventory_tree) { scope.buildAllGroupsRemove = scope.$on('buildAllGroups', function(e, inventory_name, inventory_tree) {
Rest.setUrl(inventory_tree); Rest.setUrl(inventory_tree);
@@ -253,10 +259,10 @@ angular.module('InventoryTree', ['Utilities', 'RestServices', 'GroupsHelper'])
//console.log(groups); //console.log(groups);
if (refresh) { if (refresh) {
scope.groups = groups; scope.groups = groups;
scope.$emit('groupTreeRefreshed', inventory_name, groups, emit); scope.$emit('GroupTreeRefreshed', inventory_name, groups, emit);
} }
else { else {
scope.$emit('groupTreeLoaded', inventory_name, groups, emit); scope.$emit('GroupTreeLoaded', inventory_name, groups, emit);
} }
}) })
.error( function(data, status, headers, config) { .error( function(data, status, headers, config) {
@@ -333,18 +339,4 @@ angular.module('InventoryTree', ['Utilities', 'RestServices', 'GroupsHelper'])
$('#inventory-root-node').attr('data-name', name).attr('data-description', descr).find('.activate').first().text(name); $('#inventory-root-node').attr('data-name', name).attr('data-description', descr).find('.activate').first().text(name);
} }
} }
}])
.factory('ClickNode', [ function() {
return function(params) {
var selector = params.selector; //jquery selector string to find the correct <li>
$(selector + ' .activate').first().click();
}
}])
.factory('DeleteNode', [ function() {
return function(params) {
var selector = params.selector; //jquery selector string to find the correct <li>
$(selector).first().detach();
}
}]); }]);

View File

@@ -181,7 +181,6 @@ angular.module('Utilities',['RestServices', 'Utilities'])
$rootScope.crumbCache.push(crumb); $rootScope.crumbCache.push(crumb);
} }
} }
var paths = $location.path().replace(/^\//,'').split('/'); var paths = $location.path().replace(/^\//,'').split('/');
var ppath = ''; var ppath = '';
$rootScope.breadcrumbs = []; $rootScope.breadcrumbs = [];
@@ -191,41 +190,41 @@ angular.module('Utilities',['RestServices', 'Utilities'])
if (i > 0 && paths[i].match(/\d+/)) { if (i > 0 && paths[i].match(/\d+/)) {
parent = paths[i-1]; parent = paths[i-1];
if (parent == 'inventories') { if (parent == 'inventories') {
child = 'inventory'; child = 'inventory';
} }
else { else {
child = parent.substring(0,parent.length - 1); //assumes parent ends with 's' child = parent.substring(0,parent.length - 1); //assumes parent ends with 's'
} }
// find the correct title // find the correct title
for (var j=0; j < $rootScope.crumbCache.length; j++) { for (var j=0; j < $rootScope.crumbCache.length; j++) {
if ($rootScope.crumbCache[j].path == '/' + parent + '/' + paths[i]) { if ($rootScope.crumbCache[j].path == '/' + parent + '/' + paths[i]) {
child = $rootScope.crumbCache[j].title; child = $rootScope.crumbCache[j].title;
break; break;
} }
} }
if ($rootScope.crumbCache[j] && $rootScope.crumbCache[j]['altPath'] !== undefined) { if ($rootScope.crumbCache[j] && $rootScope.crumbCache[j]['altPath'] !== undefined) {
// Use altPath to override default path construction // Use altPath to override default path construction
$rootScope.breadcrumbs.push({ title: child, path: $rootScope.crumbCache[j].altPath }); $rootScope.breadcrumbs.push({ title: child, path: $rootScope.crumbCache[j].altPath });
} }
else { else {
if (paths[i - 1] == 'hosts') { if (paths[i - 1] == 'hosts') {
// For hosts, there is no /hosts, so we need to link back to the inventory // For hosts, there is no /hosts, so we need to link back to the inventory
// We end up here when user has clicked refresh and the crumbcache is missing // We end up here when user has clicked refresh and the crumbcache is missing
$rootScope.breadcrumbs.push({ title: child, $rootScope.breadcrumbs.push({ title: child,
path: '/inventories/' + $routeParams.inventory + '/hosts' }); path: '/inventories/' + $routeParams.inventory + '/hosts' });
} }
else { else {
$rootScope.breadcrumbs.push({ title: child, path: ppath + '/' + paths[i] }); $rootScope.breadcrumbs.push({ title: child, path: ppath + '/' + paths[i] });
} }
} }
} }
else { else {
if (paths[i] == 'hosts') { if (paths[i] == 'hosts') {
$rootScope.breadcrumbs.push({ title: paths[i], path: '/inventories/' + $routeParams.inventory + $rootScope.breadcrumbs.push({ title: paths[i], path: '/inventories/' + $routeParams.inventory +
'/hosts' }); '/hosts' });
} }
else { else {
$rootScope.breadcrumbs.push({ title: paths[i], path: ppath + '/' + paths[i] }); $rootScope.breadcrumbs.push({ title: paths[i], path: ppath + '/' + paths[i] });
} }
} }
ppath += '/' + paths[i]; ppath += '/' + paths[i];

View File

@@ -149,11 +149,12 @@ angular.module('FormGenerator', ['GeneratorHelpers', 'ngCookies', 'Utilities'])
$(options.modal_selector).unbind('hidden.bs.modal'); $(options.modal_selector).unbind('hidden.bs.modal');
} }
else { else {
$('#form-modal').modal({ show: true, backdrop: 'static', keyboard: true }); var show = (options.show_modal == false) ? false : true;
$('#form-modal').modal({ show: show, backdrop: 'static', keyboard: true });
$('#form-modal').on('shown.bs.modal', function() { $('#form-modal').on('shown.bs.modal', function() {
$('#form-modal input:first').focus(); $('#form-modal input:first').focus();
}); });
$('#form-modal').on('hidden.bs.modal'); $('#form-modal').off('hidden.bs.modal');
} }
$(document).bind('keydown', function(e) { $(document).bind('keydown', function(e) {
if (e.keyCode === 27) { if (e.keyCode === 27) {