mirror of
https://github.com/ansible/awx.git
synced 2026-01-23 07:28:02 -03:30
Inventory refactor from 1.4.11
Include commits from release_1.4.11 branch up to but not including 809c99d05c4bd14dac7ef2f19767e4d196cdd1bb
This commit is contained in:
parent
b58f65ca26
commit
527e7c6943
@ -14,7 +14,7 @@ function Home($scope, $compile, $routeParams, $rootScope, $location, Wait, Objec
|
||||
ClearScope, Stream, Rest, GetBasePath, ProcessErrors, Button) {
|
||||
|
||||
ClearScope('home');
|
||||
|
||||
|
||||
var buttons, html, e, waitCount, loadedCount;
|
||||
|
||||
// Add buttons to the top of the Home page. We're using lib/ansible/generator_helpers.js-> Buttons()
|
||||
@ -31,19 +31,19 @@ function Home($scope, $compile, $routeParams, $rootScope, $location, Wait, Objec
|
||||
mode: 'all'
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
html = Button({
|
||||
btn: buttons.refresh,
|
||||
action: 'refresh',
|
||||
toolbar: true
|
||||
});
|
||||
|
||||
|
||||
html += Button({
|
||||
btn: buttons.stream,
|
||||
action: 'stream',
|
||||
toolbar: true
|
||||
});
|
||||
|
||||
|
||||
e = angular.element(document.getElementById('home-list-actions'));
|
||||
e.html(html);
|
||||
$compile(e)($scope);
|
||||
@ -137,7 +137,7 @@ function HomeGroups($scope, $filter, $compile, $location, $routeParams, LogViewe
|
||||
opt, PreviousSearchParams;
|
||||
|
||||
generator.inject(list, { mode: 'edit', scope: scope });
|
||||
|
||||
|
||||
function ellipsis(a) {
|
||||
if (a.length > 20) {
|
||||
return a.substr(0,20) + '...';
|
||||
@ -299,7 +299,7 @@ function HomeGroups($scope, $filter, $compile, $location, $routeParams, LogViewe
|
||||
};
|
||||
|
||||
scope.editGroup = function (group_id, inventory_id) {
|
||||
PreviousSearchParams = Store('CurrentSearchParams');
|
||||
PreviousSearchParams = Store('group_current_search_params');
|
||||
GroupsEdit({
|
||||
scope: scope,
|
||||
group_id: group_id,
|
||||
@ -335,7 +335,7 @@ function HomeGroups($scope, $filter, $compile, $location, $routeParams, LogViewe
|
||||
var group = Find({ list: scope.home_groups, key: 'id', val: id });
|
||||
if (group) {
|
||||
if (Empty(group.source)) {
|
||||
// if no source, do nothing.
|
||||
// if no source, do nothing.
|
||||
} else if (group.status === 'updating') {
|
||||
Alert('Update in Progress', 'The inventory update process is currently running for group <em>' +
|
||||
group.name + '</em>. Use the Refresh button to monitor the status.', 'alert-info');
|
||||
@ -410,7 +410,7 @@ function HomeGroups($scope, $filter, $compile, $location, $routeParams, LogViewe
|
||||
}
|
||||
scope.removeGroupSummaryReady = scope.$on('GroupSummaryReady', function(e, event, inventory, data) {
|
||||
var html, title;
|
||||
|
||||
|
||||
Wait('stop');
|
||||
|
||||
// Build the html for our popover
|
||||
|
||||
@ -471,238 +471,259 @@ InventoriesAdd.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log
|
||||
|
||||
|
||||
|
||||
function InventoriesEdit($scope, $location, $routeParams, $compile, $log, $rootScope, GenerateList, ClearScope, InventoryGroups, InventoryHosts, BuildTree, Wait,
|
||||
GetSyncStatusMsg, InjectHosts, HostsReload, GroupsEdit, GroupsDelete, Breadcrumbs, LoadBreadCrumbs, Empty, Rest, ProcessErrors,
|
||||
InventoryUpdate, Alert, ToggleChildren, ViewUpdateStatus, GroupsCancelUpdate, Find, EditInventoryProperties, HostsEdit,
|
||||
HostsDelete, ToggleHostEnabled, CopyMoveGroup, CopyMoveHost, Stream, GetBasePath, ShowJobSummary, ApplyEllipsis, WatchInventoryWindowResize,
|
||||
HelpDialog, InventoryGroupsHelp, Store, ViewJob, SetContainerHeights) {
|
||||
function InventoriesEdit ($scope, $location, $routeParams, $compile, GenerateList, ClearScope, Empty, Wait, Rest, Alert, LoadBreadCrumbs, GetBasePath, ProcessErrors,
|
||||
Breadcrumbs, InventoryGroups, InjectHosts, Find, HostsReload, SearchInit, PaginateInit, GetSyncStatusMsg, GetHostsStatusMsg, GroupsEdit, InventoryUpdate,
|
||||
GroupsCancelUpdate, ViewUpdateStatus, GroupsDelete, Store, HostsEdit, HostsDelete, EditInventoryProperties, ToggleHostEnabled, Stream, ShowJobSummary,
|
||||
InventoryGroupsHelp, HelpDialog, ViewJob, WatchInventoryWindowResize, SetContainerHeights, GetHostContainerRows, GetGroupContainerRows, GetGroupContainerHeight,
|
||||
GroupsCopy, HostsCopy)
|
||||
{
|
||||
|
||||
var PreviousSearchParams,
|
||||
url,
|
||||
hostScope = $scope.$new();
|
||||
|
||||
ClearScope();
|
||||
|
||||
var generator = GenerateList,
|
||||
list = InventoryGroups;
|
||||
$scope.group_breadcrumbs = [{
|
||||
name: 'All',
|
||||
id: 0,
|
||||
description: '',
|
||||
show: true,
|
||||
ngicon: null,
|
||||
has_children: false,
|
||||
related: {},
|
||||
active_class: 'active',
|
||||
show_failures: false
|
||||
}];
|
||||
|
||||
$scope.inventory_id = $routeParams.inventory_id;
|
||||
$scope.refreshHostsOnGroupRefresh = false;
|
||||
$scope.selected_group_id = null;
|
||||
|
||||
LoadBreadCrumbs({
|
||||
path: $location.path(),
|
||||
title: '{{ inventory_name }}'
|
||||
});
|
||||
Wait('start');
|
||||
|
||||
// Handle inventory sync status changes
|
||||
if ($rootScope.removeJobStatusChange) {
|
||||
$rootScope.removeJobStatusChange();
|
||||
|
||||
if ($scope.removeHostReloadComplete) {
|
||||
$scope.removeHostReloadComplete();
|
||||
}
|
||||
$rootScope.removeJobStatusChange = $rootScope.$on('JobStatusChange', function(e, data) {
|
||||
var group, stat;
|
||||
Wait('stop');
|
||||
$log.debug(data);
|
||||
if ($scope.groups) {
|
||||
// Assuming we have a list of groups available
|
||||
group = Find({ list: $scope.groups, key: 'group_id', val: data.group_id });
|
||||
if (group) {
|
||||
// And we found the affected group
|
||||
$log.debug('Received event for group: ' + group.name);
|
||||
if (data.status === 'failed' || data.status === 'successful') {
|
||||
$log.debug('Update completed. Refreshing the tree.');
|
||||
$scope.refreshGroups(group.id, group.group_id);
|
||||
}
|
||||
else {
|
||||
$log.debug('Status changed to: ' + data.status);
|
||||
stat = GetSyncStatusMsg({
|
||||
status: data.status,
|
||||
has_inventory_sources: group.has_inventory_sources,
|
||||
source: group.source
|
||||
});
|
||||
$log.debug('Changing tooltip to: ' + stat.tooltip);
|
||||
group.status = data.status;
|
||||
group.status_class = stat['class'];
|
||||
group.status_tooltip = stat.tooltip;
|
||||
group.launch_tooltip = stat.launch_tip;
|
||||
group.launch_class = stat.launch_class;
|
||||
}
|
||||
}
|
||||
$scope.removeHostReloadComplete = $scope.$on('HostReloadComplete', function() {
|
||||
if ($scope.initial_height) {
|
||||
$('#hosts-container .well').height($scope.initial_height + 49);
|
||||
$scope.initial_height = null;
|
||||
}
|
||||
});
|
||||
|
||||
// After the tree data loads for the first time, generate the groups and hosts lists
|
||||
if ($scope.removeGroupTreeLoaded) {
|
||||
$scope.removeGroupTreeLoaded();
|
||||
if ($scope.removeInventoryLoaded) {
|
||||
$scope.removeInventoryLoaded();
|
||||
}
|
||||
$scope.removeGroupTreeLoaded = $scope.$on('GroupTreeLoaded', function (event, inventory_name, groups) {
|
||||
// Add breadcrumbs
|
||||
var e, html, inventoryAutoHelp;
|
||||
$scope.removeInventoryLoaded = $scope.$on('InventoryLoaded', function() {
|
||||
var e, rows;
|
||||
|
||||
LoadBreadCrumbs({
|
||||
path: $location.path(),
|
||||
title: '{{ inventory.name }}'
|
||||
});
|
||||
|
||||
// Build page breadcrumbs
|
||||
e = angular.element(document.getElementById('breadcrumbs'));
|
||||
e.html(Breadcrumbs({ list: list, mode: 'edit' }));
|
||||
e.html(Breadcrumbs({ list: InventoryGroups, mode: 'edit' }));
|
||||
$compile(e)($scope);
|
||||
|
||||
// Add groups view
|
||||
generator.inject(list, {
|
||||
GenerateList.inject(InventoryGroups, {
|
||||
mode: 'edit',
|
||||
id: 'groups-container',
|
||||
id: 'group-list-container',
|
||||
breadCrumbs: false,
|
||||
searchSize: 'col-lg-5 col-md-5 col-sm-5',
|
||||
skipTableHead: true
|
||||
searchSize: 'col-lg-6 col-md-6 col-sm-6',
|
||||
scope: $scope
|
||||
});
|
||||
|
||||
// Keep the table header fixed while allowing the table body to scroll and still use <table> element
|
||||
html = "<table class=\"table table-condensed\" id=\"groups-table-header\">" + generator.buildHeader() + "</table>\n";
|
||||
$(html).insertBefore('#groups-container .list-table-container');
|
||||
/*SetContainerHeights({
|
||||
group_scope: $scope,
|
||||
host_scope: hostScope,
|
||||
reloadHosts: false
|
||||
});*/
|
||||
|
||||
$scope.groups = groups;
|
||||
$scope.inventory_name = inventory_name;
|
||||
|
||||
// Default the selected group to the first node
|
||||
if ($scope.groups.length > 0) {
|
||||
$scope.selected_tree_id = $scope.groups[0].id;
|
||||
$scope.selected_group_id = $scope.groups[0].group_id;
|
||||
$scope.groups[0].selected_class = 'selected';
|
||||
$scope.groups[0].active_class = 'active-row';
|
||||
$scope.selected_group_name = $scope.groups[0].name;
|
||||
} else {
|
||||
$scope.selected_tree_id = null;
|
||||
$scope.selected_group_id = null;
|
||||
if ($(window).width() > 1210) {
|
||||
$scope.initial_height = GetGroupContainerHeight() - 20;
|
||||
$('#groups-container .list-table-container').height($scope.initial_height);
|
||||
rows = GetGroupContainerRows();
|
||||
//$('#hosts-container .well').height( height );
|
||||
}
|
||||
|
||||
// Resize the containers based on viewport width/height
|
||||
SetContainerHeights({ scope: $scope, reloadHosts: false });
|
||||
else {
|
||||
rows = 20;
|
||||
}
|
||||
hostScope.host_page_size = rows;
|
||||
$scope.group_page_size = rows;
|
||||
|
||||
// Add hosts view
|
||||
$scope.show_failures = false;
|
||||
InjectHosts({
|
||||
scope: $scope,
|
||||
inventory_id: $scope.inventory_id,
|
||||
tree_id: $scope.selected_tree_id,
|
||||
group_id: $scope.selected_group_id
|
||||
group_scope: $scope,
|
||||
host_scope: hostScope,
|
||||
inventory_id: $scope.inventory.id,
|
||||
tree_id: null,
|
||||
group_id: null,
|
||||
pageSize: rows
|
||||
});
|
||||
|
||||
// As the window shrinks and expands, apply ellipsis
|
||||
setTimeout(function () {
|
||||
// Hack to keep group name from slipping to a new line
|
||||
$('#groups_table .name-column').each(function () {
|
||||
var td_width, level_width, level_padding, level, pct;
|
||||
td_width = $(this).width();
|
||||
level_width = $(this).find('.level').width();
|
||||
level_padding = parseInt($(this).find('.level').css('padding-left').replace(/px/, ''));
|
||||
level = level_width + level_padding;
|
||||
pct = (100 - Math.ceil((level / td_width) * 100)) + '%';
|
||||
$(this).find('.group-name').css({
|
||||
width: pct
|
||||
SearchInit({ scope: $scope, set: 'groups', list: InventoryGroups, url: $scope.inventory.related.root_groups });
|
||||
PaginateInit({ scope: $scope, list: InventoryGroups , url: $scope.inventory.related.root_groups, pageSize: rows });
|
||||
$scope.search(InventoryGroups.iterator, null, true);
|
||||
});
|
||||
|
||||
if ($scope.removePostRefresh) {
|
||||
$scope.removePostRefresh();
|
||||
}
|
||||
$scope.removePostRefresh = $scope.$on('PostRefresh', function(e, set) {
|
||||
if (set === 'groups') {
|
||||
$scope.groups.forEach( function(group, idx) {
|
||||
var stat, hosts_status;
|
||||
stat = GetSyncStatusMsg({
|
||||
status: group.summary_fields.inventory_source.status,
|
||||
has_inventory_sources: group.has_inventory_sources,
|
||||
source: ( (group.summary_fields.inventory_source) ? group.summary_fields.inventory_source.source : null )
|
||||
}); // from helpers/Groups.js
|
||||
$scope.groups[idx].status_class = stat['class'];
|
||||
$scope.groups[idx].status_tooltip = stat.tooltip;
|
||||
$scope.groups[idx].launch_tooltip = stat.launch_tip;
|
||||
$scope.groups[idx].launch_class = stat.launch_class;
|
||||
hosts_status = GetHostsStatusMsg({
|
||||
active_failures: group.hosts_with_active_failures,
|
||||
total_hosts: group.total_hosts,
|
||||
inventory_id: $scope.inventory.id,
|
||||
group_id: group.id
|
||||
}); // from helpers/Groups.js
|
||||
$scope.groups[idx].hosts_status_tip = hosts_status.tooltip;
|
||||
$scope.groups[idx].show_failures = hosts_status.failures;
|
||||
$scope.groups[idx].hosts_status_class = hosts_status['class'];
|
||||
|
||||
$scope.groups[idx].source = (group.summary_fields.inventory_source) ? group.summary_fields.inventory_source.source : null;
|
||||
$scope.groups[idx].status = (group.summary_fields.inventory_source) ? group.summary_fields.inventory_source.status : null;
|
||||
|
||||
});
|
||||
if ($scope.refreshHostsOnGroupRefresh) {
|
||||
$scope.refreshHostsOnGroupRefresh = false;
|
||||
HostsReload({
|
||||
scope: hostScope,
|
||||
group_id: $scope.selected_group_id,
|
||||
inventory_id: $scope.inventory.id,
|
||||
pageSize: hostScope.host_page_size
|
||||
});
|
||||
});
|
||||
ApplyEllipsis('#groups_table .group-name a');
|
||||
ApplyEllipsis('#hosts_table .host-name a');
|
||||
}, 2500); //give the window time to display
|
||||
WatchInventoryWindowResize({ scope: $scope });
|
||||
|
||||
inventoryAutoHelp = Store('inventoryAutoHelp');
|
||||
if (inventoryAutoHelp !== 'off' && $scope.autoShowGroupHelp) {
|
||||
$scope.showGroupHelp({
|
||||
autoShow: true
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// Called after tree data is reloaded on refresh button click.
|
||||
if ($scope.removeGroupTreeRefreshed) {
|
||||
$scope.removeGroupTreeRefreshed();
|
||||
}
|
||||
$scope.removeGroupTreeRefreshed = $scope.$on('GroupTreeRefreshed', function () {
|
||||
// Reapply ellipsis to groups
|
||||
setTimeout(function () {
|
||||
ApplyEllipsis('#groups_table .group-name a');
|
||||
}, 2500);
|
||||
// Reselect the preveiously selected group node, causing host view to refresh.
|
||||
$scope.showHosts($scope.selected_tree_id, $scope.selected_group_id, false);
|
||||
});
|
||||
|
||||
// Group was deleted. Now we need to refresh the group view.
|
||||
if ($scope.removeGroupDeleteCompleted) {
|
||||
$scope.removeGroupDeleteCompleted();
|
||||
}
|
||||
$scope.removeGroupDeleteCompleted = $scope.$on('GroupDeleteCompleted', function () {
|
||||
$scope.selected_tree_id = 1;
|
||||
$scope.selected_group_id = null;
|
||||
BuildTree({
|
||||
scope: $scope,
|
||||
inventory_id: $scope.inventory_id,
|
||||
refresh: true
|
||||
});
|
||||
});
|
||||
|
||||
// Respond to a group drag-n-drop
|
||||
if ($scope.removeCopMoveGroup) {
|
||||
$scope.removeCopyMoveGroup();
|
||||
}
|
||||
$scope.removeCopyMoveGroup = $scope.$on('CopyMoveGroup', function (e, inbound_tree_id, target_tree_id) {
|
||||
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) {
|
||||
Wait('start');
|
||||
$scope.selected_tree_id = tree_id;
|
||||
$scope.selected_group_id = group_id;
|
||||
$scope.hosts = [];
|
||||
$scope.show_failures = show_failures; // turn on failed hosts filter in hosts view
|
||||
for (var i = 0; i < $scope.groups.length; i++) {
|
||||
if ($scope.groups[i].id === tree_id) {
|
||||
$scope.groups[i].selected_class = 'selected';
|
||||
$scope.groups[i].active_class = 'active-row';
|
||||
$scope.selected_group_name = $scope.groups[i].name;
|
||||
} else {
|
||||
$scope.groups[i].selected_class = '';
|
||||
$scope.groups[i].active_class = '';
|
||||
}
|
||||
}
|
||||
if (Empty($scope.inventory_id)) {
|
||||
$scope.inventory_id = $scope.groups[0].inentory_id;
|
||||
else {
|
||||
Wait('stop');
|
||||
}
|
||||
HostsReload({
|
||||
scope: $scope,
|
||||
group_id: group_id,
|
||||
tree_id: tree_id,
|
||||
inventory_id: $scope.inventory_id
|
||||
|
||||
WatchInventoryWindowResize({
|
||||
group_scope: $scope,
|
||||
host_scope: hostScope
|
||||
});
|
||||
} else {
|
||||
Wait('stop');
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
// Load Inventory
|
||||
url = GetBasePath('inventory') + $routeParams.inventory_id + '/';
|
||||
Rest.setUrl(url);
|
||||
Rest.get()
|
||||
.success(function (data) {
|
||||
$scope.inventory = data;
|
||||
$scope.$emit('InventoryLoaded');
|
||||
})
|
||||
.error(function (data, status) {
|
||||
ProcessErrors($scope, data, status, null, { hdr: 'Error!', msg: 'Failed to retrieve inventory: ' + $routeParams.inventory_id +
|
||||
' GET returned status: ' + status });
|
||||
});
|
||||
|
||||
// Load group on selection
|
||||
function loadGroups(url) {
|
||||
SearchInit({ scope: $scope, set: 'groups', list: InventoryGroups, url: url });
|
||||
PaginateInit({ scope: $scope, list: InventoryGroups , url: url, pageSize: $scope.group_page_size });
|
||||
$scope.search(InventoryGroups.iterator, null, true, false, true);
|
||||
}
|
||||
|
||||
function setActiveGroupBreadcrumb() {
|
||||
$scope.group_breadcrumbs.forEach(function(crumb, idx) {
|
||||
$scope.group_breadcrumbs[idx].active_class = '';
|
||||
});
|
||||
$scope.group_breadcrumbs[$scope.group_breadcrumbs.length - 1].active_class = 'active';
|
||||
$scope.refreshHostsOnGroupRefresh = true;
|
||||
$scope.selected_group_id = ($scope.group_breadcrumbs[$scope.group_breadcrumbs.length - 1].id === 0) ? null : $scope.group_breadcrumbs[$scope.group_breadcrumbs.length - 1].id;
|
||||
}
|
||||
|
||||
$scope.refreshHosts = function() {
|
||||
HostsReload({
|
||||
scope: hostScope,
|
||||
group_id: $scope.selected_group_id,
|
||||
inventory_id: $scope.inventory.id,
|
||||
pageSize: hostScope.host_page_size
|
||||
});
|
||||
};
|
||||
|
||||
$scope.refreshGroups = function() {
|
||||
$scope.refreshHostsOnGroupRefresh = true;
|
||||
$scope.search(InventoryGroups.iterator, null, true, false, true);
|
||||
};
|
||||
|
||||
$scope.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);
|
||||
};
|
||||
|
||||
$scope.groupSelect = function(id) {
|
||||
var group = Find({ list: $scope.groups, key: 'id', val: id });
|
||||
$scope.group_breadcrumbs.push(group);
|
||||
setActiveGroupBreadcrumb();
|
||||
loadGroups(group.related.children, group.id);
|
||||
};
|
||||
|
||||
$scope.breadcrumbGroupSelect = function(id) {
|
||||
var i, url;
|
||||
$scope.group_breadcrumbs.every(function(crumb, idx) {
|
||||
if (crumb.id === id) {
|
||||
i = idx;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
$scope.group_breadcrumbs = $scope.group_breadcrumbs.slice(0,i + 1);
|
||||
if (id > 0) {
|
||||
url = $scope.group_breadcrumbs[$scope.group_breadcrumbs.length - 1].related.children;
|
||||
}
|
||||
else {
|
||||
url = $scope.inventory.related.root_groups;
|
||||
}
|
||||
setActiveGroupBreadcrumb();
|
||||
loadGroups(url);
|
||||
};
|
||||
|
||||
$scope.createGroup = function () {
|
||||
PreviousSearchParams = Store('group_current_search_params');
|
||||
GroupsEdit({
|
||||
scope: $scope,
|
||||
inventory_id: $scope.inventory_id,
|
||||
inventory_id: $scope.inventory.id,
|
||||
group_id: $scope.selected_group_id,
|
||||
mode: 'add'
|
||||
});
|
||||
};
|
||||
|
||||
$scope.editGroup = function (group_id, tree_id) {
|
||||
$scope.editGroup = function (id) {
|
||||
PreviousSearchParams = Store('group_current_search_params');
|
||||
GroupsEdit({
|
||||
scope: $scope,
|
||||
inventory_id: $scope.inventory_id,
|
||||
group_id: group_id,
|
||||
tree_id: tree_id,
|
||||
groups_reload: true,
|
||||
inventory_id: $scope.inventory.id,
|
||||
group_id: id,
|
||||
mode: 'edit'
|
||||
});
|
||||
};
|
||||
@ -715,7 +736,7 @@ function InventoriesEdit($scope, $location, $routeParams, $compile, $log, $rootS
|
||||
// if no source, do nothing.
|
||||
} else if (group.status === 'updating') {
|
||||
Alert('Update in Progress', 'The inventory update process is currently running for group <em>' +
|
||||
group.name + '</em>. Use the Refresh button to monitor the status.', 'alert-info');
|
||||
group.name + '</em> Click the <i class="fa fa-refresh"></i> button to monitor the status.', 'alert-info');
|
||||
} else {
|
||||
Wait('start');
|
||||
Rest.setUrl(group.related.inventory_source);
|
||||
@ -726,109 +747,164 @@ function InventoriesEdit($scope, $location, $routeParams, $compile, $log, $rootS
|
||||
url: data.related.update,
|
||||
group_name: data.summary_fields.group.name,
|
||||
group_source: data.source,
|
||||
tree_id: group.id,
|
||||
group_id: group.group_id
|
||||
group_id: group.id,
|
||||
});
|
||||
})
|
||||
.error(function (data, status) {
|
||||
Wait('stop');
|
||||
ProcessErrors($scope, data, status, null, { hdr: 'Error!', msg: 'Failed to retrieve inventory source: ' +
|
||||
group.related.inventory_source + ' POST returned status: ' + status });
|
||||
group.related.inventory_source + ' GET returned status: ' + status });
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$scope.cancelUpdate = function (tree_id) {
|
||||
GroupsCancelUpdate({ scope: $scope, id: tree_id });
|
||||
$scope.cancelUpdate = function (id) {
|
||||
GroupsCancelUpdate({ scope: $scope, id: id });
|
||||
};
|
||||
|
||||
$scope.toggle = function (tree_id) {
|
||||
// Expand/collapse nodes
|
||||
ToggleChildren({ scope: $scope, list: list, id: tree_id });
|
||||
};
|
||||
|
||||
$scope.refreshGroups = function (tree_id, group_id) {
|
||||
// Refresh the tree data when refresh button cicked
|
||||
if (tree_id) {
|
||||
$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 (tree_id, group_id) {
|
||||
$scope.viewUpdateStatus = function (id) {
|
||||
ViewUpdateStatus({
|
||||
scope: $scope,
|
||||
tree_id: tree_id,
|
||||
group_id: group_id
|
||||
group_id: id
|
||||
});
|
||||
};
|
||||
|
||||
$scope.deleteGroup = function (tree_id, group_id) {
|
||||
$scope.copyGroup = function(id) {
|
||||
PreviousSearchParams = Store('group_current_search_params');
|
||||
GroupsCopy({
|
||||
scope: $scope,
|
||||
group_id: id
|
||||
});
|
||||
};
|
||||
|
||||
$scope.deleteGroup = function (id) {
|
||||
GroupsDelete({
|
||||
scope: $scope,
|
||||
tree_id: tree_id,
|
||||
group_id: group_id,
|
||||
inventory_id: $scope.inventory_id
|
||||
group_id: id,
|
||||
inventory_id: $scope.inventory.id
|
||||
});
|
||||
};
|
||||
|
||||
$scope.createHost = function () {
|
||||
HostsEdit({ scope: $scope, mode: 'add', host_id: null, selected_group_id: $scope.selected_tree_id, inventory_id: $scope.inventory_id });
|
||||
};
|
||||
|
||||
$scope.editInventoryProperties = function () {
|
||||
EditInventoryProperties({ scope: $scope, inventory_id: $scope.inventory_id });
|
||||
EditInventoryProperties({ scope: $scope, inventory_id: $scope.inventory.id });
|
||||
};
|
||||
|
||||
$scope.editHost = function (host_id) {
|
||||
HostsEdit({ scope: $scope, mode: 'edit', host_id: host_id, inventory_id: $scope.inventory_id });
|
||||
hostScope.createHost = function () {
|
||||
HostsEdit({
|
||||
host_scope: hostScope,
|
||||
group_scope: $scope,
|
||||
mode: 'add',
|
||||
host_id: null,
|
||||
selected_group_id: $scope.selected_group_id,
|
||||
inventory_id: $scope.inventory.id
|
||||
});
|
||||
};
|
||||
|
||||
$scope.deleteHost = function (host_id, host_name) {
|
||||
HostsDelete({ scope: $scope, host_id: host_id, host_name: host_name });
|
||||
hostScope.editHost = function (host_id) {
|
||||
HostsEdit({
|
||||
host_scope: hostScope,
|
||||
group_scope: $scope,
|
||||
mode: 'edit',
|
||||
host_id: host_id,
|
||||
inventory_id: $scope.inventory.id
|
||||
});
|
||||
};
|
||||
|
||||
$scope.toggleHostEnabled = function (host_id, external_source) {
|
||||
ToggleHostEnabled({ scope: $scope, host_id: host_id, external_source: external_source });
|
||||
hostScope.deleteHost = function (host_id, host_name) {
|
||||
HostsDelete({
|
||||
parent_scope: $scope,
|
||||
host_scope: hostScope,
|
||||
host_id: host_id,
|
||||
host_name: host_name
|
||||
});
|
||||
};
|
||||
|
||||
hostScope.copyHost = function(id) {
|
||||
PreviousSearchParams = Store('group_current_search_params');
|
||||
HostsCopy({
|
||||
group_scope: $scope,
|
||||
host_scope: hostScope,
|
||||
host_id: id
|
||||
});
|
||||
};
|
||||
|
||||
/*hostScope.restoreSearch = function() {
|
||||
SearchInit({
|
||||
scope: hostScope,
|
||||
set: PreviousSearchParams.set,
|
||||
list: PreviousSearchParams.list,
|
||||
url: PreviousSearchParams.defaultUrl,
|
||||
iterator: PreviousSearchParams.iterator,
|
||||
sort_order: PreviousSearchParams.sort_order,
|
||||
setWidgets: false
|
||||
});
|
||||
hostScope.search('host');
|
||||
};*/
|
||||
|
||||
hostScope.toggleHostEnabled = function (host_id, external_source) {
|
||||
ToggleHostEnabled({
|
||||
parent_scope: $scope,
|
||||
host_scope: hostScope,
|
||||
host_id: host_id,
|
||||
external_source: external_source
|
||||
});
|
||||
};
|
||||
|
||||
$scope.showGroupActivity = function () {
|
||||
var url, title, group;
|
||||
if ($scope.selected_group_id) {
|
||||
group = Find({
|
||||
list: $scope.groups,
|
||||
key: 'id',
|
||||
val: $scope.selected_tree_id
|
||||
$scope.group_breadcrumbs.every(function(crumb) {
|
||||
if (crumb.id === $scope.selected_group_id) {
|
||||
group = crumb;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
url = GetBasePath('activity_stream') + '?group__id=' + $scope.selected_group_id;
|
||||
title = 'Showing all activities for group ' + group.name;
|
||||
} else {
|
||||
title = 'Showing all activities for all ' + $scope.inventory_name + ' groups';
|
||||
url = GetBasePath('activity_stream') + '?group__inventory__id=' + $scope.inventory_id;
|
||||
title = 'Showing all activities for all ' + $scope.inventory.name + ' groups';
|
||||
url = GetBasePath('activity_stream') + '?group__inventory__id=' + $scope.inventory.id;
|
||||
}
|
||||
Stream({
|
||||
scope: $scope,
|
||||
inventory_name: $scope.inventory_name,
|
||||
inventory_name: $scope.inventory.name,
|
||||
url: url,
|
||||
title: title
|
||||
title: title,
|
||||
search_iterator: 'group',
|
||||
onClose: 'GroupStreamClosed'
|
||||
});
|
||||
};
|
||||
|
||||
$scope.showHostActivity = function () {
|
||||
if ($scope.removeGroupStreamClosed) {
|
||||
$scope.removeGroupStreamClosed();
|
||||
}
|
||||
$scope.removeGroupStreamClosed = $scope.$on('GroupStreamClosed', function() {
|
||||
$scope.refreshGroups();
|
||||
});
|
||||
|
||||
hostScope.showHostActivity = function () {
|
||||
var url, title;
|
||||
title = 'Showing all activities for all ' + $scope.inventory_name + ' hosts';
|
||||
url = GetBasePath('activity_stream') + '?host__inventory__id=' + $scope.inventory_id;
|
||||
title = 'Showing all activities for all ' + $scope.inventory.name + ' hosts';
|
||||
url = GetBasePath('activity_stream') + '?host__inventory__id=' + $scope.inventory.id;
|
||||
Stream({
|
||||
scope: $scope,
|
||||
inventory_name: $scope.inventory_name,
|
||||
scope: hostScope,
|
||||
inventory_name: $scope.inventory.name,
|
||||
url: url,
|
||||
title: title
|
||||
title: title,
|
||||
search_iterator: 'host',
|
||||
onClose: 'HostStreamClosed'
|
||||
});
|
||||
};
|
||||
|
||||
$scope.showJobSummary = function (job_id) {
|
||||
if (hostScope.removeHostStreamClosed) {
|
||||
hostScope.removeHostStreamClosed();
|
||||
}
|
||||
hostScope.removeHostStreamClosed = hostScope.$on('HostStreamClosed', function() {
|
||||
$scope.refreshGroups();
|
||||
});
|
||||
|
||||
hostScope.showJobSummary = function (job_id) {
|
||||
ShowJobSummary({
|
||||
job_id: job_id
|
||||
});
|
||||
@ -848,19 +924,31 @@ function InventoriesEdit($scope, $location, $routeParams, $compile, $log, $rootS
|
||||
ViewJob({ scope: $scope, id: id });
|
||||
};
|
||||
|
||||
//Load tree data for the first time
|
||||
BuildTree({
|
||||
scope: $scope,
|
||||
inventory_id: $scope.inventory_id,
|
||||
refresh: false
|
||||
$scope.showHosts = function (group_id, show_failures) {
|
||||
// Clicked on group
|
||||
if (group_id !== null) {
|
||||
Wait('start');
|
||||
hostScope.show_failures = show_failures;
|
||||
$scope.groupSelect(group_id);
|
||||
hostScope.hosts = [];
|
||||
$scope.show_failures = show_failures; // turn on failed hosts filter in hosts view
|
||||
} else {
|
||||
Wait('stop');
|
||||
}
|
||||
};
|
||||
|
||||
if ($scope.removeGroupDeleteCompleted) {
|
||||
$scope.removeGroupDeleteCompleted();
|
||||
}
|
||||
$scope.removeGroupDeleteCompleted = $scope.$on('GroupDeleteCompleted', function() {
|
||||
$scope.refreshGroups();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
InventoriesEdit.$inject = ['$scope', '$location', '$routeParams', '$compile', '$log', '$rootScope', 'GenerateList', 'ClearScope', 'InventoryGroups', 'InventoryHosts',
|
||||
'BuildTree', 'Wait', 'GetSyncStatusMsg', 'InjectHosts', 'HostsReload', 'GroupsEdit', 'GroupsDelete', 'Breadcrumbs',
|
||||
'LoadBreadCrumbs', 'Empty', 'Rest', 'ProcessErrors', 'InventoryUpdate', 'Alert', 'ToggleChildren', 'ViewUpdateStatus', 'GroupsCancelUpdate',
|
||||
'Find', 'EditInventoryProperties', 'HostsEdit', 'HostsDelete', 'ToggleHostEnabled', 'CopyMoveGroup', 'CopyMoveHost',
|
||||
'Stream', 'GetBasePath', 'ShowJobSummary', 'ApplyEllipsis', 'WatchInventoryWindowResize', 'HelpDialog', 'InventoryGroupsHelp', 'Store',
|
||||
'ViewJob', 'SetContainerHeights'
|
||||
];
|
||||
InventoriesEdit.$inject = ['$scope', '$location', '$routeParams', '$compile', 'GenerateList', 'ClearScope', 'Empty', 'Wait', 'Rest', 'Alert', 'LoadBreadCrumbs',
|
||||
'GetBasePath', 'ProcessErrors', 'Breadcrumbs', 'InventoryGroups', 'InjectHosts', 'Find', 'HostsReload', 'SearchInit', 'PaginateInit', 'GetSyncStatusMsg',
|
||||
'GetHostsStatusMsg', 'GroupsEdit', 'InventoryUpdate', 'GroupsCancelUpdate', 'ViewUpdateStatus', 'GroupsDelete', 'Store', 'HostsEdit', 'HostsDelete',
|
||||
'EditInventoryProperties', 'ToggleHostEnabled', 'Stream', 'ShowJobSummary', 'InventoryGroupsHelp', 'HelpDialog', 'ViewJob', 'WatchInventoryWindowResize',
|
||||
'SetContainerHeights', 'GetHostContainerRows', 'GetGroupContainerRows', 'GetGroupContainerHeight', 'GroupsCopy', 'HostsCopy'
|
||||
];
|
||||
@ -319,8 +319,7 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
|
||||
// Cancel the update process
|
||||
if (Empty(group)) {
|
||||
group = Find({ list: scope.groups, key: 'id', val: id });
|
||||
scope.selected_tree_id = group.id;
|
||||
scope.selected_group_id = group.group_id;
|
||||
scope.selected_group_id = group.id;
|
||||
}
|
||||
|
||||
if (group && (group.status === 'running' || group.status === 'pending')) {
|
||||
@ -615,26 +614,23 @@ function($compile, SchedulerInit, Rest, Wait, SetSchedulesInnerDialogSize, Sched
|
||||
|
||||
.factory('GroupsEdit', ['$rootScope', '$location', '$log', '$routeParams', '$compile', 'Rest', 'Alert', 'GroupForm', 'GenerateForm',
|
||||
'Prompt', 'ProcessErrors', 'GetBasePath', 'SetNodeName', 'ParseTypeChange', 'GetSourceTypeOptions', 'InventoryUpdate',
|
||||
'LookUpInit', 'Empty', 'Wait', 'GetChoices', 'UpdateGroup', 'SourceChange', 'Find',
|
||||
'ParseVariableString', 'ToJSON', 'GroupsScheduleListInit', 'SourceForm', 'SetSchedulesInnerDialogSize', 'BuildTree',
|
||||
'LookUpInit', 'Empty', 'Wait', 'GetChoices', 'UpdateGroup', 'SourceChange', 'Find', 'WatchInventoryWindowResize',
|
||||
'ParseVariableString', 'ToJSON', 'GroupsScheduleListInit', 'SourceForm', 'SetSchedulesInnerDialogSize',
|
||||
function ($rootScope, $location, $log, $routeParams, $compile, Rest, Alert, GroupForm, GenerateForm, Prompt, ProcessErrors,
|
||||
GetBasePath, SetNodeName, ParseTypeChange, GetSourceTypeOptions, InventoryUpdate, LookUpInit, Empty, Wait,
|
||||
GetChoices, UpdateGroup, SourceChange, Find, ParseVariableString, ToJSON, GroupsScheduleListInit,
|
||||
SourceForm, SetSchedulesInnerDialogSize, BuildTree) {
|
||||
GetChoices, UpdateGroup, SourceChange, Find, WatchInventoryWindowResize, ParseVariableString, ToJSON, GroupsScheduleListInit,
|
||||
SourceForm, SetSchedulesInnerDialogSize) {
|
||||
return function (params) {
|
||||
|
||||
var parent_scope = params.scope,
|
||||
group_id = params.group_id,
|
||||
tree_id = params.tree_id,
|
||||
mode = params.mode, // 'add' or 'edit'
|
||||
inventory_id = params.inventory_id,
|
||||
groups_reload = params.groups_reload,
|
||||
generator = GenerateForm,
|
||||
group_created = false,
|
||||
defaultUrl,
|
||||
master = {},
|
||||
choicesReady,
|
||||
base = $location.path().replace(/^\//, '').split('/')[0],
|
||||
modal_scope = parent_scope.$new(),
|
||||
properties_scope = parent_scope.$new(),
|
||||
sources_scope = parent_scope.$new(),
|
||||
@ -730,7 +726,7 @@ function($compile, SchedulerInit, Rest, Wait, SetSchedulesInnerDialogSize, Sched
|
||||
height: y,
|
||||
autoOpen: false,
|
||||
minWidth: 440,
|
||||
title: 'Edit Group',
|
||||
title: (mode === 'edit') ? 'Edit Group' : 'Add Group',
|
||||
closeOnEscape: false,
|
||||
create: function () {
|
||||
$('.ui-dialog[aria-describedby="group-modal-dialog"]').find('.ui-dialog-titlebar button').empty().attr({'class': 'close'}).text('x');
|
||||
@ -1038,14 +1034,8 @@ function($compile, SchedulerInit, Rest, Wait, SetSchedulesInnerDialogSize, Sched
|
||||
}
|
||||
parent_scope.removeAddTreeRefreshed = parent_scope.$on('GroupTreeRefreshed', function() {
|
||||
// Clean up
|
||||
// Change the selected group
|
||||
if (groups_reload && parent_scope.selected_tree_id !== tree_id) {
|
||||
parent_scope.showHosts(tree_id, group_id, false);
|
||||
} else {
|
||||
Wait('stop');
|
||||
}
|
||||
//WatchInventoryWindowResize();
|
||||
parent_scope.removeAddTreeRefreshed();
|
||||
Wait('stop');
|
||||
WatchInventoryWindowResize();
|
||||
if (modal_scope.searchCleanUp) {
|
||||
modal_scope.searchCleanup();
|
||||
}
|
||||
@ -1062,42 +1052,7 @@ function($compile, SchedulerInit, Rest, Wait, SetSchedulesInnerDialogSize, Sched
|
||||
}
|
||||
modal_scope.removeSaveComplete = modal_scope.$on('SaveComplete', function (e, error) {
|
||||
if (!error) {
|
||||
// Update the parent view with any changes
|
||||
if (groups_reload) {
|
||||
$log.debug('calling UpdateGroup group_id: ' + group_id + ' name: ' + properties_scope.name + ' description: ' + properties_scope.description +
|
||||
'has_inventory_sources: ' + ((sources_scope.source && sources_scope.source.value) ? 'true' : 'false') + ' source: ' + sources_scope.source.value );
|
||||
UpdateGroup({
|
||||
scope: parent_scope,
|
||||
group_id: group_id,
|
||||
properties: {
|
||||
name: properties_scope.name,
|
||||
description: properties_scope.description,
|
||||
has_inventory_sources: (sources_scope.source && sources_scope.source.value) ? true : false,
|
||||
source: (sources_scope.source && sources_scope.source.value) ? sources_scope.source.value : ''
|
||||
}
|
||||
});
|
||||
parent_scope.$emit('GroupTreeRefreshed');
|
||||
} else if (base === 'inventories') {
|
||||
if (mode === 'add') {
|
||||
BuildTree({
|
||||
scope: parent_scope,
|
||||
inventory_id: inventory_id,
|
||||
refresh: true,
|
||||
new_group_id: group_id
|
||||
});
|
||||
}
|
||||
else {
|
||||
parent_scope.$emit('GroupTreeRefreshed');
|
||||
}
|
||||
} else if (base === 'home') {
|
||||
parent_scope.restoreSearch();
|
||||
try {
|
||||
$('#group-modal-dialog').dialog('close');
|
||||
}
|
||||
catch(err) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
modal_scope.cancelModal();
|
||||
}
|
||||
});
|
||||
|
||||
@ -1167,20 +1122,21 @@ function($compile, SchedulerInit, Rest, Wait, SetSchedulesInnerDialogSize, Sched
|
||||
|
||||
// Cancel
|
||||
modal_scope.cancelModal = function () {
|
||||
Wait('stop');
|
||||
try {
|
||||
$('#group-modal-dialog').dialog('close');
|
||||
}
|
||||
catch(e) {
|
||||
//ignore
|
||||
}
|
||||
|
||||
//if (modal_scope.searchCleanup) {
|
||||
// modal_scope.searchCleanup();
|
||||
//}
|
||||
//if (base === 'inventories') {
|
||||
// WatchInventoryWindowResize();
|
||||
//}
|
||||
if (modal_scope.searchCleanup) {
|
||||
modal_scope.searchCleanup();
|
||||
}
|
||||
if (parent_scope.restoreSearch) {
|
||||
parent_scope.restoreSearch();
|
||||
}
|
||||
else {
|
||||
Wait('stop');
|
||||
}
|
||||
};
|
||||
|
||||
// Save
|
||||
@ -1463,11 +1419,328 @@ function($compile, SchedulerInit, Rest, Wait, SetSchedulesInnerDialogSize, Sched
|
||||
scope.$emit('DisassociateGroup');
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
}
|
||||
])
|
||||
|
||||
.factory('GetRootGroups', ['Rest', 'ProcessErrors', 'GetBasePath', function(Rest, ProcessErrors, GetBasePath) {
|
||||
return function(params) {
|
||||
var scope = params.scope,
|
||||
inventory_id = params.inventory_id,
|
||||
//group_id = params.group_id,
|
||||
callback = params.callback,
|
||||
url;
|
||||
|
||||
url = GetBasePath('inventory') + inventory_id + '/root_groups/';
|
||||
Rest.setUrl(url);
|
||||
Rest.get()
|
||||
.success(function(data) {
|
||||
scope.$emit(callback, data.results);
|
||||
})
|
||||
.error(function(data, status) {
|
||||
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
|
||||
msg: 'Call to ' + url + ' failed. GET returned: ' + status });
|
||||
});
|
||||
};
|
||||
}])
|
||||
|
||||
.factory('GroupsCopy', ['$compile', 'Rest', 'ProcessErrors', 'CreateDialog', 'GetBasePath', 'Wait', 'GenerateList', 'GroupList', 'SearchInit',
|
||||
'PaginateInit', 'GetRootGroups',
|
||||
function($compile, Rest, ProcessErrors, CreateDialog, GetBasePath, Wait, GenerateList, GroupList, SearchInit, PaginateInit, GetRootGroups) {
|
||||
return function(params) {
|
||||
|
||||
var group_id = params.group_id,
|
||||
parent_scope = params.scope,
|
||||
scope = parent_scope.$new(),
|
||||
parent_group = parent_scope.selected_group_id,
|
||||
buttonSet, url, group;
|
||||
|
||||
buttonSet = [{
|
||||
label: "Cancel",
|
||||
onClick: function() {
|
||||
scope.cancel();
|
||||
},
|
||||
icon: "fa-times",
|
||||
"class": "btn btn-default",
|
||||
"id": "group-copy-cancel-button"
|
||||
},{
|
||||
label: "OK",
|
||||
onClick: function() {
|
||||
scope.performCopy();
|
||||
},
|
||||
icon: "fa-check",
|
||||
"class": "btn btn-primary",
|
||||
"id": "group-copy-ok-button"
|
||||
}];
|
||||
|
||||
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');
|
||||
$('#group-copy-dialog').dialog('open');
|
||||
$('#group-copy-ok-button').attr('disabled','disabled');
|
||||
|
||||
// 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') + parent_scope.inventory.id + '/groups/';
|
||||
url += (parent_group) ? '?not__id__in=' + group_id + ',' + parent_group : '?not__id=' + group_id;
|
||||
GenerateList.inject(GroupList, {
|
||||
mode: 'lookup',
|
||||
id: 'copy-select-container',
|
||||
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);
|
||||
});
|
||||
|
||||
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('group-copy-dialog'));
|
||||
$compile(d)(scope);
|
||||
|
||||
CreateDialog({
|
||||
id: 'group-copy-dialog',
|
||||
scope: scope,
|
||||
buttons: buttonSet,
|
||||
width: 650,
|
||||
height: 650,
|
||||
minWidth: 600,
|
||||
title: 'Copy or Move Group',
|
||||
callback: 'CopyDialogReady',
|
||||
onClose: function() {
|
||||
scope.cancel();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
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;
|
||||
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: parent_scope.inventory.id,
|
||||
callback: 'RootGroupsReady'
|
||||
});
|
||||
|
||||
scope.cancel = function() {
|
||||
$(document).off("keydown");
|
||||
try {
|
||||
$('#group-copy-dialog').dialog('close');
|
||||
}
|
||||
catch(e) {
|
||||
// ignore
|
||||
}
|
||||
scope.searchCleanup();
|
||||
parent_scope.restoreSearch();
|
||||
scope.$destroy();
|
||||
};
|
||||
|
||||
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 === '0') {
|
||||
scope[list.name][i].checked = '1';
|
||||
scope[list.name][i].success_class = 'success';
|
||||
}
|
||||
else {
|
||||
scope[list.name][i].checked = '0';
|
||||
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 === '1') {
|
||||
count++;
|
||||
}
|
||||
});
|
||||
if (count === 0) {
|
||||
$('#group-copy-ok-button').attr('disabled','disabled');
|
||||
}
|
||||
else {
|
||||
$('#group-copy-ok-button').removeAttr('disabled');
|
||||
}
|
||||
};
|
||||
|
||||
scope.toggleUseRootGroup = function() {
|
||||
var list = GroupList;
|
||||
//console.log("scope.use_root_group: " + scope.use_root_group);
|
||||
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;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
scope.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 (scope.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 () {
|
||||
scope.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 {
|
||||
scope.cancel();
|
||||
}
|
||||
});
|
||||
|
||||
// add the new group to the target
|
||||
url = (target) ?
|
||||
GetBasePath('groups') + target.id + '/children/' :
|
||||
GetBasePath('inventory') + parent_scope.inventory.id + '/groups/';
|
||||
group = {
|
||||
id: group.id,
|
||||
name: group.name,
|
||||
description: group.description,
|
||||
inventory: parent_scope.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') + parent_scope.inventory.id + '/groups/';
|
||||
|
||||
group = {
|
||||
id: group.id,
|
||||
name: group.name,
|
||||
description: group.description,
|
||||
inventory: parent_scope.inventory.id
|
||||
};
|
||||
|
||||
Rest.setUrl(url);
|
||||
Rest.post(group)
|
||||
.success(function () {
|
||||
scope.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
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
}])
|
||||
|
||||
.factory('ShowUpdateStatus', ['$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'GenerateForm',
|
||||
'Prompt', 'ProcessErrors', 'GetBasePath', 'FormatDate', 'InventoryStatusForm', 'Wait',
|
||||
function ($rootScope, $location, $log, $routeParams, Rest, Alert, GenerateForm, Prompt, ProcessErrors, GetBasePath,
|
||||
|
||||
@ -14,7 +14,8 @@
|
||||
angular.module('HostsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', 'HostListDefinition',
|
||||
'SearchHelper', 'PaginationHelpers', 'ListGenerator', 'AuthService', 'HostsHelper',
|
||||
'InventoryHelper', 'RelatedSearchHelper', 'InventoryFormDefinition', 'SelectionHelper',
|
||||
'HostGroupsFormDefinition', 'VariablesHelper', 'ModalDialog', 'LogViewerHelper'
|
||||
'HostGroupsFormDefinition', 'VariablesHelper', 'ModalDialog', 'LogViewerHelper',
|
||||
'GroupListDefinition'
|
||||
])
|
||||
|
||||
.factory('SetEnabledMsg', [ function() {
|
||||
@ -167,18 +168,21 @@ function($routeParams, Empty, InventoryHosts, GetBasePath, SearchInit, PaginateI
|
||||
return function(params) {
|
||||
|
||||
var scope = params.scope,
|
||||
parent_scope = params.parent_scope,
|
||||
group_id = params.group_id,
|
||||
inventory_id = params.inventory_id,
|
||||
list = InventoryHosts,
|
||||
pageSize = (params.pageSize) ? params.pageSize : 20,
|
||||
|
||||
url = ( !Empty(group_id) ) ? GetBasePath('groups') + group_id + '/all_hosts/' :
|
||||
GetBasePath('inventory') + inventory_id + '/hosts/';
|
||||
|
||||
scope.search_place_holder='Search ' + scope.selected_group_name;
|
||||
|
||||
//if (scope.removePostRefresh) {
|
||||
// scope.removePostRefresh();
|
||||
//}
|
||||
scope.removePostRefresh = scope.$on('PostRefresh', function(e, set) {
|
||||
if (scope.removeHostsReloadPostRefresh) {
|
||||
scope.removeHostsReloadPostRefresh();
|
||||
}
|
||||
scope.removeHostsReloadPostRefresh = scope.$on('PostRefresh', function(e, set) {
|
||||
if (set === 'hosts') {
|
||||
for (var i=0; i < scope.hosts.length; i++) {
|
||||
//Set tooltip for host enabled flag
|
||||
@ -187,7 +191,9 @@ function($routeParams, Empty, InventoryHosts, GetBasePath, SearchInit, PaginateI
|
||||
SetStatus({ scope: scope });
|
||||
setTimeout(function() { ApplyEllipsis('#hosts_table .host-name a'); }, 2500);
|
||||
Wait('stop');
|
||||
scope.$emit('HostReloadComplete');
|
||||
if (parent_scope) {
|
||||
parent_scope.$emit('HostReloadComplete');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@ -195,7 +201,7 @@ function($routeParams, Empty, InventoryHosts, GetBasePath, SearchInit, PaginateI
|
||||
SetContainerHeights({ scope: scope, reloadHosts: false });
|
||||
|
||||
SearchInit({ scope: scope, set: 'hosts', list: list, url: url });
|
||||
PaginateInit({ scope: scope, list: list, url: url });
|
||||
PaginateInit({ scope: scope, list: list, url: url, pageSize: pageSize });
|
||||
|
||||
if ($routeParams.host_name) {
|
||||
scope[list.iterator + 'InputDisable'] = false;
|
||||
@ -220,16 +226,18 @@ function($routeParams, Empty, InventoryHosts, GetBasePath, SearchInit, PaginateI
|
||||
function(GenerateList, InventoryHosts, HostsReload) {
|
||||
return function(params) {
|
||||
|
||||
var scope = params.scope,
|
||||
var group_scope = params.group_scope,
|
||||
host_scope = params.host_scope,
|
||||
inventory_id = params.inventory_id,
|
||||
group_id = params.group_id,
|
||||
pageSize = params.pageSize,
|
||||
generator = GenerateList;
|
||||
|
||||
// Inject the list html
|
||||
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: host_scope, mode: 'edit', id: 'hosts-container', breadCrumbs: false, searchSize: 'col-lg-6 col-md-6 col-sm-6' });
|
||||
|
||||
// Load data
|
||||
HostsReload({ scope: scope, group_id: group_id, inventory_id: inventory_id });
|
||||
HostsReload({ scope: host_scope, group_id: group_id, inventory_id: inventory_id, parent_scope: group_scope, cpageSize: pageSize });
|
||||
};
|
||||
}])
|
||||
|
||||
@ -336,8 +344,7 @@ function($rootScope, $location, $log, $routeParams, Rest, Alert, HostList, Gener
|
||||
|
||||
|
||||
.factory('HostsCreate', ['$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'HostForm', 'GenerateForm',
|
||||
'Prompt', 'ProcessErrors', 'GetBasePath', 'HostsReload', 'ParseTypeChange', 'Wait',
|
||||
'ToJSON',
|
||||
'Prompt', 'ProcessErrors', 'GetBasePath', 'HostsReload', 'ParseTypeChange', 'Wait', 'ToJSON',
|
||||
function($rootScope, $location, $log, $routeParams, Rest, Alert, HostForm, GenerateForm, Prompt, ProcessErrors,
|
||||
GetBasePath, HostsReload, ParseTypeChange, Wait, ToJSON) {
|
||||
return function(params) {
|
||||
@ -437,13 +444,13 @@ function($rootScope, $location, $log, $routeParams, Rest, Alert, HostForm, Gener
|
||||
|
||||
.factory('HostsEdit', ['$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'HostForm', 'GenerateForm',
|
||||
'Prompt', 'ProcessErrors', 'GetBasePath', 'HostsReload', 'ParseTypeChange', 'Wait', 'Find', 'SetStatus', 'ApplyEllipsis',
|
||||
'ToJSON', 'ParseVariableString', 'CreateDialog', 'TextareaResize', 'Empty',
|
||||
'ToJSON', 'ParseVariableString', 'CreateDialog', 'TextareaResize',
|
||||
function($rootScope, $location, $log, $routeParams, Rest, Alert, HostForm, GenerateForm, Prompt, ProcessErrors,
|
||||
GetBasePath, HostsReload, ParseTypeChange, Wait, Find, SetStatus, ApplyEllipsis, ToJSON,
|
||||
ParseVariableString, CreateDialog, TextareaResize, Empty) {
|
||||
ParseVariableString, CreateDialog, TextareaResize) {
|
||||
return function(params) {
|
||||
|
||||
var parent_scope = params.scope,
|
||||
var parent_scope = params.parent_scope,
|
||||
host_id = params.host_id,
|
||||
inventory_id = params.inventory_id,
|
||||
mode = params.mode, // 'add' or 'edit'
|
||||
@ -451,10 +458,10 @@ function($rootScope, $location, $log, $routeParams, Rest, Alert, HostForm, Gener
|
||||
generator = GenerateForm,
|
||||
form = HostForm,
|
||||
defaultUrl,
|
||||
scope = parent_scope.$new(),
|
||||
scope = params.host_scope,
|
||||
master = {},
|
||||
relatedSets = {},
|
||||
group, buttons;
|
||||
buttons, url;
|
||||
|
||||
generator.inject(HostForm, { mode: 'edit', id: 'host-modal-dialog', breadCrumbs: false, related: false, scope: scope });
|
||||
generator.reset();
|
||||
@ -581,24 +588,26 @@ function($rootScope, $location, $log, $routeParams, Rest, Alert, HostForm, Gener
|
||||
scope.$emit('hostLoaded');
|
||||
})
|
||||
.error( function(data, status) {
|
||||
ProcessErrors(scope, data, status, form,
|
||||
ProcessErrors(parent_scope, data, status, form,
|
||||
{ hdr: 'Error!', msg: 'Failed to retrieve host: ' + host_id + '. GET returned status: ' + status });
|
||||
});
|
||||
}
|
||||
else {
|
||||
// Add mode
|
||||
group = Find({ list: scope.groups, key: 'id', val: selected_group_id });
|
||||
if (!Empty(group)) {
|
||||
scope.has_inventory_sources = group.has_inventory_sources;
|
||||
scope.enabled = true;
|
||||
scope.variables = '---';
|
||||
defaultUrl = GetBasePath('groups') + group.group_id + '/hosts/';
|
||||
scope.$emit('hostVariablesLoaded');
|
||||
}
|
||||
else {
|
||||
ProcessErrors(scope, null, status, null, { hdr: 'Error',
|
||||
msg: 'Group lookup failed. Selected group id: ' + selected_group_id });
|
||||
}
|
||||
url = GetBasePath('groups') + selected_group_id + '/';
|
||||
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.$emit('hostVariablesLoaded');
|
||||
})
|
||||
.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) {
|
||||
@ -608,12 +617,12 @@ function($rootScope, $location, $log, $routeParams, Rest, Alert, HostForm, Gener
|
||||
var host, old_name;
|
||||
if (mode === 'edit') {
|
||||
// Update the name on the list
|
||||
host = Find({ list: parent_scope.hosts, key: 'id', val: host_id });
|
||||
host = Find({ list: scope.hosts, key: 'id', val: host_id });
|
||||
old_name = host.name;
|
||||
host.name = scope.name;
|
||||
host.enabled = (scope.enabled) ? true : false;
|
||||
host.enabled_flag = host.enabled;
|
||||
SetStatus({ scope: parent_scope, host: host });
|
||||
SetStatus({ scope: scope, host: host });
|
||||
// Update any titles attributes created by ApplyEllipsis
|
||||
if (old_name) {
|
||||
setTimeout(function() {
|
||||
@ -630,12 +639,7 @@ function($rootScope, $location, $log, $routeParams, Rest, Alert, HostForm, Gener
|
||||
}
|
||||
else {
|
||||
$('#host-modal-dialog').dialog('close');
|
||||
HostsReload({
|
||||
scope: parent_scope,
|
||||
group_id: parent_scope.selected_group_id,
|
||||
tree_id: parent_scope.selected_tree_id,
|
||||
inventory_id: parent_scope.inventory_id
|
||||
});
|
||||
parent_scope.refreshHosts();
|
||||
}
|
||||
|
||||
// Restore ellipsis response to window resize
|
||||
@ -691,48 +695,38 @@ function($rootScope, $location, $log, $routeParams, Rest, Alert, HostForm, Gener
|
||||
};
|
||||
|
||||
scope.cancelModal = function() {
|
||||
$('#host-modal-dialog').dialog('close');
|
||||
try {
|
||||
$('#host-modal-dialog').dialog('close');
|
||||
}
|
||||
catch(err) {
|
||||
// ignore
|
||||
}
|
||||
parent_scope.refreshHosts();
|
||||
};
|
||||
|
||||
};
|
||||
}])
|
||||
|
||||
|
||||
.factory('HostsDelete', ['$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'Prompt', 'ProcessErrors', 'GetBasePath',
|
||||
'HostsReload', 'Wait', 'Find', 'Empty',
|
||||
function($rootScope, $location, $log, $routeParams, Rest, Alert, Prompt, ProcessErrors, GetBasePath, HostsReload, Wait, Find, Empty) {
|
||||
.factory('HostsDelete', ['$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'Prompt', 'ProcessErrors', 'GetBasePath', 'HostsReload', 'Wait',
|
||||
function($rootScope, $location, $log, $routeParams, Rest, Alert, Prompt, ProcessErrors, GetBasePath, HostsReload, Wait) {
|
||||
return function(params) {
|
||||
// Remove the selected host from the current group by disassociating
|
||||
|
||||
var action_to_take, body,
|
||||
scope = params.scope,
|
||||
scope = params.parent_scope,
|
||||
host_id = params.host_id,
|
||||
host_name = params.host_name,
|
||||
group,
|
||||
url_list = [];
|
||||
|
||||
function getChildren(tree_id) {
|
||||
var parent, found, j;
|
||||
for (j = 0; j < scope.groups.length; j++) {
|
||||
if (scope.groups[j].id === tree_id || scope.groups[j].parent === parent) {
|
||||
found = true;
|
||||
url_list.push(GetBasePath('groups') + scope.groups[j].group_id + '/hosts/');
|
||||
parent = scope.groups[j].id;
|
||||
}
|
||||
else {
|
||||
if (found) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!Empty(scope.selected_group_id)) {
|
||||
group = Find({ list: scope.groups, key: 'id', val: scope.selected_tree_id });
|
||||
getChildren(group.id);
|
||||
if (scope.selected_group_id) {
|
||||
//group = Find({ list: parent_scope.groups, key: 'id', val: parent_scope.selected_group_id });
|
||||
//getChildren(group.id);
|
||||
url_list.push(GetBasePath('groups') + scope.selected_group_id + '/hosts/');
|
||||
}
|
||||
else {
|
||||
url_list.push(GetBasePath('inventory') + scope.inventory_id + '/hosts/');
|
||||
url_list.push(GetBasePath('inventory') + scope.inventory.id + '/hosts/');
|
||||
}
|
||||
|
||||
if (scope.removeHostsReload) {
|
||||
@ -740,7 +734,7 @@ function($rootScope, $location, $log, $routeParams, Rest, Alert, Prompt, Process
|
||||
}
|
||||
scope.removeHostsReload = scope.$on('hostsReload', function() {
|
||||
$('#prompt-modal').modal('hide');
|
||||
scope.showHosts(scope.selected_tree_id, scope.selected_group_id, false);
|
||||
scope.refreshHosts();
|
||||
});
|
||||
|
||||
$('#prompt-modal').on('hidden.bs.modal', function(){ Wait('stop'); });
|
||||
@ -782,6 +776,243 @@ function($rootScope, $location, $log, $routeParams, Rest, Alert, Prompt, Process
|
||||
};
|
||||
}])
|
||||
|
||||
.factory('HostsCopy', ['$compile', 'Rest', 'ProcessErrors', 'CreateDialog', 'GetBasePath', 'Wait', 'GenerateList', 'GroupList', 'SearchInit',
|
||||
'PaginateInit',
|
||||
function($compile, Rest, ProcessErrors, CreateDialog, GetBasePath, Wait, GenerateList, GroupList, SearchInit, PaginateInit) {
|
||||
return function(params) {
|
||||
|
||||
var host_id = params.host_id,
|
||||
group_scope = params.group_scope,
|
||||
parent_scope = params.host_scope,
|
||||
parent_group = group_scope.selected_group_id,
|
||||
scope = parent_scope.$new(),
|
||||
buttonSet, url, host;
|
||||
|
||||
buttonSet = [{
|
||||
label: "Cancel",
|
||||
onClick: function() {
|
||||
scope.cancel();
|
||||
},
|
||||
icon: "fa-times",
|
||||
"class": "btn btn-default",
|
||||
"id": "host-copy-cancel-button"
|
||||
},{
|
||||
label: "OK",
|
||||
onClick: function() {
|
||||
scope.performCopy();
|
||||
},
|
||||
icon: "fa-check",
|
||||
"class": "btn btn-primary",
|
||||
"id": "host-copy-ok-button"
|
||||
}];
|
||||
|
||||
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');
|
||||
$('#host-copy-dialog').dialog('open');
|
||||
$('#host-copy-ok-button').attr('disabled','disabled');
|
||||
|
||||
// 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') + group_scope.inventory.id + '/groups/';
|
||||
GenerateList.inject(GroupList, {
|
||||
mode: 'lookup',
|
||||
id: 'copy-host-select-container',
|
||||
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;
|
||||
scope.copy_choice = "copy";
|
||||
d = angular.element(document.getElementById('host-copy-dialog'));
|
||||
$compile(d)(scope);
|
||||
CreateDialog({
|
||||
id: 'host-copy-dialog',
|
||||
scope: scope,
|
||||
buttons: buttonSet,
|
||||
width: 650,
|
||||
height: 650,
|
||||
minWidth: 600,
|
||||
title: 'Copy or Move Host',
|
||||
callback: 'HostCopyDialogReady',
|
||||
onClose: function() {
|
||||
scope.cancel();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Wait('start');
|
||||
|
||||
url = GetBasePath('hosts') + host_id + '/';
|
||||
Rest.setUrl(url);
|
||||
Rest.get()
|
||||
.success(function(data) {
|
||||
host = data;
|
||||
scope.$emit('ShowDialog');
|
||||
})
|
||||
.error(function(data, status) {
|
||||
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
|
||||
msg: 'Call to ' + url + ' failed. GET returned: ' + status });
|
||||
});
|
||||
|
||||
|
||||
scope.cancel = function() {
|
||||
$(document).off("keydown");
|
||||
try {
|
||||
$('#host-copy-dialog').dialog('close');
|
||||
}
|
||||
catch(e) {
|
||||
// ignore
|
||||
}
|
||||
scope.searchCleanup();
|
||||
group_scope.restoreSearch(); // Restore all parent search stuff and refresh hosts and groups lists
|
||||
scope.$destroy();
|
||||
};
|
||||
|
||||
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 === '0') {
|
||||
scope[list.name][i].checked = '1';
|
||||
scope[list.name][i].success_class = 'success';
|
||||
}
|
||||
else {
|
||||
scope[list.name][i].checked = '0';
|
||||
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 === '1') {
|
||||
count++;
|
||||
}
|
||||
});
|
||||
if (count === 0) {
|
||||
$('#host-copy-ok-button').attr('disabled','disabled');
|
||||
}
|
||||
else {
|
||||
$('#host-copy-ok-button').removeAttr('disabled');
|
||||
}
|
||||
};
|
||||
|
||||
scope.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 (scope.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 () {
|
||||
scope.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 {
|
||||
scope.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 () {
|
||||
scope.cancel();
|
||||
})
|
||||
.error(function (data, status) {
|
||||
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
|
||||
msg: 'Failed to add ' + host.name + ' to ' + target.name + '. POST returned: ' + status
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
};
|
||||
}])
|
||||
|
||||
.factory('EditHostGroups', ['$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'GenerateForm', 'Prompt',
|
||||
'ProcessErrors', 'GetBasePath', 'HostsReload', 'ParseTypeChange', 'Wait',
|
||||
function($rootScope, $location, $log, $routeParams, Rest, Alert, GenerateForm, Prompt, ProcessErrors, GetBasePath, HostsReload,
|
||||
|
||||
@ -279,7 +279,6 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper'])
|
||||
url += connect + scope[iterator + 'ExtraParms'];
|
||||
}
|
||||
url = url.replace(/\&\&/g, '&');
|
||||
|
||||
if (calcOnly) {
|
||||
scope.$emit('searchParamsReady', url);
|
||||
}
|
||||
|
||||
@ -142,6 +142,7 @@ angular.module('InventoryGroupsDefinition', [])
|
||||
mode: 'all',
|
||||
ngClick: "copyGroup(group.id)",
|
||||
awToolTip: 'Copy or move group',
|
||||
ngShow: "group.id > 0",
|
||||
dataPlacement: "top"
|
||||
},
|
||||
"delete": {
|
||||
|
||||
@ -76,6 +76,12 @@ angular.module('InventoryHostsDefinition', [])
|
||||
awToolTip: 'Edit host',
|
||||
dataPlacement: 'top'
|
||||
},
|
||||
copy: {
|
||||
mode: 'all',
|
||||
ngClick: "copyHost(host.id)",
|
||||
awToolTip: 'Copy or move host to another group',
|
||||
dataPlacement: "top"
|
||||
},
|
||||
"delete": {
|
||||
//label: 'Delete',
|
||||
ngClick: "deleteHost(host.id, host.name)",
|
||||
@ -89,7 +95,7 @@ angular.module('InventoryHostsDefinition', [])
|
||||
create: {
|
||||
mode: 'all',
|
||||
ngClick: "createHost()",
|
||||
ngHide: 'selected_tree_id == 1', //disable when 'All Hosts' selected
|
||||
ngHide: '!selected_group_id', //disable when 'All Hosts' selected
|
||||
awToolTip: "Create a new host"
|
||||
},
|
||||
stream: {
|
||||
|
||||
@ -92,7 +92,7 @@ angular.module('StreamWidget', ['RestServices', 'Utilities', 'StreamListDefiniti
|
||||
.factory('StreamBreadCrumbs', ['$rootScope', '$location',
|
||||
function ($rootScope, $location) {
|
||||
return function () {
|
||||
// Load the breadcrumbs array. We have to do things a bit different than Utilities.LoadBreadcrumbs.
|
||||
// Load the breadcrumbs array. We have to do things a bit different than Utilities.LoadBreadcrumbs.
|
||||
// Rather than botch that all up, we'll do our own thing here.
|
||||
$rootScope.breadcrumbs = [];
|
||||
var path, title, i, j, paths = $location.path().split('/');
|
||||
@ -188,7 +188,7 @@ angular.module('StreamWidget', ['RestServices', 'Utilities', 'StreamListDefiniti
|
||||
// labels
|
||||
obj1 = activity.object1;
|
||||
obj2 = activity.object2;
|
||||
|
||||
|
||||
// objects
|
||||
obj1_obj = (activity.summary_fields[obj1]) ? activity.summary_fields[obj1][0] : null;
|
||||
if (obj1 === obj2) {
|
||||
@ -279,7 +279,7 @@ angular.module('StreamWidget', ['RestServices', 'Utilities', 'StreamListDefiniti
|
||||
n, rows, scope;
|
||||
|
||||
if (activity) {
|
||||
// Setup changes field
|
||||
// Setup changes field
|
||||
activity.changes_stringified = JSON.stringify(activity.changes, null, '\t');
|
||||
n = activity.changes_stringified.match(/\n/g);
|
||||
rows = (n) ? n.length : 1;
|
||||
@ -300,7 +300,7 @@ angular.module('StreamWidget', ['RestServices', 'Utilities', 'StreamListDefiniti
|
||||
$('#form-modal').on('show.bs.modal', function () {
|
||||
$('#form-modal-body').css({
|
||||
width: 'auto', //probably not needed
|
||||
height: 'auto', //probably not needed
|
||||
height: 'auto', //probably not needed
|
||||
'max-height': '100%'
|
||||
});
|
||||
});
|
||||
@ -349,7 +349,7 @@ angular.module('StreamWidget', ['RestServices', 'Utilities', 'StreamListDefiniti
|
||||
if (paths.length > 1 && /^\d+/.test(paths[paths.length - 1])) {
|
||||
type = paths[paths.length - 2];
|
||||
type = (type === 'inventories') ? 'inventory' : type.replace(/s$/, '');
|
||||
//defaultUrl += '?object1=' + type + '&object1__id=' +
|
||||
//defaultUrl += '?object1=' + type + '&object1__id=' +
|
||||
defaultUrl += '?' + type + '__id=' + paths[paths.length - 1];
|
||||
} else if (paths.length > 1) {
|
||||
type = paths[paths.length - 1];
|
||||
@ -368,7 +368,7 @@ angular.module('StreamWidget', ['RestServices', 'Utilities', 'StreamListDefiniti
|
||||
|
||||
// Fix inventory name. The way we're doing breadcrumbs doesn't support bind variables.
|
||||
if (inventory_name) {
|
||||
itm = Find({ list: $rootScope.breadcrumbs, key: 'title', val: '{{ inventory_name }}' });
|
||||
itm = Find({ list: $rootScope.breadcrumbs, key: 'title', val: '{{ inventory.name }}' });
|
||||
if (itm) {
|
||||
itm.title = inventory_name;
|
||||
}
|
||||
@ -424,7 +424,7 @@ angular.module('StreamWidget', ['RestServices', 'Utilities', 'StreamListDefiniti
|
||||
scope.activities.forEach(function(activity, i) {
|
||||
var row = scope.activities[i],
|
||||
type, url;
|
||||
|
||||
|
||||
if (scope.activities[i].summary_fields.actor) {
|
||||
scope.activities[i].user = "<a href=\"/#/users/" + scope.activities[i].summary_fields.actor.id + "\">" +
|
||||
scope.activities[i].summary_fields.actor.username + "</a>";
|
||||
@ -436,7 +436,7 @@ angular.module('StreamWidget', ['RestServices', 'Utilities', 'StreamListDefiniti
|
||||
deleted = /^\_delete/;
|
||||
obj1 = scope.activities[i].object1;
|
||||
obj2 = scope.activities[i].object2;
|
||||
|
||||
|
||||
if ((obj1 === "schedule" || obj2 === "schedule") && activity.summary_fields.schedule) {
|
||||
if (activity.summary_fields.inventory_source) {
|
||||
type = 'inventory_source';
|
||||
|
||||
@ -36,6 +36,7 @@
|
||||
@import "log-viewer.less";
|
||||
@import "job-details.less";
|
||||
@import "jobs.less";
|
||||
@import "inventory-edit.less";
|
||||
|
||||
|
||||
html, body { height: 100%; }
|
||||
@ -1823,7 +1824,7 @@ tr td button i {
|
||||
}
|
||||
|
||||
#hosts-container.col-lg-6 {
|
||||
margin-toop: 15px;
|
||||
margin-top: 15px;
|
||||
padding-left: 15px;
|
||||
padding-right: 15px;
|
||||
}
|
||||
|
||||
123
awx/ui/static/less/inventory-edit.less
Normal file
123
awx/ui/static/less/inventory-edit.less
Normal file
@ -0,0 +1,123 @@
|
||||
/*********************************************
|
||||
* Copyright (c) 2014 AnsibleWorks, Inc.
|
||||
*
|
||||
* inventory-edit.less
|
||||
*
|
||||
* custom animation mixins for ansible-ui
|
||||
*
|
||||
*/
|
||||
#inventory_edit {
|
||||
#breadcrumbs .nav-path {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
}
|
||||
.group-breadcrumbs {
|
||||
list-style: none;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
margin: 0 0 8px 0;
|
||||
}
|
||||
.group-breadcrumbs li {
|
||||
float: left;
|
||||
height: 26px;
|
||||
margin-top: 3px;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
.group-breadcrumbs li a {
|
||||
color: @white;
|
||||
font-weight: normal;
|
||||
text-decoration: none;
|
||||
padding: 3px 8px 3px 20px;
|
||||
background: @blue-dark; /* fallback color */
|
||||
position: relative;
|
||||
left: 0;
|
||||
top: 0;
|
||||
display: block;
|
||||
float: left;
|
||||
}
|
||||
.group-breadcrumbs li.active a {
|
||||
background: @grey;
|
||||
color: @black;
|
||||
font-weight: normal;
|
||||
}
|
||||
.group-breadcrumbs li a:after {
|
||||
content: " ";
|
||||
display: block;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-top: 13px dashed transparent; /* Go big on the size, and let overflow hide */
|
||||
border-bottom: 13px dashed transparent;
|
||||
border-left: 11px solid @blue-dark;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
margin-top: -13px;
|
||||
left: 100%;
|
||||
z-index: 2;
|
||||
}
|
||||
.group-breadcrumbs li.active a:after {
|
||||
border-left: 13px solid @grey;
|
||||
}
|
||||
.group-breadcrumbs li a:before {
|
||||
content: " ";
|
||||
display: block;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-top: 13px dashed transparent;
|
||||
border-bottom: 13px dashed transparent;
|
||||
border-left: 11px solid @white;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
margin-top: -13px;
|
||||
margin-left: 1px;
|
||||
left: 100%;
|
||||
z-index: 1;
|
||||
}
|
||||
.group-breadcrumbs li.active a:before {
|
||||
border-left: 11px solid @white;
|
||||
}
|
||||
|
||||
#group-copy-dialog,
|
||||
#host-copy-dialog {
|
||||
.highlight {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: red;
|
||||
padding-right: 5px;
|
||||
}
|
||||
.title {
|
||||
font-weight: bold;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.well {
|
||||
padding-left: 8px;
|
||||
padding-right: 8px;
|
||||
padding-top: 8px;
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
.page-row ul li a {
|
||||
font-size: 12px;
|
||||
}
|
||||
.page-row .col-lg-8 {
|
||||
width: 100%;
|
||||
}
|
||||
.page-row .col-md-8 {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
#copy-group-radio-container .form-group {
|
||||
margin-left: 20px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
#copy-group-target-container .form-group {
|
||||
margin-top: 10px;
|
||||
margin-left: 20px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
#group-list-container {
|
||||
.list-actions {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
@ -7,7 +7,7 @@
|
||||
* Build data for the tree selector table used on inventory detail page.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
'use strict';
|
||||
|
||||
angular.module('InventoryTree', ['Utilities', 'RestServices', 'GroupsHelper', 'PromptDialog'])
|
||||
@ -101,14 +101,14 @@ angular.module('InventoryTree', ['Utilities', 'RestServices', 'GroupsHelper', 'P
|
||||
}
|
||||
|
||||
function buildGroups(tree_data, parent, level) {
|
||||
|
||||
|
||||
var children, stat, hosts_status, group,
|
||||
sorted = SortNodes(tree_data),
|
||||
expand, show;
|
||||
|
||||
|
||||
sorted.forEach( function(row, i) {
|
||||
id++;
|
||||
|
||||
|
||||
stat = GetSyncStatusMsg({
|
||||
status: sorted[i].summary_fields.inventory_source.status,
|
||||
has_inventory_sources: sorted[i].has_inventory_sources,
|
||||
@ -131,7 +131,7 @@ angular.module('InventoryTree', ['Utilities', 'RestServices', 'GroupsHelper', 'P
|
||||
show = getShowState(sorted[i].id);
|
||||
if (show === null) {
|
||||
// this is a node we haven't seen before, so check the parent expand/collapse state
|
||||
// If parent is not expanded, then child should be hidden.
|
||||
// If parent is not expanded, then child should be hidden.
|
||||
show = true;
|
||||
if (parent > 0) {
|
||||
groups.every(function(g) {
|
||||
@ -249,7 +249,7 @@ angular.module('InventoryTree', ['Utilities', 'RestServices', 'GroupsHelper', 'P
|
||||
])
|
||||
|
||||
|
||||
// Update a group with a set of properties
|
||||
// Update a group with a set of properties
|
||||
.factory('UpdateGroup', ['ApplyEllipsis', 'GetSyncStatusMsg', 'Empty',
|
||||
function (ApplyEllipsis, GetSyncStatusMsg, Empty) {
|
||||
return function (params) {
|
||||
@ -258,9 +258,9 @@ angular.module('InventoryTree', ['Utilities', 'RestServices', 'GroupsHelper', 'P
|
||||
group_id = params.group_id,
|
||||
properties = params.properties,
|
||||
i, p, grp, old_name, stat;
|
||||
|
||||
|
||||
for (i = 0; i < scope.groups.length; i++) {
|
||||
if (scope.groups[i].group_id === group_id) {
|
||||
if (scope.groups[i].id === group_id) {
|
||||
grp = scope.groups[i];
|
||||
for (p in properties) {
|
||||
if (p === 'name') {
|
||||
@ -291,12 +291,12 @@ angular.module('InventoryTree', ['Utilities', 'RestServices', 'GroupsHelper', 'P
|
||||
scope.groups[i][p] = properties[p];
|
||||
}
|
||||
}
|
||||
if (scope.groups[i].id === scope.selected_tree_id) {
|
||||
/*if (scope.groups[i].id === scope.selected_tree_id) {
|
||||
//Make sure potential group name change gets reflected throughout the page
|
||||
scope.selected_group_name = scope.groups[i].name;
|
||||
scope.search_place_holder = 'Search ' + scope.groups[i].name;
|
||||
scope.hostSearchPlaceholder = 'Search ' + scope.groups[i].name;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
// Update any titles attributes created by ApplyEllipsis
|
||||
@ -406,7 +406,7 @@ angular.module('InventoryTree', ['Utilities', 'RestServices', 'GroupsHelper', 'P
|
||||
show: true
|
||||
});
|
||||
|
||||
// Respond to move
|
||||
// Respond to move
|
||||
scope.moveGroup = function () {
|
||||
var url, group, parent;
|
||||
$('#copy-prompt-modal').modal('hide');
|
||||
|
||||
@ -19,7 +19,7 @@ angular.module('Utilities', ['RestServices', 'Utilities'])
|
||||
.factory('ClearScope', [
|
||||
function () {
|
||||
return function () {
|
||||
|
||||
|
||||
$('#form-modal .modal-body').empty();
|
||||
$('#form-modal2 .modal-body').empty();
|
||||
|
||||
@ -59,7 +59,7 @@ angular.module('Utilities', ['RestServices', 'Utilities'])
|
||||
|
||||
.factory('ToggleClass', function () {
|
||||
return function (selector, cssClass) {
|
||||
// Toggles the existance of a css class on a given element
|
||||
// Toggles the existance of a css class on a given element
|
||||
if ($(selector) && $(selector).hasClass(cssClass)) {
|
||||
$(selector).removeClass(cssClass);
|
||||
} else if ($(selector)) {
|
||||
@ -69,7 +69,7 @@ angular.module('Utilities', ['RestServices', 'Utilities'])
|
||||
})
|
||||
|
||||
|
||||
/*
|
||||
/*
|
||||
* Pass in the header and message you want displayed on TB modal dialog found in index.html.
|
||||
* Assumes an #id of 'alert-modal'. Pass in an optional TB alert class (i.e. alert-danger, alert-success,
|
||||
* alert-info...). Pass an optional function(){}, if you want a specific action to occur when user
|
||||
@ -91,7 +91,7 @@ angular.module('Utilities', ['RestServices', 'Utilities'])
|
||||
backdrop: 'static'
|
||||
});
|
||||
scope.disableButtons2 = (disableButtons) ? true : false;
|
||||
|
||||
|
||||
$('#alert-modal2').on('hidden.bs.modal', function () {
|
||||
if (action) {
|
||||
action();
|
||||
@ -238,7 +238,7 @@ angular.module('Utilities', ['RestServices', 'Utilities'])
|
||||
return (a === 'ies') ? 'y' : '';
|
||||
}
|
||||
|
||||
//Keep a list of path/title mappings. When we see /organizations/XX in the path, for example,
|
||||
//Keep a list of path/title mappings. When we see /organizations/XX in the path, for example,
|
||||
//we'll know the actual organization name it maps to.
|
||||
if (!Empty(crumb)) {
|
||||
found = false;
|
||||
@ -288,7 +288,7 @@ angular.module('Utilities', ['RestServices', 'Utilities'])
|
||||
} else {
|
||||
//if (/_/.test(paths[i])) {
|
||||
// replace '_' with space and uppercase each word
|
||||
|
||||
|
||||
//}
|
||||
//title = paths[i].charAt(0).toUpperCase() + paths[i].slice(1);
|
||||
title = paths[i].replace(/(?:^|_)\S/g, toUppercase).replace(/_/g, ' ');
|
||||
@ -313,7 +313,7 @@ angular.module('Utilities', ['RestServices', 'Utilities'])
|
||||
.factory('HelpDialog', ['$rootScope', '$location', 'Store',
|
||||
function ($rootScope, $location, Store) {
|
||||
return function (params) {
|
||||
|
||||
|
||||
var defn = params.defn,
|
||||
current_step = params.step,
|
||||
autoShow = params.autoShow || false;
|
||||
@ -463,9 +463,9 @@ angular.module('Utilities', ['RestServices', 'Utilities'])
|
||||
])
|
||||
|
||||
|
||||
/*
|
||||
/*
|
||||
* Split the current path by '/' and use the array elements from 0 up to and
|
||||
* including idx as the new path. If no idx value supplied, use 0 to length - 1.
|
||||
* including idx as the new path. If no idx value supplied, use 0 to length - 1.
|
||||
*
|
||||
*/
|
||||
.factory('ReturnToCaller', ['$location', 'Empty',
|
||||
@ -496,9 +496,9 @@ angular.module('Utilities', ['RestServices', 'Utilities'])
|
||||
}
|
||||
])
|
||||
|
||||
/*
|
||||
* Display a spinning icon in the center of the screen to freeze the
|
||||
* UI while waiting on async things to complete (i.e. API calls).
|
||||
/*
|
||||
* Display a spinning icon in the center of the screen to freeze the
|
||||
* UI while waiting on async things to complete (i.e. API calls).
|
||||
* Wait('start' | 'stop');
|
||||
*
|
||||
*/
|
||||
@ -575,16 +575,16 @@ angular.module('Utilities', ['RestServices', 'Utilities'])
|
||||
}
|
||||
])
|
||||
|
||||
/*
|
||||
/*
|
||||
* Make an Options call to the API and retrieve dropdown options
|
||||
*
|
||||
* GetChoices({
|
||||
* scope: Parent $scope
|
||||
* url: API resource to access
|
||||
* url: API resource to access
|
||||
* field: API element in the response object that contains the option list.
|
||||
* variable: Scope variable that will receive the list.
|
||||
* callback: Optional. Will issue scope.$emit(callback) on completion.
|
||||
* choice_name: Optional. Used when list is found in a variable other than 'choices'.
|
||||
* choice_name: Optional. Used when list is found in a variable other than 'choices'.
|
||||
* })
|
||||
*/
|
||||
.factory('GetChoices', ['Rest', 'ProcessErrors',
|
||||
@ -655,8 +655,8 @@ angular.module('Utilities', ['RestServices', 'Utilities'])
|
||||
}
|
||||
])
|
||||
|
||||
/*
|
||||
* DeugForm({ form: <form object>, scope: <current scope object> });
|
||||
/*
|
||||
* DebugForm({ form: <form object>, scope: <current scope object> });
|
||||
*
|
||||
* Use to log the $pristine and $valid properties of each form element. Helpful when form
|
||||
* buttons fail to enable/disable properly.
|
||||
@ -721,7 +721,7 @@ angular.module('Utilities', ['RestServices', 'Utilities'])
|
||||
.factory('ApplyEllipsis', [
|
||||
function () {
|
||||
return function (selector) {
|
||||
// Add a hidden element to the DOM. We'll use this to calc the px length of
|
||||
// Add a hidden element to the DOM. We'll use this to calc the px length of
|
||||
// our target text.
|
||||
var tmp = $('#string-test');
|
||||
if (!tmp.length) {
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* FormGenerator
|
||||
*
|
||||
* Pass in a form definition and get back an html template. Use the.inject() method
|
||||
* Pass in a form definition and get back an html template. Use the.inject() method
|
||||
* to add the template to the DOM and compile.
|
||||
*
|
||||
*/
|
||||
@ -123,7 +123,7 @@ angular.module('FormGenerator', ['GeneratorHelpers', 'Utilities', 'ListGenerator
|
||||
try {
|
||||
$('#help-modal').empty().dialog('destroy');
|
||||
} catch (e) {
|
||||
//ignore any errors should the dialog not be initialized
|
||||
//ignore any errors should the dialog not be initialized
|
||||
}
|
||||
|
||||
if (options.modal) {
|
||||
@ -134,7 +134,7 @@ angular.module('FormGenerator', ['GeneratorHelpers', 'Utilities', 'ListGenerator
|
||||
if (options.modal_title_id) {
|
||||
this.scope[options.modal_title_id] = (options.mode === 'add') ? form.addTitle : form.editTitle;
|
||||
} else {
|
||||
this.scope.formModalHeader = (options.mode === 'add') ? form.addTitle : form.editTitle; //Default title for default modal
|
||||
this.scope.formModalHeader = (options.mode === 'add') ? form.addTitle : form.editTitle; //Default title for default modal
|
||||
}
|
||||
}
|
||||
if (options.modal_selector) {
|
||||
@ -189,8 +189,11 @@ angular.module('FormGenerator', ['GeneratorHelpers', 'Utilities', 'ListGenerator
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (!this.scope.$$phase) {
|
||||
this.scope.$digest();
|
||||
setTimeout(function() {
|
||||
this.scope.$digest();
|
||||
}, 100);
|
||||
}
|
||||
|
||||
return this.scope;
|
||||
@ -201,7 +204,7 @@ angular.module('FormGenerator', ['GeneratorHelpers', 'Utilities', 'ListGenerator
|
||||
// Get HTML without actually injecting into DOM. Caller is responsible for any injection.
|
||||
// Example:
|
||||
// html = GenerateForm.buildHTML(JobVarsPromptForm, { mode: 'edit', modal: true, scope: scope });
|
||||
|
||||
|
||||
this.mode = options.mode;
|
||||
this.modal = (options.modal) ? true : false;
|
||||
this.setForm(form);
|
||||
@ -351,7 +354,7 @@ angular.module('FormGenerator', ['GeneratorHelpers', 'Utilities', 'ListGenerator
|
||||
active: active,
|
||||
activate: function () {
|
||||
// Maintain in local storage of list of all accordions by page, recording
|
||||
// the active panel for each. If user navigates away and comes back,
|
||||
// the active panel for each. If user navigates away and comes back,
|
||||
// we can activate the last panely viewed.
|
||||
$('.jqui-accordion').each(function () {
|
||||
var active = $(this).accordion('option', 'active'),
|
||||
@ -542,7 +545,7 @@ angular.module('FormGenerator', ['GeneratorHelpers', 'Utilities', 'ListGenerator
|
||||
return html;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (field.type === 'alertblock') {
|
||||
html += "<div class=\"row\">\n";
|
||||
html += "<div class=\"";
|
||||
@ -1030,7 +1033,7 @@ angular.module('FormGenerator', ['GeneratorHelpers', 'Utilities', 'ListGenerator
|
||||
},
|
||||
|
||||
getActions: function (options) {
|
||||
// Use to add things like Activity Stream to a detail page
|
||||
// Use to add things like Activity Stream to a detail page
|
||||
var html = "<div class=\"list-actions\">\n", action;
|
||||
for (action in this.form.actions) {
|
||||
if (this.form.actions[action].mode === 'all' || this.form.actions[action].mode === options.mode) {
|
||||
@ -1102,8 +1105,8 @@ angular.module('FormGenerator', ['GeneratorHelpers', 'Utilities', 'ListGenerator
|
||||
|
||||
build: function (options) {
|
||||
//
|
||||
// Generate HTML. Do NOT call this function directly. Called by inject(). Returns an HTML
|
||||
// string to be injected into the current view.
|
||||
// Generate HTML. Do NOT call this function directly. Called by inject(). Returns an HTML
|
||||
// string to be injected into the current view.
|
||||
//
|
||||
var btn, button, fld, field, html = '', i, section, group,
|
||||
tab, sectionShow, offset, width;
|
||||
@ -1115,7 +1118,7 @@ angular.module('FormGenerator', ['GeneratorHelpers', 'Utilities', 'ListGenerator
|
||||
html += this.breadCrumbs(options);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (this.form.collapse && this.form.collapseMode === options.mode) {
|
||||
html += "<div id=\"" + this.form.name + "-collapse-0\" ";
|
||||
html += (this.form.collapseOpen) ? "data-open=\"true\" " : "";
|
||||
@ -1337,7 +1340,7 @@ angular.module('FormGenerator', ['GeneratorHelpers', 'Utilities', 'ListGenerator
|
||||
if (this.form.collapse && this.form.collapseMode === options.mode) {
|
||||
html += "</div>\n";
|
||||
}
|
||||
|
||||
|
||||
if ((!this.modal) && options.related && this.form.related) {
|
||||
html += this.buildCollections(options);
|
||||
}
|
||||
@ -1357,7 +1360,7 @@ angular.module('FormGenerator', ['GeneratorHelpers', 'Utilities', 'ListGenerator
|
||||
if (!options.collapseAlreadyStarted) {
|
||||
html = "<div id=\"" + this.form.name + "-collapse-1\" class=\"jqui-accordion\">\n";
|
||||
}
|
||||
|
||||
|
||||
for (itm in form.related) {
|
||||
collection = form.related[itm];
|
||||
html += "<h3 class=\"" + itm + "_collapse\">" + (collection.title || collection.editTitle) + "</h3>\n";
|
||||
@ -1370,7 +1373,7 @@ angular.module('FormGenerator', ['GeneratorHelpers', 'Utilities', 'ListGenerator
|
||||
}
|
||||
html += "</div>\n"; // accordion inner
|
||||
}
|
||||
|
||||
|
||||
if (!options.collapseAlreadyStarted) {
|
||||
html += "</div>\n"; // accordion body
|
||||
}
|
||||
@ -1386,7 +1389,7 @@ angular.module('FormGenerator', ['GeneratorHelpers', 'Utilities', 'ListGenerator
|
||||
itm = params.related,
|
||||
collection = form.related[itm],
|
||||
act, action, fld, cnt, base, fAction;
|
||||
|
||||
|
||||
if (collection.instructions) {
|
||||
html += "<div class=\"alert alert-info alert-block\">\n";
|
||||
html += "<button type=\"button\" class=\"close\" data-dismiss=\"alert\">×</button>\n";
|
||||
|
||||
@ -181,45 +181,41 @@ angular.module('ListGenerator', ['GeneratorHelpers'])
|
||||
|
||||
if (options.showSearch=== undefined || options.showSearch === true) {
|
||||
html += "<div class=\"row\">\n";
|
||||
if (list.name !== 'groups') {
|
||||
if (options.searchSize) {
|
||||
html += SearchWidget({
|
||||
iterator: list.iterator,
|
||||
template: list,
|
||||
mini: true,
|
||||
size: options.searchSize,
|
||||
searchWidgets: list.searchWidgets
|
||||
});
|
||||
} else if (options.mode === 'summary') {
|
||||
html += SearchWidget({
|
||||
iterator: list.iterator,
|
||||
template: list,
|
||||
mini: true,
|
||||
size: 'col-lg-6'
|
||||
});
|
||||
} else if (options.mode === 'lookup' || options.id !== undefined) {
|
||||
html += SearchWidget({
|
||||
iterator: list.iterator,
|
||||
template: list,
|
||||
mini: true,
|
||||
size: 'col-lg-8'
|
||||
});
|
||||
} else {
|
||||
html += SearchWidget({
|
||||
iterator: list.iterator,
|
||||
template: list,
|
||||
mini: true
|
||||
});
|
||||
}
|
||||
if (options.searchSize) {
|
||||
html += SearchWidget({
|
||||
iterator: list.iterator,
|
||||
template: list,
|
||||
mini: true,
|
||||
size: options.searchSize,
|
||||
searchWidgets: list.searchWidgets
|
||||
});
|
||||
} else if (options.mode === 'summary') {
|
||||
html += SearchWidget({
|
||||
iterator: list.iterator,
|
||||
template: list,
|
||||
mini: true,
|
||||
size: 'col-lg-6'
|
||||
});
|
||||
} else if (options.mode === 'lookup' || options.id !== undefined) {
|
||||
html += SearchWidget({
|
||||
iterator: list.iterator,
|
||||
template: list,
|
||||
mini: true,
|
||||
size: 'col-lg-8'
|
||||
});
|
||||
} else {
|
||||
html += SearchWidget({
|
||||
iterator: list.iterator,
|
||||
template: list,
|
||||
mini: true
|
||||
});
|
||||
}
|
||||
|
||||
if (options.mode !== 'lookup') {
|
||||
//actions
|
||||
base = $location.path().replace(/^\//, '').split('/')[0];
|
||||
html += "<div class=\"";
|
||||
if (list.name === 'groups') {
|
||||
html += "col-lg-12";
|
||||
} else if (options.searchSize && !options.listSize) {
|
||||
if (options.searchSize && !options.listSize) {
|
||||
// User supplied searchSize, calc the remaining
|
||||
size = parseInt(options.searchSize.replace(/([A-Z]|[a-z]|\-)/g, ''));
|
||||
size = (list.searchWidgets) ? list.searchWidgets * size : size;
|
||||
@ -416,18 +412,16 @@ angular.module('ListGenerator', ['GeneratorHelpers'])
|
||||
html += "</div>\n"; //well
|
||||
}
|
||||
|
||||
if (list.name !== 'groups') {
|
||||
if (options.mode === 'lookup' || (options.id && options.id === "form-modal-body")) {
|
||||
html += PaginateWidget({
|
||||
set: list.name,
|
||||
iterator: list.iterator
|
||||
});
|
||||
} else {
|
||||
html += PaginateWidget({
|
||||
set: list.name,
|
||||
iterator: list.iterator
|
||||
});
|
||||
}
|
||||
if (options.mode === 'lookup' || (options.id && options.id === "form-modal-body")) {
|
||||
html += PaginateWidget({
|
||||
set: list.name,
|
||||
iterator: list.iterator
|
||||
});
|
||||
} else {
|
||||
html += PaginateWidget({
|
||||
set: list.name,
|
||||
iterator: list.iterator
|
||||
});
|
||||
}
|
||||
|
||||
return html;
|
||||
|
||||
@ -3,23 +3,68 @@
|
||||
<div class="row">
|
||||
<div class="col-lg-12" id="breadcrumbs"></div>
|
||||
</div>
|
||||
<!-- <div class="row">
|
||||
<div id="hosts-title" class="col-lg-offset-6 col-lg-6">{{ selected_group_name }}</div>
|
||||
</div> -->
|
||||
|
||||
<ul class="group-breadcrumbs">
|
||||
<li ng-repeat="group_breadcrumb in group_breadcrumbs" ng-class="group_breadcrumb.active_class"><a href="" ng-click="breadcrumbGroupSelect(group_breadcrumb.id)">{{ group_breadcrumb.name }}</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="row">
|
||||
<div id="groups-container" class="col-lg-6"></div>
|
||||
<div id="groups-container" class="col-lg-6">
|
||||
<div id="group-list-container"></div>
|
||||
</div>
|
||||
<div id="hosts-container" class="col-lg-6"></div>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="inventory-modal-container"></div>
|
||||
|
||||
|
||||
<div id="group-copy-dialog" style="display: none;">
|
||||
<div id="copy-group-radio-container" class="well">
|
||||
<div class="title"><span class="highlight">1.</span> Copy or move <span ng-bind="name"></span>?</div>
|
||||
<div class="form-group">
|
||||
<label class="radio-inline">
|
||||
<input type="radio" ng-model="copy_choice" value="copy"> Copy
|
||||
</label>
|
||||
<label class="radio-inline">
|
||||
<input type="radio" ng-model="copy_choice" value="move"> Move
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div id="copy-group-target-container" class="well">
|
||||
<div class="title" ng-show="offer_root_group"><span class="highlight">2.</span> Select a target group below, OR choose the inventory root:
|
||||
<div class="form-group">
|
||||
<label><input type="checkbox" ng-model="use_root_group" ng-change="toggleUseRootGroup()"> Use the inventory root</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="title" ng-show="!offer_root_group"><span class="highlight">2.</span> Select a target group:</div>
|
||||
<div id="copy-select-container" ng-show="!use_root_group"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="host-copy-dialog" style="display: none;">
|
||||
<div id="copy-group-radio-container" class="well">
|
||||
<div class="title"><span class="highlight">1.</span> Copy or move <span ng-bind="name"></span>?</div>
|
||||
<div class="form-group">
|
||||
<label class="radio-inline">
|
||||
<input type="radio" ng-model="copy_choice" value="copy"> Copy
|
||||
</label>
|
||||
<label class="radio-inline">
|
||||
<input type="radio" ng-model="copy_choice" value="move"> Move
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div id="copy-group-target-container" class="well">
|
||||
<div class="title"><span class="highlight">2.</span> Select a target group:</div>
|
||||
<div id="copy-host-select-container"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="group-modal-dialog" style="display: none;">
|
||||
<ul id="group_tabs" class="nav nav-tabs">
|
||||
<li class="active"><a id="properties_link" ng-click="toggleTab($event, 'properties_link', 'group_tabs')"
|
||||
<li class="active"><a id="properties_link" ng-click="toggleTab($event, 'properties_link', 'group_tabs')"
|
||||
href="#properties-tab" data-toggle="tab">Properties</a></li>
|
||||
<li ng-show="showSourceTab"><a id="source_link" ng-click="toggleTab($event, 'source_link', 'group_tabs')"
|
||||
href="#sources-tab" data-toggle="tab">Source</a></li>
|
||||
<li ng-show="showSchedulesTab"><a id="schedules_link" ng-click="toggleTab($event, 'schedules_link', 'group_tabs')"
|
||||
<li ng-show="showSchedulesTab"><a id="schedules_link" ng-click="toggleTab($event, 'schedules_link', 'group_tabs')"
|
||||
href="#schedules-tab" data-toggle="tab">Schedule</a></li>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
@ -45,11 +90,11 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="host-modal-dialog" style="display: none;" class="dialog-content"></div>
|
||||
|
||||
|
||||
<div id="group-delete-dialog" style="display: none;" class="dialog-content">
|
||||
<div ng-show="groupsCount > 0 || hostsCount > 0">
|
||||
<div class="alert alert-info">
|
||||
@ -59,55 +104,55 @@
|
||||
<span ng-show="groupsCopunt > 0 && hostsCount == 0"> This group contains {{ groupsCount }} groups. </span>
|
||||
Delete or promote the group's children?</p>
|
||||
<div style="width: 50%; margin: 15px auto;">
|
||||
|
||||
|
||||
<div class="radio" ng-show="groupsCount > 0 && hostsCount > 0">
|
||||
<label>
|
||||
<input type="radio" ng-model="deleteOption" name="delete_option1" value="preserve-all"> Promote groups and hosts
|
||||
<input type="radio" ng-model="deleteOption" name="delete_option1" value="preserve-all"> Promote groups and hosts
|
||||
</label>
|
||||
</div>
|
||||
<div class="radio" ng-show="groupsCount > 0 && hostsCount > 0">
|
||||
<label>
|
||||
<input type="radio" ng-model="deleteOption" name="delete_option1" value="delete-all"> Delete groups and hosts
|
||||
<input type="radio" ng-model="deleteOption" name="delete_option1" value="delete-all"> Delete groups and hosts
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="radio" ng-show="groupsCount > 0 && hostsCount == 0">
|
||||
<label>
|
||||
<input type="radio" ng-model="deleteOption" name="delete_option2" value="preserve-all"> Promote groups
|
||||
<input type="radio" ng-model="deleteOption" name="delete_option2" value="preserve-all"> Promote groups
|
||||
</label>
|
||||
</div>
|
||||
<div class="radio" ng-show="groupsCount > 0 && hostsCount == 0">
|
||||
<label>
|
||||
<input type="radio" ng-model="deleteOption" name="delete_option2" value="delete-all"> Delete groups
|
||||
<input type="radio" ng-model="deleteOption" name="delete_option2" value="delete-all"> Delete groups
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="radio" ng-show="groupsCount == 0 && hostsCount > 0">
|
||||
<label>
|
||||
<input type="radio" ng-model="deleteOption" name="delete_option3" value="preserve-all"> Promote hosts
|
||||
<input type="radio" ng-model="deleteOption" name="delete_option3" value="preserve-all"> Promote hosts
|
||||
</label>
|
||||
</div>
|
||||
<div class="radio" ng-show="groupsCount == 0 && hostsCount > 0">
|
||||
<label>
|
||||
<input type="radio" ng-model="deleteOption" name="delete_option3" value="delete-all"> Delete hosts
|
||||
<input type="radio" ng-model="deleteOption" name="delete_option3" value="delete-all"> Delete hosts
|
||||
</label>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="help-container" style="text-align:right;">
|
||||
<a href="" id="awp-promote" href="" aw-pop-over="{{ helpText }}" aw-tool-tip="Click for help" aw-pop-over-watch="helpText" data-placement="top" data-container="body" data-title="Help" class="help-link"><i class="fa fa-question-circle"></i> click for help</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div ng-show="groupsCount == 0 && hostsCount == 0">
|
||||
<div class="alert alert-info">Delete group <em>{{ group_name }}</em>?</div>
|
||||
</div>
|
||||
<div class="alert alert-info">Delete group <em>{{ group_name }}</em>?</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div ng-include="'/static/partials/logviewer.html'"></div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
Loading…
x
Reference in New Issue
Block a user