From 8510ce6bdc0268c94e93b1d2b246d965eb8428c5 Mon Sep 17 00:00:00 2001 From: chouseknecht Date: Tue, 8 Oct 2013 16:01:49 -0400 Subject: [PATCH] AC-503 inventory->groups summary screen now in sync with latest API changes. --- awx/ui/static/js/helpers/Groups.js | 109 ++++++++++++++------- awx/ui/static/js/helpers/JobSubmission.js | 21 ++-- awx/ui/static/js/helpers/search.js | 5 +- awx/ui/static/js/lists/InventorySummary.js | 80 +++++++-------- 4 files changed, 131 insertions(+), 84 deletions(-) diff --git a/awx/ui/static/js/helpers/Groups.js b/awx/ui/static/js/helpers/Groups.js index 4db3bb2c27..8843184c08 100644 --- a/awx/ui/static/js/helpers/Groups.js +++ b/awx/ui/static/js/helpers/Groups.js @@ -137,26 +137,30 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', ' var view = GenerateList; var list = InventorySummary; var scope = view.inject(InventorySummary, { mode: 'summary', id: 'tree-form', breadCrumbs: false }); - var defaultUrl = GetBasePath('inventory') + scope['inventory_id'] + '/inventory_sources/?group__isnull=false'; + var defaultUrl = GetBasePath('inventory') + scope['inventory_id'] + '/groups/'; + //?group__isnull=false'; if (scope.PostRefreshRemove) { scope.PostRefreshRemove(); } scope.PostRefreshRemove = scope.$on('PostRefresh', function() { for (var i=0; i < scope.groups.length; i++) { - var last_update = (scope.groups[i].last_updated == null) ? '' : FormatDate(new Date(scope.groups[i].last_updated)); - var source = 'Manual'; + var last_update = null + //(scope.groups[i].last_updated == null) ? '' : FormatDate(new Date(scope.groups[i].last_updated)); + var stat, stat_class, status_tip; - stat = scope.groups[i].status; + stat = scope.groups[i].summary_fields.inventory_source.status; stat_class = stat; - switch (scope.groups[i].status) { + + switch (scope.groups[i].summary_fields.inventory_source.status) { case 'never updated': stat = 'never'; stat_class = 'never'; status_tip = 'Inventory update has not been performed. Click Update button to start it now.'; break; case 'none': + case '': stat = 'n/a'; stat_class = 'na'; status_tip = 'Not configured for inventory update.'; @@ -172,26 +176,15 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', ' break; } - switch (scope.groups[i].source) { - case 'ec2': - source = 'Amazon EC2'; - break; - case 'rackspace': - source = 'Rackspace'; - break; - } - - if (scope.groups[i].summary_fields.group.hosts_with_active_failures > 0) { + if (scope.groups[i].hosts_with_active_failures > 0) { scope.groups[i].active_failures_params = "/?has_active_failures=true"; } else { - scope.groups[i].active_failures_params = ''; + scope.groups[i].active_failures_params = "/?has_active_failures=false"; } - scope.groups[i].hosts_with_active_failures = scope.groups[i].summary_fields.group.hosts_with_active_failures; - scope.groups[i].has_active_failures = scope.groups[i].summary_fields.group.has_active_failures; scope.groups[i].status = stat; - scope.groups[i].source = source; + scope.groups[i].source = scope.groups[i].summary_fields.inventory_source.source; scope.groups[i].last_updated = last_update; scope.groups[i].status_badge_class = stat_class; scope.groups[i].status_badge_tooltip = status_tip; @@ -201,10 +194,14 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', ' SearchInit({ scope: scope, set: 'groups', list: list, url: defaultUrl }); PaginateInit({ scope: scope, list: list, url: defaultUrl }); - if ($routeParams['status']) { - // with status param post update submit + if (scope['inventorySummaryGroup']) { + scope[list.iterator + 'SearchField'] = 'name'; + scope[list.iterator + 'SearchType'] = 'iexact'; + scope[list.iterator + 'SearchValue'] = scope['inventorySummaryGroup']; + } + else if ($routeParams['status']) { + // with status param, called post update-submit scope[list.iterator + 'SearchField'] = 'status'; - //scope[list.iterator + 'SearchType'] = 'icontains'; scope[list.iterator + 'SelectShow'] = true; scope[list.iterator + 'SearchSelectOpts'] = list.fields['status'].searchOptions; for (var opt in list.fields['status'].searchOptions) { @@ -214,10 +211,43 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', ' } } } - - scope.search(list.iterator); - scope.ShowUpdateStatus = ShowUpdateStatus; + scope.search(list.iterator); + + scope.viewUpdateStatus = function(id) { + var found = false; + var group; + for (var i=0; i < scope.groups.length; i++) { + if (scope.groups[i].id == id) { + found = true; + group = scope.groups[i]; + } + } + if (found) { + if (group.summary_fields.inventory_source.source == "" || group.summary_fields.inventory_source.source == null) { + Alert('Missing Configuration', 'The selected group is not configured for inventory updates. ' + + 'You must first edit the group, provide Source settings, and then run an update.', 'alert-info'); + } + else if (group.summary_fields.inventory_source.status == "" || group.summary_fields.inventory_source.status == null || + group.summary_fields.inventory_source.status == "never updated") { + Alert('No Status Available', 'The inventory update process has not run for the selected group. Start the process by ' + + 'clicking the Update button.', 'alert-info'); + } + else { + Rest.setUrl(group.related.inventory_source); + Rest.get() + .success( function(data, status, headers, config) { + ShowUpdateStatus({ group_name: data.summary_fields.group.name, + last_update: data.related.last_update }); + }) + .error( function(data, status, headers, config) { + ProcessErrors(scope, data, status, form, + { hdr: 'Error!', msg: 'Failed to retrieve inventory source: ' + group.related.inventory_source + + ' POST returned status: ' + status }); + }); + } + } + } // Click on group name scope.GroupsEdit = function(group_id) { @@ -241,16 +271,16 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', ' scope.updateGroup = function(id) { for (var i=0; i < scope.groups.length; i++) { if (scope.groups[i].id == id) { - if (scope.groups[i].source == "" || scope.groups[i].source == null) { + if (scope.groups[i].summary_fields.inventory_source.source == "" || scope.groups[i].summary_fields.inventory_source.source == null) { Alert('Missing Configuration', 'The selected group is not configured for updates. You must first edit the group, provide Source settings, ' + 'and then run an update.', 'alert-info'); } - else if (scope.groups[i].status == 'updating') { + else if (scope.groups[i].summary_fields.inventory_source.status == 'updating') { Alert('Update in Progress', 'The inventory update process is currently running for group ' + scope.groups[i].summary_fields.group.name + '. Use the Refresh button to monitor the status.', 'alert-info'); } else { - if (scope.groups[i].source == 'Amazon EC2') { + if (scope.groups[i].summary_fields.inventory_source.source == 'ec2') { scope.sourceUsernameLabel = 'Access Key ID'; scope.sourcePasswordLabel = 'Secret Access Key'; scope.sourcePasswordConfirmLabel = 'Confirm Secret Access Key'; @@ -260,13 +290,22 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', ' scope.sourcePasswordLabel = 'Password'; scope.sourcePasswordConfirmLabel = 'Confirm Password'; } - InventoryUpdate({ - scope: scope, - group_id: id, - url: scope.groups[i].related.update, - group_name: scope.groups[i].summary_fields.group.name, - group_source: scope.groups[i].source - }); + Rest.setUrl(scope.groups[i].related.inventory_source); + Rest.get() + .success( function(data, status, headers, config) { + InventoryUpdate({ + scope: scope, + group_id: id, + url: data.related.update, + group_name: data.summary_fields.group.name, + group_source: data.source + }); + }) + .error( function(data, status, headers, config) { + ProcessErrors(scope, data, status, form, + { hdr: 'Error!', msg: 'Failed to retrieve inventory source: ' + scope.groups[i].related.inventory_source + + ' POST returned status: ' + status }); + }); } break; } diff --git a/awx/ui/static/js/helpers/JobSubmission.js b/awx/ui/static/js/helpers/JobSubmission.js index 3f26f7cf4d..850422921c 100644 --- a/awx/ui/static/js/helpers/JobSubmission.js +++ b/awx/ui/static/js/helpers/JobSubmission.js @@ -369,15 +369,24 @@ angular.module('JobSubmissionHelper', [ 'RestServices', 'Utilities', 'Credential var scope = params.scope; var inventory_id = params.inventory_id; var url = params.url; - + var group_id = params.group_id; + var group_name = params.group_name; + var group_source = params.group_source; + if (scope.removeUpdateSubmitted) { scope.removeUpdateSubmitted(); } scope.removeUpdateSubmitted = scope.$on('UpdateSubmitted', function() { // Refresh the project list after update request submitted - //$location.path(GetBasePath('inventories') + inventory_id + '/groups' - //InventorySummary({ scope: scope }); - $location.url('/inventories/' + scope['inventory_id'] + '/groups/?status=updating'); + Alert('Update Started', 'The request to start the inventory process was submitted. Monitor progress from the inventory summary screen. ' + + 'The screen will refresh every 10 seconds, or refresh manually by clicking the Refresh button.', 'alert-info'); + var node = $('#inventory-node') + var selected = $('#tree-view').jstree('get_selected'); + scope['inventorySummaryGroup'] = group_name; + selected.each(function(idx) { + $('#tree-view').jstree('deselect_node', $(this)); + }); + $('#tree-view').jstree('select_node', node); }); if (scope.removeInventorySubmit) { @@ -399,8 +408,8 @@ angular.module('JobSubmissionHelper', [ 'RestServices', 'Utilities', 'Credential Rest.get() .success( function(data, status, headers, config) { if (data.can_update) { - var extra_html = "
Starting inventory update for the " + params.group_name + - " group. Please provide the " + params.group_source + " credentials:
\n"; + var extra_html = "
Starting inventory update for the " + group_name + + " group. Please provide the " + group_source + " credentials:
\n"; scope.$emit('InventorySubmit', data.passwords_needed_to_update, extra_html); } else { diff --git a/awx/ui/static/js/helpers/search.js b/awx/ui/static/js/helpers/search.js index a27b018423..f00ed7bfa3 100644 --- a/awx/ui/static/js/helpers/search.js +++ b/awx/ui/static/js/helpers/search.js @@ -95,7 +95,6 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper']) // searchSingleValue: true // searchType: 'boolean|int|etc.' // searchValue: < value to match for boolean use 'true'|'false' > - scope[iterator + "SearchType"] = list.fields[fld].searchType; scope[iterator + 'InputDisable'] = true; scope[iterator + "SearchValue"] = list.fields[fld].searchValue; // For boolean type, SearchValue must be an object @@ -105,7 +104,7 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper']) else if (list.fields[fld].searchType == 'boolean' && list.fields[fld].searchValue == 'false') { scope[iterator + "SearchSelectValue"] = { value: 0 }; } - else if (list.fields[fld].searchType == 'boolean') { + else { scope[iterator + "SearchSelectValue"] = { value: list.fields[fld].searchValue }; } } @@ -185,7 +184,7 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper']) else if ( (list.fields[scope[iterator + 'SearchField']].searchType == 'select') && (scope[iterator + 'SearchSelectValue'].value == '' || scope[iterator + 'SearchSelectValue'].value == null) ) { - scope[iterator + 'SearchParams'] += '='; + scope[iterator + 'SearchParams'] += 'iexact='; } else { scope[iterator + 'SearchParams'] += scope[iterator + 'SearchType'] + '='; diff --git a/awx/ui/static/js/lists/InventorySummary.js b/awx/ui/static/js/lists/InventorySummary.js index 17858d9b20..b7046373f7 100644 --- a/awx/ui/static/js/lists/InventorySummary.js +++ b/awx/ui/static/js/lists/InventorySummary.js @@ -22,10 +22,7 @@ angular.module('InventorySummaryDefinition', []) name: { key: true, label: 'Group', - ngBind: "group.summary_fields.group.name", - sourceModel: 'group', - sourceField: 'name', - ngClick: "\{\{ 'GroupsEdit(' + group.group + ')' \}\}" + ngClick: "\{\{ 'GroupsEdit(' + group.id + ')' \}\}" }, hosts_with_active_failures: { label: 'Hosts with
Job Failures?', @@ -37,52 +34,55 @@ angular.module('InventorySummaryDefinition', []) searchable: false, nosort: true }, + status: { + label: 'Update
Status', + ngClick: "viewUpdateStatus(\{\{ group.id \}\})", + searchType: 'select', + badgeIcon: "\{\{ 'icon-cloud-' + group.status_badge_class \}\}", + badgeToolTip: "\{\{ group.status_badge_tooltip \}\}", + awToolTip: "\{\{ group.status_badge_tooltip \}\}", + dataPlacement: 'top', + badgeTipPlacement: 'top', + badgePlacement: 'left', + searchOptions: [ + { name: "failed", value: "failed" }, + { name: "never", value: "never updated" }, + { name: "n/a", value: "none" }, + { name: "successful", value: "successful" }, + { name: "updating", value: "updating" }], + sourceModel: 'inventory_source', + sourceField: 'status' + }, + last_updated: { + label: 'Last
Updated', + searchable: false, + nosort: true + }, + source: { + label: 'Source', + searchType: 'select', + searchOptions: [ + { name: "ec2", value: "ec2" }, + { name: "none", value: "" }, + { name: "rackspace", value: "rackspace" }], + sourceModel: 'inventory_source', + sourceField: 'source' + }, has_active_failures: { label: 'Hosts have job failures?', searchSingleValue: true, searchType: 'boolean', searchValue: 'true', searchOnly: true, - sourceModel: 'group', - sourceField: 'has_active_failures' }, last_update_failed: { label: 'Update failed?', + searchType: 'select', searchSingleValue: true, - searchType: 'boolean', - searchValue: 'true', - searchOnly: true - }, - status: { - label: 'Update
Status', - ngClick: "ShowUpdateStatus({ last_update: '{{ group.related.last_update }}', group_name: '{{ group.summary_fields.group.name }}' })", - searchType: 'select', - badgeIcon: 'icon-cloud', - badgeToolTip: "\{\{ group.status_badge_tooltip \}\}", - awToolTip: "\{\{ group.status_badge_tooltip \}\}", - dataPlacement: 'top', - badgeTipPlacement: 'top', - badgePlacement: 'left', - badgeClass: "\{\{ 'icon-cloud-' + group.status_badge_class \}\}", - searchOptions: [ - { name: "failed", value: "failed" }, - { name: "never", value: "never updated" }, - { name: "n/a", value: "none" }, - { name: "successful", value: "successful" }, - { name: "updating", value: "updating" }] - }, - last_updated: { - label: 'Last
Updated', - searchable: false - }, - source: { - label: 'Source', - searchType: 'select', - searchOptions: [ - { name: "Amazon EC2", value: "ec2" }, - { name: "Local Script", value: "file" }, - { name: "Manual", value: "" }, - { name: "Rackspace", value: "rackspace" }] + searchValue: 'failed', + searchOnly: true, + sourceModel: 'inventory_source', + sourceField: 'status' } },