mirror of
https://github.com/ansible/awx.git
synced 2026-05-18 06:47:41 -02:30
AC-611 Latest activity widget features. Tweaked current filter, but still does not include an object type. Added activty stream to Organization tab.
This commit is contained in:
@@ -846,7 +846,7 @@ body .ui-tooltip {
|
|||||||
.ui-widget-content .ui-state-focus,
|
.ui-widget-content .ui-state-focus,
|
||||||
.ui-widget-header .ui-state-focus {
|
.ui-widget-header .ui-state-focus {
|
||||||
border: 1px solid #e3e3e3;
|
border: 1px solid #e3e3e3;
|
||||||
background: #e5e3e3 url(/static/css/images/ui-bg_flat_75_e5e3e3_40x100.png) 50% 50% repeat-x;
|
background: #e5e3e3 url(/static/css/custom-theme/images/ui-bg_flat_75_e5e3e3_40x100.png) 50% 50% repeat-x;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #005580;
|
color: #005580;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,7 +84,8 @@ angular.module('ansible', [
|
|||||||
'TimerService',
|
'TimerService',
|
||||||
'StreamListDefinition',
|
'StreamListDefinition',
|
||||||
'HomeGroupListDefinition',
|
'HomeGroupListDefinition',
|
||||||
'HomeHostListDefinition'
|
'HomeHostListDefinition',
|
||||||
|
'ActivityDetailDefinition'
|
||||||
])
|
])
|
||||||
.config(['$routeProvider', function($routeProvider) {
|
.config(['$routeProvider', function($routeProvider) {
|
||||||
$routeProvider.
|
$routeProvider.
|
||||||
|
|||||||
@@ -16,28 +16,33 @@ function Home ($routeParams, $scope, $rootScope, $location, Wait, ObjectCount, J
|
|||||||
ClearScope('home'); //Garbage collection. Don't leave behind any listeners/watchers from the prior
|
ClearScope('home'); //Garbage collection. Don't leave behind any listeners/watchers from the prior
|
||||||
//scope.
|
//scope.
|
||||||
|
|
||||||
var waitCount = 4;
|
var load = function() {
|
||||||
var loadedCount = 0;
|
var waitCount = 4;
|
||||||
|
var loadedCount = 0;
|
||||||
|
|
||||||
if (!$routeParams['login']) {
|
if (!$routeParams['login']) {
|
||||||
// If we're not logging in, start the Wait widget. Otherwise, it's already running.
|
// If we're not logging in, start the Wait widget. Otherwise, it's already running.
|
||||||
Wait('start');
|
Wait('start');
|
||||||
}
|
}
|
||||||
|
|
||||||
JobStatus({ target: 'container1' });
|
JobStatus({ target: 'container1' });
|
||||||
InventorySyncStatus({ target: 'container2' });
|
InventorySyncStatus({ target: 'container2' });
|
||||||
SCMSyncStatus({ target: 'container4' });
|
SCMSyncStatus({ target: 'container4' });
|
||||||
ObjectCount({ target: 'container3' });
|
ObjectCount({ target: 'container3' });
|
||||||
|
|
||||||
|
$rootScope.$on('WidgetLoaded', function() {
|
||||||
|
// Once all the widgets report back 'loaded', turn off Wait widget
|
||||||
|
loadedCount++;
|
||||||
|
if ( loadedCount == waitCount ) {
|
||||||
|
Wait('stop');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
$rootScope.showActivity = function() { Stream(); }
|
$rootScope.showActivity = function() { Stream(); }
|
||||||
|
$rootScope.refresh = function() { load(); }
|
||||||
|
|
||||||
$rootScope.$on('WidgetLoaded', function() {
|
load();
|
||||||
// Once all the widgets report back 'loaded', turn off Wait widget
|
|
||||||
loadedCount++;
|
|
||||||
if ( loadedCount == waitCount ) {
|
|
||||||
Wait('stop');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Home.$inject=[ '$routeParams', '$scope', '$rootScope', '$location', 'Wait', 'ObjectCount', 'JobStatus', 'InventorySyncStatus',
|
Home.$inject=[ '$routeParams', '$scope', '$rootScope', '$location', 'Wait', 'ObjectCount', 'JobStatus', 'InventorySyncStatus',
|
||||||
@@ -96,6 +101,14 @@ function HomeGroups ($location, $routeParams, HomeGroupList, GenerateList, Proce
|
|||||||
PaginateInit({ scope: scope, list: list, url: defaultUrl });
|
PaginateInit({ scope: scope, list: list, url: defaultUrl });
|
||||||
|
|
||||||
// Process search params
|
// Process search params
|
||||||
|
if ($routeParams['name']) {
|
||||||
|
scope[list.iterator + 'InputDisable'] = false;
|
||||||
|
scope[list.iterator + 'SearchValue'] = $routeParams['name'];
|
||||||
|
scope[list.iterator + 'SearchField'] = 'name';
|
||||||
|
scope[list.iterator + 'SearchFieldLabel'] = list.fields['name'].label;
|
||||||
|
scope[list.iterator + 'SearchSelectValue'] = null;
|
||||||
|
}
|
||||||
|
|
||||||
if ($routeParams['has_active_failures']) {
|
if ($routeParams['has_active_failures']) {
|
||||||
scope[list.iterator + 'InputDisable'] = true;
|
scope[list.iterator + 'InputDisable'] = true;
|
||||||
scope[list.iterator + 'SearchValue'] = $routeParams['has_active_failures'];
|
scope[list.iterator + 'SearchValue'] = $routeParams['has_active_failures'];
|
||||||
@@ -181,6 +194,15 @@ function HomeHosts ($location, $routeParams, HomeHostList, GenerateList, Process
|
|||||||
SearchInit({ scope: scope, set: 'hosts', list: list, url: defaultUrl });
|
SearchInit({ scope: scope, set: 'hosts', list: list, url: defaultUrl });
|
||||||
PaginateInit({ scope: scope, list: list, url: defaultUrl });
|
PaginateInit({ scope: scope, list: list, url: defaultUrl });
|
||||||
|
|
||||||
|
// Process search params
|
||||||
|
if ($routeParams['name']) {
|
||||||
|
scope[list.iterator + 'InputDisable'] = false;
|
||||||
|
scope[list.iterator + 'SearchValue'] = $routeParams['name'];
|
||||||
|
scope[list.iterator + 'SearchField'] = 'name';
|
||||||
|
scope[list.iterator + 'SearchFieldLabel'] = list.fields['name'].label;
|
||||||
|
scope[list.iterator + 'SearchSelectValue'] = null;
|
||||||
|
}
|
||||||
|
|
||||||
if ($routeParams['has_active_failures']) {
|
if ($routeParams['has_active_failures']) {
|
||||||
scope[HomeHostList.iterator + 'InputDisable'] = true;
|
scope[HomeHostList.iterator + 'InputDisable'] = true;
|
||||||
scope[HomeHostList.iterator + 'SearchValue'] = $routeParams['has_active_failures'];
|
scope[HomeHostList.iterator + 'SearchValue'] = $routeParams['has_active_failures'];
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
function OrganizationsList ($routeParams, $scope, $rootScope, $location, $log, Rest, Alert, LoadBreadCrumbs, Prompt,
|
function OrganizationsList ($routeParams, $scope, $rootScope, $location, $log, Rest, Alert, LoadBreadCrumbs, Prompt,
|
||||||
GenerateList, OrganizationList, SearchInit, PaginateInit, ClearScope, ProcessErrors,
|
GenerateList, OrganizationList, SearchInit, PaginateInit, ClearScope, ProcessErrors,
|
||||||
GetBasePath, SelectionInit, Wait)
|
GetBasePath, SelectionInit, Wait, Stream)
|
||||||
{
|
{
|
||||||
ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior
|
ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior
|
||||||
//scope.
|
//scope.
|
||||||
@@ -36,6 +36,8 @@ function OrganizationsList ($routeParams, $scope, $rootScope, $location, $log, R
|
|||||||
PaginateInit({ scope: scope, list: list, url: defaultUrl });
|
PaginateInit({ scope: scope, list: list, url: defaultUrl });
|
||||||
scope.search(list.iterator);
|
scope.search(list.iterator);
|
||||||
|
|
||||||
|
scope.showActivity = function() { Stream(); }
|
||||||
|
|
||||||
scope.addOrganization = function() {
|
scope.addOrganization = function() {
|
||||||
$location.path($location.path() + '/add');
|
$location.path($location.path() + '/add');
|
||||||
}
|
}
|
||||||
@@ -70,7 +72,7 @@ function OrganizationsList ($routeParams, $scope, $rootScope, $location, $log, R
|
|||||||
|
|
||||||
OrganizationsList.$inject=[ '$routeParams', '$scope', '$rootScope', '$location', '$log', 'Rest', 'Alert', 'LoadBreadCrumbs', 'Prompt',
|
OrganizationsList.$inject=[ '$routeParams', '$scope', '$rootScope', '$location', '$log', 'Rest', 'Alert', 'LoadBreadCrumbs', 'Prompt',
|
||||||
'GenerateList', 'OrganizationList', 'SearchInit', 'PaginateInit', 'ClearScope', 'ProcessErrors',
|
'GenerateList', 'OrganizationList', 'SearchInit', 'PaginateInit', 'ClearScope', 'ProcessErrors',
|
||||||
'GetBasePath', 'SelectionInit', 'Wait' ];
|
'GetBasePath', 'SelectionInit', 'Wait', 'Stream'];
|
||||||
|
|
||||||
|
|
||||||
function OrganizationsAdd ($scope, $rootScope, $compile, $location, $log, $routeParams, OrganizationForm,
|
function OrganizationsAdd ($scope, $rootScope, $compile, $location, $log, $routeParams, OrganizationForm,
|
||||||
|
|||||||
59
awx/ui/static/js/forms/ActivityDetail.js
Normal file
59
awx/ui/static/js/forms/ActivityDetail.js
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
/*********************************************
|
||||||
|
* Copyright (c) 2013 AnsibleWorks, Inc.
|
||||||
|
*
|
||||||
|
* ActivityDetail.js
|
||||||
|
* Form definition for Activity Stream detail
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
angular.module('ActivityDetailDefinition', [])
|
||||||
|
.value(
|
||||||
|
'ActivityDetailForm', {
|
||||||
|
|
||||||
|
name: 'activity',
|
||||||
|
editTitle: 'Activity Detail',
|
||||||
|
well: false,
|
||||||
|
'class': 'horizontal-narrow',
|
||||||
|
|
||||||
|
fields: {
|
||||||
|
timestamp: {
|
||||||
|
label: 'Time',
|
||||||
|
type: 'text',
|
||||||
|
readonly: true
|
||||||
|
},
|
||||||
|
operation: {
|
||||||
|
label: 'Operation',
|
||||||
|
type: 'text',
|
||||||
|
readonly: true
|
||||||
|
},
|
||||||
|
object1: {
|
||||||
|
label: 'Object 1',
|
||||||
|
type: 'text',
|
||||||
|
ngHide: '!object1',
|
||||||
|
readonly: true
|
||||||
|
},
|
||||||
|
object1_name: {
|
||||||
|
label: 'Name',
|
||||||
|
type: 'text',
|
||||||
|
ngHide: '!object1',
|
||||||
|
readonly: true
|
||||||
|
},
|
||||||
|
object2: {
|
||||||
|
label: 'Object 2',
|
||||||
|
type: 'text',
|
||||||
|
ngHide: '!object2',
|
||||||
|
readonly: true
|
||||||
|
},
|
||||||
|
object2_name: {
|
||||||
|
label: 'Name',
|
||||||
|
type: 'text',
|
||||||
|
ngHide: '!object2',
|
||||||
|
readonly: true
|
||||||
|
},
|
||||||
|
changes: {
|
||||||
|
label: 'Changes',
|
||||||
|
type: 'textarea',
|
||||||
|
readonly: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}); //Form
|
||||||
@@ -126,6 +126,11 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper'])
|
|||||||
else if (list.fields[fld].searchType && list.fields[fld].searchType == 'int') {
|
else if (list.fields[fld].searchType && list.fields[fld].searchType == 'int') {
|
||||||
scope[iterator + 'HideSearchType'] = true;
|
scope[iterator + 'HideSearchType'] = true;
|
||||||
}
|
}
|
||||||
|
else if (list.fields[fld].searchType && list.fields[fld].searchType == 'isnull') {
|
||||||
|
scope[iterator + 'SearchType'] = 'isnull';
|
||||||
|
scope[iterator + 'InputDisable'] = true;
|
||||||
|
scope[iterator + 'SearchValue'] = 'true';
|
||||||
|
}
|
||||||
scope.search(iterator);
|
scope.search(iterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,6 +192,16 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper'])
|
|||||||
scope[iterator + 'SearchSelectValue'].value == null) ) {
|
scope[iterator + 'SearchSelectValue'].value == null) ) {
|
||||||
scope[iterator + 'SearchParams'] += 'iexact=';
|
scope[iterator + 'SearchParams'] += 'iexact=';
|
||||||
}
|
}
|
||||||
|
else if ( (list.fields[scope[iterator + 'SearchField']].searchType &&
|
||||||
|
(list.fields[scope[iterator + 'SearchField']].searchType == 'or')) ) {
|
||||||
|
scope[iterator + 'SearchParams'] = ''; //start over
|
||||||
|
for (var k=0; k < list.fields[scope[iterator + 'SearchField']].searchFields.length; k++) {
|
||||||
|
scope[iterator + 'SearchParams'] += '&or__' +
|
||||||
|
list.fields[scope[iterator + 'SearchField']].searchFields[k] +
|
||||||
|
'__icontains=' + escape(scope[iterator + 'SearchValue']);
|
||||||
|
}
|
||||||
|
scope[iterator + 'SearchParams'].replace(/^\&/,'');
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
scope[iterator + 'SearchParams'] += scope[iterator + 'SearchType'] + '=';
|
scope[iterator + 'SearchParams'] += scope[iterator + 'SearchType'] + '=';
|
||||||
}
|
}
|
||||||
@@ -197,9 +212,10 @@ angular.module('SearchHelper', ['RestServices', 'Utilities', 'RefreshHelper'])
|
|||||||
scope[iterator + 'SearchParams'] += scope[iterator + 'SearchSelectValue'].value;
|
scope[iterator + 'SearchParams'] += scope[iterator + 'SearchSelectValue'].value;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
//if ( list.fields[scope[iterator + 'SearchField']].searchType == undefined ||
|
if ( (list.fields[scope[iterator + 'SearchField']].searchType &&
|
||||||
// list.fields[scope[iterator + 'SearchField']].searchType == 'gtzero' ) {
|
(list.fields[scope[iterator + 'SearchField']].searchType !== 'or')) ) {
|
||||||
scope[iterator + 'SearchParams'] += escape(scope[iterator + 'SearchValue']);
|
scope[iterator + 'SearchParams'] += escape(scope[iterator + 'SearchValue']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
scope[iterator + 'SearchParams'] += (sort_order) ? '&order_by=' + escape(sort_order) : '';
|
scope[iterator + 'SearchParams'] += (sort_order) ? '&order_by=' + escape(sort_order) : '';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,6 +35,15 @@ angular.module('OrganizationListDefinition', [])
|
|||||||
ngClick: 'addOrganization()',
|
ngClick: 'addOrganization()',
|
||||||
"class": 'btn-success btn-xs',
|
"class": 'btn-success btn-xs',
|
||||||
awToolTip: 'Create a new organization'
|
awToolTip: 'Create a new organization'
|
||||||
|
},
|
||||||
|
stream: {
|
||||||
|
'class': "btn-primary btn-xs activity-btn",
|
||||||
|
ngClick: "showActivity()",
|
||||||
|
awToolTip: "View Activity Stream",
|
||||||
|
dataPlacement: "top",
|
||||||
|
icon: "icon-comments-alt",
|
||||||
|
mode: 'all',
|
||||||
|
iconSize: 'large'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -19,23 +19,45 @@ angular.module('StreamListDefinition', [])
|
|||||||
"class": "table-condensed",
|
"class": "table-condensed",
|
||||||
|
|
||||||
fields: {
|
fields: {
|
||||||
|
timestamp: {
|
||||||
|
label: 'Event Time',
|
||||||
|
key: true,
|
||||||
|
desc: true,
|
||||||
|
noLink: true,
|
||||||
|
searchable: false
|
||||||
|
},
|
||||||
user: {
|
user: {
|
||||||
label: 'User',
|
label: 'User',
|
||||||
linkTo: "\{\{ activity.userLink \}\}",
|
ngBindHtml: 'activity.user',
|
||||||
sourceModel: 'user',
|
sourceModel: 'user',
|
||||||
sourceField: 'username',
|
sourceField: 'username',
|
||||||
awToolTip: "\{\{ userToolTip \}\}",
|
awToolTip: "\{\{ userToolTip \}\}",
|
||||||
dataPlacement: 'top'
|
dataPlacement: 'top'
|
||||||
},
|
},
|
||||||
timestamp: {
|
|
||||||
label: 'Event Time',
|
|
||||||
},
|
|
||||||
objects: {
|
objects: {
|
||||||
label: 'Objects',
|
label: 'Objects',
|
||||||
ngBindHtml: 'activity.objects'
|
ngBindHtml: 'activity.objects',
|
||||||
|
sortField: "object1__name,object2__name",
|
||||||
|
searchable: false
|
||||||
|
},
|
||||||
|
object_name: {
|
||||||
|
label: 'Object name',
|
||||||
|
searchOnly: true,
|
||||||
|
searchType: 'or',
|
||||||
|
searchFields: ['object1__name', 'object2__name']
|
||||||
},
|
},
|
||||||
description: {
|
description: {
|
||||||
label: 'Description'
|
label: 'Description',
|
||||||
|
ngBindHtml: 'activity.description',
|
||||||
|
nosort: true,
|
||||||
|
searchable: false
|
||||||
|
},
|
||||||
|
system_event: {
|
||||||
|
label: 'System event?',
|
||||||
|
searchOnly: true,
|
||||||
|
searchType: 'isnull',
|
||||||
|
sourceModel: 'user',
|
||||||
|
sourceField: 'username'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -61,5 +83,14 @@ angular.module('StreamListDefinition', [])
|
|||||||
},
|
},
|
||||||
|
|
||||||
fieldActions: {
|
fieldActions: {
|
||||||
|
edit: {
|
||||||
|
label: 'View',
|
||||||
|
ngClick: "showDetail(\{\{ activity.id \}\})",
|
||||||
|
icon: 'icon-zoom-in',
|
||||||
|
"class": 'btn-default btn-xs',
|
||||||
|
awToolTip: 'View event details',
|
||||||
|
dataPlacement: 'top'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
@@ -27,7 +27,7 @@ angular.module('StreamWidget', ['RestServices', 'Utilities', 'StreamListDefiniti
|
|||||||
|
|
||||||
// Try not to overlap footer. Because stream is positioned absolute, the parent
|
// Try not to overlap footer. Because stream is positioned absolute, the parent
|
||||||
// doesn't resize correctly when stream is loaded.
|
// doesn't resize correctly when stream is loaded.
|
||||||
$('#tab-content-container').css({ 'min-height': stream.height() });
|
$('#tab-content-container').css({ 'min-height': stream.height() + 50 });
|
||||||
|
|
||||||
// Slide in stream
|
// Slide in stream
|
||||||
stream.show('slide', {'direction': 'left'}, {'duration': 500, 'queue': false });
|
stream.show('slide', {'direction': 'left'}, {'duration': 500, 'queue': false });
|
||||||
@@ -35,9 +35,10 @@ angular.module('StreamWidget', ['RestServices', 'Utilities', 'StreamListDefiniti
|
|||||||
}
|
}
|
||||||
}])
|
}])
|
||||||
|
|
||||||
.factory('HideStream', [ 'ClearScope', function(ClearScope) {
|
.factory('HideStream', [ function() {
|
||||||
return function() {
|
return function() {
|
||||||
// Remove the stream widget
|
// Remove the stream widget
|
||||||
|
|
||||||
var stream = $('#stream-container');
|
var stream = $('#stream-container');
|
||||||
stream.hide('slide', {'direction': 'left'}, {'duration': 500, 'queue': false });
|
stream.hide('slide', {'direction': 'left'}, {'duration': 500, 'queue': false });
|
||||||
|
|
||||||
@@ -54,15 +55,139 @@ angular.module('StreamWidget', ['RestServices', 'Utilities', 'StreamListDefiniti
|
|||||||
}
|
}
|
||||||
}])
|
}])
|
||||||
|
|
||||||
|
.factory('FixUrl', [ function() {
|
||||||
|
return function(u) {
|
||||||
|
return u.replace(/\/api\/v1\//,'/#/');
|
||||||
|
}
|
||||||
|
}])
|
||||||
|
|
||||||
|
.factory('BuildUrl', [ function() {
|
||||||
|
return function(obj) {
|
||||||
|
var url = '/#/';
|
||||||
|
switch(obj.base) {
|
||||||
|
case 'group':
|
||||||
|
case 'host':
|
||||||
|
url += 'home/' + obj.base + 's/?name=' + obj.name;
|
||||||
|
break;
|
||||||
|
case 'inventory':
|
||||||
|
url += 'inventories/' + obj.id;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
url += obj.base + 's/' + obj.id;
|
||||||
|
}
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
}])
|
||||||
|
|
||||||
|
.factory('BuildDescription', ['FixUrl', 'BuildUrl', function(FixUrl, BuildUrl) {
|
||||||
|
return function(activity) {
|
||||||
|
var descr = '';
|
||||||
|
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) {
|
||||||
|
descr += activity.summary_fields.object2.base + ' <a href=\"' + BuildUrl(activity.summary_fields.object2) + '\">'
|
||||||
|
+ activity.summary_fields.object2.name + '</a>' + [ (activity.operation == 'disassociate') ? ' from ' : ' to '];
|
||||||
|
}
|
||||||
|
if (activity.summary_fields.object1) {
|
||||||
|
descr += activity.summary_fields.object1.base + ' <a href=\"' + BuildUrl(activity.summary_fields.object1) + '\">'
|
||||||
|
+ activity.summary_fields.object1.name + '</a>';
|
||||||
|
}
|
||||||
|
return descr;
|
||||||
|
}
|
||||||
|
}])
|
||||||
|
|
||||||
|
.factory('ShowDetail', ['Rest', 'Alert', 'GenerateForm', 'ProcessErrors', 'GetBasePath', 'FormatDate', 'ActivityDetailForm',
|
||||||
|
function(Rest, Alert, GenerateForm, ProcessErrors, GetBasePath, FormatDate, ActivityDetailForm) {
|
||||||
|
return function(activity_id) {
|
||||||
|
|
||||||
|
var generator = GenerateForm;
|
||||||
|
var form = ActivityDetailForm;
|
||||||
|
var scope;
|
||||||
|
|
||||||
|
var url = GetBasePath('activity_stream') + activity_id + '/';
|
||||||
|
|
||||||
|
// Retrieve detail record and prepopulate the form
|
||||||
|
Rest.setUrl(url);
|
||||||
|
Rest.get()
|
||||||
|
.success( function(data, status, headers, config) {
|
||||||
|
// load up the form
|
||||||
|
var results = data;
|
||||||
|
|
||||||
|
$('#form-modal').on('show.bs.modal', function (e) {
|
||||||
|
$('#form-modal-body').css({
|
||||||
|
width:'auto', //probably not needed
|
||||||
|
height:'auto', //probably not needed
|
||||||
|
'max-height':'100%'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
//var n = results['changes'].match(/\n/g);
|
||||||
|
//var rows = (n) ? n.length : 1;
|
||||||
|
//rows = (rows < 1) ? 3 : 10;
|
||||||
|
form.fields['changes'].rows = 10;
|
||||||
|
scope = generator.inject(form, { mode: 'edit', modal: true, related: false});
|
||||||
|
generator.reset();
|
||||||
|
for (var fld in form.fields) {
|
||||||
|
if (results[fld]) {
|
||||||
|
if (fld == 'timestamp') {
|
||||||
|
scope[fld] = FormatDate(new Date(results[fld]));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
scope[fld] = results[fld];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (results.summary_fields.object1) {
|
||||||
|
scope['object1_name'] = results.summary_fields.object1.name;
|
||||||
|
}
|
||||||
|
if (results.summary_fields.object2) {
|
||||||
|
scope['object2_name'] = results.summary_fields.object2.name;
|
||||||
|
}
|
||||||
|
scope['changes'] = JSON.stringify(results['changes'], null, '\t');
|
||||||
|
scope.formModalAction = function() {
|
||||||
|
$('#form-modal').modal("hide");
|
||||||
|
}
|
||||||
|
scope.formModalActionLabel = 'OK';
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.error( function(data, status, headers, config) {
|
||||||
|
$('#form-modal').modal("hide");
|
||||||
|
ProcessErrors(scope, data, status, form,
|
||||||
|
{ hdr: 'Error!', msg: 'Failed to retrieve activity: ' + activity_id + '. GET status: ' + status });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}])
|
||||||
|
|
||||||
.factory('Stream', ['$rootScope', '$location', 'Rest', 'GetBasePath', 'ProcessErrors', 'Wait', 'StreamList', 'SearchInit',
|
.factory('Stream', ['$rootScope', '$location', 'Rest', 'GetBasePath', 'ProcessErrors', 'Wait', 'StreamList', 'SearchInit',
|
||||||
'PaginateInit', 'GenerateList', 'FormatDate', 'ShowStream', 'HideStream',
|
'PaginateInit', 'GenerateList', 'FormatDate', 'ShowStream', 'HideStream', 'BuildDescription', 'FixUrl', 'ShowDetail',
|
||||||
function($rootScope, $location, Rest, GetBasePath, ProcessErrors, Wait, StreamList, SearchInit, PaginateInit, GenerateList,
|
function($rootScope, $location, Rest, GetBasePath, ProcessErrors, Wait, StreamList, SearchInit, PaginateInit, GenerateList,
|
||||||
FormatDate, ShowStream, HideStream) {
|
FormatDate, ShowStream, HideStream, BuildDescription, FixUrl, ShowDetail) {
|
||||||
return function(params) {
|
return function(params) {
|
||||||
|
|
||||||
var list = StreamList;
|
var list = StreamList;
|
||||||
var defaultUrl = GetBasePath('activity_stream');
|
var defaultUrl = GetBasePath('activity_stream');
|
||||||
var view = GenerateList;
|
var view = GenerateList;
|
||||||
|
var base = $location.path().replace(/^\//,'').split('/')[0];
|
||||||
|
|
||||||
|
if (base !== 'home') {
|
||||||
|
var type = (base == 'inventories') ? 'inventory' : base.replace(/s$/,'');
|
||||||
|
defaultUrl += '?or__object1=' + type + '&or__object2=' + type;
|
||||||
|
}
|
||||||
|
|
||||||
// Push the current page onto browser histor. If user clicks back button, restore current page without
|
// Push the current page onto browser histor. If user clicks back button, restore current page without
|
||||||
// stream widget
|
// stream widget
|
||||||
@@ -80,14 +205,16 @@ angular.module('StreamWidget', ['RestServices', 'Utilities', 'StreamListDefiniti
|
|||||||
});
|
});
|
||||||
|
|
||||||
scope.closeStream = function() {
|
scope.closeStream = function() {
|
||||||
HideStream();
|
HideStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
scope.refreshStream = function() {
|
scope.refreshStream = function() {
|
||||||
scope.search(list.iterator);
|
scope.search(list.iterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
function fixUrl(u) { return u.replace(/\/api\/v1\//,'/#/'); }
|
scope.showDetail = function(id) {
|
||||||
|
ShowDetail(id);
|
||||||
|
}
|
||||||
|
|
||||||
if (scope.removePostRefresh) {
|
if (scope.removePostRefresh) {
|
||||||
scope.removePostRefresh();
|
scope.removePostRefresh();
|
||||||
@@ -97,24 +224,38 @@ angular.module('StreamWidget', ['RestServices', 'Utilities', 'StreamListDefiniti
|
|||||||
// Convert event_time date to local time zone
|
// Convert event_time date to local time zone
|
||||||
cDate = new Date(scope['activities'][i].timestamp);
|
cDate = new Date(scope['activities'][i].timestamp);
|
||||||
scope['activities'][i].timestamp = FormatDate(cDate);
|
scope['activities'][i].timestamp = FormatDate(cDate);
|
||||||
|
|
||||||
// Display username
|
// 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';
|
'system';
|
||||||
if (scope['activities'][i].user !== 'System') {
|
if (scope['activities'][i].user !== 'system') {
|
||||||
scope['activities'][i].userLink = (scope['activities'][i].summary_fields.user) ? fixUrl(scope['activities'][i].related.user) :
|
// 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>";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Objects
|
// Objects
|
||||||
var href;
|
var href;
|
||||||
|
var deleted = /^\_delete/;
|
||||||
if (scope['activities'][i].summary_fields.object1) {
|
if (scope['activities'][i].summary_fields.object1) {
|
||||||
href = fixUrl(scope['activities'][i].related.object_1);
|
if ( !deleted.test(scope['activities'][i].summary_fields.object1.name) ) {
|
||||||
scope['activities'][i].objects = "<a href=\"" + href + "\">" + scope['activities'][i].summary_fields.object1.name + "</a>";
|
href = FixUrl(scope['activities'][i].related.object1);
|
||||||
|
scope['activities'][i].objects = "<a href=\"" + href + "\">" + scope['activities'][i].summary_fields.object1.name + "</a>";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
scope['activities'][i].objects = scope['activities'][i].summary_fields.object1.name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (scope['activities'][i].summary_fields.object2) {
|
if (scope['activities'][i].summary_fields.object2) {
|
||||||
href = fixUrl(scope['activities'][i].related.object_2);
|
if ( !deleted.test(scope['activities'][i].summary_fields.object2.name) ) {
|
||||||
scope['activities'][i].objects += ", <a href=\"" + href + "\">" + scope['activities'][i].summary_fields.object2.name + "</a>";
|
href = FixUrl(scope['activities'][i].related.object2);
|
||||||
|
scope['activities'][i].objects += ", <a href=\"" + href + "\">" + scope['activities'][i].summary_fields.object2.name + "</a>";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
scope['activities'][i].objects += scope['activities'][i].summary_fields.object2.name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
scope['activities'][i].description = BuildDescription(scope['activities'][i]);
|
||||||
}
|
}
|
||||||
ShowStream();
|
ShowStream();
|
||||||
});
|
});
|
||||||
@@ -123,7 +264,6 @@ angular.module('StreamWidget', ['RestServices', 'Utilities', 'StreamListDefiniti
|
|||||||
SearchInit({ scope: scope, set: list.name, list: list, url: defaultUrl });
|
SearchInit({ scope: scope, set: list.name, list: list, url: defaultUrl });
|
||||||
PaginateInit({ scope: scope, list: list, url: defaultUrl });
|
PaginateInit({ scope: scope, list: list, url: defaultUrl });
|
||||||
scope.search(list.iterator);
|
scope.search(list.iterator);
|
||||||
|
|
||||||
}
|
}
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
@@ -75,6 +75,7 @@
|
|||||||
<script src="{{ STATIC_URL }}js/forms/License.js"></script>
|
<script src="{{ STATIC_URL }}js/forms/License.js"></script>
|
||||||
<script src="{{ STATIC_URL }}js/forms/HostGroups.js"></script>
|
<script src="{{ STATIC_URL }}js/forms/HostGroups.js"></script>
|
||||||
<script src="{{ STATIC_URL }}js/forms/InventoryStatus.js"></script>
|
<script src="{{ STATIC_URL }}js/forms/InventoryStatus.js"></script>
|
||||||
|
<script src="{{ STATIC_URL }}js/forms/ActivityDetail.js"></script>
|
||||||
<script src="{{ STATIC_URL }}js/lists/Users.js"></script>
|
<script src="{{ STATIC_URL }}js/lists/Users.js"></script>
|
||||||
<script src="{{ STATIC_URL }}js/lists/Organizations.js"></script>
|
<script src="{{ STATIC_URL }}js/lists/Organizations.js"></script>
|
||||||
<script src="{{ STATIC_URL }}js/lists/Admins.js"></script>
|
<script src="{{ STATIC_URL }}js/lists/Admins.js"></script>
|
||||||
|
|||||||
Reference in New Issue
Block a user