diff --git a/awx/ui/static/js/helpers/Hosts.js b/awx/ui/static/js/helpers/Hosts.js
index 6501a0f0d9..4a1d637fd7 100644
--- a/awx/ui/static/js/helpers/Hosts.js
+++ b/awx/ui/static/js/helpers/Hosts.js
@@ -175,19 +175,20 @@ function($routeParams, Empty, InventoryHosts, GetBasePath, SearchInit, PaginateI
scope.search_place_holder='Search ' + scope.selected_group_name;
- if (scope.removePostRefresh) {
- scope.removePostRefresh();
- }
- scope.removePostRefresh = scope.$on('PostRefresh', function() {
- for (var i=0; i < scope.hosts.length; i++) {
- //Set tooltip for host enabled flag
- scope.hosts[i].enabled_flag = scope.hosts[i].enabled;
- //SetHostStatus(scope.hosts[i]);
+ //if (scope.removePostRefresh) {
+ // scope.removePostRefresh();
+ //}
+ scope.removePostRefresh = scope.$on('PostRefresh', function(e, set) {
+ if (set === 'hosts') {
+ for (var i=0; i < scope.hosts.length; i++) {
+ //Set tooltip for host enabled flag
+ scope.hosts[i].enabled_flag = scope.hosts[i].enabled;
+ }
+ SetStatus({ scope: scope });
+ setTimeout(function() { ApplyEllipsis('#hosts_table .host-name a'); }, 2500);
+ Wait('stop');
+ scope.$emit('HostReloadComplete');
}
- SetStatus({ scope: scope });
- setTimeout(function() { ApplyEllipsis('#hosts_table .host-name a'); }, 2500);
- Wait('stop');
- scope.$emit('HostReloadComplete');
});
// Size containers based on viewport
@@ -222,14 +223,13 @@ function(GenerateList, InventoryHosts, HostsReload) {
var scope = params.scope,
inventory_id = params.inventory_id,
group_id = params.group_id,
- tree_id = params.tree_id,
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' });
// Load data
- HostsReload({ scope: scope, group_id: group_id, tree_id: tree_id, inventory_id: inventory_id });
+ HostsReload({ scope: scope, group_id: group_id, inventory_id: inventory_id });
};
}])
@@ -239,7 +239,8 @@ function(GetBasePath, Rest, Wait, ProcessErrors, Alert, Find, SetEnabledMsg) {
var id = params.host_id,
external_source = params.external_source,
- scope = params.scope,
+ parent_scope = params.parent_scope,
+ host_scope = params.host_scope,
host;
function setMsg(host) {
@@ -251,7 +252,7 @@ function(GetBasePath, Rest, Wait, ProcessErrors, Alert, Find, SetEnabledMsg) {
if (!external_source) {
// Host is not managed by an external source
Wait('start');
- host = Find({ list: scope.hosts, key: 'id', val: id });
+ host = Find({ list: host_scope.hosts, key: 'id', val: id });
setMsg(host);
Rest.setUrl(GetBasePath('hosts') + id + '/');
@@ -262,8 +263,7 @@ function(GetBasePath, Rest, Wait, ProcessErrors, Alert, Find, SetEnabledMsg) {
.error( function(data, status) {
// Flip the enabled flag back
setMsg(host);
- Wait('stop');
- ProcessErrors(scope, data, status, null,
+ ProcessErrors(parent_scope, data, status, null,
{ hdr: 'Error!', msg: 'Failed to update host. PUT returned status: ' + status });
});
}
diff --git a/awx/ui/static/js/helpers/inventory.js b/awx/ui/static/js/helpers/inventory.js
index e22df667e5..8fe6eafc29 100644
--- a/awx/ui/static/js/helpers/inventory.js
+++ b/awx/ui/static/js/helpers/inventory.js
@@ -14,69 +14,88 @@ angular.module('InventoryHelper', ['RestServices', 'Utilities', 'OrganizationLis
'InventoryHelper', 'InventoryFormDefinition', 'ParseHelper', 'SearchHelper', 'VariablesHelper',
])
+
.factory('GetGroupContainerHeight', [ function() {
return function() {
return $(window).height() - $('.main-menu').outerHeight() - $('#main_tabs').outerHeight() - $('#breadcrumbs').outerHeight() -
- $('.site-footer').outerHeight() - $('#groups-container .list-actions').outerHeight() - $('#groups-table-header').height() - 15;
+ $('.site-footer').outerHeight() - $('.group-breadcrumbs').outerHeight() - $('#groups-container #search-widget-container').outerHeight() - $('#groups_table thead').height() - 70;
};
}])
.factory('GetHostContainerRows', [ function() {
return function() {
var height = $('#hosts-container .well').height() - $('#hosts-constainer .well .row').height() - $('#hosts_table thead').height();
- return Math.floor(height / 27) - 1;
+ return Math.floor(height / 30) - 2;
+ };
+}])
+
+.factory('GetGroupContainerRows', [ function() {
+ return function() {
+ var height = $('#groups-container .list-table-container').height();
+ return Math.floor(height / 31) - 2;
};
}])
.factory('SetContainerHeights', [ 'GetGroupContainerHeight', 'GetHostContainerRows', function(GetGroupContainerHeight, GetHostContainerRows) {
return function(params) {
- var scope = (params && params.scope) ? params.scope : null,
+ var group_scope = params.group_scope,
+ host_scope = params.host_scope,
reloadHosts = (params && params.reloadHosts) ? true : false,
height, rows;
if ($(window).width() > 1210) {
height = GetGroupContainerHeight();
$('#groups-container .list-table-container').height(height);
- $('#hosts-container .well').height( $('#groups-container').height() - 49 );
+ $('#hosts-container .well').height( $('#groups-container .well').height());
}
else {
$('#groups-container .list-table-container').height('auto');
$('#hosts-container .well').height('auto');
}
- $('#groups-container .list-table-container').mCustomScrollbar("update");
+ //$('#groups-container .list-table-container').mCustomScrollbar("update");
if (reloadHosts) {
// we need ro recalc the the page size
if ($(window).width() > 1210) {
rows = GetHostContainerRows();
- scope.host_page_size = rows;
+ host_scope.host_page_size = rows;
+ group_scope.group_page_size = rows;
}
else {
// on small screens we go back to the default
- scope.host_page_size = 20;
+ host_scope.host_page_size = 20;
+ group_scope.group_page_size = 20;
}
- scope.changePageSize('hosts', 'host');
+ host_scope.changePageSize('hosts', 'host');
+ group_scope.changePageSize('groups', 'group');
}
};
}])
+
.factory('WatchInventoryWindowResize', ['ApplyEllipsis', 'SetContainerHeights',
function (ApplyEllipsis, SetContainerHeights) {
return function (params) {
// Call to set or restore window resize
- var scope = params.scope;
+ var group_scope = params.group_scope,
+ host_scope = params.host_scope;
+ $(window).off("resize");
$(window).resize(_.debounce(function() {
// Hack to stop group-name div slipping to a new line
- $('#groups_table .name-column').each(function () {
- var 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 });
- });
+ //$('#groups_table .name-column').each(function () {
+ // var 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 });
+ //});
ApplyEllipsis('#groups_table .group-name a');
ApplyEllipsis('#hosts_table .host-name a');
- SetContainerHeights({ scope: scope, reloadHosts: true });
+ SetContainerHeights({
+ group_scope: group_scope,
+ host_scope: host_scope,
+ reloadHosts: true
+ });
}, 500));
};
}
diff --git a/awx/ui/static/js/helpers/refresh.js b/awx/ui/static/js/helpers/refresh.js
index 18a1e2bfef..3d1fa03e6a 100644
--- a/awx/ui/static/js/helpers/refresh.js
+++ b/awx/ui/static/js/helpers/refresh.js
@@ -24,11 +24,9 @@ angular.module('RefreshHelper', ['RestServices', 'Utilities', 'PaginationHelpers
var scope = params.scope,
set = params.set,
iterator = params.iterator,
- url = params.url;
-
- //scope[iterator + "HidePaginator"] = true;
+ url = params.url,
+ deferWaitStop = params.deferWaitStop;
- //scope[iterator + 'Loading'] = true;
scope.current_url = url;
Rest.setUrl(url);
Rest.get()
@@ -48,8 +46,10 @@ angular.module('RefreshHelper', ['RestServices', 'Utilities', 'PaginationHelpers
scope[set] = data.results;
scope[iterator + 'Loading'] = false;
scope[iterator + 'HidePaginator'] = false;
- Wait('stop');
- scope.$emit('PostRefresh');
+ if (!deferWaitStop) {
+ Wait('stop');
+ }
+ scope.$emit('PostRefresh', set);scope.$emit('PostRefresh');
})
.error(function (data, status) {
scope[iterator + 'HoldInput'] = false;
diff --git a/awx/ui/static/js/helpers/search.js b/awx/ui/static/js/helpers/search.js
index f0e5e29aa6..d0f6b5ca69 100644
--- a/awx/ui/static/js/helpers/search.js
+++ b/awx/ui/static/js/helpers/search.js
@@ -30,7 +30,7 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper'])
iterator = (params.iterator) ? params.iterator : list.iterator,
setWidgets = (params.setWidgets === false) ? false : true,
sort_order = params.sort_order || '',
- widgets, i, modifier, current_params;
+ widgets, i, modifier;
function setDefaults(widget) {
// Set default values
@@ -69,7 +69,7 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper'])
}
// A field marked as key may not be 'searchable', and there might not be a 'defaultSearchField',
- // so find the first searchable field.
+ // so find the first searchable field.
if (Empty(scope[iterator + 'SearchField' + modifier])) {
for (fld in list.fields) {
if (list.fields[fld].searchWidget === undefined && widget === 1 ||
@@ -139,7 +139,7 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper'])
}
}
- current_params = {
+ scope[iterator + '_current_search_params'] = {
set: set,
defaultUrl: defaultUrl,
list: list,
@@ -147,7 +147,8 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper'])
sort_order: sort_order
};
- Store('CurrentSearchParams', current_params); // Save in case Activity Stream widget needs to restore
+ Store(iterator + '_current_search_params', scope[iterator + '_current_search_params']);
+ Store('CurrentSearchParams', scope[iterator + '_current_search_params']); // Keeping this around for activity stream
// Functions to handle search widget changes
@@ -247,19 +248,19 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper'])
if (scope.removeDoSearch) {
scope.removeDoSearch();
}
- scope.removeDoSearch = scope.$on('doSearch', function (e, iterator, page, load, calcOnly) {
+ scope.removeDoSearch = scope.$on('doSearch', function (e, iterator, page, load, calcOnly, deferWaitStop) {
//
// Execute the search
//
var url = (calcOnly) ? '' : defaultUrl,
connect;
-
+
if (!calcOnly) {
scope[iterator + 'Loading'] = (load === undefined || load === true) ? true : false;
scope[iterator + 'Page'] = (page) ? parseInt(page) - 1 : 0;
}
- //finalize and execute the query
+ //finalize and execute the query
if (scope[iterator + 'SearchParams']) {
if (/\/$/.test(url)) {
url += '?' + scope[iterator + 'SearchParams'];
@@ -287,7 +288,8 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper'])
scope: scope,
set: set,
iterator: iterator,
- url: url
+ url: url,
+ deferWaitStop: deferWaitStop
});
}
});
@@ -296,7 +298,7 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper'])
if (scope.removePrepareSearch) {
scope.removePrepareSearch();
}
- scope.removePrepareSearch = scope.$on('prepareSearch', function (e, iterator, page, load, calcOnly) {
+ scope.removePrepareSearch = scope.$on('prepareSearch', function (e, iterator, page, load, calcOnly, deferWaitStop) {
//
// Start building the search key/value pairs. This will process each search widget, if the
// selected field is an object type (used on activity stream).
@@ -342,13 +344,13 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper'])
}
}
}
- scope.$emit('prepareSearch2', iterator, page, load, calcOnly);
+ scope.$emit('prepareSearch2', iterator, page, load, calcOnly, deferWaitStop);
});
if (scope.removePrepareSearch2) {
scope.removePrepareSearch2();
}
- scope.removePrepareSearch2 = scope.$on('prepareSearch2', function (e, iterator, page, load, calcOnly) {
+ scope.removePrepareSearch2 = scope.$on('prepareSearch2', function (e, iterator, page, load, calcOnly, deferWaitStop) {
// Continue building the search by examining the remaining search widgets. If we're looking at activity_stream,
// there's more than one.
var i, modifier,
@@ -397,8 +399,10 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper'])
list.fields[scope[iterator + 'SearchField' + modifier]].searchType === 'gtzero') {
scope[iterator + 'SearchParams'] += 'gt=0';
} else if ( (list.fields[scope[iterator + 'SearchField' + modifier]].searchType === 'select') &&
- Empty(scope[iterator + 'SearchSelectValue' + modifier].value) ) {
+ Empty(scope[iterator + 'SearchSelectValue' + modifier].value) && !/\_\_$/.test(scope[iterator + 'SearchParams']) ) {
scope[iterator + 'SearchParams'] += '=iexact=';
+ } else if (/\_\_$/.test(scope[iterator + 'SearchParams'])) {
+ scope[iterator + 'SearchParams'] += 'icontains=';
} else {
scope[iterator + 'SearchParams'] += scope[iterator + 'SearchType' + modifier] + '=';
}
@@ -431,7 +435,7 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper'])
scope[iterator + 'SearchParams'] += 'order_by=' + encodeURI(sort_order);
}
- scope.$emit('doSearch', iterator, page, load, calcOnly);
+ scope.$emit('doSearch', iterator, page, load, calcOnly, deferWaitStop);
});
scope.startSearch = function (e, iterator) {
@@ -441,22 +445,25 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper'])
}
};
- /**
+ /**
* Initiate a searh.
*
- * @iterator: required, list.iterator value
- * @Page: optional. Added to accomodate back function on Job Events detail.
- * @Load: optional, set to false if 'Loading' message not desired
- * @calcOnly: optiona, set to true when you want to calc or figure out search params without executing the search
+ * @iterator: required, list.iterator value
+ * @Page: optional. Added to accomodate back function on Job Events detail.
+ * @Load: optional, set to false if 'Loading' message not desired
+ * @calcOnly: optional, set to true when you want to calc or figure out search params without executing the search
+ * @deferWaitStop: optional, when true refresh.js will NOT issue Wait('stop'), thus leaving the spinner. Caller is then
+ * responsible for stopping the spinner post refresh.
*/
- scope.search = function (iterator, page, load, calcOnly) {
+ scope.search = function (iterator, page, load, calcOnly, deferWaitStop) {
page = page || null;
load = (load || !scope[set] || scope[set].length === 0) ? true : false;
calcOnly = (calcOnly) ? true : false;
+ deferWaitStop = (deferWaitStop) ? true : false;
if (load) {
scope[set] = []; //clear the list array to make sure 'Loading' is the only thing visible on the list
}
- scope.$emit('prepareSearch', iterator, page, load, calcOnly);
+ scope.$emit('prepareSearch', iterator, page, load, calcOnly, deferWaitStop);
};
@@ -471,7 +478,7 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper'])
});
// Toggle the icon for the clicked column
- // and set the sort direction
+ // and set the sort direction
var icon = $('#' + iterator + '-' + fld + '-header i'),
direction = '';
if (icon.hasClass('fa-sort')) {
@@ -498,6 +505,10 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper'])
sort_order = direction + fld;
}
}
+
+ scope[list.iterator + '_current_search_params'].sort_order = sort_order;
+ Store(iterator + '_current_search_params', scope[iterator + '_current_search_params']);
+
scope.search(list.iterator);
};
diff --git a/awx/ui/static/js/lists/Groups.js b/awx/ui/static/js/lists/Groups.js
index 02fdd68f74..89381bae13 100644
--- a/awx/ui/static/js/lists/Groups.js
+++ b/awx/ui/static/js/lists/Groups.js
@@ -12,8 +12,8 @@
angular.module('GroupListDefinition', [])
.value('GroupList', {
- name: 'groups',
- iterator: 'group',
+ name: 'copy_groups',
+ iterator: 'copy_group',
selectTitle: 'Copy Groups',
editTitle: 'Groups',
index: true,
@@ -23,22 +23,10 @@ angular.module('GroupListDefinition', [])
name: {
key: true,
label: 'Name'
- },
- description: {
- label: 'Description'
}
},
- actions: {
- help: {
- awPopOver: "Choose groups by clicking on each group you wish to add. Click the Select button to add the groups to " +
- "the selected inventory group.",
- dataContainer: '#form-modal .modal-content',
- mode: 'all',
- awToolTip: 'Click for help',
- dataTitle: 'Adding Groups'
- }
- },
+ actions: { },
fieldActions: {
edit: {
diff --git a/awx/ui/static/js/lists/Hosts.js b/awx/ui/static/js/lists/Hosts.js
index 257d43536c..769fe22e83 100644
--- a/awx/ui/static/js/lists/Hosts.js
+++ b/awx/ui/static/js/lists/Hosts.js
@@ -2,7 +2,7 @@
* Copyright (c) 2014 AnsibleWorks, Inc.
*
* Hosts.js
- * List view object for Users data model.
+ * List view object for Hosts data model.
*
*
*/
@@ -12,8 +12,8 @@
angular.module('HostListDefinition', [])
.value('HostList', {
- name: 'hosts',
- iterator: 'host',
+ name: 'copy_hosts',
+ iterator: 'copy_host',
selectTitle: 'Add Existing Hosts',
editTitle: 'Hosts',
index: true,
@@ -22,41 +22,11 @@ angular.module('HostListDefinition', [])
fields: {
name: {
key: true,
- label: 'Host Name',
- linkTo: "/inventories/{{ inventory_id }}/hosts/{{ host.id }}"
- },
- description: {
- label: 'Description'
+ label: 'Host Name'
}
},
- actions: {
- help: {
- awPopOver: "Select hosts by clicking on each host you wish to add. Add the selected hosts to the group by clicking the Select button.",
- dataContainer: '#form-modal .modal-content',
- mode: 'all',
- awToolTip: 'Click for help',
- dataTitle: 'Selecting Hosts'
- }
- },
+ actions: { },
- fieldActions: {
- edit: {
- label: 'Edit',
- ngClick: "editHost({{ host.id }})",
- icon: 'icon-edit',
- "class": 'btn-xs',
- awToolTip: 'Edit host',
- dataPlacement: 'top'
- },
-
- "delete": {
- label: 'Delete',
- ngClick: "deleteHost(host.id, host.name)",
- icon: 'icon-trash',
- "class": 'btn-xs',
- awToolTip: 'Delete host',
- dataPlacement: 'top'
- }
- }
+ fieldActions: { }
});
\ No newline at end of file
diff --git a/awx/ui/static/js/lists/InventoryGroups.js b/awx/ui/static/js/lists/InventoryGroups.js
index 00d2ad2499..34c6dff9d9 100644
--- a/awx/ui/static/js/lists/InventoryGroups.js
+++ b/awx/ui/static/js/lists/InventoryGroups.js
@@ -13,28 +13,57 @@ angular.module('InventoryGroupsDefinition', [])
showTitle: false,
well: true,
index: false,
- hover: false,
- hasChildren: true,
- filterBy: '{ show: true }',
+ hover: true,
'class': 'table-no-border',
- awCustomScroll: true,
fields: {
name: {
label: 'Groups',
key: true,
- ngClick: "showHosts(group.id,group.group_id, false)",
- columnClick: "showHosts(group.id,group.group_id, false)",
- ngClass: "group.selected_class",
- hasChildren: true,
- columnClass: 'col-lg-10 col-md-10 col-sm-10 col-xs-9',
- nosort: true,
- awDroppable: "{{ group.isDroppable }}",
- awDraggable: "{{ group.isDraggable }}",
- dataContainment: "#groups_table",
- dataTreeId: "{{ group.id }}",
- dataGroupId: "{{ group.group_id }}",
- dataType: "group"
+ ngClick: "groupSelect(group.id)",
+ columnClick: "groupSelect(group.id)",
+ columnClass: 'col-lg-10 col-md-10 col-sm-10 col-xs-7'
+ },
+ source: {
+ label: 'Source',
+ searchType: 'select',
+ searchOptions: [{
+ name: "ec2",
+ value: "ec2"
+ }, {
+ name: "none",
+ value: ""
+ }, {
+ name: "rax",
+ value: "rax"
+ }],
+ sourceModel: 'inventory_source',
+ sourceField: 'source',
+ searchOnly: true
+ },
+ has_external_source: {
+ label: 'Has external source?',
+ searchType: 'in',
+ searchValue: 'ec2,rax',
+ searchOnly: true,
+ sourceModel: 'inventory_source',
+ sourceField: 'source'
+ },
+ has_active_failures: {
+ label: 'Has failed hosts?',
+ searchSingleValue: true,
+ searchType: 'boolean',
+ searchValue: 'true',
+ searchOnly: true
+ },
+ last_update_failed: {
+ label: 'Update failed?',
+ searchType: 'select',
+ searchSingleValue: true,
+ searchValue: 'failed',
+ searchOnly: true,
+ sourceModel: 'inventory_source',
+ sourceField: 'status'
}
},
@@ -64,13 +93,12 @@ angular.module('InventoryGroupsDefinition', [])
fieldActions: {
- columnClass: 'col-lg-2 col-md-2 col-sm-2 col-xs-3',
+ columnClass: 'col-lg-2 col-md-2 col-sm-2 col-xs-5',
label: false,
sync_status: {
mode: 'all',
ngClick: "viewUpdateStatus(group.id, group.group_id)",
- ngShow: "group.id > 1", // hide for all hosts
awToolTip: "{{ group.status_tooltip }}",
dataTipWatch: "group.status_tooltip",
iconClass: "{{ 'fa icon-cloud-' + group.status_class }}",
@@ -80,7 +108,6 @@ angular.module('InventoryGroupsDefinition', [])
failed_hosts: {
mode: 'all',
awToolTip: "{{ group.hosts_status_tip }}",
- ngShow: "group.id > 1", // hide for all hosts
dataPlacement: "top",
ngClick: "showHosts(group.id, group.group_id, group.show_failures)",
iconClass: "{{ 'fa icon-job-' + group.hosts_status_class }}"
@@ -91,7 +118,7 @@ angular.module('InventoryGroupsDefinition', [])
ngClick: 'updateGroup(group.id)',
awToolTip: "{{ group.launch_tooltip }}",
dataTipWatch: "group.launch_tooltip",
- ngShow: "group.id > 1 && (group.status !== 'running' && group.status !== 'pending' && group.status !== 'updating')",
+ ngShow: "group.status !== 'running' && group.status !== 'pending' && group.status !== 'updating'",
ngClass: "group.launch_class",
dataPlacement: "top"
},
@@ -101,7 +128,7 @@ angular.module('InventoryGroupsDefinition', [])
ngClick: "cancelUpdate(group.id)",
awToolTip: "Cancel sync process",
'class': 'red-txt',
- ngShow: "group.id > 1 && (group.status == 'running' || group.status == 'pending' || group.status == 'updating')",
+ ngShow: "group.status == 'running' || group.status == 'pending' || group.status == 'updating'",
dataPlacement: "top"
},
edit: {
@@ -109,7 +136,12 @@ angular.module('InventoryGroupsDefinition', [])
mode: 'all',
ngClick: "editGroup(group.group_id, group.id)",
awToolTip: 'Edit group',
- ngShow: "group.id > 1", // hide for all hosts
+ dataPlacement: "top"
+ },
+ copy: {
+ mode: 'all',
+ ngClick: "copyGroup(group.id)",
+ awToolTip: 'Copy or move group',
dataPlacement: "top"
},
"delete": {
@@ -117,9 +149,7 @@ angular.module('InventoryGroupsDefinition', [])
mode: 'all',
ngClick: "deleteGroup(group.id, group.group_id)",
awToolTip: 'Delete group',
- ngShow: "group.id != 1", // hide for all hosts
dataPlacement: "top"
}
}
- });
-
+ });
\ No newline at end of file
diff --git a/awx/ui/static/js/lists/InventoryHosts.js b/awx/ui/static/js/lists/InventoryHosts.js
index 707804e7cb..b8a1e1e867 100644
--- a/awx/ui/static/js/lists/InventoryHosts.js
+++ b/awx/ui/static/js/lists/InventoryHosts.js
@@ -18,9 +18,9 @@ angular.module('InventoryHostsDefinition', [])
showTitle: false,
well: true,
index: false,
- hover: false,
+ hover: true,
hasChildren: true,
- 'class': 'table-condensed table-no-border',
+ 'class': 'table-no-border',
fields: {
name: {
@@ -28,10 +28,9 @@ angular.module('InventoryHostsDefinition', [])
label: 'Hosts',
ngClick: "editHost(host.id)",
searchPlaceholder: "search_place_holder",
- columnClass: 'col-lg-10 col-md-10 col-sm-10 col-xs-9',
+ columnClass: 'col-lg-10 col-md-10 col-sm-10 col-xs-7',
dataHostId: "{{ host.id }}",
- dataType: "host",
- awDraggable: "true"
+ dataType: "host"
},
enabled: {
label: 'Disabled?',
@@ -51,7 +50,7 @@ angular.module('InventoryHostsDefinition', [])
fieldActions: {
- columnClass: 'col-lg-2 col-md-2 col-sm-2 col-xs-3',
+ columnClass: 'col-lg-2 col-md-2 col-sm-2 col-xs-5',
label: false,
enabled_flag: {