diff --git a/awx/ui/static/js/forms/ActivityDetail.js b/awx/ui/static/js/forms/ActivityDetail.js index b228382f2e..7cce68036c 100644 --- a/awx/ui/static/js/forms/ActivityDetail.js +++ b/awx/ui/static/js/forms/ActivityDetail.js @@ -13,6 +13,8 @@ angular.module('ActivityDetailDefinition', []) editTitle: 'Activity Detail', well: false, 'class': 'horizontal-narrow', + formFieldSize: 'col-lg-10', + formLabelSize: 'col-lg-2', fields: { timestamp: { @@ -20,6 +22,11 @@ angular.module('ActivityDetailDefinition', []) type: 'text', readonly: true }, + user: { + label: 'Initiated By', + type: 'text', + readonly: true + }, id: { label: 'Event ID', type: 'text', @@ -31,7 +38,7 @@ angular.module('ActivityDetailDefinition', []) readonly: true }, object1: { - label: 'Object 1', + label: 'Resource', type: 'text', ngHide: '!object1', readonly: true @@ -43,7 +50,7 @@ angular.module('ActivityDetailDefinition', []) readonly: true }, object2: { - label: 'Object 2', + label: 'Related', type: 'text', ngHide: '!object2', readonly: true @@ -56,8 +63,8 @@ angular.module('ActivityDetailDefinition', []) }, changes: { label: 'Changes', - type: 'textarea', - ngHide: '!changes', + type: 'lgtextarea', + ngHide: "!changes || changes =='' || changes == 'null'", readonly: true } } diff --git a/awx/ui/static/js/helpers/search.js b/awx/ui/static/js/helpers/search.js index bca7bf816d..f3edabcdfc 100644 --- a/awx/ui/static/js/helpers/search.js +++ b/awx/ui/static/js/helpers/search.js @@ -105,8 +105,10 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper']) } } } - - for (var i=1; i <= 3; i++) { + + // Set default values for each search widget on the page + var widgets = (list.searchWidgets) ? list.searchWidgets : 1; + for (var i=1; i <= widgets; i++) { var modifier = (i == 1) ? '' : i; if ( $('#search-widget-container' + modifier) ) { setDefaults(i); @@ -169,9 +171,13 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper']) scope.search(iterator); } - scope.resetSearch = function(iterator, widget) { + scope.resetSearch = function(iterator) { // Respdond to click of reset button - setDefaults(widget); + var widgets = (list.searchWidgets) ? list.searchWidgets : 1; + for (var i=1; i <= widgets; i++) { + // Clear each search widget + setDefaults(i); + } // Force removal of search keys from the URL window.location = '/#' + $location.path(); scope.search(iterator); @@ -245,6 +251,7 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper']) found_objects = 0; for (var i=1; i <= widgets; i++) { modifier = (i == 1) ? '' : i; + scope[iterator + 'HoldInput' + modifier] = true; //Block any input until we're done. Refresh.js will flip this back. if ($('#search-widget-container' + modifier) && list.fields[scope[iterator + 'SearchField' + modifier]] && list.fields[scope[iterator + 'SearchField' + modifier]].searchObject && @@ -258,12 +265,12 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper']) if ( $('#search-widget-container' + modifier) ) { if (list.fields[scope[iterator + 'SearchField' + modifier]] && list.fields[scope[iterator + 'SearchField' + modifier]].searchObject && - list.fields[scope[iterator + 'SearchField' + modifier]].searchObject !== 'all') { - scope[iterator + 'HoldInput' + modifier] = true; + list.fields[scope[iterator + 'SearchField' + modifier]].searchObject !== 'all') { if (scope[iterator + 'SearchValue' + modifier]) { var objs = list.fields[scope[iterator + 'SearchField' + modifier]].searchObject; - var objUrl = GetBasePath('base') + objs + '/?name__icontains=' + scope[iterator + 'SearchValue']; + var objUrl = GetBasePath('base') + objs + '/?name__icontains=' + scope[iterator + 'SearchValue' + modifier]; Rest.setUrl(objUrl); + Rest.setHeader({ widget: i }); Rest.get() .success( function(data, status, headers, config) { var pk=''; @@ -271,8 +278,7 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper']) pk += "," + data.results[j].id; } pk = pk.replace(/^\,/,''); - console.log(config); - scope.$emit('foundObject', iterator, page, load, spin, i, pk); + scope.$emit('foundObject', iterator, page, load, spin, config.headers['widget'], pk); }) .error( function(data, status, headers, config) { ProcessErrors(scope, data, status, null, diff --git a/awx/ui/static/js/lists/Streams.js b/awx/ui/static/js/lists/Streams.js index 9e83071d74..8c2391c66b 100644 --- a/awx/ui/static/js/lists/Streams.js +++ b/awx/ui/static/js/lists/Streams.js @@ -37,14 +37,8 @@ angular.module('StreamListDefinition', []) searchPlaceholder: 'Initiated by username', searchWidget: 1 }, - objects: { - label: 'Objects', - ngBindHtml: 'activity.objects', - nosort: true, - searchable: false - }, description: { - label: 'Description', + label: 'Action', ngBindHtml: 'activity.description', nosort: true, searchable: false @@ -64,7 +58,7 @@ angular.module('StreamListDefinition', []) label: 'All', searchOnly: true, searchObject: 'all', - searchPlaceholder: 'All primary objects', + searchPlaceholder: 'All resources', searchWidget: 2, searchField: 'object1' }, @@ -72,7 +66,7 @@ angular.module('StreamListDefinition', []) label: 'Credential', searchOnly: true, searchObject: 'credentials', - searchPlaceholder: 'Primary credential name', + searchPlaceholder: 'Credential name', searchWidget: 2, searchField: 'object1' }, @@ -80,7 +74,7 @@ angular.module('StreamListDefinition', []) label: 'Group', searchOnly: true, searchObject: 'groups', - searchPlaceholder: 'Primary group name', + searchPlaceholder: 'Group name', searchWidget: 2, searchField: 'object1' }, @@ -88,7 +82,7 @@ angular.module('StreamListDefinition', []) label: 'Host', searchOnly: true, searchObject: 'hosts', - searchPlaceholder: 'Primary host name', + searchPlaceholder: 'Host name', searchWidget: 2, searchField: 'object1' }, @@ -96,7 +90,7 @@ angular.module('StreamListDefinition', []) label: 'Inventory', searchOnly: true, searchObject: 'inventories', - searchPlaceholder: 'Primary inventory name', + searchPlaceholder: 'Inventory name', searchWidget: 2, searchField: 'object1' }, @@ -104,7 +98,7 @@ angular.module('StreamListDefinition', []) label: 'Job Template', searchOnly: true, searchObject: 'job_templates', - searchPlaceholder: 'Primary job template name', + searchPlaceholder: 'Job template name', searchWidget: 2, searchField: 'object1' }, @@ -112,7 +106,7 @@ angular.module('StreamListDefinition', []) label: 'Organization', searchOnly: true, searchObject: 'organizations', - searchPlaceholder: 'Primary organization name', + searchPlaceholder: 'Organization name', searchWidget: 2, searchField: 'object1' }, @@ -120,7 +114,7 @@ angular.module('StreamListDefinition', []) label: 'Project', searchOnly: true, searchObject: 'projects', - searchPlaceholder: 'Primary project name', + searchPlaceholder: 'Project name', searchWidget: 2, searchField: 'object1' }, @@ -139,7 +133,7 @@ angular.module('StreamListDefinition', []) label: 'All', searchOnly: true, searchObject: 'all', - searchPlaceholder: 'All related objects', + searchPlaceholder: 'All related resources', searchWidget: 3, searchField: 'object2' }, @@ -219,6 +213,15 @@ angular.module('StreamListDefinition', []) ngClick: "refreshStream()", iconSize: 'large' }, + reset: { + dataPlacement: 'top', + icon: "icon-undo", + mode: 'all', + 'class': 'btn-xs btn-primary', + awToolTip: "Reset the search filter", + ngClick: "resetSearch()", + iconSize: 'large' + }, close: { dataPlacement: 'top', icon: "icon-arrow-left", diff --git a/awx/ui/static/js/widgets/Stream.js b/awx/ui/static/js/widgets/Stream.js index 84a2dd3a88..3274f19947 100644 --- a/awx/ui/static/js/widgets/Stream.js +++ b/awx/ui/static/js/widgets/Stream.js @@ -82,14 +82,14 @@ angular.module('StreamWidget', ['RestServices', 'Utilities', 'StreamListDefiniti .factory('BuildDescription', ['FixUrl', 'BuildUrl', function(FixUrl, BuildUrl) { return function(activity) { var descr = ''; - if (activity.summary_fields.user) { + /*if (activity.summary_fields.user) { // this is a user transaction var usr = FixUrl(activity.related.user); descr += 'User ' + activity.summary_fields.user.username + ' '; } else { descr += 'System '; - } + }*/ descr += activity.operation; descr += (/e$/.test(activity.operation)) ? 'd ' : 'ed '; if (activity.summary_fields.object2 && activity.summary_fields.object2.name) { @@ -110,8 +110,8 @@ angular.module('StreamWidget', ['RestServices', 'Utilities', 'StreamListDefiniti } }]) - .factory('ShowDetail', ['Rest', 'Alert', 'GenerateForm', 'ProcessErrors', 'GetBasePath', 'FormatDate', 'ActivityDetailForm', - function(Rest, Alert, GenerateForm, ProcessErrors, GetBasePath, FormatDate, ActivityDetailForm) { + .factory('ShowDetail', ['Rest', 'Alert', 'GenerateForm', 'ProcessErrors', 'GetBasePath', 'FormatDate', 'ActivityDetailForm', 'Empty', + function(Rest, Alert, GenerateForm, ProcessErrors, GetBasePath, FormatDate, ActivityDetailForm, Empty) { return function(activity_id) { var generator = GenerateForm; @@ -157,7 +157,10 @@ angular.module('StreamWidget', ['RestServices', 'Utilities', 'StreamListDefiniti if (results.summary_fields.object2) { scope['object2_name'] = results.summary_fields.object2.name; } - scope['changes'] = JSON.stringify(results['changes'], null, '\t'); + scope['user'] = (results.summary_fields.user) ? results.summary_fields.user.username : 'system'; + scope['changes'] = results['changes']; + //scope['changes'] = (!Empty(results['changes'])) ? JSON.parse(scope.variables) : ''; + //scope['changes'] = JSON.stringify(results['changes'], null, '\t'); scope.formModalAction = function() { $('#form-modal').modal("hide"); } diff --git a/awx/ui/static/lib/ansible/RestServices.js b/awx/ui/static/lib/ansible/RestServices.js index 489d86e8e4..182ec4b0d8 100644 --- a/awx/ui/static/lib/ansible/RestServices.js +++ b/awx/ui/static/lib/ansible/RestServices.js @@ -46,9 +46,9 @@ function($http, $rootScope, $cookieStore, $q, Authorization) { }, setHeader: function(hdr) { - // Passin in { key: value } pairs to be added to the header + // Pass in { key: value } pairs to be added to the header for (var h in hdr) { - this.headers[h] = hdr.h; + this.headers[h] = hdr[h]; } }, get: function(args) { @@ -79,10 +79,11 @@ function($http, $rootScope, $cookieStore, $q, Authorization) { return this.createResponse({ detail: 'Token is expired' }, 401); } else if (token) { + this.setHeader({ Authorization: 'Token ' + token }); return $http({ method: 'POST', url: this.url, - headers: { 'Authorization': 'Token ' + token }, + headers: this.headers, data: data }); } else { @@ -96,10 +97,11 @@ function($http, $rootScope, $cookieStore, $q, Authorization) { return this.createResponse({ detail: 'Token is expired' }, 401); } else if (token) { + this.setHeader({ Authorization: 'Token ' + token }); return $http({ method: 'PUT', url: this.url, - headers: { 'Authorization': 'Token ' + token }, + headers: this.headers, data: data }); } else { @@ -113,10 +115,11 @@ function($http, $rootScope, $cookieStore, $q, Authorization) { return this.createResponse({ detail: 'Token is expired' }, 401); } else if (token) { + this.setHeader({ Authorization: 'Token ' + token }); return $http({ method: 'DELETE', url: this.url, - headers: { 'Authorization': 'Token ' + token }, + headers: this.headers, data: data }); } else { @@ -130,10 +133,11 @@ function($http, $rootScope, $cookieStore, $q, Authorization) { return this.createResponse({ detail: 'Token is expired' }, 401); } else if (token) { + this.setHeader({ Authorization: 'Token ' + token }); return $http({ method: 'OPTIONS', url: this.url, - headers: { 'Authorization': 'Token ' + token } + headers: this.headers }); } else { diff --git a/awx/ui/static/lib/ansible/form-generator.js b/awx/ui/static/lib/ansible/form-generator.js index b7cb2955fb..604a43bb4d 100644 --- a/awx/ui/static/lib/ansible/form-generator.js +++ b/awx/ui/static/lib/ansible/form-generator.js @@ -898,6 +898,34 @@ angular.module('FormGenerator', ['GeneratorHelpers', 'ngCookies', 'Utilities']) html += "\n"; } + if (field.type == 'lgtextarea') { + // Use for modal, readonly textarea fields + html += "
\n"; + html += ""; + html += "
\n"; + html += "
\n"; + html += "
" + html += "