From e99ac9d668795bf3abfef48ce21d762d6c9cd265 Mon Sep 17 00:00:00 2001 From: Chris Houseknecht Date: Tue, 12 Nov 2013 21:09:50 +0000 Subject: [PATCH] AC-502 all links for Inventory widget on home page now work. Modified responding controllers to process all search parameters. Fixed Hosts and Groups links in the Summary widget. Added ability to edit host using modal dialog from /home/hosts page. --- awx/ui/static/js/controllers/Home.js | 66 +++++++++-- awx/ui/static/js/controllers/Inventories.js | 16 ++- awx/ui/static/js/helpers/Groups.js | 1 - awx/ui/static/js/helpers/Hosts.js | 5 +- awx/ui/static/js/helpers/search.js | 107 +++++++++--------- awx/ui/static/js/lists/Inventories.js | 5 + .../static/js/widgets/InventorySyncStatus.js | 21 +++- awx/ui/static/js/widgets/ObjectCount.js | 20 +++- 8 files changed, 170 insertions(+), 71 deletions(-) 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 += "\n"; html += "