Hooked up copy/move hosts and groups

This commit is contained in:
Michael Abashian 2017-04-25 17:46:11 -04:00 committed by Jared Tabor
parent e435b6505a
commit 9fb8b6579f
11 changed files with 356 additions and 53 deletions

View File

@ -0,0 +1,72 @@
/*************************************************
* Copyright (c) 2016 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
export default
['$scope', '$state', '$stateParams', 'GroupManageService', 'CopyMoveGroupList', 'group', 'Dataset',
function($scope, $state, $stateParams, GroupManageService, CopyMoveGroupList, group, Dataset){
var list = CopyMoveGroupList;
$scope.item = group;
$scope.submitMode = $stateParams.groups === undefined ? 'move' : 'copy';
$scope.toggle_row = function(id){
// toggle off anything else currently selected
_.forEach($scope.groups, (item) => {return item.id === id ? item.checked = 1 : item.checked = null;});
// yoink the currently selected thing
$scope.selected = _.find($scope.groups, (item) => {return item.id === id;});
};
$scope.formCancel = function(){
$state.go('^');
};
$scope.formSave = function(){
switch($scope.submitMode) {
case 'copy':
GroupManageService.associateGroup(group, $scope.selected.id).then(() => $state.go('^', null, {reload: true}));
break;
case 'move':
switch($scope.targetRootGroup){
case true:
// disassociating group will bubble it to the root group level
GroupManageService.disassociateGroup(group.id, _.last($stateParams.group)).then(() => $state.go('^', null, {reload: true}));
break;
default:
// at the root group level, no dissassociation is needed
if (!$stateParams.group){
GroupManageService.associateGroup(group, $scope.selected.id).then(() => $state.go('^', null, {reload: true}));
}
else{
// unsure if orphaned resources get garbage collected, safe bet is to associate before disassociate
GroupManageService.associateGroup(group, $scope.selected.id).then(() => {
GroupManageService.disassociateGroup(group.id, _.last($stateParams.group))
.then(() => $state.go('^', null, {reload: true}));
});
}
break;
}
}
};
$scope.toggleTargetRootGroup = function(){
$scope.selected = !$scope.selected;
// cannot perform copy operations to root group level
$scope.submitMode = 'move';
// toggle off anything currently selected in the list, for clarity
_.forEach($scope.groups, (item) => {item.checked = null;});
// disable list selections
$('#copyMove-list :input').each((idx, el) => {
$(el).prop('disabled', (idx, value) => !value);
});
};
function init(){
$scope.atRootLevel = $stateParams.group ? false : true;
// search init
$scope.list = list;
$scope[`${list.iterator}_dataset`] = Dataset.data;
$scope[list.name] = $scope[`${list.iterator}_dataset`].results;
}
init();
}];

View File

@ -0,0 +1,24 @@
/*************************************************
* Copyright (c) 2015 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
export default {
name: 'groups',
iterator: 'copy',
selectTitle: 'Copy Groups',
index: false,
well: false,
emptyListText: 'PLEASE CREATE ADDITIONAL GROUPS / HOSTS TO PERFORM THIS ACTION',
fields: {
name: {
key: true,
label: 'Target Group Name'
}
},
basePath: 'api/v2/inventories/{{$stateParams.inventory_id}}/groups'
};

View File

@ -0,0 +1,50 @@
/*************************************************
* Copyright (c) 2016 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
export default
['$scope', '$state', '$stateParams', 'HostManageService', 'CopyMoveGroupList', 'host', 'Dataset',
function($scope, $state, $stateParams, HostManageService, CopyMoveGroupList, host, Dataset){
var list = CopyMoveGroupList;
$scope.item = host;
$scope.submitMode = 'copy';
$scope.toggle_row = function(id){
// toggle off anything else currently selected
_.forEach($scope.groups, (item) => {return item.id === id ? item.checked = 1 : item.checked = null;});
// yoink the currently selected thing
$scope.selected = _.find($scope.groups, (item) => {return item.id === id;});
};
$scope.formCancel = function(){
$state.go('^');
};
$scope.formSave = function(){
switch($scope.submitMode) {
case 'copy':
HostManageService.associateGroup(host, $scope.selected.id).then(() => $state.go('^'));
break;
case 'move':
// at the root group level, no dissassociation is needed
if (!$stateParams.group){
HostManageService.associateGroup(host, $scope.selected.id).then(() => $state.go('^', null, {reload: true}));
}
else{
HostManageService.associateGroup(host, $scope.selected.id).then(() => {
HostManageService.disassociateGroup(host, _.last($stateParams.group))
.then(() => $state.go('^', null, {reload: true}));
});
}
break;
}
};
var init = function(){
// search init
$scope.list = list;
$scope[`${list.iterator}_dataset`] = Dataset.data;
$scope[list.name] = $scope[`${list.iterator}_dataset`].results;
};
init();
}];

View File

@ -0,0 +1,33 @@
@import "./client/src/shared/branding/colors.default.less";
#Inventory-copyMovePanel {
.List-searchRow {
width: 50%;
}
.Form-header {
width: 50%;
margin-top: -20px;
}
.Form-saveButton {
&:disabled {
border-color: @default-icon-hov;
}
}
}
.copyMove-choices {
float: right;
width: 25%;
text-align: right;
}
.copyMove-buttons{
height: 30px;
margin-top: 20px;
button {
margin-left: 20px;
}
}
.copyMove-root{
margin-top: 10px;
}

View File

@ -0,0 +1,21 @@
<div class="Panel copyMove-panel">
<div class="Form-header">
<div class="Form-title ng-binding">{{item.name}}</div>
</div>
<div class="form-group copyMove-choices clearfix">
<label class="radio-inline" ng-disabled="atRootLevel || targetRootGroup">
<input type="radio" ng-model="submitMode" value="copy" class="ng-pristine ng-valid ng-touched" ng-disabled="atRootLevel || targetRootGroup"> Copy
</label>
<label class="radio-inline">
<input type="radio" ng-model="submitMode" value="move" class="ng-pristine ng-untouched ng-valid"> Move
</label>
</div>
<div id="copyMove-list" ui-view="copyMoveList"></div>
<div class="copyMove-root form-group pull-left" ng-hide="atRootLevel">
<span><input type="checkbox" ng-model="targetRootGroup" ng-change="toggleTargetRootGroup()"> Use the inventory root</span>
</div>
<div class="copyMove-buttons">
<button type="button" class="pull-right btn btn-sm Form-saveButton" ng-disabled="!selected" ng-click="formSave()">Save</button>
<button type="button" class="pull-right btn btn-sm btn-default Form-cancelButton" ng-click="formCancel()">Cancel</button>
</div>
</div>

View File

@ -0,0 +1,98 @@
/*************************************************
* Copyright (c) 2016 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
import {templateUrl} from '../../shared/template-url/template-url.factory';
import { N_ } from '../../i18n';
import CopyMoveGroupsController from './copy-move-groups.controller';
import CopyMoveHostsController from './copy-move-hosts.controller';
var copyMoveGroupRoute = {
name: 'inventories.edit.groups.copyMoveGroup',
url: '/copy-move-group/{group_id:int}',
searchPrefix: 'copy',
data: {
group_id: 'group_id',
},
params: {
copy_search: {
value: {
not__id__in: null
},
dynamic: true,
squash: ''
}
},
ncyBreadcrumb: {
label: N_("COPY OR MOVE") + " {{item.name}}"
},
resolve: {
Dataset: ['CopyMoveGroupList', 'QuerySet', '$stateParams', 'GetBasePath', 'group',
function(list, qs, $stateParams, GetBasePath, group) {
$stateParams.copy_search.not__id__in = ($stateParams.group && $stateParams.group.length > 0 ? group.id + ',' + _.last($stateParams.group) : group.id.toString());
let path = GetBasePath('inventory') + $stateParams.inventory_id + '/groups/';
return qs.search(path, $stateParams.copy_search);
}
],
group: ['GroupManageService', '$stateParams', function(GroupManageService, $stateParams){
return GroupManageService.get({id: $stateParams.group_id}).then(res => res.data.results[0]);
}]
},
views: {
'copyMove@inventories' : {
controller: CopyMoveGroupsController,
templateUrl: templateUrl('inventories/copy-move/copy-move'),
},
'copyMoveList@inventories.edit.groups.copyMoveGroup': {
templateProvider: function(CopyMoveGroupList, generateList) {
let html = generateList.build({
list: CopyMoveGroupList,
mode: 'lookup',
input_type: 'radio'
});
return html;
}
}
}
};
var copyMoveHostRoute = {
name: 'inventories.edit.hosts.copyMoveHost',
url: '/copy-move-host/{host_id}',
searchPrefix: 'copy',
ncyBreadcrumb: {
label: N_("COPY OR MOVE") + " {{item.name}}"
},
resolve: {
Dataset: ['CopyMoveGroupList', 'QuerySet', '$stateParams', 'GetBasePath',
function(list, qs, $stateParams, GetBasePath) {
let path = GetBasePath('inventory') + $stateParams.inventory_id + '/groups/';
return qs.search(path, $stateParams.copy_search);
}
],
host: ['HostManageService', '$stateParams', function(HostManageService, $stateParams){
return HostManageService.get({id: $stateParams.host_id}).then(res => res.data.results[0]);
}]
},
views: {
'copyMove@inventories': {
templateUrl: templateUrl('inventories/copy-move/copy-move'),
controller: CopyMoveHostsController,
},
'copyMoveList@inventories.edit.hosts.copyMoveHost': {
templateProvider: function(CopyMoveGroupList, generateList, $stateParams, GetBasePath) {
let list = CopyMoveGroupList;
list.basePath = GetBasePath('inventory') + $stateParams.inventory_id + '/groups/';
let html = generateList.build({
list: CopyMoveGroupList,
mode: 'lookup',
input_type: 'radio'
});
return html;
}
}
}
};
export {copyMoveGroupRoute, copyMoveHostRoute};

View File

@ -0,0 +1,15 @@
/*************************************************
* Copyright (c) 2015 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
import CopyMoveGroupsController from './copy-move-groups.controller';
import CopyMoveHostsController from './copy-move-hosts.controller';
import CopyMoveGroupList from './copy-move-groups.list';
export default
angular.module('manageCopyMove', [])
.controller('CopyMoveGroupsController', CopyMoveGroupsController)
.controller('CopyMoveHostsController', CopyMoveHostsController)
.value('CopyMoveGroupList', CopyMoveGroupList);

View File

@ -194,7 +194,7 @@
};
$scope.copyMoveGroup = function(id){
// TODO: implement
$state.go('inventories.edit.groups.copyMoveGroup', {group_id: id, groups: $stateParams.groups});
};
var cleanUpStateChangeListener = $rootScope.$on('$stateChangeSuccess', function(event, toState, toParams) {

View File

@ -1,4 +1,5 @@
<div class="tab-pane" id="inventories-panel">
<div ui-view="copyMove"></div>
<div ui-view="adhocForm"></div>
<div ui-view="groupForm"></div>
<div ui-view="hostForm"></div>

View File

@ -20,6 +20,8 @@ import InventoryForm from './inventory.form';
import InventoryManageService from './inventory-manage.service';
import adHocRoute from './adhoc/adhoc.route';
import ansibleFacts from './ansible_facts/main';
import { copyMoveGroupRoute, copyMoveHostRoute } from './copy-move/copy-move.route';
import copyMove from './copy-move/main';
export default
angular.module('inventory', [
adhoc.name,
@ -31,7 +33,8 @@ angular.module('inventory', [
inventoryAdd.name,
inventoryEdit.name,
inventoryList.name,
ansibleFacts.name
ansibleFacts.name,
copyMove.name
])
.factory('InventoryForm', InventoryForm)
.factory('InventoryList', InventoryList)
@ -41,6 +44,34 @@ angular.module('inventory', [
let stateDefinitions = stateDefinitionsProvider.$get(),
stateExtender = $stateExtenderProvider.$get();
function factsConfig(stateName) {
return {
name: stateName,
url: '/ansible_facts',
ncyBreadcrumb: {
label: N_("FACTS")
},
views: {
'related': {
controller: 'AnsibleFactsController',
templateUrl: templateUrl('inventories/ansible_facts/ansible_facts')
}
},
resolve: {
Facts: ['$stateParams', 'GetBasePath', 'Rest',
function($stateParams, GetBasePath, Rest) {
let ansibleFactsUrl = GetBasePath('hosts') + $stateParams.host_id + '/ansible_facts';
Rest.setUrl(ansibleFactsUrl);
return Rest.get()
.success(function(data) {
return data;
});
}
]
}
};
}
function generateInventoryStates() {
let basicInventoryAdd = stateDefinitions.generateTree({
@ -224,31 +255,7 @@ angular.module('inventory', [
}
};
let relatedHostsAnsibleFacts = {
name: 'inventories.edit.hosts.edit.ansible_facts',
url: '/ansible_facts',
ncyBreadcrumb: {
label: N_("FACTS")
},
views: {
'related': {
controller: 'AnsibleFactsController',
templateUrl: templateUrl('inventories/ansible_facts/ansible_facts')
}
},
resolve: {
Facts: ['$stateParams', 'GetBasePath', 'Rest',
function($stateParams, GetBasePath, Rest) {
let ansibleFactsUrl = GetBasePath('hosts') + $stateParams.host_id + '/ansible_facts';
Rest.setUrl(ansibleFactsUrl);
return Rest.get()
.success(function(data) {
return data;
});
}
]
}
};
let relatedHostsAnsibleFacts = factsConfig('inventories.edit.hosts.edit.ansible_facts');
return Promise.all([
basicInventoryAdd,
@ -296,7 +303,9 @@ angular.module('inventory', [
stateExtender.buildDefinition(listSchedules),
stateExtender.buildDefinition(addSchedule),
stateExtender.buildDefinition(editSchedule),
stateExtender.buildDefinition(relatedHostsAnsibleFacts)
stateExtender.buildDefinition(relatedHostsAnsibleFacts),
stateExtender.buildDefinition(copyMoveGroupRoute),
stateExtender.buildDefinition(copyMoveHostRoute)
])
};
});
@ -347,31 +356,7 @@ angular.module('inventory', [
}
});
let hostAnsibleFacts = {
name: 'hosts.edit.ansible_facts',
url: '/ansible_facts',
ncyBreadcrumb: {
label: N_("FACTS")
},
views: {
'related': {
controller: 'AnsibleFactsController',
templateUrl: templateUrl('inventories/ansible_facts/ansible_facts')
}
},
resolve: {
Facts: ['$stateParams', 'GetBasePath', 'Rest',
function($stateParams, GetBasePath, Rest) {
let ansibleFactsUrl = GetBasePath('hosts') + $stateParams.host_id + '/ansible_facts';
Rest.setUrl(ansibleFactsUrl);
return Rest.get()
.success(function(data) {
return data;
});
}
]
}
};
let hostAnsibleFacts = factsConfig('hosts.edit.ansible_facts');
return Promise.all([
hostTree

View File

@ -156,4 +156,8 @@ export default ['$scope', 'RelatedHostsListDefinition', '$rootScope', 'GetBasePa
$state.go('^.adhoc', {pattern: pattern});
};
$scope.copyMoveHost = function(id) {
$state.go('inventories.edit.hosts.copyMoveHost', {host_id: id});
};
}];