diff --git a/awx/ui/static/js/controllers/Home.js b/awx/ui/static/js/controllers/Home.js
index ad863752dc..735604c501 100644
--- a/awx/ui/static/js/controllers/Home.js
+++ b/awx/ui/static/js/controllers/Home.js
@@ -95,12 +95,51 @@ function HomeGroups ($location, $routeParams, HomeGroupList, GenerateList, Proce
SearchInit({ scope: scope, set: 'groups', list: list, url: defaultUrl });
PaginateInit({ scope: scope, list: list, url: defaultUrl });
+ // Process search params
if ($routeParams['has_active_failures']) {
- scope[HomeGroupList.iterator + 'InputDisable'] = true;
- scope[HomeGroupList.iterator + 'SearchValue'] = $routeParams['has_active_failures'];
- scope[HomeGroupList.iterator + 'SearchField'] = 'has_active_failures';
- scope[HomeGroupList.iterator + 'SearchFieldLabel'] = HomeGroupList.fields['has_active_failures'].label;
- scope[HomeGroupList.iterator + 'SearchSelectValue'] = ($routeParams['has_active_failures'] == 'true') ? { value: 1 } : { value: 0 };
+ scope[list.iterator + 'InputDisable'] = true;
+ scope[list.iterator + 'SearchValue'] = $routeParams['has_active_failures'];
+ scope[list.iterator + 'SearchField'] = 'has_active_failures';
+ scope[list.iterator + 'SearchFieldLabel'] = list.fields['has_active_failures'].label;
+ scope[list.iterator + 'SearchSelectValue'] = ($routeParams['has_active_failures'] == 'true') ? { value: 1 } : { value: 0 };
+ }
+
+ if ($routeParams['status'] && !$routeParams['source']) {
+ scope[list.iterator + 'SearchField'] = 'status';
+ scope[list.iterator + 'SelectShow'] = true;
+ scope[list.iterator + 'SearchSelectOpts'] = list.fields['status'].searchOptions;
+ scope[list.iterator + 'SearchFieldLabel'] = list.fields['status'].label.replace(/\
/g,' ');
+ for (var opt in list.fields['status'].searchOptions) {
+ if (list.fields['status'].searchOptions[opt].value == $routeParams['status']) {
+ scope[list.iterator + 'SearchSelectValue'] = list.fields['status'].searchOptions[opt];
+ break;
+ }
+ }
+ }
+
+ if ($routeParams['source']) {
+ scope[list.iterator + 'SearchField'] = 'source';
+ scope[list.iterator + 'SelectShow'] = true;
+ scope[list.iterator + 'SearchSelectOpts'] = list.fields['source'].searchOptions;
+ scope[list.iterator + 'SearchFieldLabel'] = list.fields['source'].label.replace(/\
/g,' ');
+ for (var opt in list.fields['source'].searchOptions) {
+ if (list.fields['source'].searchOptions[opt].value == $routeParams['source']) {
+ scope[list.iterator + 'SearchSelectValue'] = list.fields['source'].searchOptions[opt];
+ break;
+ }
+ }
+
+ if ($routeParams['status']) {
+ scope[list.iterator + 'ExtraParms'] = '&inventory_source__status__icontains=' + $routeParams['status'];
+ }
+ }
+
+ if ($routeParams['has_external_source']) {
+ scope[list.iterator + 'SearchField'] = 'has_external_source';
+ scope[list.iterator + 'SearchValue'] = list.fields['has_external_source'].searchValue;
+ scope[list.iterator + 'InputDisable'] = true;
+ scope[list.iterator + 'SearchType'] = 'in';
+ scope[list.iterator + 'SearchFieldLabel'] = list.fields['has_external_source'].label;
}
scope.search(list.iterator);
@@ -117,7 +156,7 @@ HomeGroups.$inject = [ '$location', '$routeParams', 'HomeGroupList', 'GenerateLi
function HomeHosts ($location, $routeParams, HomeHostList, GenerateList, ProcessErrors, LoadBreadCrumbs, ReturnToCaller, ClearScope,
- GetBasePath, SearchInit, PaginateInit, FormatDate, SetHostStatus, ToggleHostEnabled) {
+ GetBasePath, SearchInit, PaginateInit, FormatDate, SetHostStatus, ToggleHostEnabled, HostsEdit) {
ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior
//scope.
@@ -156,10 +195,23 @@ function HomeHosts ($location, $routeParams, HomeHostList, GenerateList, Process
scope.toggle_host_enabled = function(id, sources) { ToggleHostEnabled(id, sources, scope); }
+ scope.editHost = function(host_id, host_name) {
+ var host;
+ for (var i=0; i < scope['hosts'].length; i++) {
+ if (scope['hosts'][i].id == host_id) {
+ host = scope['hosts'][i];
+ break;
+ }
+ }
+ if (host) {
+ HostsEdit({ host_id: host_id, inventory_id: host.inventory, group_id: null, hostsReload: false });
+ }
+ }
+
}
HomeGroups.$inject = [ '$location', '$routeParams', 'HomeGroupList', 'GenerateList', 'ProcessErrors', 'LoadBreadCrumbs', 'ReturnToCaller',
'ClearScope', 'GetBasePath', 'SearchInit', 'PaginateInit', 'FormatDate', 'HostsStatusMsg', 'UpdateStatusMsg', 'ViewUpdateStatus',
- 'SetHostStatus', 'ToggleHostEnabled'
+ 'SetHostStatus', 'ToggleHostEnabled', 'HostsEdit'
];
\ No newline at end of file
diff --git a/awx/ui/static/js/controllers/Inventories.js b/awx/ui/static/js/controllers/Inventories.js
index 5b17f45f98..55fba75cec 100644
--- a/awx/ui/static/js/controllers/Inventories.js
+++ b/awx/ui/static/js/controllers/Inventories.js
@@ -37,7 +37,6 @@ function InventoriesList ($scope, $rootScope, $location, $log, $routeParams, Res
}
if ($routeParams['has_active_failures']) {
- //scope.resetSearch(InventoryHostsForm.iterator);
scope[InventoryList.iterator + 'InputDisable'] = true;
scope[InventoryList.iterator + 'SearchValue'] = $routeParams['has_active_failures'];
scope[InventoryList.iterator + 'SearchField'] = 'has_active_failures';
@@ -45,6 +44,21 @@ function InventoriesList ($scope, $rootScope, $location, $log, $routeParams, Res
scope[InventoryList.iterator + 'SearchSelectValue'] = ($routeParams['has_active_failures'] == 'true') ? { value: 1 } : { value: 0 };
}
+ if ($routeParams['has_inventory_sources']) {
+ scope[InventoryList.iterator + 'InputDisable'] = true;
+ scope[InventoryList.iterator + 'SearchValue'] = $routeParams['has_inventory_sources'];
+ scope[InventoryList.iterator + 'SearchField'] = 'has_inventory_sources';
+ scope[InventoryList.iterator + 'SearchFieldLabel'] = InventoryList.fields['has_inventory_sources'].label;
+ scope[InventoryList.iterator + 'SearchSelectValue'] = ($routeParams['has_inventory_sources'] == 'true') ? { value: 1 } : { value: 0 };
+ }
+
+ if ($routeParams['inventory_sources_with_failures']) {
+ // pass a value of true, however this field actually contains an integer value
+ scope[InventoryList.iterator + 'InputDisable'] = true;
+ scope[InventoryList.iterator + 'SearchField'] = 'inventory_sources_with_failures';
+ scope[InventoryList.iterator + 'SearchFieldLabel'] = InventoryList.fields['inventory_sources_with_failures'].label;
+ }
+
scope.search(list.iterator);
LoadBreadCrumbs();
diff --git a/awx/ui/static/js/helpers/Groups.js b/awx/ui/static/js/helpers/Groups.js
index bf28beb401..56ba78810f 100644
--- a/awx/ui/static/js/helpers/Groups.js
+++ b/awx/ui/static/js/helpers/Groups.js
@@ -393,7 +393,6 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
scope[list.iterator + 'InputDisable'] = true;
scope[list.iterator + 'SearchType'] = 'in';
scope[list.iterator + 'SearchFieldLabel'] = list.fields['has_external_source'].label;
- //=ec2,rackspace,file)
}
else if ($routeParams['status']) {
// with status param, called post update-submit
diff --git a/awx/ui/static/js/helpers/Hosts.js b/awx/ui/static/js/helpers/Hosts.js
index 1b41de81d9..bf1d246e20 100644
--- a/awx/ui/static/js/helpers/Hosts.js
+++ b/awx/ui/static/js/helpers/Hosts.js
@@ -278,6 +278,7 @@ angular.module('HostsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', 'H
var host_id = params.host_id;
var inventory_id = params.inventory_id;
var group_id = params.group_id;
+ var hostsReload = (params.hostsReload == undefined || params.hostsReload) ? true : false;
var generator = GenerateForm;
var form = HostForm;
@@ -367,7 +368,9 @@ angular.module('HostsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', 'H
function finished() {
$('#form-modal').modal('hide');
- scope.$emit('hostsReload');
+ if (hostsReload) {
+ scope.$emit('hostsReload');
+ }
}
try {
diff --git a/awx/ui/static/js/helpers/search.js b/awx/ui/static/js/helpers/search.js
index 00fc5d7ee4..d9ac0443cf 100644
--- a/awx/ui/static/js/helpers/search.js
+++ b/awx/ui/static/js/helpers/search.js
@@ -25,57 +25,62 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper'])
var list = params.list;
var iterator = (params.iterator) ? params.iterator : list.iterator;
var sort_order;
-
- // Set default values
- for (fld in list.fields) {
- if (list.fields[fld].key) {
- if (list.fields[fld].sourceModel) {
- var fka = list.fields[fld].sourceModel + '__' + list.fields[fld].sourceField;
- sort_order = (list.fields[fld].desc) ? '-' + fka : fka;
- }
- else {
- sort_order = (list.fields[fld].desc) ? '-' + fld : fld;
- }
- if (list.fields[fld].searchable == undefined || list.fields[fld].searchable == true) {
- scope[iterator + 'SearchField'] = fld;
- scope[iterator + 'SearchFieldLabel'] = list.fields[fld].label;
- }
- break;
+
+ function setDefaults() {
+ // Set default values
+ for (fld in list.fields) {
+ if (list.fields[fld].key) {
+ if (list.fields[fld].sourceModel) {
+ var fka = list.fields[fld].sourceModel + '__' + list.fields[fld].sourceField;
+ sort_order = (list.fields[fld].desc) ? '-' + fka : fka;
+ }
+ else {
+ sort_order = (list.fields[fld].desc) ? '-' + fld : fld;
+ }
+ if (list.fields[fld].searchable == undefined || list.fields[fld].searchable == true) {
+ scope[iterator + 'SearchField'] = fld;
+ scope[iterator + 'SearchFieldLabel'] = list.fields[fld].label;
+ }
+ break;
+ }
}
- }
- if (!scope[iterator + 'SearchField']) {
- // A field marked as key may not be 'searchable'
- for (fld in list.fields) {
- if (list.fields[fld].searchable == undefined || list.fields[fld].searchable == true) {
- scope[iterator + 'SearchField'] = fld;
- scope[iterator + 'SearchFieldLabel'] = list.fields[fld].label;
- break;
+ if (!scope[iterator + 'SearchField']) {
+ // A field marked as key may not be 'searchable'
+ for (fld in list.fields) {
+ if (list.fields[fld].searchable == undefined || list.fields[fld].searchable == true) {
+ scope[iterator + 'SearchField'] = fld;
+ scope[iterator + 'SearchFieldLabel'] = list.fields[fld].label;
+ break;
+ }
}
- }
- }
+ }
- scope[iterator + 'SearchType'] = 'icontains';
- scope[iterator + 'SearchTypeLabel'] = 'Contains';
- scope[iterator + 'SearchParams'] = '';
- scope[iterator + 'SearchValue'] = '';
- scope[iterator + 'SelectShow'] = false; // show/hide the Select
- scope[iterator + 'HideSearchType'] = false;
- scope[iterator + 'InputDisable'] = false;
+ scope[iterator + 'SearchType'] = 'icontains';
+ scope[iterator + 'SearchTypeLabel'] = 'Contains';
+ scope[iterator + 'SearchParams'] = '';
+ scope[iterator + 'SearchValue'] = '';
+ scope[iterator + 'SelectShow'] = false; // show/hide the Select
+ scope[iterator + 'HideSearchType'] = false;
+ scope[iterator + 'InputDisable'] = false;
+ scope[iterator + 'ExtraParms'] = '';
- var f = scope[iterator + 'SearchField']
- if (list.fields[f].searchType && ( list.fields[f].searchType == 'boolean'
- || list.fields[f].searchType == 'select')) {
- scope[iterator + 'SelectShow'] = true;
- scope[iterator + 'SearchSelectOpts'] = list.fields[f].searchOptions;
- }
- if (list.fields[f].searchType && list.fields[f].searchType == 'int') {
- scope[iterator + 'HideSearchType'] = true;
- }
- if (list.fields[f].searchType && list.fields[f].searchType == 'gtzero') {
- scope[iterator + "InputHide"] = true;
- }
-
+ var f = scope[iterator + 'SearchField']
+ if (list.fields[f].searchType && ( list.fields[f].searchType == 'boolean'
+ || list.fields[f].searchType == 'select')) {
+ scope[iterator + 'SelectShow'] = true;
+ scope[iterator + 'SearchSelectOpts'] = list.fields[f].searchOptions;
+ }
+ if (list.fields[f].searchType && list.fields[f].searchType == 'int') {
+ scope[iterator + 'HideSearchType'] = true;
+ }
+ if (list.fields[f].searchType && list.fields[f].searchType == 'gtzero') {
+ scope[iterator + "InputHide"] = true;
+ }
+ }
+
+ setDefaults();
+
// Functions to handle search widget changes
scope.setSearchField = function(iterator, fld, label) {
scope[iterator + 'SearchFieldLabel'] = label;
@@ -126,12 +131,7 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper'])
scope.resetSearch = function(iterator) {
// Respdond to click of reset button
- scope[iterator + "SearchValue"] = '';
- scope[iterator + "SearchSelectValue"] = '';
- scope[iterator + 'SelectShow'] = false;
- scope[iterator + 'HideSearchType'] = false;
- scope[iterator + 'InputHide'] = false;
- scope[iterator + 'InputDisable'] = false;
+ setDefaults();
// Force removal of search keys from the URL
window.location = '/#' + $location.path();
}
@@ -224,6 +224,9 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper'])
if (page) {
url += '&page=' + page;
}
+ if (scope[iterator + 'ExtraParms']) {
+ url += scope[iterator + 'ExtraParms'];
+ }
Refresh({ scope: scope, set: set, iterator: iterator, url: url });
}
diff --git a/awx/ui/static/js/lists/Inventories.js b/awx/ui/static/js/lists/Inventories.js
index a65130fdae..f81b785a16 100644
--- a/awx/ui/static/js/lists/Inventories.js
+++ b/awx/ui/static/js/lists/Inventories.js
@@ -72,6 +72,11 @@ angular.module('InventoriesListDefinition', [])
searchType: 'boolean',
searchValue: 'true',
searchOnly: true
+ },
+ inventory_sources_with_failures: {
+ label: 'Has inventory update failures?',
+ searchType: 'gtzero',
+ searchOnly: true
}
},
diff --git a/awx/ui/static/js/widgets/InventorySyncStatus.js b/awx/ui/static/js/widgets/InventorySyncStatus.js
index dc0066383f..c28ec1f983 100644
--- a/awx/ui/static/js/widgets/InventorySyncStatus.js
+++ b/awx/ui/static/js/widgets/InventorySyncStatus.js
@@ -20,7 +20,7 @@ angular.module('InventorySyncStatusWidget', ['RestServices', 'Utilities'])
var hostCount = 0;
var hostFails = 0;
var counts = 0;
- var expectedCounts = 4;
+ var expectedCounts = 5;
var target = params.target;
var results = [];
var expected;
@@ -71,15 +71,15 @@ angular.module('InventorySyncStatusWidget', ['RestServices', 'Utilities'])
html += makeRow({ label: 'Inventories',
count: inventoryCount,
fail: inventoryFails,
- link: GetBasePath('inventory'),
- fail_link: GetBasePath('inventory') + '/?status=failed' });
+ link: '/#/inventories/?has_inventory_sources=true',
+ fail_link: '/#/inventories/?inventory_sources_with_failures=true' });
rowcount++;
}
if (groupCount > 0) {
html += makeRow({ label: 'Groups',
count: groupCount,
fail: groupFails,
- link: '/#/home/groups/?has_inventory_sources=true',
+ link: '/#/home/groups/?has_external_source=true',
fail_link: '/#/home/groups/?status=failed' });
rowcount++;
}
@@ -122,7 +122,17 @@ angular.module('InventorySyncStatusWidget', ['RestServices', 'Utilities'])
{ hdr: 'Error!', msg: 'Failed to get ' + url + '. GET status: ' + status });
});
- inventoryFails = 0;
+ var url = GetBasePath('inventory') + '?inventory_sources_with_failures__gt=0&page=1';
+ Rest.setUrl(url);
+ Rest.get()
+ .success( function(data, status, headers, config) {
+ inventoryFails=data.count;
+ scope.$emit('CountReceived');
+ })
+ .error( function(data, status, headers, config) {
+ ProcessErrors(scope, data, status, null,
+ { hdr: 'Error!', msg: 'Failed to get ' + url + '. GET status: ' + status });
+ });
url = GetBasePath('inventory_sources') + '?source__in=ec2,rackspace&page=1';
Rest.setUrl(url);
@@ -215,7 +225,6 @@ angular.module('InventorySyncStatusWidget', ['RestServices', 'Utilities'])
Rest.get()
.success( function(data, status, headers, config) {
// figure out the scm_type we're looking at and its label
- console.log('config');
var label = getLabel(config);
var count = data.count;
var fail = 0;
diff --git a/awx/ui/static/js/widgets/ObjectCount.js b/awx/ui/static/js/widgets/ObjectCount.js
index e677e6b688..6c86e0571e 100644
--- a/awx/ui/static/js/widgets/ObjectCount.js
+++ b/awx/ui/static/js/widgets/ObjectCount.js
@@ -45,16 +45,30 @@ angular.module('ObjectCountWidget', ['RestServices', 'Utilities'])
for (var i=0; i < keys.length; i++) {
html += "