mirror of
https://github.com/ansible/awx.git
synced 2026-01-13 11:00:03 -03:30
Inventory refactor: dragging a host to a group will copy it.
This commit is contained in:
parent
28cbed72c8
commit
a8203742aa
@ -303,7 +303,7 @@ InventoriesAdd.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$lo
|
||||
function InventoriesEdit ($scope, $location, $routeParams, $compile, GenerateList, ClearScope, InventoryGroups, InventoryHosts, BuildTree, Wait,
|
||||
GetSyncStatusMsg, InjectHosts, HostsReload, GroupsAdd, GroupsEdit, GroupsDelete, Breadcrumbs, LoadBreadCrumbs, Empty,
|
||||
Rest, ProcessErrors, InventoryUpdate, Alert, ToggleChildren, ViewUpdateStatus, GroupsCancelUpdate, Find,
|
||||
HostsCreate, EditInventoryProperties, HostsEdit, HostsDelete, ToggleHostEnabled, CopyMoveGroup)
|
||||
HostsCreate, EditInventoryProperties, HostsEdit, HostsDelete, ToggleHostEnabled, CopyMoveGroup, CopyMoveHost)
|
||||
{
|
||||
ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior
|
||||
//scope.
|
||||
@ -377,6 +377,14 @@ function InventoriesEdit ($scope, $location, $routeParams, $compile, GenerateLis
|
||||
CopyMoveGroup({ scope: $scope, target_tree_id: target_tree_id, inbound_tree_id: inbound_tree_id });
|
||||
});
|
||||
|
||||
// Respond to a host drag-n-drop
|
||||
if ($scope.removeCopMoveHost) {
|
||||
$scope.removeCopyMoveHost();
|
||||
}
|
||||
$scope.removeCopyMoveHost = $scope.$on('CopyMoveHost', function(e, target_tree_id, host_id) {
|
||||
CopyMoveHost({ scope: $scope, target_tree_id: target_tree_id, host_id: host_id });
|
||||
});
|
||||
|
||||
$scope.showHosts = function(tree_id, group_id, show_failures) {
|
||||
// Clicked on group
|
||||
if (tree_id !== null) {
|
||||
@ -454,7 +462,6 @@ function InventoriesEdit ($scope, $location, $routeParams, $compile, GenerateLis
|
||||
// Expand/collapse nodes
|
||||
if (tree_id !== $scope.selected_tree_id) {
|
||||
$scope.showHosts(tree_id, Find({ list: $scope.groups, key: 'id', val: tree_id }).group_id, false);
|
||||
console.log('set group_id to: ' + $scope.selected_group_id);
|
||||
}
|
||||
ToggleChildren({ scope: $scope, list: list, id: tree_id });
|
||||
}
|
||||
@ -505,6 +512,6 @@ InventoriesEdit.$inject = [ '$scope', '$location', '$routeParams', '$compile', '
|
||||
'BuildTree', 'Wait', 'GetSyncStatusMsg', 'InjectHosts', 'HostsReload', 'GroupsAdd', 'GroupsEdit', 'GroupsDelete',
|
||||
'Breadcrumbs', 'LoadBreadCrumbs', 'Empty', 'Rest', 'ProcessErrors', 'InventoryUpdate', 'Alert', 'ToggleChildren',
|
||||
'ViewUpdateStatus', 'GroupsCancelUpdate', 'Find', 'HostsCreate', 'EditInventoryProperties', 'HostsEdit',
|
||||
'HostsDelete', 'ToggleHostEnabled', 'CopyMoveGroup'
|
||||
'HostsDelete', 'ToggleHostEnabled', 'CopyMoveGroup', 'CopyMoveHost'
|
||||
];
|
||||
|
||||
|
||||
@ -35,43 +35,8 @@ angular.module('InventoryGroupsDefinition', [])
|
||||
dataContainment: "#groups_table",
|
||||
dataTreeId: "\{\{ group.id \}\}",
|
||||
dataGroupId: "\{\{ group.group_id \}\}",
|
||||
dataAccept: "dropAccept" //function determining when draggable is accepted by droppable
|
||||
dataType: "group"
|
||||
}
|
||||
/*source: {
|
||||
label: 'Source',
|
||||
searchType: 'select',
|
||||
searchOptions: [
|
||||
{ name: "ec2", value: "ec2" },
|
||||
{ name: "none", value: "" },
|
||||
{ name: "rax", value: "rax" }],
|
||||
sourceModel: 'inventory_source',
|
||||
sourceField: 'source',
|
||||
searchOnly: true
|
||||
},
|
||||
has_external_source: {
|
||||
label: 'Has external source?',
|
||||
searchType: 'in',
|
||||
searchValue: 'ec2,rax',
|
||||
searchOnly: true,
|
||||
sourceModel: 'inventory_source',
|
||||
sourceField: 'source'
|
||||
},
|
||||
has_active_failures: {
|
||||
label: 'Has failed hosts?',
|
||||
searchSingleValue: true,
|
||||
searchType: 'boolean',
|
||||
searchValue: 'true',
|
||||
searchOnly: true
|
||||
},
|
||||
last_update_failed: {
|
||||
label: 'Update failed?',
|
||||
searchType: 'select',
|
||||
searchSingleValue: true,
|
||||
searchValue: 'failed',
|
||||
searchOnly: true,
|
||||
sourceModel: 'inventory_source',
|
||||
sourceField: 'status'
|
||||
}*/
|
||||
},
|
||||
|
||||
actions: {
|
||||
|
||||
@ -26,7 +26,10 @@ angular.module('InventoryHostsDefinition', [])
|
||||
label: 'Hosts',
|
||||
ngClick: "editHost(\{\{ host.id \}\})",
|
||||
searchPlaceholder: "search_place_holder",
|
||||
columnClass: 'col-lg-9'
|
||||
columnClass: 'col-lg-9',
|
||||
dataHostId: "\{\{ host.id \}\}",
|
||||
dataType: "host",
|
||||
awDraggable: "true"
|
||||
},
|
||||
/*groups: {
|
||||
label: 'Groups',
|
||||
|
||||
@ -375,10 +375,116 @@ angular.module('InventoryTree', ['Utilities', 'RestServices', 'GroupsHelper', 'P
|
||||
var target_name = (Empty(target.group_id)) ? 'inventory' : target.name;
|
||||
Wait('stop');
|
||||
ProcessErrors(scope, data, status, null,
|
||||
{ hdr: 'Error!', msg: 'Failed to add ' + node.attr('name') + ' to ' +
|
||||
{ hdr: 'Error!', msg: 'Failed to add ' + inbound.name + ' to ' +
|
||||
target_name + '. POST returned status: ' + status });
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}])
|
||||
|
||||
// Copy a host after drag-n-drop
|
||||
.factory('CopyMoveHost', ['$compile', 'Alert', 'ProcessErrors', 'Find', 'Wait', 'Rest', 'Empty', 'GetBasePath',
|
||||
function($compile, Alert, ProcessErrors, Find, Wait, Rest, Empty, GetBasePath) {
|
||||
return function(params) {
|
||||
|
||||
var scope = params.scope;
|
||||
var target = Find({ list: scope.groups, key: 'id', val: params.target_tree_id });
|
||||
var host = Find({ list: scope.hosts, key: 'id', val: params.host_id });
|
||||
|
||||
var found = false;
|
||||
|
||||
if (host.summary_fields.all_groups) {
|
||||
for (var i=0; i< host.summary_fields.all_groups.length; i++) {
|
||||
if (host.summary_fields.all_groups[i].id == target.group_id) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
var html = '';
|
||||
html += "<div id=\"copy-alert-modal\" class=\"modal fade\">\n";
|
||||
html += "<div class=\"modal-dialog\">\n";
|
||||
html += "<div class=\"modal-content\">\n";
|
||||
html += "<div class=\"modal-header\">\n";
|
||||
html += "<button type=\"button\" class=\"close\" ng-hide=\"disableButtons\" data-target=\"#copy-alert-modal\"\n";
|
||||
html += "data-dismiss=\"modal\" class=\"modal\" aria-hidden=\"true\">×</button>\n";
|
||||
html += "<h3>Already in Group</h3>\n";
|
||||
html += "</div>\n";
|
||||
html += "<div class=\"modal-body\">\n";
|
||||
html += "<div class=\"alert alert-info\"><p>Host " + host.name + " is already in group " + target.name + ".</p></div>\n";
|
||||
html += "</div>\n";
|
||||
html += "<div class=\"modal-footer\">\n";
|
||||
html += "<a href=\"#\" data-target=\"#copy-alert-modal\" data-dismiss=\"modal\" class=\"btn btn-primary\">OK</a>\n";
|
||||
html += "</div>\n";
|
||||
html += "</div>\n";
|
||||
html += "</div>\n";
|
||||
html += "</div>\n";
|
||||
|
||||
// Inject our custom dialog
|
||||
var e = angular.element(document.getElementById('inventory-modal-container'));
|
||||
e.empty().append(html);
|
||||
$compile(e)(scope);
|
||||
|
||||
// Display it
|
||||
$('#copy-alert-modal').modal({
|
||||
backdrop: 'static',
|
||||
keyboard: true,
|
||||
show: true
|
||||
});
|
||||
|
||||
}
|
||||
else {
|
||||
// Build the html for our prompt dialog
|
||||
var html = '';
|
||||
html += "<div id=\"copy-prompt-modal\" class=\"modal fade\">\n";
|
||||
html += "<div class=\"modal-dialog\">\n";
|
||||
html += "<div class=\"modal-content\">\n";
|
||||
html += "<div class=\"modal-header\">\n";
|
||||
html += "<button type=\"button\" class=\"close\" data-target=\"#copy-prompt-modal\" " +
|
||||
"data-dismiss=\"modal\" aria-hidden=\"true\">×</button>\n";
|
||||
html += "<h3>Copy Group</h3>\n";
|
||||
html += "</div>\n";
|
||||
html += "<div class=\"modal-body\">\n";
|
||||
html += "<p>Are you sure you want to copy host " + host.name + ' to group ' + target.name + '?</p>';
|
||||
html += "</div>\n";
|
||||
html += "<div class=\"modal-footer\">\n";
|
||||
html += "<a href=\"#\" data-target=\"#prompt-modal\" data-dismiss=\"modal\" class=\"btn btn-default\">No</a>\n";
|
||||
html += "<a href=\"\" data-target=\"#prompt-modal\" ng-click=\"copyHost()\" class=\"btn btn-primary\">Yes</a>\n";
|
||||
html += "</div>\n";
|
||||
html += "</div><!-- modal-content -->\n";
|
||||
html += "</div><!-- modal-dialog -->\n";
|
||||
html += "</div><!-- modal -->\n";
|
||||
|
||||
// Inject our custom dialog
|
||||
var e = angular.element(document.getElementById('inventory-modal-container'));
|
||||
e.empty().append(html);
|
||||
$compile(e)(scope);
|
||||
|
||||
// Display it
|
||||
$('#copy-prompt-modal').modal({
|
||||
backdrop: 'static',
|
||||
keyboard: true,
|
||||
show: true
|
||||
});
|
||||
|
||||
scope.copyHost = function() {
|
||||
$('#copy-prompt-modal').modal('hide');
|
||||
Wait('start');
|
||||
Rest.setUrl(GetBasePath('groups') + target.group_id + '/hosts/');
|
||||
Rest.post(host)
|
||||
.success(function(data, status, headers, config) {
|
||||
// Signal the controller to refresh the hosts view
|
||||
scope.$emit('GroupTreeRefreshed');
|
||||
})
|
||||
.error(function(data, status, headers, config) {
|
||||
Wait('stop');
|
||||
ProcessErrors(scope, data, status, null,
|
||||
{ hdr: 'Error!', msg: 'Failed to add ' + host.name + ' to ' +
|
||||
target.name + '. POST returned status: ' + status });
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}]);
|
||||
|
||||
@ -554,30 +554,41 @@ angular.module('AWDirectives', ['RestServices', 'Utilities', 'AuthService'])
|
||||
// the following is inventory specific accept checking and
|
||||
// drop processing.
|
||||
accept: function(draggable) {
|
||||
if ($(this).attr('data-group-id') == draggable.attr('data-group-id')) {
|
||||
// No dropping a node onto itself (or a copy)
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
// No dropping a node into a group that already has the node
|
||||
var node = Find({ list: scope.groups, key: 'id', val: parseInt($(this).attr('data-tree-id')) });
|
||||
if (node) {
|
||||
var group = parseInt(draggable.attr('data-group-id'));
|
||||
var found = false;
|
||||
// For whatever reason indexOf() would not work...
|
||||
for (var i=0; i < node.children.length; i++) {
|
||||
if (node.children[i] == group) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
return (found) ? false : true;
|
||||
}
|
||||
else {
|
||||
// this shouldn't be possible
|
||||
if (draggable.attr('data-type') == 'group') {
|
||||
// Dropped a group
|
||||
if ($(this).attr('data-group-id') == draggable.attr('data-group-id')) {
|
||||
// No dropping a node onto itself (or a copy)
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
// No dropping a node into a group that already has the node
|
||||
var node = Find({ list: scope.groups, key: 'id', val: parseInt($(this).attr('data-tree-id')) });
|
||||
if (node) {
|
||||
var group = parseInt(draggable.attr('data-group-id'));
|
||||
var found = false;
|
||||
// For whatever reason indexOf() would not work...
|
||||
for (var i=0; i < node.children.length; i++) {
|
||||
if (node.children[i] == group) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
return (found) ? false : true;
|
||||
}
|
||||
else {
|
||||
// Node not found. This shouldn't be possible
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (draggable.attr('data-type') == 'host') {
|
||||
// Dropped a host
|
||||
var node = Find({ list: scope.groups, key: 'id', val: parseInt($(this).attr('data-tree-id')) });
|
||||
return (node.id > 1) ? true : false;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
over: function(e, ui) {
|
||||
@ -589,7 +600,12 @@ angular.module('AWDirectives', ['RestServices', 'Utilities', 'AuthService'])
|
||||
drop: function(e, ui) {
|
||||
// Drag-n-drop succeeded. Trigger a response from the inventory.edit controller
|
||||
$(this).removeClass('droppable-hover');
|
||||
scope.$emit('CopyMoveGroup', ui.draggable.attr('data-tree-id'), $(this).attr('data-tree-id'));
|
||||
if (ui.draggable.attr('data-type') == 'group') {
|
||||
scope.$emit('CopyMoveGroup', ui.draggable.attr('data-tree-id'), $(this).attr('data-tree-id'));
|
||||
}
|
||||
else if (ui.draggable.attr('data-type') == 'host') {
|
||||
scope.$emit('CopyMoveHost', $(this).attr('data-tree-id'), ui.draggable.attr('data-host-id'));
|
||||
}
|
||||
},
|
||||
tolerance: 'touch'
|
||||
});
|
||||
|
||||
@ -517,6 +517,8 @@ angular.module('GeneratorHelpers', ['GeneratorHelpers'])
|
||||
html += (field.dataContainment) ? Attr(field, 'dataContainment') : '';
|
||||
html += (field.dataTreeId) ? Attr(field, 'dataTreeId') : '';
|
||||
html += (field.dataGroupId) ? Attr(field, 'dataGroupId') : '';
|
||||
html += (field.dataHostId) ? Attr(field, 'dataHostId') : '';
|
||||
html += (field.dataType) ? Attr(field, 'dataType') : '';
|
||||
}
|
||||
if (field.awToolTip) {
|
||||
html += Attr(field, 'awToolTip');
|
||||
|
||||
@ -15,19 +15,19 @@
|
||||
*/
|
||||
|
||||
angular.module('PromptDialog', ['Utilities'])
|
||||
.factory('Prompt', ['Alert', function(Alert) {
|
||||
.factory('Prompt', ['$rootScope', '$compile', 'Alert', function($rootScope, $compile, Alert) {
|
||||
return function(params) {
|
||||
|
||||
var dialog = angular.element(document.getElementById('prompt-modal'));
|
||||
var scope = dialog.scope();
|
||||
var scope = dialog.scope();
|
||||
|
||||
scope.promptHeader = params.hdr;
|
||||
scope.promptBody = params.body;
|
||||
scope.promptAction = params.action;
|
||||
|
||||
var cls = (params['class'] == null || params['class'] == undefined) ? 'btn-danger' : params['class'];
|
||||
|
||||
$('#prompt_action_btn').addClass(cls); // Use jquery because django template engine conflicts with Angular's
|
||||
// use of {{...}}
|
||||
$('#prompt_action_btn').removeClass(cls).addClass(cls);
|
||||
|
||||
$(dialog).modal({
|
||||
backdrop: 'static',
|
||||
|
||||
@ -263,7 +263,7 @@
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-target="#alert-modal"
|
||||
<button type="button" class="close" data-target="#form-modal2"
|
||||
data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h3 ng-bind-html-unsafe="formModal2Header"></h3>
|
||||
</div>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user