diff --git a/awx/ui/static/js/controllers/Inventories.js b/awx/ui/static/js/controllers/Inventories.js index 7960a6257d..44208ce494 100644 --- a/awx/ui/static/js/controllers/Inventories.js +++ b/awx/ui/static/js/controllers/Inventories.js @@ -316,7 +316,7 @@ function InventoriesEdit ($scope, $location, $routeParams, $compile, GenerateLis GetSyncStatusMsg, InjectHosts, HostsReload, GroupsAdd, GroupsEdit, GroupsDelete, Breadcrumbs, LoadBreadCrumbs, Empty, Rest, ProcessErrors, InventoryUpdate, Alert, ToggleChildren, ViewUpdateStatus, GroupsCancelUpdate, Find, HostsCreate, EditInventoryProperties, HostsEdit, HostsDelete, ToggleHostEnabled, CopyMoveGroup, CopyMoveHost, - Stream, GetBasePath, ShowJobSummary) + Stream, GetBasePath, ShowJobSummary, ApplyEllipsis, WatchInventoryWindowResize) { ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior //scope. @@ -360,6 +360,11 @@ function InventoriesEdit ($scope, $location, $routeParams, $compile, GenerateLis // Add hosts view $scope.show_failures = false; InjectHosts({ scope: $scope, inventory_id: $scope.inventory_id, tree_id: $scope.selected_tree_id, group_id: $scope.selected_group_id }); + + // As the window shrinks and expands, apply ellipsis + setTimeout(function() { ApplyEllipsis('#groups_table .group-name a'); }, 2500); //give the window time to display + WatchInventoryWindowResize(); + }); @@ -368,6 +373,8 @@ function InventoriesEdit ($scope, $location, $routeParams, $compile, GenerateLis $scope.removeGroupTreeRefreshed(); } $scope.removeGroupTreeRefreshed = $scope.$on('GroupTreeRefreshed', function(e, inventory_name, groups) { + // Reapply ellipsis to groups + setTimeout(function() { ApplyEllipsis('#groups_table .group-name a'); }, 2500); // Reselect the preveiously selected group node, causing host view to refresh. $scope.showHosts($scope.selected_tree_id, $scope.selected_group_id, false); }); @@ -525,12 +532,14 @@ function InventoriesEdit ($scope, $location, $routeParams, $compile, GenerateLis //Load tree data for the first time BuildTree({ scope: $scope, inventory_id: $scope.inventory_id, refresh: false }); + } InventoriesEdit.$inject = [ '$scope', '$location', '$routeParams', '$compile', 'GenerateList', 'ClearScope', 'InventoryGroups', 'InventoryHosts', 'BuildTree', 'Wait', 'GetSyncStatusMsg', 'InjectHosts', 'HostsReload', 'GroupsAdd', 'GroupsEdit', 'GroupsDelete', 'Breadcrumbs', 'LoadBreadCrumbs', 'Empty', 'Rest', 'ProcessErrors', 'InventoryUpdate', 'Alert', 'ToggleChildren', 'ViewUpdateStatus', 'GroupsCancelUpdate', 'Find', 'HostsCreate', 'EditInventoryProperties', 'HostsEdit', - 'HostsDelete', 'ToggleHostEnabled', 'CopyMoveGroup', 'CopyMoveHost', 'Stream', 'GetBasePath', 'ShowJobSummary' + 'HostsDelete', 'ToggleHostEnabled', 'CopyMoveGroup', 'CopyMoveHost', 'Stream', 'GetBasePath', 'ShowJobSummary', + 'ApplyEllipsis', 'WatchInventoryWindowResize' ]; diff --git a/awx/ui/static/js/helpers/Groups.js b/awx/ui/static/js/helpers/Groups.js index bc43f150ce..073620cd2d 100644 --- a/awx/ui/static/js/helpers/Groups.js +++ b/awx/ui/static/js/helpers/Groups.js @@ -341,10 +341,10 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', ' .factory('GroupsAdd', ['$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'GroupForm', 'GenerateForm', 'Prompt', 'ProcessErrors', 'GetBasePath', 'ParseTypeChange', 'GroupsEdit', 'Wait', 'GetChoices', - 'GetSourceTypeOptions', 'LookUpInit', 'BuildTree', 'SourceChange', + 'GetSourceTypeOptions', 'LookUpInit', 'BuildTree', 'SourceChange', 'WatchInventoryWindowResize', function($rootScope, $location, $log, $routeParams, Rest, Alert, GroupForm, GenerateForm, Prompt, ProcessErrors, GetBasePath, ParseTypeChange, GroupsEdit, Wait, GetChoices, GetSourceTypeOptions, LookUpInit, BuildTree, - SourceChange) { + SourceChange, WatchInventoryWindowResize) { return function(params) { var inventory_id = params.inventory_id; @@ -387,11 +387,13 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', ' } scope.removeSaveComplete = scope.$on('SaveComplete', function(e, group_id, error) { if (!error) { - if (scope.searchCleanup) + if (scope.searchCleanup) { scope.searchCleanup(); + } scope.formModalActionDisabled = false; scope.showGroupHelp = false; //get rid of the Hint BuildTree({ scope: parent_scope, inventory_id: inventory_id, refresh: true, new_group_id: group_id }); + WatchInventoryWindowResize(); } }); @@ -484,6 +486,7 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', ' if (scope.searchCleanup) { scope.searchCleanup(); } + WatchInventoryWindowResize(); } // Save @@ -589,9 +592,10 @@ 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', 'Find', + 'WatchInventoryWindowResize', function($rootScope, $location, $log, $routeParams, Rest, Alert, GroupForm, GenerateForm, Prompt, ProcessErrors, GetBasePath, SetNodeName, ParseTypeChange, GetSourceTypeOptions, InventoryUpdate, GetUpdateIntervalOptions, - LookUpInit, Empty, Wait, GetChoices, UpdateGroup, SourceChange, Find) { + LookUpInit, Empty, Wait, GetChoices, UpdateGroup, SourceChange, Find, WatchInventoryWindowResize) { return function(params) { var parent_scope = params.scope; @@ -855,6 +859,7 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', ' else { Wait('stop'); } + WatchInventoryWindowResize(); } }); @@ -936,6 +941,7 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', ' if (scope.searchCleanup) { scope.searchCleanup(); } + WatchInventoryWindowResize(); } // Save @@ -1076,9 +1082,9 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', ' .factory('ShowUpdateStatus', ['$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'GenerateForm', - 'Prompt', 'ProcessErrors', 'GetBasePath', 'FormatDate', 'InventoryStatusForm', 'Wait', 'Empty', + 'Prompt', 'ProcessErrors', 'GetBasePath', 'FormatDate', 'InventoryStatusForm', 'Wait', 'Empty', 'WatchInventoryWindowResize', function($rootScope, $location, $log, $routeParams, Rest, Alert, GenerateForm, Prompt, ProcessErrors, GetBasePath, - FormatDate, InventoryStatusForm, Wait, Empty) { + FormatDate, InventoryStatusForm, Wait, Empty, WatchInventoryWindowResize) { return function(params) { var group_name = params.group_name; @@ -1102,9 +1108,15 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', ' scope.formModalAction = function() { $('#form-modal').modal("hide"); if (parent_scope && parent_scope.showHosts && !Empty(tree_id)) { - if (parent_scope.selected_tree_id !== tree_id) + if (parent_scope.selected_tree_id !== tree_id) { parent_scope.showHosts(tree_id, group_id, false); + } } + WatchInventoryWindowResize(); + } + + scope.cancelModal = function() { + WatchInventoryWindowResize(); } if (scope.removeUpdateStatusReady) { diff --git a/awx/ui/static/js/helpers/Hosts.js b/awx/ui/static/js/helpers/Hosts.js index 74df35b788..beb4d89a8f 100644 --- a/awx/ui/static/js/helpers/Hosts.js +++ b/awx/ui/static/js/helpers/Hosts.js @@ -77,21 +77,21 @@ angular.module('HostsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', 'H return -1 * (a - b); }); title = "Recent Jobs"; - html = "\n"; + html = "
\n"; html += "\n"; html += "\n"; html += "\n"; html += "\n"; html += "\n"; for (var j=0; j < jobs.length; j++) { var job = jobs[j]; html += "\n"; - html += "\n"; - html += "\n"; - html += "\n"; + html += "\n"; + html += "\n"; + html += "\n"; html += "\n"; } html += "\n"; @@ -128,8 +128,9 @@ angular.module('HostsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', 'H }]) .factory('HostsReload', [ '$routeParams', 'Empty', 'InventoryHosts', 'GetBasePath', 'SearchInit', 'PaginateInit', 'Wait', - 'SetHostStatus', 'SetStatus', - function($routeParams, Empty, InventoryHosts, GetBasePath, SearchInit, PaginateInit, Wait, SetHostStatus, SetStatus) { + 'SetHostStatus', 'SetStatus', 'ApplyEllipsis', + function($routeParams, Empty, InventoryHosts, GetBasePath, SearchInit, PaginateInit, Wait, SetHostStatus, SetStatus, + ApplyEllipsis) { return function(params) { var scope = params.scope; @@ -153,6 +154,7 @@ angular.module('HostsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', 'H //SetHostStatus(scope.hosts[i]); } SetStatus({ scope: scope }); + setTimeout(function() { ApplyEllipsis('#hosts_table .host-name a'); }, 2500); Wait('stop'); scope.$emit('HostReloadComplete'); }); @@ -304,9 +306,9 @@ angular.module('HostsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', 'H .factory('HostsCreate', ['$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'HostForm', 'GenerateForm', - 'Prompt', 'ProcessErrors', 'GetBasePath', 'HostsReload', 'ParseTypeChange', 'Wait', + 'Prompt', 'ProcessErrors', 'GetBasePath', 'HostsReload', 'ParseTypeChange', 'Wait', 'WatchInventoryWindowResize', function($rootScope, $location, $log, $routeParams, Rest, Alert, HostForm, GenerateForm, Prompt, ProcessErrors, - GetBasePath, HostsReload, ParseTypeChange, Wait) { + GetBasePath, HostsReload, ParseTypeChange, Wait, WatchInventoryWindowResize) { return function(params) { var parent_scope = params.scope; @@ -349,11 +351,14 @@ angular.module('HostsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', 'H scope.removeHostSaveComplete = scope.$on('HostSaveComplete', function() { Wait('stop'); $('#form-modal').modal('hide'); + HostsReload({ scope: parent_scope, group_id: parent_scope.selected_group_id, tree_id: parent_scope.selected_tree_id, inventory_id: parent_scope.inventory_id }); + + WatchInventoryWindowResize(); }); // Save @@ -417,15 +422,20 @@ angular.module('HostsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', 'H // Defaults generator.reset(); }; - + + scope.cancelModal = function() { + WatchInventoryWindowResize(); + } + } }]) .factory('HostsEdit', ['$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'HostForm', 'GenerateForm', - 'Prompt', 'ProcessErrors', 'GetBasePath', 'HostsReload', 'ParseTypeChange', 'Wait', 'Find', 'SetStatus', + 'Prompt', 'ProcessErrors', 'GetBasePath', 'HostsReload', 'ParseTypeChange', 'Wait', 'Find', 'SetStatus', 'ApplyEllipsis', + 'WatchInventoryWindowResize', function($rootScope, $location, $log, $routeParams, Rest, Alert, HostForm, GenerateForm, Prompt, ProcessErrors, - GetBasePath, HostsReload, ParseTypeChange, Wait, Find, SetStatus) { + GetBasePath, HostsReload, ParseTypeChange, Wait, Find, SetStatus, ApplyEllipsis, WatchInventoryWindowResize) { return function(params) { var parent_scope = params.scope; @@ -513,13 +523,29 @@ angular.module('HostsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', 'H scope.removeSaveCompleted = scope.$on('saveCompleted', function() { // Update the name on the list var host = Find({ list: parent_scope.hosts, key: 'id', val: host_id }); + var old_name = host.name; host.name = scope.name; host.enabled = scope.enabled; host.enabled_flag = scope.enabled; SetStatus({ scope: parent_scope, host: host }); - // Close modal - Wait('stop'); - $('#form-modal').modal('hide'); + + // Update any titles attributes created by ApplyEllipsis + if (old_name) { + setTimeout(function() { + $('#hosts_table .host-name a[title="' + old_name + '"').attr('title', host.name); + ApplyEllipsis('#hosts_table .host-name a'); + // Close modal + Wait('stop'); + $('#form-modal').modal('hide'); + }, 2000); + } + else { + // Close modal + Wait('stop'); + $('#form-modal').modal('hide'); + } + // Restore ellipsis response to window resize + WatchInventoryWindowResize(); }); // Save changes to the parent @@ -580,6 +606,11 @@ angular.module('HostsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', 'H } scope.parseType = 'yaml'; } + + scope.cancelModal = function() { + WatchInventoryWindowResize(); + } + } }]) diff --git a/awx/ui/static/js/helpers/inventory.js b/awx/ui/static/js/helpers/inventory.js index ce5be78385..d88f5132e5 100644 --- a/awx/ui/static/js/helpers/inventory.js +++ b/awx/ui/static/js/helpers/inventory.js @@ -12,6 +12,20 @@ angular.module('InventoryHelper', [ 'RestServices', 'Utilities', 'OrganizationLi 'InventoryHelper', 'InventoryFormDefinition', 'ParseHelper', 'SearchHelper' ]) + .factory('WatchInventoryWindowResize', ['ApplyEllipsis', function(ApplyEllipsis) { + return function() { + // Call to set or restore window resize + var timeOut; + $(window).resize(function() { + clearTimeout(timeOut); + timeOut = setTimeout(function() { + ApplyEllipsis('#groups_table .group-name a'); + ApplyEllipsis('#hosts_table .host-name a'); + }, 100); + }); + } + }]) + .factory('SaveInventory', ['InventoryForm', 'Rest', 'Alert', 'ProcessErrors', 'LookUpInit', 'OrganizationList', 'GetBasePath', 'ParseTypeChange', 'Wait', function(InventoryForm, Rest, Alert, ProcessErrors, LookUpInit, OrganizationList, GetBasePath, ParseTypeChange, Wait) { @@ -102,16 +116,12 @@ angular.module('InventoryHelper', [ 'RestServices', 'Utilities', 'OrganizationLi var PreviousSearchParams = Store('CurrentSearchParams'); form.well = false; - //form.formLabelSize = 'col-lg-3'; - //form.formFieldSize = 'col-lg-9'; var scope = generator.inject(form, {mode: 'edit', modal: true, related: false, modal_show: false }); /* Reset form properties. Otherwise it screws up future requests of the Inventories detail page */ form.well = true; - //delete form.formLabelSize; - //delete form.formFieldSize; - + ParseTypeChange(scope,'inventory_variables', 'inventoryParseType'); scope.inventoryParseType = 'yaml'; scope.formModalActionLabel = 'Save'; diff --git a/awx/ui/static/js/lists/InventoryGroups.js b/awx/ui/static/js/lists/InventoryGroups.js index f341e42b69..79b8e9750f 100644 --- a/awx/ui/static/js/lists/InventoryGroups.js +++ b/awx/ui/static/js/lists/InventoryGroups.js @@ -29,7 +29,6 @@ angular.module('InventoryGroupsDefinition', []) ngClass: "group.selected_class", hasChildren: true, columnClass: 'col-lg-9 col-md-9 col-sm-7 col-xs-7', - 'class': 'ellipsis', nosort: true, awDroppable: "\{\{ group.isDroppable \}\}", awDraggable: "\{\{ group.isDraggable \}\}", diff --git a/awx/ui/static/js/lists/InventoryHosts.js b/awx/ui/static/js/lists/InventoryHosts.js index d59854352b..3efae93e01 100644 --- a/awx/ui/static/js/lists/InventoryHosts.js +++ b/awx/ui/static/js/lists/InventoryHosts.js @@ -26,7 +26,7 @@ angular.module('InventoryHostsDefinition', []) label: 'Hosts', ngClick: "editHost(\{\{ host.id \}\})", searchPlaceholder: "search_place_holder", - columnClass: 'col-lg-9 ellipsis', + columnClass: 'col-lg-9 col-md-9 col-sm-7 col-xs-7', dataHostId: "\{\{ host.id \}\}", dataType: "host", awDraggable: "true" @@ -91,6 +91,9 @@ angular.module('InventoryHostsDefinition', []) }, actions: { + + columnClass: 'col-lg-3 col-md-3 col-sm-5 col-xs-5', + create: { mode: 'all', ngClick: "createHost()", diff --git a/awx/ui/static/less/ansible-ui.less b/awx/ui/static/less/ansible-ui.less index 0666752e3d..306d5288cb 100644 --- a/awx/ui/static/less/ansible-ui.less +++ b/awx/ui/static/less/ansible-ui.less @@ -66,7 +66,12 @@ body.modal-open { .ellipsis { white-space: nowrap; overflow: hidden; - text-overflow: ellipsis; + text-overflow: ellipsis; +} + +.group-name { + display: inline-block; + width: 90%; } a { @@ -193,20 +198,22 @@ textarea { } /* TB tooltip overrides */ - + .popover-content, .popover-content { + width: 100%; + } .popover { - z-index: 2000; + z-index: 2000; } .tooltip { - z-index: 1050; - opacity: 1.0; + z-index: 1050; + opacity: 1.0; } - .alert { +.alert { margin-top: 15px; margin-bottom: 15px; - } +} hr { border-color: #e3e3e3; @@ -1132,6 +1139,10 @@ input[type="checkbox"].checkbox-no-label { .draggable-clone { opacity: .60; font-weight: bold; + /*z-index: 2000; + overflow: visible; + whitespace: wrap; + text-overflow: clip;*/ } .droppable-hover { @@ -1139,7 +1150,10 @@ input[type="checkbox"].checkbox-no-label { color: @info-color; padding: 6px; border: 1px solid @info-border; - border-radius: 4px; + border-radius: 4px; + /*overflow: visible; + whitespace: wrap; + text-overflow: clip;*/ } diff --git a/awx/ui/static/lib/ansible/InventoryTree.js b/awx/ui/static/lib/ansible/InventoryTree.js index 7b31832698..bafdb5f01a 100644 --- a/awx/ui/static/lib/ansible/InventoryTree.js +++ b/awx/ui/static/lib/ansible/InventoryTree.js @@ -173,18 +173,21 @@ angular.module('InventoryTree', ['Utilities', 'RestServices', 'GroupsHelper', 'P // Update a group with a set of properties - .factory('UpdateGroup', [ function() { + .factory('UpdateGroup', ['ApplyEllipsis', function(ApplyEllipsis) { return function(params) { var scope = params.scope; var group_id = params.group_id; var properties = params.properties; // object of key:value pairs to update - + var old_name; for (var i=0; i < scope.groups.length; i++) { if (scope.groups[i].group_id == group_id) { var grp = scope.groups[i]; for (var p in properties) { - scope.groups[i][p] = properties[p]; + if (p == 'name') { + old_name = scope.groups[i].name; + } + scope.groups[i][p] = properties[p]; } } if (scope.groups[i].id == scope.selected_tree_id) { @@ -194,6 +197,15 @@ angular.module('InventoryTree', ['Utilities', 'RestServices', 'GroupsHelper', 'P scope.hostSearchPlaceholder = 'Search ' + scope.groups[i].name; } } + + // Update any titles attributes created by ApplyEllipsis + if (old_name) { + setTimeout(function() { + $('#groups_table .group-name a[title="' + old_name + '"').attr('title',properties.name); + ApplyEllipsis('#groups_table .group-name a'); + }, 2500); + } + } }]) diff --git a/awx/ui/static/lib/ansible/Utilities.js b/awx/ui/static/lib/ansible/Utilities.js index dfed22aea3..4d4ba92c40 100644 --- a/awx/ui/static/lib/ansible/Utilities.js +++ b/awx/ui/static/lib/ansible/Utilities.js @@ -539,18 +539,18 @@ angular.module('Utilities',['RestServices', 'Utilities']) }]) - /* Store - * - * Wrapper for local storage. All local storage requests flow through here so that we can - * stringify/unstringify objects and respond to future issues in one place. For example, - * we may at some point want to only use session storage rather than local storage. We might - * want to add a test for whether or not local/session storage exists for the browser, etc. - * - * store(key,value) will store the value using the key - * - * store(key) retrieves the value of the key - * - */ + /* Store + * + * Wrapper for local storage. All local storage requests flow through here so that we can + * stringify/unstringify objects and respond to future issues in one place. For example, + * we may at some point want to only use session storage rather than local storage. We might + * want to add a test for whether or not local/session storage exists for the browser, etc. + * + * store(key,value) will store the value using the key + * + * store(key) retrieves the value of the key + * + */ .factory('Store', ['Empty', function(Empty) { return function(key, value) { if (!Empty(value)) { @@ -562,8 +562,59 @@ angular.module('Utilities',['RestServices', 'Utilities']) var val = localStorage[key]; return (!Empty(val)) ? JSON.parse(val) : null; } - } - }]) + + } + }]) + + /* + * + * ApplyEllipsis() + * + */ + .factory('ApplyEllipsis', [ function() { + return function(selector) { + // Add a hidden element to the DOM. We'll use this to calc the px length of + // our target text. + var tmp = $('#string-test'); + if (!tmp.length) { + $('body').append(''); + tmp = $('#string-test'); + } + // Find and process the text. + $(selector).each(function() { + var setTitle = true; + var txt; + if ($(this).attr('title')) { + txt = $(this).attr('title'); + setTitle = false; + } + else { + txt = $(this).text(); + } + tmp.text(txt); + var w = tmp.width(); //text width + var pw = $(this).parent().width(); //parent width + if (w > pw) { + // text is wider than parent width + if (setTitle) { + // Save the original text in the title + $(this).attr('title',txt); + } + var cw = w / txt.length; // px width per character + var df = w - pw; // difference in px + txt = txt.substr(0, txt.length - (Math.ceil(df / cw) + 3)); + $(this).text(txt + '...'); + } + if (pw > w && !setTitle) { + // the parent has expanded and we previously set the title text + var txt = $(this).attr('title'); + $(this).text(txt); + } + }); + + } + }]); + diff --git a/awx/ui/static/lib/ansible/directives.js b/awx/ui/static/lib/ansible/directives.js index 0225526dfc..004e5deae3 100644 --- a/awx/ui/static/lib/ansible/directives.js +++ b/awx/ui/static/lib/ansible/directives.js @@ -582,7 +582,6 @@ angular.module('AWDirectives', ['RestServices', 'Utilities', 'AuthService', 'Job found = true; break; } - } return (found) ? false : true; } diff --git a/awx/ui/static/lib/ansible/generator-helpers.js b/awx/ui/static/lib/ansible/generator-helpers.js index 9d29e82882..2253508c2a 100644 --- a/awx/ui/static/lib/ansible/generator-helpers.js +++ b/awx/ui/static/lib/ansible/generator-helpers.js @@ -471,9 +471,16 @@ angular.module('GeneratorHelpers', ['GeneratorHelpers']) // Add collapse/expand icon --used on job_events page if (list['hasChildren'] && field.hasChildren) { - html += " " + - " "; - //ng-show=\"'\{\{ " + list.iterator + ".related.children \}\}' !== ''\" + html += " " + + " "; + //ng-show=\"'\{\{ " + list.iterator + ".related.children \}\}' !== ''\" + } + + if (list.name == 'groups') { + html += "
"; + } + if (list.name == 'hosts') { + html += "
"; } // Start the Link @@ -550,9 +557,14 @@ angular.module('GeneratorHelpers', ['GeneratorHelpers']) && options.mode != 'lookup' && options.mode != 'select' && !field.noLink && !field.ngBindHtml ) { html += ""; } + + if (list.name == 'hosts' || list.name == 'groups') { + html += "
"; + } + // close ngShow html += (field.ngShow) ? "" : ""; - + // Specific to Job Events page -showing event detail/results html += (field.appendHTML) ? "
- AnsibleWorks AWX + Ansible Tower @@ -244,7 +244,7 @@
ID\n"; - html += "Status\n"; - html += "Name\n"; + html += "Status\n"; + html += "Name\n"; html += "
" + job.id + " " + job.status + "" + job.name + "" + job.id + "" + job.name + "