diff --git a/awx/ui/client/src/helpers/Hosts.js b/awx/ui/client/src/helpers/Hosts.js
index 6a7b864e02..e6730f1dd2 100644
--- a/awx/ui/client/src/helpers/Hosts.js
+++ b/awx/ui/client/src/helpers/Hosts.js
@@ -825,7 +825,9 @@ return function(params) {
scope.name = host.name;
scope.copy_choice = "copy";
d = angular.element(document.getElementById('host-copy-dialog'));
+ console.info('hosts helper compile scope', d, scope);
$compile(d)(scope);
+ console.info('compiled', $compile(d)(scope));
CreateDialog({
id: 'host-copy-dialog',
scope: scope,
diff --git a/awx/ui/client/src/inventories/manage/copy/copy-groups-directive/copy-groups.directive.controller.js b/awx/ui/client/src/inventories/manage/copy/copy-groups-directive/copy-groups.directive.controller.js
new file mode 100644
index 0000000000..f0a1149726
--- /dev/null
+++ b/awx/ui/client/src/inventories/manage/copy/copy-groups-directive/copy-groups.directive.controller.js
@@ -0,0 +1,303 @@
+function copyGroupsDirectiveController($compile, $state, $scope, $location, Rest, ProcessErrors, CreateDialog,
+ GetBasePath, Wait, GenerateList, GroupList, SearchInit, PaginateInit, GetRootGroups, ParamPass, Store) {
+ var vm = this;
+ var name;
+
+ var params = ParamPass.get();
+
+ if (params !== undefined) {
+ var group_id = $state.params.group_id,
+ parent_scope = params.scope,
+ scope = parent_scope.$new(),
+ parent_group = parent_scope.selected_group_id,
+ url, group;
+ } else {
+ var group_id = $state.params.group_id;
+ var parent_scope = $scope.$new();
+ var scope = parent_scope.$new();
+ }
+
+ var inventory_id = $state.params.inventory_id;
+ var PreviousSearchParams = Store('group_current_search_params');
+
+ if (scope.removeGroupsCopyPostRefresh) {
+ scope.removeGroupsCopyPostRefresh();
+ }
+
+ scope.removeGroupCopyPostRefresh = scope.$on('PostRefresh', function() {
+ scope.copy_groups.forEach(function(row, i) {
+ scope.copy_groups[i].checked = '0';
+ });
+ Wait('stop');
+
+ // prevent backspace from navigation when not in input or textarea field
+ $(document).on('keydown', function(e) {
+ if (e.which === 8 && !$(e.target).is('input[type="text"], textarea')) {
+ e.preventDefault();
+ }
+ });
+
+ });
+
+ if (scope.removeCopyDialogReady) {
+ scope.removeCopyDialogReady();
+ }
+
+ scope.removeCopyDialogReady = scope.$on('CopyDialogReady', function() {
+ var url = GetBasePath('inventory') + inventory_id + '/groups/';
+ url += (parent_group) ? '?not__id__in=' + group_id + ',' + parent_group : '?not__id=' + group_id;
+ GenerateList.inject(GroupList, {
+ mode: 'lookup',
+ id: 'copyMove-directive--copyGroupSelect',
+ scope: scope
+ });
+ SearchInit({
+ scope: scope,
+ set: GroupList.name,
+ list: GroupList,
+ url: url
+ });
+ PaginateInit({
+ scope: scope,
+ list: GroupList,
+ url: url,
+ mode: 'lookup'
+ });
+ scope.search(GroupList.iterator);
+ });
+
+ if (scope.removeShowDialog) {
+ scope.removeShowDialog();
+ }
+
+ scope.removeShowDialog = scope.$on('ShowDialog', function() {
+ var d;
+ scope.name = group.name;
+ scope.copy_choice = "copy";
+ d = angular.element(document.getElementById('copyMove-directive--copyGroupSelect'));
+ $compile(d)(scope);
+ scope.$emit('CopyDialogReady');
+ });
+
+ if (scope.removeRootGroupsReady) {
+ scope.removeRootGroupsReady();
+ }
+
+ scope.removeRootGroupsReady = scope.$on('RootGroupsReady', function(e, root_groups) {
+ scope.offer_root_group = true;
+ scope.use_root_group = false;
+ root_groups.every(function(row) {
+ if (row.id === group_id) {
+ scope.offer_root_group = false;
+ return false;
+ }
+ return true;
+ });
+ url = GetBasePath('groups') + group_id + '/';
+ Rest.setUrl(url);
+ Rest.get()
+ .success(function(data) {
+ group = data;
+ vm.name = group.name;
+ scope.$emit('ShowDialog');
+ })
+ .error(function(data, status) {
+ ProcessErrors(scope, data, status, null, {
+ hdr: 'Error!',
+ msg: 'Call to ' + url + ' failed. GET returned: ' + status
+ });
+ });
+ });
+
+ Wait('start');
+
+ GetRootGroups({
+ scope: scope,
+ group_id: group_id,
+ inventory_id: $state.params.inventory_id,
+ callback: 'RootGroupsReady'
+ });
+
+ var restoreSearch = function() {
+ // Restore search params and related stuff, plus refresh
+ // groups and hosts lists
+ SearchInit({
+ scope: $scope,
+ set: PreviousSearchParams.set,
+ list: PreviousSearchParams.list,
+ url: PreviousSearchParams.defaultUrl,
+ iterator: PreviousSearchParams.iterator,
+ sort_order: PreviousSearchParams.sort_order,
+ setWidgets: false
+ });
+ $scope.refreshHostsOnGroupRefresh = true;
+ //$scope.search(InventoryGroups.iterator, null, true, false, true);
+ }
+
+ var cancel = function() {
+ restoreSearch(); // Restore all parent search stuff and refresh hosts and groups lists
+ scope.$destroy();
+ $state.go('inventoryManage', {}, {
+ reload: true
+ });
+ };
+
+ var allowSave = false;
+ scope['toggle_' + GroupList.iterator] = function(id) {
+ var count = 0,
+ list = GroupList;
+ scope[list.name].forEach(function(row, i) {
+ if (row.id === id) {
+ if (row.checked) {
+ scope[list.name][i].success_class = 'success';
+ } else {
+ scope[list.name][i].success_class = '';
+ }
+ } else {
+ scope[list.name][i].checked = 0;
+ scope[list.name][i].success_class = '';
+ }
+ });
+ // Check if any rows are checked
+ scope[list.name].forEach(function(row) {
+ if (row.checked) {
+ count++;
+ }
+ });
+ if (count === 0) {
+ vm.allowSave = false;
+ } else {
+ vm.allowSave = true;
+ }
+ };
+
+ scope.toggleUseRootGroup = function() {
+ var list = GroupList;
+ if (scope.use_root_group) {
+ $('#group-copy-ok-button').removeAttr('disabled');
+ } else {
+ // check for group selection
+ $('#group-copy-ok-button').attr('disabled', 'disabled');
+ scope[list.name].every(function(row) {
+ if (row.checked === 1) {
+ $('#group-copy-ok-button').removeAttr('disabled');
+ return false;
+ }
+ return true;
+ });
+ }
+ };
+
+ var performCopy = function() {
+ var list = GroupList,
+ target,
+ url;
+
+ Wait('start');
+
+ if (scope.use_root_group) {
+ target = null;
+ } else {
+ scope[list.name].every(function(row) {
+ if (row.checked === 1) {
+ target = row;
+ return false;
+ }
+ return true;
+ });
+ }
+
+ if (vm.copy_choice === 'move') {
+ // Respond to move
+
+ // disassociate the group from the original parent
+ if (scope.removeGroupRemove) {
+ scope.removeGroupRemove();
+ }
+ scope.removeGroupRemove = scope.$on('RemoveGroup', function() {
+ if (parent_group > 0) {
+ // Only remove a group from a parent when the parent is a group and not the inventory root
+ url = GetBasePath('groups') + parent_group + '/children/';
+ Rest.setUrl(url);
+ Rest.post({
+ id: group.id,
+ disassociate: 1
+ })
+ .success(function() {
+ vm.cancel();
+ })
+ .error(function(data, status) {
+ ProcessErrors(scope, data, status, null, {
+ hdr: 'Error!',
+ msg: 'Failed to remove ' + group.name + ' from group ' + parent_group + '. POST returned: ' + status
+ });
+ });
+ } else {
+ vm.cancel();
+ }
+ });
+
+ // add the new group to the target
+ url = (target) ?
+ GetBasePath('groups') + target.id + '/children/' :
+ GetBasePath('inventory') + inventory_id + '/groups/';
+ group = {
+ id: group.id,
+ name: group.name,
+ description: group.description,
+ inventory: inventory_id
+ };
+ Rest.setUrl(url);
+ Rest.post(group)
+ .success(function() {
+ scope.$emit('RemoveGroup');
+ })
+ .error(function(data, status) {
+ var target_name = (target) ? target.name : 'inventory';
+ ProcessErrors(scope, data, status, null, {
+ hdr: 'Error!',
+ msg: 'Failed to add ' + group.name + ' to ' + target_name + '. POST returned: ' + status
+ });
+ });
+ } else {
+ // Respond to copy by adding the new group to the target
+ url = (target) ?
+ GetBasePath('groups') + target.id + '/children/' :
+ GetBasePath('inventory') + inventory_id + '/groups/';
+
+ group = {
+ id: group.id,
+ name: group.name,
+ description: group.description,
+ inventory: inventory_id
+ };
+
+ Rest.setUrl(url);
+ Rest.post(group)
+ .success(function() {
+ vm.cancel();
+ })
+ .error(function(data, status) {
+ var target_name = (target) ? target.name : 'inventory';
+ ProcessErrors(scope, data, status, null, {
+ hdr: 'Error!',
+ msg: 'Failed to add ' + group.name + ' to ' + target_name + '. POST returned: ' + status
+ });
+ });
+ }
+ };
+
+ var copy_choice = 'copy';
+
+ angular.extend(vm, {
+ cancel: cancel,
+ performCopy: performCopy,
+ copy_choice: copy_choice,
+ name: name,
+ allowSave: allowSave
+ });
+};
+
+export default ['$compile', '$state', '$scope', '$location', 'Rest', 'ProcessErrors', 'CreateDialog', 'GetBasePath', 'Wait', 'generateList', 'GroupList', 'SearchInit',
+ 'PaginateInit', 'GetRootGroups', 'ParamPass', 'Store', copyGroupsDirectiveController
+];
diff --git a/awx/ui/client/src/inventories/manage/copy/copy-groups-directive/copy-groups.directive.js b/awx/ui/client/src/inventories/manage/copy/copy-groups-directive/copy-groups.directive.js
new file mode 100644
index 0000000000..f71cba7158
--- /dev/null
+++ b/awx/ui/client/src/inventories/manage/copy/copy-groups-directive/copy-groups.directive.js
@@ -0,0 +1,25 @@
+/*************************************************
+ * Copyright (c) 2015 Ansible, Inc.
+ *
+ * All Rights Reserved
+ *************************************************/
+
+/* jshint unused: vars */
+import copyGroupsDirectiveController from './copy-groups.directive.controller';
+
+export default ['templateUrl',
+ function(templateUrl) {
+ return {
+ restrict: 'EA',
+ scope: true,
+ replace: true,
+ templateUrl: templateUrl('inventories/manage/copy/copy-groups-directive/copy-groups.directive'),
+ link: function(scope, element, attrs) {
+
+ },
+ controller: copyGroupsDirectiveController,
+ controllerAs: 'vm',
+ bindToController: true
+ };
+ }
+];
diff --git a/awx/ui/client/src/inventories/manage/copy/copy-groups-directive/copy-groups.directive.partial.html b/awx/ui/client/src/inventories/manage/copy/copy-groups-directive/copy-groups.directive.partial.html
new file mode 100644
index 0000000000..d82ca6956f
--- /dev/null
+++ b/awx/ui/client/src/inventories/manage/copy/copy-groups-directive/copy-groups.directive.partial.html
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/awx/ui/client/src/inventories/manage/copy/copy-hosts-directive/copy-hosts.directive.controller.js b/awx/ui/client/src/inventories/manage/copy/copy-hosts-directive/copy-hosts.directive.controller.js
new file mode 100644
index 0000000000..bf596c5cef
--- /dev/null
+++ b/awx/ui/client/src/inventories/manage/copy/copy-hosts-directive/copy-hosts.directive.controller.js
@@ -0,0 +1,238 @@
+function copyHostsDirectiveController($compile, $state, $scope, Rest, ProcessErrors, CreateDialog, GetBasePath, Wait, GenerateList, GroupList, SearchInit, PaginateInit, ParamPass, Store) {
+ var vm = this;
+ var name;
+
+ var host_id = $state.params.host_id;
+ var inventory_id = $state.params.inventory_id;
+ var url, host;
+
+ var params = ParamPass.get();
+ if (params !== undefined) {
+ var group_scope = params.group_scope,
+ parent_scope = params.host_scope,
+ parent_group = group_scope.selected_group_id,
+ scope = parent_scope.$new();
+ } else {
+ var group_scope = $scope.$new();
+ var parent_scope = $scope.$new();
+ var scope = parent_scope.$new();
+ }
+
+ var PreviousSearchParams = Store('group_current_search_params');
+
+ if (scope.removeHostCopyPostRefresh) {
+ scope.removeHostCopyPostRefresh();
+ }
+ scope.removeHostCopyPostRefresh = scope.$on('PostRefresh', function() {
+ scope.copy_groups.forEach(function(row, i) {
+ scope.copy_groups[i].checked = '0';
+ });
+ Wait('stop');
+ // prevent backspace from navigation when not in input or textarea field
+ $(document).on("keydown", function(e) {
+ if (e.which === 8 && !$(e.target).is('input[type="text"], textarea')) {
+ e.preventDefault();
+ }
+ });
+ });
+
+ if (scope.removeHostCopyDialogReady) {
+ scope.removeHostCopyDialogReady();
+ }
+ scope.removeCopyDialogReady = scope.$on('HostCopyDialogReady', function() {
+ var url = GetBasePath('inventory') + inventory_id + '/groups/';
+ GenerateList.inject(GroupList, {
+ mode: 'lookup',
+ id: 'copyMove-directive--copyHostSelect',
+ scope: scope
+ //,
+ //instructions: instructions
+ });
+ SearchInit({
+ scope: scope,
+ set: GroupList.name,
+ list: GroupList,
+ url: url
+ });
+ PaginateInit({
+ scope: scope,
+ list: GroupList,
+ url: url,
+ mode: 'lookup'
+ });
+ scope.search(GroupList.iterator, null, true, false);
+ });
+
+ if (scope.removeShowDialog) {
+ scope.removeShowDialog();
+ }
+ scope.removeShowDialog = scope.$on('ShowDialog', function() {
+ var d;
+ scope.name = host.name;
+ d = angular.element(document.getElementById('copyMove-directive--copyHostPanel'));
+ $compile(d)(scope);
+ scope.$emit('HostCopyDialogReady');
+ });
+
+ Wait('start');
+
+ url = GetBasePath('hosts') + host_id + '/';
+ Rest.setUrl(url);
+ Rest.get()
+ .success(function(data) {
+ host = data;
+ vm.name = host.name;
+ scope.$emit('ShowDialog');
+ })
+ .error(function(data, status) {
+ ProcessErrors(scope, data, status, null, {
+ hdr: 'Error!',
+ msg: 'Call to ' + url + ' failed. GET returned: ' + status
+ });
+ });
+
+ var cancel = function() {
+ $(document).off("keydown");
+ restoreSearch(); // Restore all parent search stuff and refresh hosts and groups lists
+ scope.$destroy();
+ $state.go('inventoryManage', {}, {
+ reload: true
+ });
+ };
+
+ var allowSave = false;
+ scope['toggle_' + GroupList.iterator] = function(id) {
+ var count = 0,
+ list = GroupList;
+ scope[list.name].forEach(function(row, i) {
+ if (row.id === id) {
+ if (row.checked) {
+ scope[list.name][i].success_class = 'success';
+ } else {
+ scope[list.name][i].success_class = '';
+ }
+ } else {
+ scope[list.name][i].checked = 0;
+ scope[list.name][i].success_class = '';
+ }
+ });
+ // Check if any rows are checked
+ scope[list.name].forEach(function(row) {
+ if (row.checked) {
+ count++;
+ }
+ });
+ if (count === 0) {
+ vm.allowSave = false;
+ } else {
+ vm.allowSave = true;
+ }
+ };
+
+ var restoreSearch = function() {
+ // Restore search params and related stuff, plus refresh
+ // groups and hosts lists
+ SearchInit({
+ scope: $scope,
+ set: PreviousSearchParams.set,
+ list: PreviousSearchParams.list,
+ url: PreviousSearchParams.defaultUrl,
+ iterator: PreviousSearchParams.iterator,
+ sort_order: PreviousSearchParams.sort_order,
+ setWidgets: false
+ });
+ $scope.refreshHostsOnGroupRefresh = true;
+ }
+
+ var performCopy = function() {
+ var list = GroupList,
+ target,
+ url;
+
+ Wait('start');
+
+ if (scope.use_root_group) {
+ target = null;
+ } else {
+ scope[list.name].every(function(row) {
+ if (row.checked === 1) {
+ target = row;
+ return false;
+ }
+ return true;
+ });
+ }
+
+ if (vm.copy_choice === 'move') {
+ // Respond to move
+ // disassociate the host from the original parent
+ if (scope.removeHostRemove) {
+ scope.removeHostRemove();
+ }
+ scope.removeHostRemove = scope.$on('RemoveHost', function() {
+ if (parent_group > 0) {
+ // Only remove a host from a parent when the parent is a group and not the inventory root
+ url = GetBasePath('groups') + parent_group + '/hosts/';
+ Rest.setUrl(url);
+ Rest.post({
+ id: host.id,
+ disassociate: 1
+ })
+ .success(function() {
+ vm.cancel();
+ })
+ .error(function(data, status) {
+ ProcessErrors(scope, data, status, null, {
+ hdr: 'Error!',
+ msg: 'Failed to remove ' + host.name + ' from group ' + parent_group + '. POST returned: ' + status
+ });
+ });
+ } else {
+ vm.cancel();
+ }
+ });
+
+ // add the new host to the target
+ url = GetBasePath('groups') + target.id + '/hosts/';
+ Rest.setUrl(url);
+ Rest.post(host)
+ .success(function() {
+ scope.$emit('RemoveHost');
+ })
+ .error(function(data, status) {
+ ProcessErrors(scope, data, status, null, {
+ hdr: 'Error!',
+ msg: 'Failed to add ' + host.name + ' to ' + target.name + '. POST returned: ' + status
+ });
+ });
+ } else {
+ // Respond to copy by adding the new host to the target
+ url = GetBasePath('groups') + target.id + '/hosts/';
+ Rest.setUrl(url);
+ Rest.post(host)
+ .success(function() {
+ vm.cancel();
+ })
+ .error(function(data, status) {
+ ProcessErrors(scope, data, status, null, {
+ hdr: 'Error!',
+ msg: 'Failed to add ' + host.name + ' to ' + target.name + '. POST returned: ' + status
+ });
+ });
+ }
+ };
+
+
+ var copy_choice = 'copy';
+
+ angular.extend(vm, {
+ copy_choice: copy_choice,
+ name: name,
+ cancel: cancel,
+ allowSave: allowSave
+ })
+};
+
+export default ['$compile', '$state', '$scope', 'Rest', 'ProcessErrors', 'CreateDialog', 'GetBasePath', 'Wait', 'generateList', 'GroupList', 'SearchInit',
+ 'PaginateInit', 'ParamPass', 'Store', copyHostsDirectiveController
+];
diff --git a/awx/ui/client/src/inventories/manage/copy/copy-hosts-directive/copy-hosts.directive.js b/awx/ui/client/src/inventories/manage/copy/copy-hosts-directive/copy-hosts.directive.js
new file mode 100644
index 0000000000..794a932012
--- /dev/null
+++ b/awx/ui/client/src/inventories/manage/copy/copy-hosts-directive/copy-hosts.directive.js
@@ -0,0 +1,25 @@
+/*************************************************
+ * Copyright (c) 2015 Ansible, Inc.
+ *
+ * All Rights Reserved
+ *************************************************/
+
+/* jshint unused: vars */
+import copyHostsDirectiveController from './copy-hosts.directive.controller';
+
+export default ['templateUrl',
+ function(templateUrl) {
+ return {
+ restrict: 'EA',
+ scope: true,
+ replace: true,
+ templateUrl: templateUrl('inventories/manage/copy/copy-hosts-directive/copy-hosts.directive'),
+ link: function(scope, element, attrs) {
+
+ },
+ controller: copyHostsDirectiveController,
+ controllerAs: 'vm',
+ bindToController: true
+ };
+ }
+];
diff --git a/awx/ui/client/src/inventories/manage/copy/copy-hosts-directive/copy-hosts.directive.partial.html b/awx/ui/client/src/inventories/manage/copy/copy-hosts-directive/copy-hosts.directive.partial.html
new file mode 100644
index 0000000000..aa2990434a
--- /dev/null
+++ b/awx/ui/client/src/inventories/manage/copy/copy-hosts-directive/copy-hosts.directive.partial.html
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/awx/ui/client/src/inventories/manage/copy/copy.block.less b/awx/ui/client/src/inventories/manage/copy/copy.block.less
new file mode 100644
index 0000000000..34b93417f6
--- /dev/null
+++ b/awx/ui/client/src/inventories/manage/copy/copy.block.less
@@ -0,0 +1,30 @@
+@import "awx/ui/client/src/shared/branding/colors.default.less";
+
+#Inventory-copyMovePanel {
+ .List-searchRow {
+ width: 50%;
+ }
+
+ .ui-dialog-buttonpane.ui-widget-content {
+ border: none;
+ text-align: right;
+ margin-top: 15px;
+ }
+
+ .Form-header {
+ width: 50%;
+ margin-top: -20px;
+ }
+
+ .Form-saveButton {
+ &:disabled {
+ border-color: @default-icon-hov;
+ }
+ }
+}
+
+.copyMove-directive--copyMoveChoices {
+ float: right;
+ width: 25%;
+ text-align: right;
+}
diff --git a/awx/ui/client/src/inventories/manage/copy/copy.controller.js b/awx/ui/client/src/inventories/manage/copy/copy.controller.js
new file mode 100644
index 0000000000..f16525d057
--- /dev/null
+++ b/awx/ui/client/src/inventories/manage/copy/copy.controller.js
@@ -0,0 +1,16 @@
+function inventoryManageCopyCtrl($state) {
+ var vm = this;
+
+ var cancelPanel = function() {
+ $state.go('inventoryManage', {}, {
+ reload: true
+ })
+ };
+
+ angular.extend(vm, {
+ cancelPanel: cancelPanel
+ });
+};
+
+export default ['$state', inventoryManageCopyCtrl
+];
diff --git a/awx/ui/client/src/inventories/manage/copy/copy.partial.html b/awx/ui/client/src/inventories/manage/copy/copy.partial.html
new file mode 100644
index 0000000000..ff19016e98
--- /dev/null
+++ b/awx/ui/client/src/inventories/manage/copy/copy.partial.html
@@ -0,0 +1,10 @@
+
diff --git a/awx/ui/client/src/inventories/manage/copy/copy.route.js b/awx/ui/client/src/inventories/manage/copy/copy.route.js
new file mode 100644
index 0000000000..cd1f58d6cb
--- /dev/null
+++ b/awx/ui/client/src/inventories/manage/copy/copy.route.js
@@ -0,0 +1,61 @@
+/*************************************************
+ * Copyright (c) 2016 Ansible, Inc.
+ *
+ * All Rights Reserved
+ *************************************************/
+import {
+ templateUrl
+} from '../../../shared/template-url/template-url.factory';
+
+import inventoryManageCopyCtrl from './copy.controller';
+
+export default {
+ copy: {
+ name: 'inventoryManage.copy',
+ route: '/copy',
+ templateUrl: templateUrl('inventories/manage/copy/copy'),
+ ncyBreadcrumb: {
+ label: "COPY"
+ },
+ resolve: {
+ features: ['FeaturesService', function(FeaturesService) {
+ return FeaturesService.get();
+ }],
+ },
+ controller: inventoryManageCopyCtrl,
+ controllerAs: 'vm',
+ bindToController: true,
+ },
+ copyGroup: {
+ name: 'inventoryManage.copy.group',
+ route: '/group/:group_id?groups',
+ template: '
',
+ data: {
+ group_id: 'group_id',
+ },
+ ncyBreadcrumb: {
+ label: "GROUP"
+ },
+ resolve: {
+ features: ['FeaturesService', function(FeaturesService) {
+ return FeaturesService.get();
+ }]
+ }
+ },
+ copyHost: {
+ name: 'inventoryManage.copy.host',
+ route: '/host/:host_id?groups',
+ template: '
',
+ data: {
+ host_id: 'host_id',
+ },
+ ncyBreadcrumb: {
+ label: "HOST"
+ },
+ resolve: {
+ features: ['FeaturesService', function(FeaturesService) {
+ return FeaturesService.get();
+ }]
+ }
+ }
+};
diff --git a/awx/ui/client/src/inventories/manage/copy/main.js b/awx/ui/client/src/inventories/manage/copy/main.js
new file mode 100644
index 0000000000..f6da96f0a0
--- /dev/null
+++ b/awx/ui/client/src/inventories/manage/copy/main.js
@@ -0,0 +1,19 @@
+/*************************************************
+ * Copyright (c) 2015 Ansible, Inc.
+ *
+ * All Rights Reserved
+ *************************************************/
+
+import route from './copy.route';
+import copyGroupsDirective from './copy-groups-directive/copy-groups.directive';
+import copyHostsDirective from './copy-hosts-directive/copy-hosts.directive';
+
+export default
+angular.module('inventory-copy', [])
+ .directive('copyGroups', copyGroupsDirective)
+ .directive('copyHosts', copyHostsDirective)
+ .run(['$stateExtender', function($stateExtender) {
+ $stateExtender.addState(route.copy);
+ $stateExtender.addState(route.copyGroup);
+ $stateExtender.addState(route.copyHost);
+ }]);
diff --git a/awx/ui/client/src/inventories/manage/inventory-manage.controller.js b/awx/ui/client/src/inventories/manage/inventory-manage.controller.js
index 508a74d4c2..ac64e2137a 100644
--- a/awx/ui/client/src/inventories/manage/inventory-manage.controller.js
+++ b/awx/ui/client/src/inventories/manage/inventory-manage.controller.js
@@ -309,6 +309,7 @@ function InventoriesManage($log, $scope, $rootScope, $location,
$scope.restoreSearch = function() {
// Restore search params and related stuff, plus refresh
// groups and hosts lists
+ console.info('the set', PreviousSearchParams.set);
SearchInit({
scope: $scope,
set: PreviousSearchParams.set,
@@ -400,10 +401,16 @@ function InventoriesManage($log, $scope, $rootScope, $location,
$scope.copyGroup = function(id) {
PreviousSearchParams = Store('group_current_search_params');
- GroupsCopy({
- scope: $scope,
- group_id: id
- });
+ // GroupsCopy({
+ // scope: $scope,
+ // group_id: id
+ // });
+ var params = {
+ scope: $scope
+ }
+ ParamPass.set(params);
+ $location.search('groups', null);
+ $state.go('inventoryManage.copy.group', {group_id: id});
};
$scope.deleteGroup = function (id) {
@@ -455,11 +462,21 @@ function InventoriesManage($log, $scope, $rootScope, $location,
hostScope.copyHost = function(id) {
PreviousSearchParams = Store('group_current_search_params');
- HostsCopy({
- group_scope: $scope,
- host_scope: hostScope,
- host_id: id
- });
+ // HostsCopy({
+ // group_scope: $scope,
+ // host_scope: hostScope,
+ // host_id: id
+ // });
+
+ var params = {
+ group_scope: $scope,
+ host_scope: hostScope,
+ host_id: id
+ }
+
+ ParamPass.set(params);
+
+ $state.go('inventoryManage.copy.host', {host_id: id});
};
hostScope.toggleHostEnabled = function (host_id, external_source) {
diff --git a/awx/ui/client/src/inventories/manage/main.js b/awx/ui/client/src/inventories/manage/main.js
index 075ba36887..435db696f7 100644
--- a/awx/ui/client/src/inventories/manage/main.js
+++ b/awx/ui/client/src/inventories/manage/main.js
@@ -8,11 +8,13 @@ import route from './inventory-manage.route';
import manageHosts from './manage-hosts/main';
import manageGroups from './manage-groups/main';
+import copy from './copy/main';
export default
angular.module('inventoryManage', [
manageHosts.name,
- manageGroups.name
+ manageGroups.name,
+ copy.name,
])
.run(['$stateExtender', function($stateExtender) {
$stateExtender.addState(route);
diff --git a/awx/ui/client/src/inventories/manage/manage-hosts/directive/manage-hosts.directive.controller.js b/awx/ui/client/src/inventories/manage/manage-hosts/directive/manage-hosts.directive.controller.js
index b14bed39e6..c44ee6cdea 100644
--- a/awx/ui/client/src/inventories/manage/manage-hosts/directive/manage-hosts.directive.controller.js
+++ b/awx/ui/client/src/inventories/manage/manage-hosts/directive/manage-hosts.directive.controller.js
@@ -11,7 +11,7 @@ function manageHostsDirectiveController($rootScope, $location, $log, $stateParam
var vm = this;
var params = ParamPass.get();
- if(params === undefined) {
+ if (params === undefined) {
params = {};
params.host_scope = $scope.$new();
params.group_scope = $scope.$new();
@@ -29,7 +29,7 @@ function manageHostsDirectiveController($rootScope, $location, $log, $stateParam
relatedSets = {},
url, form_scope;
- var host_id = $stateParams.host_id || undefined;
+ var host_id = $stateParams.host_id || undefined;
form_scope =
generator.inject(HostForm, {
@@ -94,6 +94,11 @@ function manageHostsDirectiveController($rootScope, $location, $log, $stateParam
scope.enabled = true;
scope.variables = '---';
defaultUrl = data.related.hosts;
+ scope.parseType = 'yaml';
+ ParseTypeChange({
+ scope: scope,
+ field_id: 'host_variables',
+ });
//scope.$emit('hostVariablesLoaded');
scope.parseType = 'yaml';
ParseTypeChange({
@@ -183,7 +188,7 @@ function manageHostsDirectiveController($rootScope, $location, $log, $stateParam
angular.extend(vm, {
cancelPanel: cancelPanel,
saveHost: saveHost,
- mode: mode
+ mode: mode
});
}
diff --git a/awx/ui/client/src/shared/Utilities.js b/awx/ui/client/src/shared/Utilities.js
index e8015b4cc5..ee2e3b1d9d 100644
--- a/awx/ui/client/src/shared/Utilities.js
+++ b/awx/ui/client/src/shared/Utilities.js
@@ -882,7 +882,9 @@ angular.module('Utilities', ['RestServices', 'Utilities', 'sanitizeFilter'])
}
function get() {
- return savedData;
+ var returnData = savedData;
+ savedData = undefined;
+ return returnData;
}
return {
diff --git a/awx/ui/client/src/shared/stateExtender.provider.js b/awx/ui/client/src/shared/stateExtender.provider.js
index 35d530db08..1d28041400 100644
--- a/awx/ui/client/src/shared/stateExtender.provider.js
+++ b/awx/ui/client/src/shared/stateExtender.provider.js
@@ -1,10 +1,9 @@
-
-export default function($stateProvider){
- this.$get = function(){
+export default function($stateProvider) {
+ this.$get = function() {
return {
addState: function(state) {
var route = state.route || state.url;
- $stateProvider.state(state.name , {
+ $stateProvider.state(state.name, {
url: route,
controller: state.controller,
templateUrl: state.templateUrl,
@@ -14,6 +13,8 @@ export default function($stateProvider){
ncyBreadcrumb: state.ncyBreadcrumb,
onEnter: state.onEnter,
onExit: state.onExit,
+ template: state.template,
+ controllerAs: state.controllerAs
views: state.views
});
}