Merge pull request #1741 from leigh-johnson/InventoryManageHosts

Refactor Inventory > Manage > Hosts > Add/Edit, update Hosts list on Group selection
This commit is contained in:
Leigh 2016-04-29 15:34:26 -04:00
commit f2f6230818
13 changed files with 218 additions and 370 deletions

View File

@ -15,14 +15,23 @@ export default
.value('HostForm', {
addTitle: 'Create Host',
editTitle: '{{ name }}',
editTitle: '{{ host.name }}',
name: 'host',
well: false,
formLabelSize: 'col-lg-3',
formFieldSize: 'col-lg-9',
cancelButton: false,
showHeader: false,
iterator: 'host',
headerFields:{
enabled: {
class: 'Form-header-field',
ngClick: 'toggleHostEnabled(host)',
type: 'toggle',
editRequired: false,
awToolTip: "<p>Indicates if a host is available and should be included in running jobs.</p><p>For hosts that " +
"are part of an external inventory, this flag cannot be changed. It will be set by the inventory sync process.</p>",
dataTitle: 'Host Enabled',
}
},
fields: {
name: {
label: 'Host Name',
@ -45,19 +54,6 @@ export default
addRequired: false,
editRequired: false
},
enabled: {
label: 'Enabled?',
type: 'checkbox',
addRequired: false,
editRequired: false,
"default": true,
awPopOver: "<p>Indicates if a host is available and should be included in running jobs.</p><p>For hosts that " +
"are part of an external inventory, this flag cannot be changed. It will be set by the inventory sync process.</p>",
dataTitle: 'Host Enabled',
dataPlacement: 'right',
dataContainer: 'body',
ngDisabled: 'has_inventory_sources == true'
},
variables: {
label: 'Variables',
type: 'textarea',
@ -84,17 +80,15 @@ export default
}
},
buttons: { //for now always generates <button> tags
/*
buttons: {
save: {
ngClick: 'formSave()', //$scope.function to call on click, optional
ngDisabled: true //Disable when $pristine or $invalid, optional
ngClick: 'formSave()',
ngDisabled: true
},
reset: {
ngClick: 'formReset()',
ngDisabled: true //Disabled when $pristine
cancel: {
ngClick: 'formCancel()',
ngDisabled: true
}
*/
},
related: {}

View File

@ -236,47 +236,6 @@ angular.module('HostsHelper', [ 'RestServices', 'Utilities', listGenerator.name,
};
}])
.factory('ToggleHostEnabled', [ 'GetBasePath', 'Rest', 'Wait', 'ProcessErrors', 'Alert', 'Find', 'SetEnabledMsg',
function(GetBasePath, Rest, Wait, ProcessErrors, Alert, Find, SetEnabledMsg) {
return function(params) {
var id = params.host_id,
external_source = params.external_source,
parent_scope = params.parent_scope,
host_scope = params.host_scope,
host;
function setMsg(host) {
host.enabled = (host.enabled) ? false : true;
host.enabled_flag = host.enabled;
SetEnabledMsg(host);
}
if (!external_source) {
// Host is not managed by an external source
Wait('start');
host = Find({ list: host_scope.hosts, key: 'id', val: id });
setMsg(host);
Rest.setUrl(GetBasePath('hosts') + id + '/');
Rest.put(host)
.success( function() {
Wait('stop');
})
.error( function(data, status) {
// Flip the enabled flag back
setMsg(host);
ProcessErrors(parent_scope, data, status, null,
{ hdr: 'Error!', msg: 'Failed to update host. PUT returned status: ' + status });
});
}
else {
Alert('Action Not Allowed', 'This host is managed by an external cloud source. Disable it at the external source, ' +
'then run an inventory sync to update Tower with the new status.', 'alert-info');
}
};
}])
.factory('HostsList', ['$rootScope', '$location', '$log', '$stateParams', 'Rest', 'Alert', 'HostList', 'generateList',
'Prompt', 'SearchInit', 'PaginateInit', 'ProcessErrors', 'GetBasePath', 'HostsAdd', 'HostsReload', 'SelectionInit',
function($rootScope, $location, $log, $stateParams, Rest, Alert, HostList, GenerateList, Prompt, SearchInit,

View File

@ -16,7 +16,7 @@ function InventoriesManage($log, $scope, $rootScope, $location,
InjectHosts, Find, HostsReload, SearchInit, PaginateInit, GetSyncStatusMsg,
GetHostsStatusMsg, GroupsEdit, InventoryUpdate, GroupsCancelUpdate,
ViewUpdateStatus, GroupsDelete, Store, HostsEdit, HostsDelete,
EditInventoryProperties, ToggleHostEnabled, ShowJobSummary,
EditInventoryProperties, ShowJobSummary,
InventoryGroupsHelp, HelpDialog,
GroupsCopy, HostsCopy, $stateParams, ParamPass) {
@ -331,8 +331,15 @@ function InventoriesManage($log, $scope, $rootScope, $location,
}
groups.push(group.id);
groups = groups.join();
$state.transitionTo('inventoryManage', {inventory_id: $state.params.inventory_id, groups: groups}, { notify: false });
$state.transitionTo('inventoryManage', {inventory_id: $state.params.inventory_id, groups: groups}, { notify: false});
loadGroups(group.related.children, group.id);
$scope.selected_group_id = group.id;
HostsReload({
scope: hostScope,
group_id: $scope.selected_group_id,
inventory_id: $scope.inventory.id,
pageSize: hostScope.host_page_size
});
};
$scope.createGroup = function () {
@ -476,15 +483,6 @@ function InventoriesManage($log, $scope, $rootScope, $location,
$state.go('inventoryManage.copy.host', {host_id: id});
};
hostScope.toggleHostEnabled = function (host_id, external_source) {
ToggleHostEnabled({
parent_scope: $scope,
host_scope: hostScope,
host_id: host_id,
external_source: external_source
});
};
hostScope.showJobSummary = function (job_id) {
ShowJobSummary({
job_id: job_id
@ -533,7 +531,6 @@ export default [
'SearchInit', 'PaginateInit', 'GetSyncStatusMsg', 'GetHostsStatusMsg',
'GroupsEdit', 'InventoryUpdate', 'GroupsCancelUpdate', 'ViewUpdateStatus',
'GroupsDelete', 'Store', 'HostsEdit', 'HostsDelete',
'EditInventoryProperties', 'ToggleHostEnabled', 'ShowJobSummary',
'InventoryGroupsHelp', 'HelpDialog', 'GroupsCopy',
'EditInventoryProperties', 'ShowJobSummary', 'InventoryGroupsHelp', 'HelpDialog', 'GroupsCopy',
'HostsCopy', '$stateParams', 'ParamPass', InventoriesManage,
];

View File

@ -1,7 +1,6 @@
<div class="tab-pane" id="inventory_edit">
<div ui-view></div>
<div ng-cloak id="htmlTemplate">
<div class="row">
<div id="groups-container" class="col-lg-6">
<div id="group-list-container" class="Panel"></div>

View File

@ -1,198 +0,0 @@
/*************************************************
* Copyright (c) 2016 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
function manageHostsDirectiveController($rootScope, $location, $log, $stateParams, $state, $scope, Rest, Alert, HostForm,
GenerateForm, Prompt, ProcessErrors, GetBasePath, HostsReload, ParseTypeChange, Wait,
Find, SetStatus, ApplyEllipsis, ToJSON, ParseVariableString, CreateDialog, TextareaResize, ParamPass) {
var vm = this;
var params = ParamPass.get();
if (params === undefined) {
params = {};
params.host_scope = $scope.$new();
params.group_scope = $scope.$new();
}
var parent_scope = params.host_scope,
group_scope = params.group_scope,
inventory_id = $stateParams.inventory_id,
mode = $state.current.data.mode, // 'add' or 'edit'
selected_group_id = params.selected_group_id,
generator = GenerateForm,
form = HostForm,
defaultUrl,
scope = parent_scope.$new(),
master = {},
relatedSets = {},
url, form_scope;
var host_id = $stateParams.host_id || undefined;
var hostName = '';
form_scope =
generator.inject(HostForm, {
mode: mode,
id: 'host-panel-form',
related: false,
scope: scope,
});
generator.reset();
// Retrieve detail record and prepopulate the form
if (mode === 'edit') {
defaultUrl = GetBasePath('hosts') + host_id + '/';
Rest.setUrl(defaultUrl);
Rest.get()
.success(function(data) {
vm.hostName = data.name;
var set, fld, related;
for (fld in form.fields) {
if (data[fld]) {
scope[fld] = data[fld];
master[fld] = scope[fld];
}
}
related = data.related;
for (set in form.related) {
if (related[set]) {
relatedSets[set] = {
url: related[set],
iterator: form.related[set].iterator
};
}
}
scope.variable_url = data.related.variable_data;
scope.has_inventory_sources = data.has_inventory_sources;
scope.parseType = 'yaml';
ParseTypeChange({
scope: scope,
field_id: 'host_variables',
});
})
.error(function(data, status) {
ProcessErrors(parent_scope, data, status, form, {
hdr: 'Error!',
msg: 'Failed to retrieve host: ' + host_id + '. GET returned status: ' + status
});
});
} else {
if (selected_group_id) {
// adding hosts to a group
url = GetBasePath('groups') + selected_group_id + '/';
} else {
// adding hosts to the top-level (inventory)
url = GetBasePath('inventory') + inventory_id + '/';
}
// Add mode
Rest.setUrl(url);
Rest.get()
.success(function(data) {
scope.has_inventory_sources = data.has_inventory_sources;
scope.enabled = true;
scope.variables = '---';
defaultUrl = data.related.hosts;
scope.parseType = 'yaml';
ParseTypeChange({
scope: scope,
field_id: 'host_variables',
});
scope.parseType = 'yaml';
ParseTypeChange({
scope: scope,
field_id: 'host_variables',
});
})
.error(function(data, status) {
ProcessErrors(parent_scope, data, status, form, {
hdr: 'Error!',
msg: 'Failed to retrieve group: ' + selected_group_id + '. GET returned status: ' + status
});
});
}
if (scope.removeSaveCompleted) {
scope.removeSaveCompleted();
}
scope.removeSaveCompleted = scope.$on('saveCompleted', function() {
Wait('stop');
try {
$('#host-modal-dialog').dialog('close');
} catch (err) {
// ignore
}
if (group_scope && group_scope.refreshHosts) {
group_scope.refreshHosts();
}
if (parent_scope.refreshHosts) {
parent_scope.refreshHosts();
}
scope.$destroy();
$state.go('inventoryManage', {}, {
reload: true
});
});
// Save changes to the parent
var saveHost = function() {
Wait('start');
var fld, data = {};
try {
data.variables = ToJSON(scope.parseType, scope.variables, true);
for (fld in form.fields) {
data[fld] = scope[fld];
}
data.inventory = inventory_id;
Rest.setUrl(defaultUrl);
if (mode === 'edit') {
Rest.put(data)
.success(function() {
scope.$emit('saveCompleted');
})
.error(function(data, status) {
ProcessErrors(scope, data, status, form, {
hdr: 'Error!',
msg: 'Failed to update host: ' + host_id + '. PUT returned status: ' + status
});
});
} else {
Rest.post(data)
.success(function() {
scope.$emit('saveCompleted');
})
.error(function(data, status) {
ProcessErrors(scope, data, status, form, {
hdr: 'Error!',
msg: 'Failed to create host. POST returned status: ' + status
});
});
}
} catch (e) {
// ignore. ToJSON will have already alerted the user
}
};
var cancelPanel = function() {
scope.$destroy();
if (scope.codeMirror) {
scope.codeMirror.destroy();
}
$state.go('inventoryManage');
};
angular.extend(vm, {
cancelPanel: cancelPanel,
saveHost: saveHost,
mode: mode,
hostName: hostName
});
}
export default ['$rootScope', '$location', '$log', '$stateParams', '$state', '$scope', 'Rest', 'Alert', 'HostForm',
'GenerateForm', 'Prompt', 'ProcessErrors', 'GetBasePath', 'HostsReload', 'ParseTypeChange',
'Wait', 'Find', 'SetStatus', 'ApplyEllipsis', 'ToJSON', 'ParseVariableString',
'CreateDialog', 'TextareaResize', 'ParamPass', manageHostsDirectiveController
];

View File

@ -1,25 +0,0 @@
/*************************************************
* Copyright (c) 2015 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
/* jshint unused: vars */
import manageHostsDirectiveController from './manage-hosts.directive.controller';
export default ['templateUrl', 'ParamPass',
function(templateUrl, ParamPass) {
return {
restrict: 'EA',
scope: true,
replace: true,
templateUrl: templateUrl('inventories/manage/manage-hosts/directive/manage-hosts.directive'),
link: function(scope, element, attrs) {
},
controller: manageHostsDirectiveController,
controllerAs: 'vm',
bindToController: true
};
}
];

View File

@ -1,20 +0,0 @@
<div>
<div class="Form-header">
<div class="Form-title" ng-if="vm.mode === 'edit'">{{vm.hostName}}</div>
<div class="Form-title" ng-if="vm.mode === 'add'">Create Host</div>
<div class="Form-exitHolder">
<button class="Form-exit" ng-click="vm.cancelPanel()">
<i class="fa fa-times-circle"></i>
</button>
</div>
</div>
<div id="host-panel-form"></div>
<div class="ui-dialog-buttonpane ui-widget-content ui-helper-clearfix">
<div class="ui-dialog-buttonset">
<button type="button" class="btn btn-primary Form-saveButton" id="Inventory-hostManage--okButton" ng-click="vm.saveHost()">
Save</button>
<button type="button" class="btn btn-default Form-cancelButton" id="Inventory-hostManage--cancelButton" ng-click="vm.cancelPanel()">
Cancel</button>
</div>
</div>
</div>

View File

@ -1,16 +1,16 @@
/*************************************************
* Copyright (c) 2015 Ansible, Inc.
* Copyright (c) 2016 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
import route from './manage-hosts.route';
import manageHostsDirective from './directive/manage-hosts.directive';
import {ManageHostsAdd, ManageHostsEdit} from './manage-hosts.route';
import service from './manage-hosts.service';
export default
angular.module('manage-hosts', [])
.directive('manageHosts', manageHostsDirective)
.run(['$stateExtender', function($stateExtender) {
$stateExtender.addState(route.edit);
$stateExtender.addState(route.add);
}]);
angular.module('manageHosts', [])
.service('ManageHostsService', service)
.run(['$stateExtender', function($stateExtender){
$stateExtender.addState(ManageHostsAdd);
$stateExtender.addState(ManageHostsEdit);
}]);

View File

@ -0,0 +1,42 @@
/*************************************************
* Copyright (c) 2016 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
export default
['$state', '$stateParams', '$scope', 'HostForm', 'ParseTypeChange', 'GenerateForm', 'ManageHostsService',
function($state, $stateParams, $scope, HostForm, ParseTypeChange, GenerateForm, ManageHostsService){
var generator = GenerateForm,
form = HostForm;
$scope.parseType = 'yaml';
$scope.extraVars = '---';
$scope.formCancel = function(){
$state.go('^', null, {reload: true});
};
$scope.toggleEnabled = function(){
$scope.host.enabled = !$scope.host.enabled;
};
$scope.formSave = function(){;
var params = {
variables: $scope.extraVars === '---' || $scope.extraVars === '{}' ? null : $scope.extraVars,
name: $scope.name,
description: $scope.description,
enabled: $scope.host.enabled,
inventory: $stateParams.inventory_id
};
ManageHostsService.post(params).then(function(res){
$state.go('^', null, {reload: true});
});
};
var init = function(){
$scope.host = {enabled: true};
generator.inject(form, {mode: 'add', related: false, id: 'Inventory-hostManage--panel', scope: $scope});
ParseTypeChange({
scope: $scope,
field_id: 'host_variables',
variable: 'extraVars',
});
};
init();
}];

View File

@ -0,0 +1,45 @@
/*************************************************
* Copyright (c) 2016 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
export default
['$state', '$stateParams', '$scope', 'HostForm', 'ParseTypeChange', 'GenerateForm', 'ManageHostsService', 'host',
function($state, $stateParams, $scope, HostForm, ParseTypeChange, GenerateForm, ManageHostsService, host){
var generator = GenerateForm,
form = HostForm;
$scope.parseType = 'yaml';
$scope.formCancel = function(){
$state.go('^', null, {reload: true});
};
$scope.toggleHostEnabled = function(){
$scope.host.enabled = !$scope.host.enabled;
};
$scope.formSave = function(){
var host = {
id: $scope.host.id,
variables: $scope.extraVars === '---' || $scope.extraVars === '{}' ? null : $scope.extraVars,
name: $scope.name,
description: $scope.description,
enabled: $scope.host.enabled
};
ManageHostsService.put(host).then(function(res){
$state.go('^', null, {reload: true});
});
};
var init = function(){
$scope.host = host;
$scope.extraVars = host.variables === '' ? '---' : host.variables;
generator.inject(form, {mode: 'edit', related: false, id: 'Inventory-hostManage--panel', scope: $scope});
$scope.extraVars = $scope.host.variables === '' ? '---' : $scope.host.variables;
$scope.name = host.name;
$scope.description = host.description;
ParseTypeChange({
scope: $scope,
field_id: 'host_variables',
variable: 'extraVars',
});
};
init();
}];

View File

@ -1,5 +1,4 @@
<div class="tab-pane" id="Inventory-hostManage">
<div ng-cloak id="Inventory-hostManage--panel" class="Panel">
<manage-hosts></manage-hosts>
</div>
</div>

View File

@ -3,44 +3,47 @@
*
* All Rights Reserved
*************************************************/
import {
templateUrl
} from '../../../shared/template-url/template-url.factory';
import {templateUrl} from '../../../shared/template-url/template-url.factory';
import addController from './manage-hosts-add.controller';
import editController from './manage-hosts-edit.controller';
export default {
edit: {
name: 'inventoryManage.editHost',
route: '/:host_id/editHost',
templateUrl: templateUrl('inventories/manage/manage-hosts/manage-hosts'),
data: {
host_id: 'host_id',
mode: 'edit'
},
ncyBreadcrumb: {
label: "INVENTORY EDIT HOSTS"
},
resolve: {
features: ['FeaturesService', function(FeaturesService) {
return FeaturesService.get();
}]
}
var ManageHostsEdit = {
name: 'inventoryManage.editHost',
route: '/host/:host_id',
controller: editController,
templateUrl: templateUrl('inventories/manage/manage-hosts/manage-hosts'),
ncyBreadcrumb: {
label: "INVENTORY EDIT HOSTS"
},
add: {
name: 'inventoryManage.addHost',
route: '/addHost',
templateUrl: templateUrl('inventories/manage/manage-hosts/manage-hosts'),
data: {
mode: 'add'
},
ncyBreadcrumb: {
label: "INVENTORY ADD HOST"
},
resolve: {
features: ['FeaturesService', function(FeaturesService) {
return FeaturesService.get();
}]
}
data: {
mode: 'edit'
},
resolve: {
features: ['FeaturesService', function(FeaturesService) {
return FeaturesService.get();
}],
host: ['$stateParams', 'ManageHostsService', function($stateParams, ManageHostsService){
return ManageHostsService.get({id: $stateParams.host_id}).then(function(res){
return res.data.results[0];
});
}]
}
};
var ManageHostsAdd = {
name: 'inventoryManage.addHost',
route: '/host/add',
controller: addController,
templateUrl: templateUrl('inventories/manage/manage-hosts/manage-hosts'),
ncyBreadcrumb: {
label: "INVENTORY ADD HOST"
},
data: {
mode: 'add'
},
resolve: {
features: ['FeaturesService', function(FeaturesService) {
return FeaturesService.get();
}]
}
};
export {ManageHostsAdd, ManageHostsEdit};

View File

@ -0,0 +1,53 @@
/*************************************************
* Copyright (c) 2016 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
export default
['$rootScope', 'Rest', 'GetBasePath', 'ProcessErrors',
function($rootScope, Rest, GetBasePath, ProcessErrors){
return {
stringifyParams: function(params){
return _.reduce(params, (result, value, key) => {
return result + key + '=' + value + '&';
}, '');
},
get: function(params){
var url = GetBasePath('hosts') + '?' + this.stringifyParams(params);
Rest.setUrl(url);
return Rest.get()
.success(function(res){
return res;
})
.error(function(data, status) {
ProcessErrors($rootScope, data, status, null, { hdr: 'Error!',
msg: 'Call to ' + url + '. GET returned: ' + status });
});
},
post: function(params){
var url = GetBasePath('hosts');
Rest.setUrl(url);
return Rest.post(params)
.success(function(res){
return res;
})
.error(function(data, status) {
ProcessErrors($rootScope, data, status, null, { hdr: 'Error!',
msg: 'Call to ' + url + '. GET returned: ' + status });
});
},
put: function(host){
var url = GetBasePath('hosts') + host.id;
Rest.setUrl(url);
return Rest.put(host)
.success(function(res){
return res;
})
.error(function(data, status) {
ProcessErrors($rootScope, data, status, null, { hdr: 'Error!',
msg: 'Call to ' + url + '. GET returned: ' + status });
});
}
};
}];