forked from shaba/openuds
Improved Service providers section over administration client implementation. js now shows logs for providers & for services
This commit is contained in:
parent
744515f11f
commit
b9aff159d8
@ -15,6 +15,11 @@
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.wst.validation.validationbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.python.pydev.pythonNature</nature>
|
||||
|
8
server/.settings/org.eclipse.wst.validation.prefs
Normal file
8
server/.settings/org.eclipse.wst.validation.prefs
Normal file
@ -0,0 +1,8 @@
|
||||
DELEGATES_PREFERENCE=delegateValidatorList
|
||||
USER_BUILD_PREFERENCE=enabledBuildValidatorList
|
||||
USER_MANUAL_PREFERENCE=enabledManualValidatorList
|
||||
USER_PREFERENCE=overrideGlobalPreferencesfalse
|
||||
eclipse.preferences.version=1
|
||||
override=false
|
||||
suspend=false
|
||||
vf.version=3
|
@ -36,7 +36,6 @@ from django.utils.translation import ugettext_lazy as _
|
||||
from uds.models import Authenticator
|
||||
from uds.core import auths
|
||||
|
||||
|
||||
from users_groups import Users, Groups
|
||||
from uds.REST import NotFound
|
||||
from uds.REST.model import ModelHandler
|
||||
|
@ -34,8 +34,10 @@ from __future__ import unicode_literals
|
||||
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
|
||||
from uds.models import Service
|
||||
|
||||
from uds.core.util import log
|
||||
from uds.core.Environment import Environment
|
||||
from uds.REST.model import DetailHandler
|
||||
from uds.REST import NotFound, ResponseError, RequestError
|
||||
@ -90,7 +92,7 @@ class Services(DetailHandler):
|
||||
service.data = service.getInstance(self._params).serialize()
|
||||
service.save()
|
||||
except Service.DoesNotExist:
|
||||
raise NotFound('Item not found')
|
||||
self.invalidItemException()
|
||||
except IntegrityError: # Duplicate key probably
|
||||
raise RequestError('Element already exists (duplicate key error)')
|
||||
except Exception:
|
||||
@ -108,7 +110,7 @@ class Services(DetailHandler):
|
||||
|
||||
service.delete()
|
||||
except:
|
||||
raise NotFound('service not found')
|
||||
self.invalidItemException()
|
||||
|
||||
return 'deleted'
|
||||
|
||||
@ -155,3 +157,11 @@ class Services(DetailHandler):
|
||||
except Exception as e:
|
||||
logger.exception('getGui')
|
||||
raise ResponseError(unicode(e))
|
||||
|
||||
def getLogs(self, parent, item):
|
||||
try:
|
||||
item = parent.services.get(pk=item)
|
||||
logger.debug('Getting logs for {0}'.format(item))
|
||||
return log.getLogs(item)
|
||||
except:
|
||||
self.invalidItemException()
|
@ -37,6 +37,8 @@ from django.utils.translation import ugettext as _
|
||||
from django.db import IntegrityError
|
||||
from uds.REST.handlers import Handler
|
||||
|
||||
from uds.core.util import log
|
||||
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@ -46,6 +48,7 @@ OVERVIEW = 'overview'
|
||||
TYPES = 'types'
|
||||
TABLEINFO = 'tableinfo'
|
||||
GUI = 'gui'
|
||||
LOG = 'log'
|
||||
|
||||
# Base for Gui Related mixins
|
||||
class BaseModelHandler(Handler):
|
||||
@ -151,7 +154,13 @@ class BaseModelHandler(Handler):
|
||||
|
||||
# Exceptions
|
||||
def invalidRequestException(self):
|
||||
raise RequestError('Invalid Request')
|
||||
raise RequestError(_('Invalid Request'))
|
||||
|
||||
def invalidMethodException(self):
|
||||
raise NotFound(_('Method not found'))
|
||||
|
||||
def invalidItemException(self):
|
||||
raise NotFound(_('Item not found'))
|
||||
|
||||
# Details do not have types at all
|
||||
# so, right now, we only process details petitions for Handling & tables info
|
||||
@ -208,6 +217,8 @@ class DetailHandler(BaseModelHandler):
|
||||
return sorted(gui, key=lambda f: f['gui']['order'])
|
||||
elif self._args[0] == TYPES:
|
||||
return self.getTypes(parent, self._args[1])
|
||||
elif self._args[1] == LOG:
|
||||
return self.getLogs(parent, self._args[0])
|
||||
|
||||
return self.fallbackGet()
|
||||
|
||||
@ -252,6 +263,7 @@ class DetailHandler(BaseModelHandler):
|
||||
def fallbackGet(self):
|
||||
raise self.invalidRequestException()
|
||||
|
||||
# Override this to provide functionality
|
||||
# Default (as sample) getItems
|
||||
def getItems(self, parent, item):
|
||||
if item is None: # Returns ALL detail items
|
||||
@ -279,6 +291,9 @@ class DetailHandler(BaseModelHandler):
|
||||
|
||||
def getTypes(self, parent, forType):
|
||||
return [] # Default is that details do not have types
|
||||
|
||||
def getLogs(self, parent, item):
|
||||
self.invalidMethodException()
|
||||
|
||||
class ModelHandler(BaseModelHandler):
|
||||
'''
|
||||
@ -335,6 +350,11 @@ class ModelHandler(BaseModelHandler):
|
||||
logger.debug('Found type {0}'.format(v))
|
||||
return found
|
||||
|
||||
# log related
|
||||
def getLogs(self, item):
|
||||
logger.debug('Default getLogs invoked')
|
||||
return log.getLogs(item)
|
||||
|
||||
# gui related
|
||||
def getGui(self, type_):
|
||||
self.invalidRequestException()
|
||||
@ -357,7 +377,7 @@ class ModelHandler(BaseModelHandler):
|
||||
detail = detailCls(self, path, self._params, *args, parent = item)
|
||||
method = getattr(detail, self._operation)
|
||||
except AttributeError:
|
||||
raise NotFound('method not found')
|
||||
self.invalidMethodException()
|
||||
|
||||
return method()
|
||||
|
||||
@ -394,25 +414,33 @@ class ModelHandler(BaseModelHandler):
|
||||
self.fillIntanceFields(val, res)
|
||||
return res
|
||||
except:
|
||||
raise NotFound('item not found')
|
||||
self.invalidItemException()
|
||||
|
||||
# nArgs > 1
|
||||
# Request type info or gui, or detail
|
||||
if self._args[0] == TYPES:
|
||||
if nArgs != 2:
|
||||
raise RequestError('invalid request')
|
||||
self.invalidRequestException()
|
||||
return self.getType(self._args[1])
|
||||
elif self._args[0] == GUI:
|
||||
if nArgs != 2:
|
||||
raise RequestError('invalid request')
|
||||
self.invalidRequestException()
|
||||
gui = self.getGui(self._args[1])
|
||||
return sorted(gui, key=lambda f: f['gui']['order'])
|
||||
elif self._args[1] == LOG:
|
||||
if nArgs != 2:
|
||||
self.invalidRequestException()
|
||||
try:
|
||||
item = self.model.objects.filter(pk=self._args[0])[0]
|
||||
except:
|
||||
self.invalidItemException()
|
||||
return self.getLogs(item)
|
||||
|
||||
# If has detail and is requesting detail
|
||||
if self.detail is not None:
|
||||
return self.processDetail()
|
||||
|
||||
raise RequestError('invalid request')
|
||||
self.invalidRequestException()
|
||||
|
||||
def post(self):
|
||||
# right now
|
||||
@ -421,7 +449,7 @@ class ModelHandler(BaseModelHandler):
|
||||
if self._args[0] == 'test':
|
||||
return 'tested'
|
||||
|
||||
raise NotFound('Method not found')
|
||||
self.invalidMethodException()
|
||||
|
||||
def put(self):
|
||||
logger.debug('method PUT for {0}, {1}'.format(self.__class__.__name__, self._args))
|
||||
|
@ -169,6 +169,7 @@ function BasicModelRest(path, options) {
|
||||
// Requests paths
|
||||
this.path = path;
|
||||
this.getPath = options.getPath || path;
|
||||
this.logPath = options.logPath || path;
|
||||
this.putPath = options.putPath || path;
|
||||
this.testPath = options.testPath || (path + '/test');
|
||||
this.delPath = options.delPath || path;
|
||||
@ -248,6 +249,19 @@ BasicModelRest.prototype = {
|
||||
fail: fail_fnc
|
||||
});
|
||||
|
||||
},
|
||||
// -------------
|
||||
// Log methods
|
||||
// -------------
|
||||
getLogs: function(itemId, success_fnc, fail_fnc) {
|
||||
"use strict";
|
||||
var path = this.logPath + '/' + itemId + '/' + 'log';
|
||||
return this._requestPath(path, {
|
||||
cacheKey: '.',
|
||||
success: success_fnc,
|
||||
fail: fail_fnc
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
// -------------
|
||||
@ -374,6 +388,25 @@ DetailModelRestApi.prototype = {
|
||||
"use strict";
|
||||
return this.base.get(success_fnc, fail_fnc);
|
||||
},
|
||||
list: function(success_fnc, fail_fnc) { // This is "almost" an alias for get
|
||||
"use strict";
|
||||
return this.base.list(success_fnc, fail_fnc);
|
||||
},
|
||||
overview: function(success_fnc, fail_fnc) {
|
||||
"use strict";
|
||||
return this.base.overview(success_fnc, fail_fnc);
|
||||
},
|
||||
item: function(itemId, success_fnc, fail_fnc) {
|
||||
"use strict";
|
||||
return this.base.item(itemId, success_fnc, fail_fnc);
|
||||
},
|
||||
// -------------
|
||||
// Log methods
|
||||
// -------------
|
||||
getLogs: function(itemId, success_fnc, fail_fnc) {
|
||||
"use strict";
|
||||
return this.base.getLogs(itemId, success_fnc, fail_fnc);
|
||||
},
|
||||
put: function(data, options) {
|
||||
"use strict";
|
||||
return this.base.put(data, options);
|
||||
@ -412,18 +445,6 @@ DetailModelRestApi.prototype = {
|
||||
"use strict";
|
||||
return this.base.tableInfo(success_fnc, fail_fnc);
|
||||
},
|
||||
list: function(success_fnc, fail_fnc) { // This is "almost" an alias for get
|
||||
"use strict";
|
||||
return this.base.list(success_fnc, fail_fnc);
|
||||
},
|
||||
overview: function(success_fnc, fail_fnc) {
|
||||
"use strict";
|
||||
return this.base.overview(success_fnc, fail_fnc);
|
||||
},
|
||||
item: function(itemId, success_fnc, fail_fnc) {
|
||||
"use strict";
|
||||
return this.base.item(itemId, success_fnc, fail_fnc);
|
||||
},
|
||||
types: function(success_fnc, fail_fnc) {
|
||||
"use strict";
|
||||
if( this.options.types ) {
|
||||
|
@ -38,13 +38,39 @@ gui.providers.link = function(event) {
|
||||
},
|
||||
};
|
||||
|
||||
var serviceLogTable;
|
||||
var prevTables = [];
|
||||
var clearDetails = function() {
|
||||
gui.doLog('Clearing details');
|
||||
$.each(prevTables, function(undefined, tbl){
|
||||
var $tbl = $(tbl).dataTable();
|
||||
$tbl.fnClearTable();
|
||||
$tbl.fnDestroy();
|
||||
});
|
||||
|
||||
if( serviceLogTable ) {
|
||||
var $tbl = $(serviceLogTable).dataTable();
|
||||
$tbl.fnClearTable();
|
||||
$tbl.fnDestroy();
|
||||
$('#services-log-placeholder').empty();
|
||||
serviceLogTable = undefined;
|
||||
}
|
||||
|
||||
prevTables = [];
|
||||
$('#services-placeholder').empty();
|
||||
$('#logs-placeholder').empty();
|
||||
$('#services-log-placeholder').empty();
|
||||
|
||||
$('#detail-placeholder').addClass('hidden');
|
||||
};
|
||||
|
||||
api.templates.get('providers', function(tmpl) {
|
||||
gui.clearWorkspace();
|
||||
gui.appendToWorkspace(api.templates.evaluate(tmpl, {
|
||||
providers : 'providers-placeholder',
|
||||
services : 'services-placeholder',
|
||||
services_log : 'services-log-placeholder',
|
||||
logs: 'logs-placeholder',
|
||||
}));
|
||||
gui.setLinksEvents();
|
||||
|
||||
@ -61,17 +87,14 @@ gui.providers.link = function(event) {
|
||||
}*/
|
||||
return true;
|
||||
},
|
||||
onRowDeselect: function() {
|
||||
clearDetails();
|
||||
},
|
||||
onRowSelect : function(selected) {
|
||||
gui.tools.blockUI();
|
||||
gui.doLog(selected[0]);
|
||||
|
||||
$.each(prevTables, function(undefined, tbl){
|
||||
var $tbl = $(tbl).dataTable();
|
||||
$tbl.fnClearTable();
|
||||
$tbl.fnDestroy();
|
||||
});
|
||||
prevTables = [];
|
||||
$('#services-placeholder').empty();
|
||||
clearDetails();
|
||||
$('#detail-placeholder').removeClass('hidden');
|
||||
|
||||
var id = selected[0].id;
|
||||
// Giving the name compossed with type, will ensure that only styles will be reattached once
|
||||
@ -80,6 +103,33 @@ gui.providers.link = function(event) {
|
||||
var servicesTable = services.table({
|
||||
container : 'services-placeholder',
|
||||
rowSelect : 'single',
|
||||
onRowSelect: function(sselected) {
|
||||
gui.tools.blockUI();
|
||||
var sId = sselected[0].id;
|
||||
|
||||
if( serviceLogTable ) {
|
||||
var $tbl = $(serviceLogTable).dataTable();
|
||||
$tbl.fnClearTable();
|
||||
$tbl.fnDestroy();
|
||||
$('#services-log-placeholder').empty();
|
||||
}
|
||||
|
||||
serviceLogTable = services.logTable(sId, {
|
||||
container: 'services-log-placeholder',
|
||||
onLoad: function() {
|
||||
gui.tools.unblockUI();
|
||||
}
|
||||
});
|
||||
},
|
||||
onRowDeselect : function() {
|
||||
if( serviceLogTable ) {
|
||||
var $tbl = $(serviceLogTable).dataTable();
|
||||
$tbl.fnClearTable();
|
||||
$tbl.fnDestroy();
|
||||
$('#services-log-placeholder').empty();
|
||||
}
|
||||
serviceLogTable = undefined;
|
||||
},
|
||||
onCheck: function(check, items) {
|
||||
if( check == 'delete' ) {
|
||||
for( var i in items ) {
|
||||
@ -100,7 +150,12 @@ gui.providers.link = function(event) {
|
||||
},
|
||||
});
|
||||
|
||||
var logTable = gui.providers.logTable(id, {
|
||||
container : 'logs-placeholder',
|
||||
});
|
||||
|
||||
prevTables.push(servicesTable);
|
||||
prevTables.push(logTable);
|
||||
},
|
||||
buttons : [ 'new', 'edit', 'delete', 'xls' ],
|
||||
onNew : gui.methods.typedNew(gui.providers, gettext('New provider'), gettext('Error creating provider'), testButton),
|
||||
@ -129,6 +184,21 @@ gui.authenticators.link = function(event) {
|
||||
};
|
||||
|
||||
var prevTables = [];
|
||||
var clearDetails = function() {
|
||||
$.each(prevTables, function(undefined, tbl){
|
||||
var $tbl = $(tbl).dataTable();
|
||||
$tbl.fnClearTable();
|
||||
$tbl.fnDestroy();
|
||||
});
|
||||
|
||||
$('#users-placeholder').empty();
|
||||
$('#groups-placeholder').empty();
|
||||
$('#logs-placeholder').empty();
|
||||
|
||||
$('#detail-placeholder').addClass('hidden');
|
||||
|
||||
prevTables = [];
|
||||
};
|
||||
|
||||
gui.doLog('enter auths');
|
||||
api.templates.get('authenticators', function(tmpl) {
|
||||
@ -137,28 +207,24 @@ gui.authenticators.link = function(event) {
|
||||
auths : 'auths-placeholder',
|
||||
users : 'users-placeholder',
|
||||
groups: 'groups-placeholder',
|
||||
logs: 'logs-placeholder',
|
||||
}));
|
||||
gui.setLinksEvents();
|
||||
|
||||
gui.authenticators.table({
|
||||
var tableId = gui.authenticators.table({
|
||||
container : 'auths-placeholder',
|
||||
rowSelect : 'single',
|
||||
buttons : [ 'new', 'edit', 'delete', 'xls' ],
|
||||
onRowDeselect: function() {
|
||||
clearDetails();
|
||||
},
|
||||
onRowSelect : function(selected) {
|
||||
|
||||
// We can have lots of users, so memory can grow up rapidly if we do not keep thins clena
|
||||
// To do so, we empty previous table contents before storing new table contents
|
||||
// Anyway, TabletTools will keep "leaking" memory, but we can handle a little "leak" that will be fixed as soon as we change the section
|
||||
$.each(prevTables, function(undefined, tbl){
|
||||
var $tbl = $(tbl).dataTable();
|
||||
$tbl.fnClearTable();
|
||||
$tbl.fnDestroy();
|
||||
});
|
||||
|
||||
$('#users-placeholder').empty();
|
||||
$('#groups-placeholder').empty();
|
||||
|
||||
prevTables = [];
|
||||
clearDetails();
|
||||
$('#detail-placeholder').removeClass('hidden');
|
||||
|
||||
gui.tools.blockUI();
|
||||
var id = selected[0].id;
|
||||
@ -184,9 +250,14 @@ gui.authenticators.link = function(event) {
|
||||
},
|
||||
});
|
||||
|
||||
var logTable = gui.authenticators.logTable(id, {
|
||||
container : 'logs-placeholder',
|
||||
});
|
||||
|
||||
// So we can destroy the tables beforing adding new ones
|
||||
prevTables.push(grpTable);
|
||||
prevTables.push(usrTable);
|
||||
prevTables.push(logTable);
|
||||
|
||||
return false;
|
||||
},
|
||||
|
@ -50,7 +50,7 @@ GuiElement.prototype = {
|
||||
// buttons: array of visible buttons (strings), valid are [ 'new', 'edit', 'refresh', 'delete', 'xls' ],
|
||||
// rowSelect: type of allowed row selection, valid values are 'single' and 'multi'
|
||||
// scrollToTable: if True, will scroll page to show table
|
||||
// deferedRender: if True, datatable will be created with "bDeferRender": true, that will improve a lot creation
|
||||
// deferedRender: if True, datatable will be created with "bDeferRender": true, that will improve a lot creation of huge tables
|
||||
//
|
||||
// onLoad: Event (function). If defined, will be invoked when table is fully loaded.
|
||||
// Receives 1 parameter, that is the gui element (GuiElement) used to render table
|
||||
@ -85,7 +85,7 @@ GuiElement.prototype = {
|
||||
// 4.- the DataTable that raised the event
|
||||
table : function(options) {
|
||||
"use strict";
|
||||
gui.doLog('Types: ', this.types);
|
||||
|
||||
options = options || {};
|
||||
gui.doLog('Composing table for ' + this.name);
|
||||
var tableId = this.name + '-table';
|
||||
@ -102,13 +102,6 @@ GuiElement.prototype = {
|
||||
return data;
|
||||
};
|
||||
|
||||
// Datetime renderer (with specified format)
|
||||
var renderDate = function(format) {
|
||||
return function(data, type, full) {
|
||||
return api.tools.strftime(format, new Date(data*1000));
|
||||
};
|
||||
};
|
||||
|
||||
// Icon renderer, based on type (created on init methods in styles)
|
||||
var renderTypeIcon = function(data, type, value){
|
||||
if( type == 'display' ) {
|
||||
@ -160,14 +153,14 @@ GuiElement.prototype = {
|
||||
switch(opts.type) {
|
||||
case 'date':
|
||||
column.sType = 'date';
|
||||
column.mRender = renderDate(api.tools.djangoFormat(get_format('SHORT_DATE_FORMAT')));
|
||||
column.mRender = gui.tools.renderDate(api.tools.djangoFormat(get_format('SHORT_DATE_FORMAT')));
|
||||
break;
|
||||
case 'datetime':
|
||||
column.sType = 'date';
|
||||
column.mRender = renderDate(api.tools.djangoFormat(get_format('SHORT_DATETIME_FORMAT')));
|
||||
column.mRender = gui.tools.renderDate(api.tools.djangoFormat(get_format('SHORT_DATETIME_FORMAT')));
|
||||
break;
|
||||
case 'time':
|
||||
column.mRender = renderDate(api.tools.djangoFormat(get_format('TIME_FORMAT')));
|
||||
column.mRender = gui.tools.renderDate(api.tools.djangoFormat(get_format('TIME_FORMAT')));
|
||||
break;
|
||||
case 'iconType':
|
||||
//columnt.sType = 'html'; // html is default, so this is not needed
|
||||
@ -192,7 +185,7 @@ GuiElement.prototype = {
|
||||
});
|
||||
// Responsive style for tables, using tables.css and this code generates the "titles" for vertical display on small sizes
|
||||
$('#style-' + tableId).remove(); // Remove existing style for table before adding new one
|
||||
$(api.templates.evaluate('tmpl_responsive_table', {
|
||||
$(api.templates.evaluate('tmpl_comp_responsive_table', {
|
||||
tableId: tableId,
|
||||
columns: columns,
|
||||
})).appendTo('head');
|
||||
@ -392,19 +385,19 @@ GuiElement.prototype = {
|
||||
// Initializes oTableTools
|
||||
var oTableTools = {
|
||||
"aButtons" : btns,
|
||||
"sRowSelect": options.rowSelect || 'single',
|
||||
"sRowSelect": options.rowSelect || 'none',
|
||||
};
|
||||
|
||||
if (options.onRowSelect) {
|
||||
var rowSelectedFnc = options.onRowSelect;
|
||||
oTableTools.fnRowSelected = function() {
|
||||
rowSelectedFnc(this.fnGetSelectedData(), $('#' + tableId).dataTable(), this);
|
||||
rowSelectedFnc(this.fnGetSelectedData(), $('#' + tableId).dataTable(), self);
|
||||
};
|
||||
}
|
||||
if (options.onRowDeselect) {
|
||||
var rowDeselectedFnc = options.onRowDeselect;
|
||||
oTableTools.fnRowDeselected = function() {
|
||||
rowDeselectedFnc(this.fnGetSelectedData(), $('#' + tableId).dataTable(), this);
|
||||
rowDeselectedFnc(this.fnGetSelectedData(), $('#' + tableId).dataTable(), self);
|
||||
};
|
||||
}
|
||||
|
||||
@ -425,6 +418,7 @@ GuiElement.prototype = {
|
||||
$('#' + tableId + '_filter input').addClass('form-control');
|
||||
// Add refresh action to panel
|
||||
$(table.refreshSelector).click(refreshFnc);
|
||||
|
||||
// Add tooltips to "new" buttons
|
||||
$('.DTTT_dropdown [data-toggle="tooltip"]').tooltip({
|
||||
container:'body',
|
||||
@ -443,6 +437,80 @@ GuiElement.prototype = {
|
||||
}); // End Overview data
|
||||
}); // End Tableinfo data
|
||||
|
||||
return '#' + tableId;
|
||||
},
|
||||
logTable: function(itemId, options) {
|
||||
"use strict";
|
||||
options = options || {};
|
||||
gui.doLog('Composing log for ' + this.name);
|
||||
var tableId = this.name + '-table-log';
|
||||
var self = this; // Store this for child functions
|
||||
|
||||
// Renderers for columns
|
||||
var columns = [
|
||||
{
|
||||
"mData" : 'date',
|
||||
"sTitle" : gettext('Date'),
|
||||
"mRender" : gui.tools.renderDate(api.tools.djangoFormat(get_format('SHORT_DATE_FORMAT') + ' ' + get_format('TIME_FORMAT'))),
|
||||
"bSortable" : true,
|
||||
"bSearchable" : true,
|
||||
},
|
||||
{
|
||||
"mData" : 'level',
|
||||
"sTitle" : gettext('level'),
|
||||
"mRender" : gui.tools.renderLogLovel(),
|
||||
"sWidth" : "5em",
|
||||
"bSortable" : true,
|
||||
"bSearchable" : true,
|
||||
},
|
||||
{
|
||||
"mData" : 'source',
|
||||
"sTitle" : gettext('source'),
|
||||
"sWidth" : "5em",
|
||||
"bSortable" : true,
|
||||
"bSearchable" : true,
|
||||
},
|
||||
{
|
||||
"mData" : 'message',
|
||||
"sTitle" : gettext('message'),
|
||||
"bSortable" : true,
|
||||
"bSearchable" : true,
|
||||
},
|
||||
];
|
||||
|
||||
var table = gui.table(options.title || gettext('Logs'), tableId);
|
||||
if (options.container === undefined) {
|
||||
gui.appendToWorkspace('<div class="row"><div class="col-lg-12">' + table.text + '</div></div>');
|
||||
} else {
|
||||
$('#' + options.container).empty();
|
||||
$('#' + options.container).append(table.text);
|
||||
}
|
||||
|
||||
// Responsive style for tables, using tables.css and this code generates the "titles" for vertical display on small sizes
|
||||
$('#style-' + tableId).remove(); // Remove existing style for table before adding new one
|
||||
$(api.templates.evaluate('tmpl_comp_responsive_table', {
|
||||
tableId: tableId,
|
||||
columns: columns,
|
||||
})).appendTo('head');
|
||||
|
||||
self.rest.getLogs(itemId, function(data){
|
||||
gui.doLog(data);
|
||||
|
||||
$('#' + tableId).dataTable({
|
||||
"aaData" : data,
|
||||
"oTableTools" : {"aButtons" : [],},
|
||||
"aoColumns" : columns,
|
||||
"oLanguage" : gui.config.dataTablesLanguage,
|
||||
"sDom" : "<'row'<'col-xs-8'T><'col-xs-4'f>r>t<'row'<'col-xs-5'i><'col-xs-7'p>>",
|
||||
"bDeferRender": options.deferedRender || false,
|
||||
});
|
||||
|
||||
// if table rendered event
|
||||
if( options.onLoad ) {
|
||||
options.onLoad(self);
|
||||
}
|
||||
});
|
||||
|
||||
return '#' + tableId;
|
||||
},
|
||||
};
|
||||
|
@ -47,6 +47,28 @@
|
||||
});
|
||||
});
|
||||
},
|
||||
// Datetime renderer (with specified format)
|
||||
renderDate : function(format) {
|
||||
return function(data, type, full) {
|
||||
return api.tools.strftime(format, new Date(data*1000));
|
||||
};
|
||||
},
|
||||
// Log level rendererer
|
||||
renderLogLovel : function() {
|
||||
var levels = {
|
||||
10000 : 'OTHER',
|
||||
20000 : 'DEBUG',
|
||||
30000 : 'INFO',
|
||||
40000 : 'WARN',
|
||||
50000 : 'ERROR',
|
||||
60000 : 'FATAL'
|
||||
};
|
||||
|
||||
return function(data, type, full) {
|
||||
return levels[data] || 'OTHER';
|
||||
}
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
}(window.gui = window.gui || {}, jQuery));
|
@ -45,10 +45,6 @@
|
||||
text: '<span class="fa fa-eraser"></span> <span class="label-tbl-button">' + gettext('Delete') + '</span>',
|
||||
css: 'disabled btn3d-default btn3d btn3d-tables',
|
||||
},
|
||||
'refresh': {
|
||||
text: '<span class="fa fa-refresh"></span> <span class="label-tbl-button">' + gettext('Refresh') + '</span>',
|
||||
css: 'btn3d-primary btn3d btn3d-tables',
|
||||
},
|
||||
'xls': {
|
||||
text: '<span class="fa fa-save"></span> <span class="label-tbl-button">' + gettext('Xls') + '</span>',
|
||||
css: 'btn3d-info btn3d btn3d-tables',
|
||||
@ -61,7 +57,7 @@
|
||||
var panelId = 'panel-' + table_id;
|
||||
|
||||
return {
|
||||
text: api.templates.evaluate('tmpl_table', {
|
||||
text: api.templates.evaluate('tmpl_comp_table', {
|
||||
panelId: panelId,
|
||||
icon: options.icon || 'table',
|
||||
size: options.size || 12,
|
||||
@ -85,21 +81,9 @@
|
||||
return '<div class="row"><div class="col-lg-12"><ol class="breadcrumb">' + list + "</ol></div></div>";
|
||||
};
|
||||
|
||||
gui.minimizePanel = function(panelId) {
|
||||
var title = $(panelId).attr('data-minimized');
|
||||
$(panelId).hide('slow', function(){
|
||||
$('<span class="label label-primary panel-icon"><b class="fa fa-plus-square-o"></b> ' + title + '</span>')
|
||||
.appendTo('#minimized')
|
||||
.click(function(){
|
||||
this.remove();
|
||||
$(panelId).show('slow');
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
gui.modal = function(id, title, content, options) {
|
||||
options = options || {};
|
||||
return api.templates.evaluate('tmpl_modal', {
|
||||
return api.templates.evaluate('tmpl_comp_modal', {
|
||||
id: id,
|
||||
title: title,
|
||||
content: content,
|
||||
|
@ -15,14 +15,14 @@
|
||||
<div id="detail-placeholder" class="row hidden">
|
||||
<div class="col-xs-12">
|
||||
<ul class="nav nav-tabs">
|
||||
<li><a href="#{{ users }}" data-toggle="tab">Users</a></li>
|
||||
<li><a href="#{{ groups }}" data-toggle="tab">Groups</a></li>
|
||||
<li><a href="#{{ logs }}" data-toggle="tab">Logs</a></li>
|
||||
<li class="active"><a href="#{{ users }}" data-toggle="tab">{% endverbatim %}{% trans 'Users' %}{% verbatim %}</a></li>
|
||||
<li><a href="#{{ groups }}" data-toggle="tab">{% endverbatim %}{% trans 'Groups' %}{% verbatim %}</a></li>
|
||||
<li><a href="#{{ logs }}" data-toggle="tab">{% endverbatim %}{% trans 'Logs' %}{% verbatim %}</a></li>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane fade in active" id="{{ users }}"></div>
|
||||
<div class="tab-pane fade" id="{{ groups }}"></div>
|
||||
<div class="tab-pane fade" id="{{ logs }}"></div>
|
||||
<div class="tab-pane fade" id="{{ logs }}">...</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -12,7 +12,26 @@
|
||||
<div class="row">
|
||||
<div id="{{ providers }}" class="col-xs-12"></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div id="{{ services }}" class="col-xs-12"></div>
|
||||
<div id="detail-placeholder" class="row hidden">
|
||||
<div class="col-xs-12">
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="active"><a href="#{{ services }}_tab" data-toggle="tab">{% endverbatim %}{% trans 'Services' %}{% verbatim %}</a></li>
|
||||
<li><a href="#{{ logs }}" data-toggle="tab">{% endverbatim %}{% trans 'Logs' %}{% verbatim %}</a></li>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane fade in active" id="{{ services }}_tab">
|
||||
<div class="row">
|
||||
<div class="col-xs-12" id="{{ services }}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-12" id="{{ services_log }}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="{{ logs }}">...</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endverbatim %}
|
Loading…
Reference in New Issue
Block a user