From 353858cf28afd81c51d165621ef448fa5dd1ae43 Mon Sep 17 00:00:00 2001 From: Chris Houseknecht Date: Mon, 11 Nov 2013 19:16:16 +0000 Subject: [PATCH] AC-502 Fixed links on home page status widget. Added home/hosts page. --- awx/ui/static/js/app.js | 5 +- awx/ui/static/js/controllers/Home.js | 68 ++++++++++++--- awx/ui/static/js/controllers/Inventories.js | 12 ++- awx/ui/static/js/helpers/Hosts.js | 68 ++++++++------- awx/ui/static/js/lists/HomeHosts.js | 93 +++++++++++++++++++++ awx/ui/static/js/widgets/JobStatus.js | 6 +- awx/ui/templates/ui/index.html | 1 + 7 files changed, 206 insertions(+), 47 deletions(-) create mode 100644 awx/ui/static/js/lists/HomeHosts.js diff --git a/awx/ui/static/js/app.js b/awx/ui/static/js/app.js index c92697f086..7752795972 100644 --- a/awx/ui/static/js/app.js +++ b/awx/ui/static/js/app.js @@ -83,7 +83,8 @@ angular.module('ansible', [ 'CredentialsHelper', 'TimerService', 'StreamListDefinition', - 'HomeGroupListDefinition' + 'HomeGroupListDefinition', + 'HomeHostListDefinition' ]) .config(['$routeProvider', function($routeProvider) { $routeProvider. @@ -250,6 +251,8 @@ angular.module('ansible', [ when('/home', { templateUrl: urlPrefix + 'partials/home.html', controller: Home }). when('/home/groups', { templateUrl: urlPrefix + 'partials/subhome.html', controller: HomeGroups }). + + when('/home/hosts', { templateUrl: urlPrefix + 'partials/subhome.html', controller: HomeHosts }). otherwise({redirectTo: '/home'}); }]) diff --git a/awx/ui/static/js/controllers/Home.js b/awx/ui/static/js/controllers/Home.js index 922f4e0fa5..db95ce2cf9 100644 --- a/awx/ui/static/js/controllers/Home.js +++ b/awx/ui/static/js/controllers/Home.js @@ -94,20 +94,14 @@ function HomeGroups ($location, $routeParams, HomeGroupList, GenerateList, Proce SearchInit({ scope: scope, set: 'groups', list: list, url: defaultUrl }); PaginateInit({ scope: scope, list: list, url: defaultUrl }); - if ($routeParams['status']) { - // with status param, called post update-submit - 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['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.search(list.iterator); LoadBreadCrumbs(); @@ -118,5 +112,53 @@ function HomeGroups ($location, $routeParams, HomeGroupList, GenerateList, Proce HomeGroups.$inject = [ '$location', '$routeParams', 'HomeGroupList', 'GenerateList', 'ProcessErrors', 'LoadBreadCrumbs', 'ReturnToCaller', 'ClearScope', 'GetBasePath', 'SearchInit', 'PaginateInit', 'FormatDate', 'HostsStatusMsg', 'UpdateStatusMsg', 'ViewUpdateStatus' + ]; + + +function HomeHosts ($location, $routeParams, HomeHostList, GenerateList, ProcessErrors, LoadBreadCrumbs, ReturnToCaller, ClearScope, + GetBasePath, SearchInit, PaginateInit, FormatDate, SetHostStatus) { + + ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior + //scope. + + var generator = GenerateList; + var list = HomeHostList; + var defaultUrl=GetBasePath('hosts'); + + var scope = generator.inject(list, { mode: 'edit' }); + var base = $location.path().replace(/^\//,'').split('/')[0]; + + if (scope.removePostRefresh) { + scope.removePostRefresh(); + } + scope.removePostRefresh = scope.$on('PostRefresh', function() { + for (var i=0; i < scope.hosts.length; i++) { + scope['hosts'][i]['inventory_name'] = scope['hosts'][i]['summary_fields']['inventory']['name']; + SetHostStatus(scope['hosts'][i]); + } + }); + + SearchInit({ scope: scope, set: 'hosts', list: list, url: defaultUrl }); + PaginateInit({ scope: scope, list: list, url: defaultUrl }); + + if ($routeParams['has_active_failures']) { + scope[HomeHostList.iterator + 'InputDisable'] = true; + scope[HomeHostList.iterator + 'SearchValue'] = $routeParams['has_active_failures']; + scope[HomeHostList.iterator + 'SearchField'] = 'has_active_failures'; + scope[HomeHostList.iterator + 'SearchFieldLabel'] = HomeHostList.fields['has_active_failures'].label; + scope[HomeHostList.iterator + 'SearchSelectValue'] = ($routeParams['has_active_failures'] == 'true') ? { value: 1 } : { value: 0 }; + } + + scope.search(list.iterator); + + LoadBreadCrumbs(); + + scope.viewUpdateStatus = function(id) { ViewUpdateStatus({ scope: scope, group_id: id }) }; + + } + +HomeGroups.$inject = [ '$location', '$routeParams', 'HomeGroupList', 'GenerateList', 'ProcessErrors', 'LoadBreadCrumbs', 'ReturnToCaller', + 'ClearScope', 'GetBasePath', 'SearchInit', 'PaginateInit', 'FormatDate', 'HostsStatusMsg', 'UpdateStatusMsg', 'ViewUpdateStatus', + 'SetHostStatus' ]; \ 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 8ece087afb..02d49e7911 100644 --- a/awx/ui/static/js/controllers/Inventories.js +++ b/awx/ui/static/js/controllers/Inventories.js @@ -24,9 +24,19 @@ function InventoriesList ($scope, $rootScope, $location, $log, $routeParams, Res var scope = view.inject(InventoryList, { mode: mode }); // Inject our view $rootScope.flashMessage = null; - + SearchInit({ scope: scope, set: 'inventories', list: list, url: defaultUrl }); PaginateInit({ scope: scope, list: list, url: defaultUrl }); + + 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'; + scope[InventoryList.iterator + 'SearchFieldLabel'] = InventoryList.fields['has_active_failures'].label; + scope[InventoryList.iterator + 'SearchSelectValue'] = ($routeParams['has_active_failures'] == 'true') ? { value: 1 } : { value: 0 }; + } + scope.search(list.iterator); LoadBreadCrumbs(); diff --git a/awx/ui/static/js/helpers/Hosts.js b/awx/ui/static/js/helpers/Hosts.js index 529f29ebf2..51cbc1c0e0 100644 --- a/awx/ui/static/js/helpers/Hosts.js +++ b/awx/ui/static/js/helpers/Hosts.js @@ -13,6 +13,42 @@ angular.module('HostsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', 'H 'InventoryFormDefinition', 'SelectionHelper', 'HostGroupsFormDefinition', 'InventoryHostsFormDefinition' ]) + + + .factory('SetHostStatus', [ function() { + return function(host) { + // Set status related fields on a host object + host.activeFailuresLink = '/#/hosts/' + host.id + '/job_host_summaries/?inventory=' + host.inventory + + '&host_name=' + escape(host.name); + if (host.has_active_failures == true) { + host.badgeToolTip = 'Most recent job failed. Click to view jobs.'; + host.active_failures = 'failed'; + } + else if (host.has_active_failures == false && host.last_job == null) { + host.has_active_failures = 'none'; + host.badgeToolTip = "No job data available."; + host.active_failures = 'n/a'; + } + else if (host.has_active_failures == false && host.last_job !== null) { + hast.badgeToolTip = "Most recent job successful. Click to view jobs."; + host.active_failures = 'success'; + } + + host.enabled_flag = host.enabled; + if (host.has_inventory_sources) { + // Inventory sync managed, so not clickable + host.enabledToolTip = (host.enabled) ? 'Ready! Availabe to running jobs.' : + 'Out to lunch! This host is not available to running jobs.'; + } + else { + // Clickable + host.enabledToolTip = (host.enabled) ? 'Ready! Available to running jobs. Click to toggle.' : + 'Out to lunch! Host not available to running jobs. Click to toggle.'; + } + + } + }]) + .factory('HostsList', ['$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'HostList', 'GenerateList', 'Prompt', 'SearchInit', 'PaginateInit', 'ProcessErrors', 'GetBasePath', 'HostsAdd', 'HostsReload', @@ -404,7 +440,8 @@ angular.module('HostsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', 'H .factory('HostsReload', ['$location', '$routeParams', 'SearchInit', 'PaginateInit', 'InventoryHostsForm', 'GetBasePath', 'Wait', - function($location, $routeParams, SearchInit, PaginateInit, InventoryHostsForm, GetBasePath, Wait) { + 'SetHostStatus', + function($location, $routeParams, SearchInit, PaginateInit, InventoryHostsForm, GetBasePath, Wait, SetHostStatus) { return function(params) { // Rerfresh the Hosts view on right side of page @@ -439,34 +476,7 @@ angular.module('HostsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', 'H } for (var i=0; i < scope.hosts.length; i++) { - // Add the value displayed in Job Status column - scope.hosts[i].activeFailuresLink = '/#/hosts/' + scope.hosts[i].id + '/job_host_summaries/?inventory=' + scope['inventory_id'] + - '&host_name=' + escape(scope.hosts[i].name); - if (scope.hosts[i].has_active_failures == true) { - scope.hosts[i].badgeToolTip = 'Most recent job failed. Click to view jobs.'; - scope.hosts[i].active_failures = 'failed'; - } - else if (scope.hosts[i].has_active_failures == false && scope.hosts[i].last_job == null) { - scope.hosts[i].has_active_failures = 'none'; - scope.hosts[i].badgeToolTip = "No job data available."; - scope.hosts[i].active_failures = 'n/a'; - } - else if (scope.hosts[i].has_active_failures == false && scope.hosts[i].last_job !== null) { - scope.hosts[i].badgeToolTip = "Most recent job successful. Click to view jobs."; - scope.hosts[i].active_failures = 'success'; - } - - scope.hosts[i].enabled_flag = scope.hosts[i].enabled; - if (scope.hosts[i].has_inventory_sources) { - // Inventory sync managed, so not clickable - scope.hosts[i].enabledToolTip = (scope.hosts[i].enabled) ? 'Ready! Availabe to running jobs.' : - 'Out to lunch! This host is not available to running jobs.'; - } - else { - // Clickable - scope.hosts[i].enabledToolTip = (scope.hosts[i].enabled) ? 'Ready! Available to running jobs. Click to toggle.' : - 'Out to lunch! Host not available to running jobs. Click to toggle.'; - } + SetHostStatus(scope.hosts[i]); } if (group_id == null || group_id == undefined) { diff --git a/awx/ui/static/js/lists/HomeHosts.js b/awx/ui/static/js/lists/HomeHosts.js new file mode 100644 index 0000000000..0f3cd755f4 --- /dev/null +++ b/awx/ui/static/js/lists/HomeHosts.js @@ -0,0 +1,93 @@ +/********************************************* + * Copyright (c) 2013 AnsibleWorks, Inc. + * + * HomeHosts.js + * + * List view object for Hosts data model. Used + * on the home tab. + * + */ +angular.module('HomeHostListDefinition', []) + .value( + 'HomeHostList', { + + name: 'hosts', + iterator: 'host', + selectTitle: 'Add Existing Hosts', + editTitle: 'Hosts', + index: true, + well: true, + + fields: { + name: { + key: true, + label: 'Name', + columnClass: 'col-lg-3 col-md3 col-sm-2', + ngClick: "editHost(\{\{ host.id \}\}, '\{\{ host.name \}\}')" + }, + inventory_name: { + label: 'Inventory', + sourceModel: 'inventory', + sourceField: 'name', + columnClass: 'col-lg-3 col-md3 col-sm-2', + linkTo: "\{\{ '/#/inventories/' + group.inventory \}\}" + }, + active_failures: { + label: 'Job Status', + ngHref: "\{\{ host.activeFailuresLink \}\}", + awToolTip: "\{\{ host.badgeToolTip \}\}", + dataPlacement: 'top', + badgeNgHref: '\{\{ host.activeFailuresLink \}\}', + badgeIcon: "\{\{ 'icon-failures-' + host.has_active_failures \}\}", + badgePlacement: 'left', + badgeToolTip: "\{\{ host.badgeToolTip \}\}", + badgeTipPlacement: 'top', + searchable: false, + nosort: true + }, + enabled_flag: { + label: 'Enabled', + badgeIcon: "\{\{ 'icon-enabled-' + host.enabled \}\}", + badgePlacement: 'left', + badgeToolTip: "\{\{ host.enabledToolTip \}\}", + badgeTipPlacement: "top", + ngClick: "toggle_host_enabled(\{\{ host.id \}\}, \{\{ host.has_inventory_sources \}\})", + searchable: false, + showValue: false + }, + groups: { + label: 'Groups', + searchable: true, + sourceModel: 'groups', + sourceField: 'name', + nosort: true + }, + enabled: { + label: 'Disabled?', + searchSingleValue: true, + searchType: 'boolean', + searchValue: 'false', + searchOnly: true + }, + has_active_failures: { + label: 'Has failed jobs?', + searchSingleValue: true, + searchType: 'boolean', + searchValue: 'true', + searchOnly: true + }, + has_inventory_sources: { + label: 'Has external source?', + searchSingleValue: true, + searchType: 'boolean', + searchValue: 'true', + searchOnly: true + } + }, + + actions: { + }, + + fieldActions: { + } + }); diff --git a/awx/ui/static/js/widgets/JobStatus.js b/awx/ui/static/js/widgets/JobStatus.js index a95801577c..238c56e302 100644 --- a/awx/ui/static/js/widgets/JobStatus.js +++ b/awx/ui/static/js/widgets/JobStatus.js @@ -74,10 +74,10 @@ angular.module('JobStatusWidget', ['RestServices', 'Utilities']) if (inventoryCount > 0) { html += makeRow({ label: 'Inventories', - link: '/#/home/inventories', + link: '/#/inventories', count: inventoryCount, fail: inventoryFails, - fail_link: '/#/home/inventories/?has_active_failures=true' + fail_link: '/#/inventories/?has_active_failures=true' }); rowcount++; } @@ -94,7 +94,7 @@ angular.module('JobStatusWidget', ['RestServices', 'Utilities']) if (hostCount > 0) { html += makeRow({ label: 'Hosts', - link: '#/home/hosts', + link: '/#/home/hosts', count: hostCount, fail: hostFails, fail_link: '/#/home/hosts/?has_active_failures=true' diff --git a/awx/ui/templates/ui/index.html b/awx/ui/templates/ui/index.html index 152a1be3c4..e3d5e6378a 100644 --- a/awx/ui/templates/ui/index.html +++ b/awx/ui/templates/ui/index.html @@ -92,6 +92,7 @@ +