Activity stream- completed modification to Rest lib. Fixed searches on activity stream allow search by object type and object name. Improved detail modal so that more of the changes box is visible. Moved search reset button to the right. There is now only one reset button per list, not one per filter widget.

This commit is contained in:
Chris Houseknecht 2013-11-19 02:25:37 +00:00
parent 3d11f604a9
commit 3377927c00
8 changed files with 98 additions and 44 deletions

View File

@ -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
}
}

View File

@ -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,

View File

@ -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",

View File

@ -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 <a href=\"' + usr + '\">' + activity.summary_fields.user.username + '</a> ';
}
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");
}

View File

@ -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 {

View File

@ -898,6 +898,34 @@ angular.module('FormGenerator', ['GeneratorHelpers', 'ngCookies', 'Utilities'])
html += "</div>\n";
}
if (field.type == 'lgtextarea') {
// Use for modal, readonly textarea fields
html += "<div class=\"label-text " + getLabelWidth() + "\">\n";
html += "<label class=\"control-label\">";
html += (field.icon) ? this.icon(field.icon) : "";
html += (field.label) ? field.label : '';
html += "</label>";
html += "</div>\n";
html += "<div class=\"col-lg-12\">\n";
html += "<div style=\"padding-left:10px;\">"
html += "<textarea ";
html += (field.rows) ? this.attr(field, 'rows') : "";
html += "ng-model=\"" + fld + '" ';
html += 'name="' + fld + '" ';
html += "class=\"form-control";
html += (field['class']) ? " " + field['class'] : "";
html += "\" ";
html += (field.ngChange) ? this.attr(field,'ngChange') : "";
html += buildId(field, fld, this.form);
html += (field.placeholder) ? this.attr(field,'placeholder') : "";
html += (options.mode == 'edit' && field.editRequired) ? "required " : "";
html += (options.mode == 'add' && field.addRequired) ? "required " : "";
html += (field.readonly || field.showonly) ? "readonly " : "";
html += "></textarea>\n";
html += "</div>\n";
html += "</div>\n";
}
html += "</div>\n";
}

View File

@ -538,9 +538,13 @@ angular.module('GeneratorHelpers', ['GeneratorHelpers'])
html += "</div><!-- col-lg-x -->\n";
}
// Spinner
html += "<div class=\"col-lg-1 col-md-1 col-sm-1 col-xs-1\"><i class=\"icon-spinner icon-spin icon-large\" ng-show=\"" + iterator +
"SearchSpin == true\"></i></div>\n";
// Reset button and spinner
html += "<div class=\"col-lg-1 col-md-1 col-sm-1 col-xs-1\">\n";
//html += "<button type=\"button\" class=\"btn btn-default btn-sm\" ng-click=\"resetSearch('" + iterator + "')\" " +
// "aw-tool-tip=\"Reset filter\" data-placement=\"top\"><i class=\"icon-undo\"></i></button>\n";
html += "<i class=\"icon-spinner icon-spin icon-large\" ng-show=\"" + iterator + "SearchSpin == true\"></i>\n";
html += "</div>\n";
return html;

View File

@ -216,7 +216,6 @@ angular.module('ListGenerator', ['GeneratorHelpers'])
// User supplied searchSize, calc the remaining
var size = parseInt(options.searchSize.replace(/([A-Z]|[a-z]|\-)/g,''));
size = (list.searchWidgets) ? list.searchWidgets * size : size;
console.log('size: ' + (12 - size - 1));
html += 'col-lg-' + (12 - size - 1);
}
else if (options.mode == 'summary') {