From 8860b5c2adf16ae55b50270bd7c497126b862326 Mon Sep 17 00:00:00 2001 From: chris Houseknecht Date: Mon, 20 Jan 2014 18:48:58 -0500 Subject: [PATCH] AC-951 Whenever the object name is not available or starts with '_delete' check for the name in changes.name. Also fixed server deep link issues between activity stream, home/group and home/inventory, and inventory. --- awx/ui/static/js/controllers/Home.js | 39 +++++++++++----- awx/ui/static/js/controllers/Inventories.js | 2 +- awx/ui/static/js/helpers/Groups.js | 37 +++++++++++----- awx/ui/static/js/lists/HomeGroups.js | 12 +++-- awx/ui/static/js/lists/HomeHosts.js | 6 ++- awx/ui/static/js/lists/Streams.js | 3 +- awx/ui/static/js/widgets/Stream.js | 49 ++++++++++++++++----- 7 files changed, 106 insertions(+), 42 deletions(-) diff --git a/awx/ui/static/js/controllers/Home.js b/awx/ui/static/js/controllers/Home.js index 27aa25f14c..39d72ec2e2 100644 --- a/awx/ui/static/js/controllers/Home.js +++ b/awx/ui/static/js/controllers/Home.js @@ -95,7 +95,7 @@ Home.$inject=['$scope', '$compile', '$routeParams', '$rootScope', '$location', ' function HomeGroups ($location, $routeParams, HomeGroupList, GenerateList, ProcessErrors, LoadBreadCrumbs, ReturnToCaller, ClearScope, - GetBasePath, SearchInit, PaginateInit, FormatDate, GetHostsStatusMsg, GetSyncStatusMsg, ViewUpdateStatus, Stream) { + GetBasePath, SearchInit, PaginateInit, FormatDate, GetHostsStatusMsg, GetSyncStatusMsg, ViewUpdateStatus, Stream, GroupsEdit) { ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior //scope. @@ -155,6 +155,14 @@ function HomeGroups ($location, $routeParams, HomeGroupList, GenerateList, Proce scope[list.iterator + 'SearchSelectValue'] = null; } + if ($routeParams['id']) { + scope[list.iterator + 'InputDisable'] = false; + scope[list.iterator + 'SearchValue'] = $routeParams['id']; + scope[list.iterator + 'SearchField'] = 'id'; + scope[list.iterator + 'SearchFieldLabel'] = list.fields['id'].label; + scope[list.iterator + 'SearchSelectValue'] = null; + } + if ($routeParams['has_active_failures']) { scope[list.iterator + 'InputDisable'] = true; scope[list.iterator + 'SearchValue'] = $routeParams['has_active_failures']; @@ -206,6 +214,10 @@ function HomeGroups ($location, $routeParams, HomeGroupList, GenerateList, Proce LoadBreadCrumbs(); scope.showActivity = function() { Stream(); } + + scope.editGroup = function(group_id, inventory_id) { + GroupsEdit({ scope: scope, group_id: group_id, inventory_id: inventory_id, groups_reload: false }); + } scope.viewUpdateStatus = function(id) { scope.groups = scope.home_groups; @@ -216,12 +228,12 @@ function HomeGroups ($location, $routeParams, HomeGroupList, GenerateList, Proce HomeGroups.$inject = [ '$location', '$routeParams', 'HomeGroupList', 'GenerateList', 'ProcessErrors', 'LoadBreadCrumbs', 'ReturnToCaller', 'ClearScope', 'GetBasePath', 'SearchInit', 'PaginateInit', 'FormatDate', 'GetHostsStatusMsg', 'GetSyncStatusMsg', 'ViewUpdateStatus', - 'Stream' + 'Stream', 'GroupsEdit' ]; function HomeHosts ($location, $routeParams, HomeHostList, GenerateList, ProcessErrors, LoadBreadCrumbs, ReturnToCaller, ClearScope, - GetBasePath, SearchInit, PaginateInit, FormatDate, SetHostStatus, ToggleHostEnabled, HostsEdit, Stream) { + GetBasePath, SearchInit, PaginateInit, FormatDate, SetHostStatus, ToggleHostEnabled, HostsEdit, Stream, Find) { ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior //scope. @@ -254,6 +266,14 @@ function HomeHosts ($location, $routeParams, HomeHostList, GenerateList, Process scope[HomeHostList.iterator + 'SearchFieldLabel'] = list.fields['name'].label; } + if ($routeParams['id']) { + scope[HomeHostList.iterator + 'InputDisable'] = false; + scope[HomeHostList.iterator + 'SearchValue'] = $routeParams['id']; + scope[HomeHostList.iterator + 'SearchField'] = 'id'; + scope[HomeHostList.iterator + 'SearchFieldLabel'] = list.fields['id'].label; + scope[HomeHostList.iterator + 'SearchSelectValue'] = null; + } + if ($routeParams['has_active_failures']) { scope[HomeHostList.iterator + 'InputDisable'] = true; scope[HomeHostList.iterator + 'SearchValue'] = $routeParams['has_active_failures']; @@ -270,20 +290,15 @@ function HomeHosts ($location, $routeParams, HomeHostList, GenerateList, Process scope.toggle_host_enabled = function(id, sources) { ToggleHostEnabled({ host_id: id, external_source: sources, scope: 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; - } - } + var host = Find({ list: scope.hosts, key: 'id', val: host_id }); if (host) { - HostsEdit({ host_id: host_id, inventory_id: host.inventory, group_id: null, hostsReload: false }); + HostsEdit({ scope: scope, host_id: host_id, inventory_id: host.inventory, group_id: null, hostsReload: false }); } } } HomeHosts.$inject = [ '$location', '$routeParams', 'HomeHostList', 'GenerateList', 'ProcessErrors', 'LoadBreadCrumbs', 'ReturnToCaller', - 'ClearScope', 'GetBasePath', 'SearchInit', 'PaginateInit', 'FormatDate', 'SetHostStatus', 'ToggleHostEnabled', 'HostsEdit', 'Stream' + 'ClearScope', 'GetBasePath', 'SearchInit', 'PaginateInit', 'FormatDate', 'SetHostStatus', 'ToggleHostEnabled', 'HostsEdit', 'Stream', + 'Find' ]; diff --git a/awx/ui/static/js/controllers/Inventories.js b/awx/ui/static/js/controllers/Inventories.js index 22284fb3db..28640ecd65 100644 --- a/awx/ui/static/js/controllers/Inventories.js +++ b/awx/ui/static/js/controllers/Inventories.js @@ -417,7 +417,7 @@ function InventoriesEdit ($scope, $location, $routeParams, $compile, GenerateLis } $scope.editGroup = function(group_id, tree_id) { - GroupsEdit({ scope: $scope, inventory_id: $scope.inventory_id, group_id: group_id, tree_id: tree_id }); + GroupsEdit({ scope: $scope, inventory_id: $scope.inventory_id, group_id: group_id, tree_id: tree_id, groups_reload: true }); } // Launch inventory sync diff --git a/awx/ui/static/js/helpers/Groups.js b/awx/ui/static/js/helpers/Groups.js index 41a7a68b5a..db91ae80bd 100644 --- a/awx/ui/static/js/helpers/Groups.js +++ b/awx/ui/static/js/helpers/Groups.js @@ -580,16 +580,17 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', ' .factory('GroupsEdit', ['$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'GroupForm', 'GenerateForm', 'Prompt', 'ProcessErrors', 'GetBasePath', 'SetNodeName', 'ParseTypeChange', 'GetSourceTypeOptions', 'InventoryUpdate', - 'GetUpdateIntervalOptions', 'LookUpInit', 'Empty', 'Wait', 'GetChoices', 'UpdateGroup', 'SourceChange', + 'GetUpdateIntervalOptions', 'LookUpInit', 'Empty', 'Wait', 'GetChoices', 'UpdateGroup', 'SourceChange', 'Find', function($rootScope, $location, $log, $routeParams, Rest, Alert, GroupForm, GenerateForm, Prompt, ProcessErrors, GetBasePath, SetNodeName, ParseTypeChange, GetSourceTypeOptions, InventoryUpdate, GetUpdateIntervalOptions, - LookUpInit, Empty, Wait, GetChoices, UpdateGroup, SourceChange) { + LookUpInit, Empty, Wait, GetChoices, UpdateGroup, SourceChange, Find) { return function(params) { var parent_scope = params.scope; var group_id = params.group_id; var tree_id = params.tree_id; var inventory_id = params.inventory_id; + var groups_reload = params.groups_reload; var generator = GenerateForm; var form = GroupForm; @@ -809,15 +810,26 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', ' scope.removeSaveComplete = scope.$on('SaveComplete', function(e, error) { if (!error) { // Update the view with any changes - UpdateGroup({ - scope: parent_scope, - group_id: group_id, - properties: { - name: scope.name, - description: scope.description, - has_inventory_sources: (scope.source) ? true : false - } - }); + if (groups_reload) { + UpdateGroup({ + scope: parent_scope, + group_id: group_id, + properties: { + name: scope.name, + description: scope.description, + has_inventory_sources: (scope.source) ? true : false + } + }); + } + else if (scope.home_groups) { + // When home.groups controller is calling, update the groups array + var g = Find({ list: parent_scope.home_groups, key: 'id', val: group_id }); + if (g) { + g.name = scope.name; + g.description = scope.description; + } + } + //Clean up if (scope.searchCleanUp) scope.searchCleanup(); @@ -827,12 +839,13 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', ' $('#form-modal').modal('hide'); // Change the selected group - if (parent_scope.selected_tree_id !== tree_id) + if (groups_reload && parent_scope.selected_tree_id !== tree_id) { parent_scope.showHosts(tree_id, group_id, false); } else { Wait('stop'); } + } }); if (scope.removeFormSaveSuccess) { diff --git a/awx/ui/static/js/lists/HomeGroups.js b/awx/ui/static/js/lists/HomeGroups.js index 48d763c512..10fa6a82c8 100644 --- a/awx/ui/static/js/lists/HomeGroups.js +++ b/awx/ui/static/js/lists/HomeGroups.js @@ -22,16 +22,16 @@ angular.module('HomeGroupListDefinition', []) name: { key: true, label: 'Group', - ngClick: "\{\{ 'GroupsEdit(' + group.id + ')' \}\}", - columnClass: 'col-lg-3 col-md3 col-sm-2', - linkTo: "\{\{ '/#/inventories/' + group.inventory + '/' \}\}" + ngClick: "editGroup(group.id, group.inventory)", + columnClass: 'col-lg-3 col-md3 col-sm-2' + //linkTo: "\{\{ '/#/inventories/' + group.inventory + '/' \}\}" }, inventory_name: { label: 'Inventory', sourceModel: 'inventory', sourceField: 'name', columnClass: 'col-lg-3 col-md3 col-sm-2', - linkTo: "\{\{ '/#/inventories/' + group.inventory \}\}" + linkTo: "\{\{ '/#/inventories/' + group.inventory + '/' \}\}" }, failed_hosts: { label: 'Failed Hosts', @@ -107,6 +107,10 @@ angular.module('HomeGroupListDefinition', []) searchOnly: true, sourceModel: 'inventory_source', sourceField: 'status' + }, + id: { + label: 'ID', + searchOnly: true } }, diff --git a/awx/ui/static/js/lists/HomeHosts.js b/awx/ui/static/js/lists/HomeHosts.js index 3a995d56bd..9ddd8fa054 100644 --- a/awx/ui/static/js/lists/HomeHosts.js +++ b/awx/ui/static/js/lists/HomeHosts.js @@ -31,7 +31,7 @@ angular.module('HomeHostListDefinition', []) sourceModel: 'inventory', sourceField: 'name', columnClass: 'col-lg-3 col-md3 col-sm-2', - linkTo: "\{\{ '/#/inventories/?name=' + host.summary_fields.inventory.name \}\}" + linkTo: "\{\{ '/#/inventories/' + host.inventory \}\}" }, active_failures: { label: 'Job Status', @@ -77,6 +77,10 @@ angular.module('HomeHostListDefinition', []) searchType: 'boolean', searchValue: 'true', searchOnly: true + }, + id: { + label: 'ID', + searchOnly: true } }, diff --git a/awx/ui/static/js/lists/Streams.js b/awx/ui/static/js/lists/Streams.js index db2c3f3b2e..d4f47358b0 100644 --- a/awx/ui/static/js/lists/Streams.js +++ b/awx/ui/static/js/lists/Streams.js @@ -41,7 +41,8 @@ angular.module('StreamListDefinition', []) label: 'Action', ngBindHtml: 'activity.description', nosort: true, - searchable: false + searchable: false, + columnClass: 'col-lg-7' }, system_event: { label: 'System event', diff --git a/awx/ui/static/js/widgets/Stream.js b/awx/ui/static/js/widgets/Stream.js index 0dcb6bfa5b..404fda8696 100644 --- a/awx/ui/static/js/widgets/Stream.js +++ b/awx/ui/static/js/widgets/Stream.js @@ -121,13 +121,13 @@ angular.module('StreamWidget', ['RestServices', 'Utilities', 'StreamListDefiniti switch(obj.base) { case 'group': case 'host': - url += 'home/' + obj.base + 's/?name=' + obj.name; + url += 'home/' + obj.base + 's/?id=' + obj.id; break; case 'inventory': - url += 'inventories/' + obj.id; + url += 'inventories/' + obj.id + '/'; break; default: - url += obj.base + 's/' + obj.id; + url += obj.base + 's/' + obj.id + '/'; } return url; } @@ -135,6 +135,11 @@ angular.module('StreamWidget', ['RestServices', 'Utilities', 'StreamListDefiniti .factory('BuildDescription', ['FixUrl', 'BuildUrl', function(FixUrl, BuildUrl) { return function(activity) { + + function stripDeleted(s) { + return s.replace(/^_deleted_\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d+\+\d+:\d+_/,''); + } + var descr = ''; var descr_nolink; descr += activity.operation; @@ -142,25 +147,47 @@ angular.module('StreamWidget', ['RestServices', 'Utilities', 'StreamListDefiniti descr_nolink = descr; var obj1 = activity.object1; var obj2 = activity.object2; - if (activity.summary_fields[obj2] && activity.summary_fields[obj2][0].name) { + var name; + if (activity.summary_fields[obj2] && activity.summary_fields[obj2][0].name + && !/^_delete/.test(activity.summary_fields[obj2][0].name)) { activity.summary_fields[obj2][0]['base'] = obj2; descr += obj2 + ' ' + activity.summary_fields[obj2][0].name + '' + ( (activity.operation == 'disassociate') ? ' from ' : ' to ' ); descr_nolink += obj2 + ' ' + activity.summary_fields[obj2][0].name + ( (activity.operation == 'disassociate') ? ' from ' : ' to ' ); } - else if (activity.object2) { - descr += activity.object2[0] + ( (activity.operation == 'disassociate') ? ' from ' : ' to ' ); - descr_nolink += activity.object2[0] + ( (activity.operation == 'disassociate') ? ' from ' : ' to ' ); + else if (activity.object2) { + name = ''; + if (activity.summary_fields[obj2] && activity.summary_fields[obj2][0].name) { + name = ' ' + stripDeleted(activity.summary_fields[obj2][0].name); + } + descr += activity.object2[0] + name + ( (activity.operation == 'disassociate') ? ' from ' : ' to ' ); + descr_nolink += activity.object2[0] + name + ( (activity.operation == 'disassociate') ? ' from ' : ' to ' ); } - if (activity.summary_fields[obj1] && activity.summary_fields[obj1][0].name) { + if (activity.summary_fields[obj1] && activity.summary_fields[obj1][0].name + && !/^\_delete/.test(activity.summary_fields[obj1][0].name)) { activity.summary_fields[obj1][0]['base'] = obj1; descr += obj1 + ' ' + activity.summary_fields[obj1][0].name + ''; descr_nolink += obj1 + ' ' + activity.summary_fields[obj1][0].name; } - else if (activity.object1) { - descr += activity.object1; - descr_nolink += activity.object1; + else if (activity.object1) { + name = ''; + if ( ((!(activity.summary_fields[obj1] && activity.summary_fields[obj1][0].name)) || + activity.summary_fields[obj1] && activity.summary_fields[obj1][0].name && + /^_delete/.test(activity.summary_fields[obj1][0].name)) + && (activity.changes && activity.changes.name) ) { + if (typeof activity.changes.name == 'string') { + name = ' ' + activity.changes.name; + } + else if (typeof activity.changes.name == 'object' && Array.isArray(activity.changes.name)) { + name = ' ' + activity.changes.name[0] + } + } + else if (activity.summary_fields[obj1] && activity.summary_fields[obj1][0].name) { + name = ' ' + stripDeleted(activity.summary_fields[obj1][0].name); + } + descr += activity.object1 + name; + descr_nolink += activity.object1 + name; } activity['description'] = descr; activity['description_nolink'] = descr_nolink;