Activity stream: implemented new search. Fixed a bunch of things related to the new data structure. Fixed /home/groups page.

This commit is contained in:
chris Houseknecht 2014-01-16 05:00:22 -05:00
parent a90de488e1
commit 06abf29d50
8 changed files with 97 additions and 68 deletions

View File

@ -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, HostsStatusMsg, GetSyncStatusMsg, ViewUpdateStatus, Stream) {
GetBasePath, SearchInit, PaginateInit, FormatDate, GetHostsStatusMsg, GetSyncStatusMsg, ViewUpdateStatus, Stream) {
ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior
//scope.
@ -122,7 +122,7 @@ function HomeGroups ($location, $routeParams, HomeGroupList, GenerateList, Proce
// Set values for Failed Hosts column
scope.home_groups[i].failed_hosts = scope.home_groups[i].hosts_with_active_failures + ' / ' + scope.home_groups[i].total_hosts;
msg = HostsStatusMsg({
msg = GetHostsStatusMsg({
active_failures: scope.home_groups[i].hosts_with_active_failures,
total_hosts: scope.home_groups[i].total_hosts,
inventory_id: scope.home_groups[i].inventory,
@ -135,7 +135,8 @@ function HomeGroups ($location, $routeParams, HomeGroupList, GenerateList, Proce
scope.home_groups[i].failed_hosts_link = msg['url'];
scope.home_groups[i].failed_hosts_class = msg['class'];
scope.home_groups[i].status = update_status['status'];
scope.home_groups[i].source = scope.groups[i].summary_fields.inventory_source.source;
scope.home_groups[i].source = (scope.home_groups[i].summary_fields.inventory_source) ?
scope.home_groups[i].summary_fields.inventory_source.source : null;
scope.home_groups[i].last_updated = last_update;
scope.home_groups[i].status_badge_class = update_status['class'];
scope.home_groups[i].status_badge_tooltip = update_status['tooltip'];
@ -205,12 +206,17 @@ function HomeGroups ($location, $routeParams, HomeGroupList, GenerateList, Proce
LoadBreadCrumbs();
scope.showActivity = function() { Stream(); }
scope.viewUpdateStatus = function(id) { ViewUpdateStatus({ scope: scope, group_id: id }) };
scope.viewUpdateStatus = function(id) {
scope.groups = scope.home_groups;
ViewUpdateStatus({ scope: scope, tree_id: id })
};
}
HomeGroups.$inject = [ '$location', '$routeParams', 'HomeGroupList', 'GenerateList', 'ProcessErrors', 'LoadBreadCrumbs', 'ReturnToCaller',
'ClearScope', 'GetBasePath', 'SearchInit', 'PaginateInit', 'FormatDate', 'HostsStatusMsg', 'GetSyncStatusMsg', 'ViewUpdateStatus', 'Stream'
'ClearScope', 'GetBasePath', 'SearchInit', 'PaginateInit', 'FormatDate', 'GetHostsStatusMsg', 'GetSyncStatusMsg', 'ViewUpdateStatus',
'Stream'
];

View File

@ -93,7 +93,10 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
var found = false;
var group = Find({ list: scope.groups, key: 'id', val: tree_id });
scope.showHosts(tree_id, group_id, false);
if (scope.showHosts) {
if (scope.selected_tree_id !== tree_id)
scope.showHosts(tree_id, group_id, false);
}
if (group) {
if (Empty(group.source)) {
@ -141,9 +144,7 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
// Return values for use on host status indicator
if (active_failures > 0) {
tip = active_failures +
[ (active_failures == 1) ? ' host' : ' hosts' ] + ' with failed jobs.' +
[ (active_failures == 1) ? ' host' : ' hosts' ] + '.';
tip = total_hosts + ( (total_hosts == 1) ? ' host' : ' hosts' ) + '. ' + active_failures + ' with failed jobs.';
html_class = 'true';
failures = true;
}
@ -156,7 +157,7 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
}
else {
// many hosts with 0 failures
tip = 'No job failures';
tip = total_hosts + ( (total_hosts == 1) ? ' host' : ' hosts' ) + '. No job failures';
html_class = 'false';
}
}

View File

@ -249,7 +249,8 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper'])
}
Refresh({ scope: scope, set: set, iterator: iterator, url: url });
});
/*
if (scope.removeFoundObject) {
scope.removeFoundObject();
}
@ -269,8 +270,9 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper'])
scope.$emit('prepareSearch2', iterator, page, load, spin);
}
});
*/
if (scope.removeResultWarning) {
/*if (scope.removeResultWarning) {
scope.removeResultWarning();
}
scope.removeResultWarning = scope.$on('resultWarning', function(e, objs, length) {
@ -278,6 +280,7 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper'])
var label = (objs == 'inventory') ? 'inventories' : objs.replace(/s$/,'');
Alert('Warning', 'The number of matching ' + label + ' was too large. We limited your search to the first 30.', 'alert-info');
});
*/
if (scope.removePrepareSearch) {
scope.removePrepareSearch();
@ -293,6 +296,7 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper'])
var modifier;
// Determine how many object values we're dealing with.
/*
expected_objects = 0;
found_objects = 0;
for (var i=1; i <= widgets; i++) {
@ -305,18 +309,27 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper'])
expected_objects++;
}
}
*/
for (var i=1; i <= widgets; i++) {
var modifier = (i == 1) ? '' : i;
if ( $('#search-widget-container' + modifier) ) {
if (list.fields[scope[iterator + 'SearchField' + modifier]] &&
list.fields[scope[iterator + 'SearchField' + modifier]].searchObject) {
// Search field of object type
if (list.fields[scope[iterator + 'SearchField' + modifier]].searchObject !== 'all') {
// An object type is selected
scope[iterator + 'HideAllStartBtn' + modifier] = false;
if (scope[iterator + 'SearchValue' + modifier]) {
// A search value was entered
scope[iterator + 'ShowStartBtn' + modifier] = false;
var objs = list.fields[scope[iterator + 'SearchField' + modifier]].searchObject;
var objUrl = GetBasePath('base') + objs + '/?name__icontains=' + scope[iterator + 'SearchValue' + modifier];
scope[iterator + 'SearchParams'] += '&' +
list.fields[scope[iterator + 'SearchField' + modifier]].searchObject +
'__name__icontains=' +
scope[iterator + 'SearchValue' + modifier];
//var objUrl = GetBasePath('base') + objs + '/?name__icontains=' + scope[iterator + 'SearchValue' + modifier];
/*
Rest.setUrl(objUrl);
Rest.setHeader({ widget: i });
Rest.setHeader({ object: objs });
@ -340,10 +353,11 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper'])
{ hdr: 'Error!', msg: 'Retrieving list of ' + objs + ' where name contains: ' + scope[iterator + 'SearchValue' + modifier] +
' GET returned status: ' + status });
});
}
*/
}
else {
scope[iterator + 'ShowStartBtn' + modifier] = true;
scope.$emit('foundObject', iterator, page, load, spin, i, null);
//scope.$emit('foundObject', iterator, page, load, spin, i, null);
}
}
else {
@ -353,10 +367,11 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper'])
}
}
}
if (expected_objects == 0) {
scope.$emit('prepareSearch2', iterator, page, load, spin);
//if (expected_objects == 0) {
// No search widgets contain objects
scope.$emit('prepareSearch2', iterator, page, load, spin);
}
// scope.$emit('prepareSearch2', iterator, page, load, spin);
//}
});
if (scope.removePrepareSearch2) {

View File

@ -24,7 +24,7 @@ angular.module('HomeGroupListDefinition', [])
label: 'Group',
ngClick: "\{\{ 'GroupsEdit(' + group.id + ')' \}\}",
columnClass: 'col-lg-3 col-md3 col-sm-2',
linkTo: "\{\{ '/#/inventories/' + group.inventory + '/groups/?name=' + group.name \}\}"
linkTo: "\{\{ '/#/inventories/' + group.inventory + '/' \}\}"
},
inventory_name: {
label: 'Inventory',
@ -36,7 +36,7 @@ angular.module('HomeGroupListDefinition', [])
failed_hosts: {
label: 'Failed Hosts',
ngHref: "\{\{ group.failed_hosts_link \}\}",
badgeIcon: "\{\{ 'icon-failures-' + group.failed_hosts_class \}\}",
badgeIcon: "\{\{ 'fa icon-failures-' + group.failed_hosts_class \}\}",
badgeNgHref: "\{\{ group.failed_hosts_link \}\}",
badgePlacement: 'left',
badgeToolTip: "\{\{ group.failed_hosts_tip \}\}",
@ -51,7 +51,7 @@ angular.module('HomeGroupListDefinition', [])
label: 'Status',
ngClick: "viewUpdateStatus(\{\{ group.id \}\})",
searchType: 'select',
badgeIcon: "\{\{ 'icon-cloud-' + group.status_badge_class \}\}",
badgeIcon: "\{\{ 'fa fa-cloud ' + group.status_badge_class \}\}",
badgeToolTip: "\{\{ group.status_badge_tooltip \}\}",
awToolTip: "\{\{ group.status_badge_tooltip \}\}",
dataPlacement: 'top',
@ -117,9 +117,6 @@ angular.module('HomeGroupListDefinition', [])
mode: 'all',
ngShow: "user_is_superuser"
}
},
fieldActions: {
}
});

View File

@ -29,12 +29,12 @@ angular.module('StreamListDefinition', [])
},
user: {
label: 'Initiated by',
ngBindHtml: 'activity.user',
sourceModel: 'user',
//ngBindHtml: 'activity.user',
sourceModel: 'actor',
sourceField: 'username',
awToolTip: "\{\{ userToolTip \}\}",
dataPlacement: 'top',
searchPlaceholder: 'Initiated by username',
//awToolTip: "\{\{ userToolTip \}\}",
//dataPlacement: 'top',
searchPlaceholder: 'Username',
searchWidget: 1
},
description: {
@ -47,7 +47,7 @@ angular.module('StreamListDefinition', [])
label: 'System event',
searchOnly: true,
searchType: 'isnull',
sourceModel: 'user',
sourceModel: 'actor',
sourceField: 'username',
searchWidget: 1
},
@ -60,12 +60,11 @@ angular.module('StreamListDefinition', [])
searchObject: 'all',
searchPlaceholder: 'All resources',
searchWidget: 2,
searchField: 'object1'
},
credential_search: {
label: 'Credential',
searchOnly: true,
searchObject: 'credentials',
searchObject: 'credential',
searchPlaceholder: 'Credential name',
searchWidget: 2,
searchField: 'object1'
@ -73,7 +72,7 @@ angular.module('StreamListDefinition', [])
group_search: {
label: 'Group',
searchOnly: true,
searchObject: 'groups',
searchObject: 'group',
searchPlaceholder: 'Group name',
searchWidget: 2,
searchField: 'object1'
@ -81,7 +80,7 @@ angular.module('StreamListDefinition', [])
host_search: {
label: 'Host',
searchOnly: true,
searchObject: 'hosts',
searchObject: 'host',
searchPlaceholder: 'Host name',
searchWidget: 2,
searchField: 'object1'
@ -89,7 +88,7 @@ angular.module('StreamListDefinition', [])
inventory_search: {
label: 'Inventory',
searchOnly: true,
searchObject: 'inventories',
searchObject: 'inventory',
searchPlaceholder: 'Inventory name',
searchWidget: 2,
searchField: 'object1'
@ -97,7 +96,7 @@ angular.module('StreamListDefinition', [])
job_template_search: {
label: 'Job Template',
searchOnly: true,
searchObject: 'job_templates',
searchObject: 'job_template',
searchPlaceholder: 'Job template name',
searchWidget: 2,
searchField: 'object1'
@ -105,7 +104,7 @@ angular.module('StreamListDefinition', [])
organization_search: {
label: 'Organization',
searchOnly: true,
searchObject: 'organizations',
searchObject: 'organization',
searchPlaceholder: 'Organization name',
searchWidget: 2,
searchField: 'object1'
@ -113,7 +112,7 @@ angular.module('StreamListDefinition', [])
project_search: {
label: 'Project',
searchOnly: true,
searchObject: 'projects',
searchObject: 'project',
searchPlaceholder: 'Project name',
searchWidget: 2,
searchField: 'object1'
@ -121,7 +120,7 @@ angular.module('StreamListDefinition', [])
user_search: {
label: 'User',
searchOnly: true,
searchObject: 'users',
searchObject: 'user',
searchPlaceholder: 'Primary username',
searchWidget: 2,
searchField: 'object1'
@ -140,7 +139,7 @@ angular.module('StreamListDefinition', [])
credential_search3: {
label: 'Credential',
searchOnly: true,
searchObject: 'credentials',
searchObject: 'credential',
searchPlaceholder: 'Related credential name',
searchWidget: 3,
searchField: 'object2'
@ -148,7 +147,7 @@ angular.module('StreamListDefinition', [])
group_search3: {
label: 'Group',
searchOnly: true,
searchObject: 'groups',
searchObject: 'group',
searchPlaceholder: 'Related group name',
searchWidget: 3,
searchField: 'object2'
@ -156,7 +155,7 @@ angular.module('StreamListDefinition', [])
host_search3: {
label: 'Host',
searchOnly: true,
searchObject: 'hosts',
searchObject: 'host',
searchPlaceholder: 'Related host name',
searchWidget: 3,
searchField: 'object2'
@ -164,7 +163,7 @@ angular.module('StreamListDefinition', [])
inventory_search3: {
label: 'Inventory',
searchOnly: true,
searchObject: 'inventories',
searchObject: 'inventory',
searchPlaceholder: 'Related inventory name',
searchWidget: 3,
searchField: 'object2'
@ -172,7 +171,7 @@ angular.module('StreamListDefinition', [])
job_template_search3: {
label: 'Job Template',
searchOnly: true,
searchObject: 'job_templates',
searchObject: 'job_template',
searchPlaceholder: 'Related job template name',
searchWidget: 3,
searchField: 'object2'
@ -180,7 +179,7 @@ angular.module('StreamListDefinition', [])
organization_search3: {
label: 'Organization',
searchOnly: true,
searchObject: 'organizations',
searchObject: 'organization',
searchPlaceholder: 'Related organization name',
searchWidget: 3,
searchField: 'object2'
@ -188,7 +187,7 @@ angular.module('StreamListDefinition', [])
project_search3: {
label: 'Project',
searchOnly: true,
searchObject: 'projects',
searchObject: 'project',
searchPlaceholder: 'Related project name',
searchWidget: 3,
searchField: 'object2'
@ -196,7 +195,7 @@ angular.module('StreamListDefinition', [])
user_search3: {
label: 'User',
searchOnly: true,
searchObject: 'users',
searchObject: 'user',
searchPlaceholder: 'Related username',
searchWidget: 3,
searchField: 'object2'

View File

@ -146,16 +146,20 @@ angular.module('StreamWidget', ['RestServices', 'Utilities', 'StreamListDefiniti
}*/
descr += activity.operation;
descr += (/e$/.test(activity.operation)) ? 'd ' : 'ed ';
if (activity.summary_fields.object2 && activity.summary_fields.object2.name) {
descr += activity.summary_fields.object2.base + ' <a href=\"' + BuildUrl(activity.summary_fields.object2) + '\">'
+ activity.summary_fields.object2.name + '</a>' + [ (activity.operation == 'disassociate') ? ' from ' : ' to '];
var obj1 = activity.object1;
var obj2 = activity.object2;
if (activity.summary_fields[obj2] && activity.summary_fields[obj2][0].name) {
activity.summary_fields[obj2][0].base = obj2;
descr += obj2 + ' <a href=\"' + BuildUrl(activity.summary_fields[obj2]) + '\">'
+ activity.summary_fields[obj2][0].name + '</a>' + ( (activity.operation == 'disassociate') ? ' from ' : ' to ' );
}
else if (activity.object2) {
descr += activity.object2 + [ (activity.operation == 'disassociate') ? ' from ' : ' to '];
descr += activity.object2[0] + ( (activity.operation == 'disassociate') ? ' from ' : ' to ' );
}
if (activity.summary_fields.object1 && activity.summary_fields.object1.name) {
descr += activity.summary_fields.object1.base + ' <a href=\"' + BuildUrl(activity.summary_fields.object1) + '\">'
+ activity.summary_fields.object1.name + '</a>';
if (activity.summary_fields[obj1] && activity.summary_fields[obj1][0].name) {
activity.summary_fields[obj1][0].base = obj2;
descr += obj1 + ' <a href=\"' + BuildUrl(activity.summary_fields[obj1]) + '\">'
+ activity.summary_fields[obj1][0].name + '</a>';
}
else if (activity.object1) {
descr += activity.object1;
@ -222,8 +226,6 @@ angular.module('StreamWidget', ['RestServices', 'Utilities', 'StreamListDefiniti
scope.formModalCancelShow = false;
scope.formModalInfo = false;
//scope.formModalHeader = results.summary_fields.project.name + '<span class="subtitle"> - SCM Status</span>';
$('#form-modal .btn-success').removeClass('btn-success').addClass('btn-none');
$('#form-modal').addClass('skinny-modal');
if (!scope.$$phase) {
scope.$digest();
}
@ -311,40 +313,48 @@ angular.module('StreamWidget', ['RestServices', 'Utilities', 'StreamListDefiniti
scope['activities'][i].timestamp = FormatDate(cDate);
// Display username
scope['activities'][i].user = (scope['activities'][i].summary_fields.user) ? scope['activities'][i].summary_fields.user.username :
/*scope['activities'][i].user = (scope['activities'][i].summary_fields.user) ? scope['activities'][i].summary_fields.user.username :
'system';
if (scope['activities'][i].user !== 'system') {
// turn user into a link when not 'system'
scope['activities'][i].user = "<a href=\"" + FixUrl(scope['activities'][i].related.user) + "\">" +
scope['activities'][i].user + "</a>";
}*/
if (scope['activities'][i]['summary_fields']['actor']) {
scope['activities'][i]['user'] = scope['activities'][i]['summary_fields']['actor']['username'];
}
else {
scope['activities'][i]['user'] = 'system';
}
// Objects
var href;
var deleted = /^\_delete/;
if (scope['activities'][i].summary_fields.object1 && scope['activities'][i].summary_fields.object1.name) {
if ( !deleted.test(scope['activities'][i].summary_fields.object1.name) ) {
var obj1 = scope['activities'][i].object1;
var obj2 = scope['activities'][i].object2;
if ( obj1 && scope['activities'][i].summary_fields[obj1] && scope['activities'][i].summary_fields[obj1].name) {
if ( !deleted.test(scope['activities'][i].summary_fields[obj1].name) ) {
href = BuildUrl(scope['activities'][i].summary_fields.object1);
scope['activities'][i].objects = "<a href=\"" + href + "\">" + scope['activities'][i].summary_fields.object1.name + "</a>";
scope['activities'][i].objects = "<a href=\"" + href + "\">" + scope['activities'][i].summary_fields[obj1].name + "</a>";
}
else {
scope['activities'][i].objects = scope['activities'][i].summary_fields.object1.name;
scope['activities'][i].objects = scope['activities'][i].summary_fields[obj1].name;
}
}
else if (scope['activities'][i].object1) {
scope['activities'][i].objects = scope['activities'][i].object1;
}
if (scope['activities'][i].summary_fields.object2 && scope['activities'][i].summary_fields.object2.name) {
if (obj2 && scope['activities'][i].summary_fields[obj2] && scope['activities'][i].summary_fields[obj2].name) {
if ( !deleted.test(scope['activities'][i].summary_fields.object2.name) ) {
href = BuildUrl(scope['activities'][i].summary_fields.object2);
scope['activities'][i].objects += ", <a href=\"" + href + "\">" + scope['activities'][i].summary_fields.object2.name + "</a>";
scope['activities'][i].objects += ", <a href=\"" + href + "\">" + scope['activities'][i].summary_fields[obj2].name + "</a>";
}
else {
scope['activities'][i].objects += "," + scope['activities'][i].summary_fields.object2.name;
scope['activities'][i].objects += "," + scope['activities'][i].summary_fields[obj2].name;
}
}
else if (scope['activities'][i].object2) {
scope['activities'][i].objects += ", " + scope['activities'][i].object1;
scope['activities'][i].objects += ", " + scope['activities'][i].object2;
}
// Description

View File

@ -959,6 +959,7 @@ input[type="checkbox"].checkbox-no-label {
.field-badge {
font-size: 12px;
margin-right: 3px;
}
.license-warning,

View File

@ -289,7 +289,7 @@ angular.module('ListGenerator', ['GeneratorHelpers'])
if (options.mode == 'select' || options.mode == 'lookup') {
html += "<th>Select</th>";
}
else if (options.mode == 'edit') {
else if (options.mode == 'edit' && list.fieldActions) {
html += "<th class=\"actions-column";
html += (list.fieldActions && list.fieldActions.columnClass) ? " " + list.fieldActions.columnClass : "";
html += "\">Actions</th>\n";