1
0
mirror of https://github.com/dkmstr/openuds.git synced 2024-12-22 13:34:04 +03:00

* Fixed a bunch of javascript things

* Added "gui" method to api, so we can get a description of what fields are needed for an specific item.
Added REST capacity to process gui requests
Updated translations
This commit is contained in:
Adolfo Gómez 2013-11-20 03:16:56 +00:00
parent 805b225552
commit 2bf0c3e59a
29 changed files with 4866 additions and 1449 deletions

View File

@ -37,7 +37,7 @@ from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
from django.utils.translation import ugettext as _, activate
from django.conf import settings
from handlers import Handler, HandlerError, AccessDenied
from handlers import Handler, HandlerError, AccessDenied, NotFound
import time
import logging
@ -150,6 +150,10 @@ class Dispatcher(View):
return response
except HandlerError as e:
return http.HttpResponseBadRequest(unicode(e))
except AccessDenied as e:
return http.HttpResponseForbidden(unicode(e))
except NotFound as e:
return http.Http404(unicode(e))
except Exception as e:
logger.exception('Error processing request')
return http.HttpResponseServerError(unicode(e))

View File

@ -46,6 +46,9 @@ AUTH_TOKEN_HEADER = 'HTTP_X_AUTH_TOKEN'
class HandlerError(Exception):
pass
class NotFound(HandlerError):
pass
class AccessDenied(HandlerError):
pass

View File

@ -38,7 +38,7 @@ from uds.core import auths
from users import Users
from uds.REST import Handler, HandlerError
from uds.REST import Handler, NotFound
from uds.REST.mixins import ModelHandlerMixin, ModelTypeHandlerMixin, ModelTableHandlerMixin
import logging
@ -65,6 +65,13 @@ class Types(ModelTypeHandlerMixin, Handler):
def enum_types(self):
return auths.factory().providers().values()
def getGui(self, type_):
try:
return auths.factory().lookup(type_).guiDescription()
except:
raise NotFound('type not found')
class TableInfo(ModelTableHandlerMixin, Handler):
path = 'authenticators'

View File

@ -32,6 +32,7 @@
'''
from __future__ import unicode_literals
from handlers import NotFound
from django.utils.translation import ugettext as _
import logging
@ -85,7 +86,7 @@ class ModelHandlerMixin(object):
detail = detailCls(self, path, parent = item)
return getattr(detail, self._operation)()
except:
return {'error': 'method not found' }
raise NotFound('method not found')
def get(self):
logger.debug('method GET for {0}, {1}'.format(self.__class__.__name__, self._args))
@ -97,10 +98,9 @@ class ModelHandlerMixin(object):
return self.processDetail()
try:
item = list(self.getItems(pk=self._args[0]))[0]
return list(self.getItems(pk=self._args[0]))[0]
except:
return {'error': 'not found' }
raise NotFound('item not found')
class ModelTypeHandlerMixin(object):
'''
@ -122,13 +122,31 @@ class ModelTypeHandlerMixin(object):
def getTypes(self, *args, **kwargs):
for type_ in self.enum_types():
try:
yield self.type_as_dict(type_)
except:
logger.exception('Exception enumerating types')
yield self.type_as_dict(type_)
def get(self):
return list(self.getTypes())
logger.debug(self._args)
nArgs = len(self._args)
if nArgs == 0:
return list(self.getTypes())
found = None
for v in self.getTypes():
if v['type'] == self._args[0]:
found = v
break
if found is None:
raise NotFound('type not found')
logger.debug('Found type {0}'.format(v))
if nArgs == 1:
return found
if self._args[1] == 'gui':
gui = self.getGui(self._args[0])
logger.debug("GUI: {0}".format(gui))
return gui
class ModelTableHandlerMixin(object):

View File

@ -32,7 +32,7 @@
'''
from __future__ import unicode_literals
from django.utils.translation import ugettext as _
from django.utils.translation import get_language, ugettext as _
import cPickle
import logging
@ -255,8 +255,8 @@ class gui(object):
alter original values.
'''
data = self._data.copy()
data['label'] = _(data['label'])
data['tooltip'] = _(data['tooltip'])
data['label'] = data['label'] != '' and _(data['label']) or ''
data['tooltip'] = data['tooltip'] != '' and _(data['tooltip']) or ''
return data
@property
@ -816,6 +816,7 @@ class UserInterface(object):
object: If not none, object that will get its "initGui" invoked
This will only happen (not to be None) in Services.
'''
logger.debug('Active languaje for gui translation: {0}'.format(get_language()))
if obj is not None:
obj.initGui() # We give the "oportunity" to fill necesary gui data before providing it to client

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-11-17 04:21+0100\n"
"POT-Creation-Date: 2013-11-20 04:05+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -18,14 +18,10 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: static/adm/js/gui-elements.js:7
#: static/adm/js/gui-elements.js:33
msgid "Service Providers"
msgstr "Service-Provider"
#: static/adm/js/gui-elements.js:81
msgid "Connectivity"
msgstr "Konnektivität"
#: static/adm/js/gui.js:18
msgid "_MENU_ records per page"
msgstr "_MENU_ Datensätze pro Seite"
@ -70,19 +66,19 @@ msgstr "Nächste"
msgid "Previous"
msgstr "Vorherige"
#: static/adm/js/gui.js:80
#: static/adm/js/gui.js:75
msgid "Deployed services"
msgstr "Bereitgestellten Dienste"
#: static/adm/js/gui.js:349
#: static/adm/js/gui.js:360
msgid "Edit"
msgstr "Bearbeiten"
#: static/adm/js/gui.js:358
#: static/adm/js/gui.js:369
msgid "Delete"
msgstr "Löschen"
#: static/adm/js/gui.js:367
#: static/adm/js/gui.js:378
msgid "Refresh"
msgstr "Aktualisieren"
@ -161,3 +157,7 @@ msgstr "November"
#: static/adm/js/strftime.js:35
msgid "December"
msgstr "Dezember"
#: static/adm/js/tools.js:46
msgid "Just a moment..."
msgstr "Einen Moment..."

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-11-17 04:21+0100\n"
"POT-Creation-Date: 2013-11-20 04:05+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -18,14 +18,10 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: static/adm/js/gui-elements.js:7
#: static/adm/js/gui-elements.js:33
msgid "Service Providers"
msgstr "Proveedores de servicios"
#: static/adm/js/gui-elements.js:81
msgid "Connectivity"
msgstr "Conectividad"
#: static/adm/js/gui.js:18
msgid "_MENU_ records per page"
msgstr "Registros _MENU_ por página"
@ -70,19 +66,19 @@ msgstr "Próxima"
msgid "Previous"
msgstr "Anterior"
#: static/adm/js/gui.js:80
#: static/adm/js/gui.js:75
msgid "Deployed services"
msgstr "Servicios desplegados"
#: static/adm/js/gui.js:349
#: static/adm/js/gui.js:360
msgid "Edit"
msgstr "Editar"
#: static/adm/js/gui.js:358
#: static/adm/js/gui.js:369
msgid "Delete"
msgstr "Borrar"
#: static/adm/js/gui.js:367
#: static/adm/js/gui.js:378
msgid "Refresh"
msgstr "Actualización"
@ -161,3 +157,7 @@ msgstr "Noviembre"
#: static/adm/js/strftime.js:35
msgid "December"
msgstr "Diciembre"
#: static/adm/js/tools.js:46
msgid "Just a moment..."
msgstr "Un momento..."

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-11-17 04:21+0100\n"
"POT-Creation-Date: 2013-11-20 04:05+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -18,14 +18,10 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: static/adm/js/gui-elements.js:7
#: static/adm/js/gui-elements.js:33
msgid "Service Providers"
msgstr "Fournisseurs de services"
#: static/adm/js/gui-elements.js:81
msgid "Connectivity"
msgstr "Connectivité"
#: static/adm/js/gui.js:18
msgid "_MENU_ records per page"
msgstr "Documents _MENU_ par page"
@ -70,19 +66,19 @@ msgstr "Prochaine"
msgid "Previous"
msgstr "Précédent"
#: static/adm/js/gui.js:80
#: static/adm/js/gui.js:75
msgid "Deployed services"
msgstr "Services déployés"
#: static/adm/js/gui.js:349
#: static/adm/js/gui.js:360
msgid "Edit"
msgstr "Edit"
#: static/adm/js/gui.js:358
#: static/adm/js/gui.js:369
msgid "Delete"
msgstr "Supprimer"
#: static/adm/js/gui.js:367
#: static/adm/js/gui.js:378
msgid "Refresh"
msgstr "Actualisation"
@ -161,3 +157,7 @@ msgstr "Novembre"
#: static/adm/js/strftime.js:35
msgid "December"
msgstr "Décembre"
#: static/adm/js/tools.js:46
msgid "Just a moment..."
msgstr "Un instant..."

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-11-17 04:21+0100\n"
"POT-Creation-Date: 2013-11-20 04:05+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -18,14 +18,10 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: static/adm/js/gui-elements.js:7
#: static/adm/js/gui-elements.js:33
msgid "Service Providers"
msgstr "Fornitori di servizi"
#: static/adm/js/gui-elements.js:81
msgid "Connectivity"
msgstr "Connettività"
#: static/adm/js/gui.js:18
msgid "_MENU_ records per page"
msgstr "Record _MENU_ per pagina"
@ -70,19 +66,19 @@ msgstr "Prossimo"
msgid "Previous"
msgstr "Precedente"
#: static/adm/js/gui.js:80
#: static/adm/js/gui.js:75
msgid "Deployed services"
msgstr "Servizi distribuiti"
#: static/adm/js/gui.js:349
#: static/adm/js/gui.js:360
msgid "Edit"
msgstr "Modifica"
#: static/adm/js/gui.js:358
#: static/adm/js/gui.js:369
msgid "Delete"
msgstr "Eliminare"
#: static/adm/js/gui.js:367
#: static/adm/js/gui.js:378
msgid "Refresh"
msgstr "Aggiornamento"
@ -161,3 +157,7 @@ msgstr "Novembre"
#: static/adm/js/strftime.js:35
msgid "December"
msgstr "Dicembre"
#: static/adm/js/tools.js:46
msgid "Just a moment..."
msgstr "Solo un momento..."

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-11-17 04:21+0100\n"
"POT-Creation-Date: 2013-11-20 04:05+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -18,14 +18,10 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: static/adm/js/gui-elements.js:7
#: static/adm/js/gui-elements.js:33
msgid "Service Providers"
msgstr "Prestadores de serviços"
#: static/adm/js/gui-elements.js:81
msgid "Connectivity"
msgstr "Conectividade"
#: static/adm/js/gui.js:18
msgid "_MENU_ records per page"
msgstr "Registros _MENU_ por página"
@ -70,19 +66,19 @@ msgstr "Próxima"
msgid "Previous"
msgstr "Anterior"
#: static/adm/js/gui.js:80
#: static/adm/js/gui.js:75
msgid "Deployed services"
msgstr "Serviços implantados"
#: static/adm/js/gui.js:349
#: static/adm/js/gui.js:360
msgid "Edit"
msgstr "Editar"
#: static/adm/js/gui.js:358
#: static/adm/js/gui.js:369
msgid "Delete"
msgstr "Excluir"
#: static/adm/js/gui.js:367
#: static/adm/js/gui.js:378
msgid "Refresh"
msgstr "Atualização"
@ -161,3 +157,7 @@ msgstr "Novembro"
#: static/adm/js/strftime.js:35
msgid "December"
msgstr "Dezembro de"
#: static/adm/js/tools.js:46
msgid "Just a moment..."
msgstr "Só um momento..."

View File

@ -1,5 +1,6 @@
/* jshint strict: true */
(function(api, $, undefined) {
"use strict";
// "public" methods
api.doLog = function(data) {
if (api.debug) {
@ -17,8 +18,11 @@
return new Cache(cacheName);
};
api.getJson = function(path, success_fnc) {
url = api.url_for(path);
api.getJson = function(path, options) {
options = options || {};
var success_fnc = options.success || function(){};
var url = api.url_for(path);
api.doLog('Ajax GET Json for "' + url + '"');
$.ajax({
url : url,
@ -27,10 +31,7 @@
success : function(data) {
api.doLog('Success on "' + url + '".');
api.doLog('Received ' + JSON.stringify(data));
if (success_fnc !== undefined) {
api.doLog('Executing success method');
success_fnc(data);
}
success_fnc(data);
},
beforeSend : function(request) {
request.setRequestHeader(api.auth_header, api.token);
@ -39,12 +40,13 @@
};
// Public attributes
api.debug = false;
api.debug = true;
}(window.api = window.api || {}, jQuery));
// Cache related
function Cache(cacheName) {
"use strict";
api.cacheTable = api.cacheTable || {};
api.cacheTable[cacheName] = api.cacheTable[cacheName] || {};
@ -55,6 +57,7 @@ function Cache(cacheName) {
Cache.prototype = {
get: function(key, not_found_fnc){
"use strict";
not_found_fnc = not_found_fnc || function() { return undefined; };
if( this.cache[key] === undefined ) {
@ -64,7 +67,8 @@ Cache.prototype = {
},
put: function(key, value) {
this.cache[key] = value;
"use strict";
this.cache[key] = value;
},
};
@ -74,6 +78,7 @@ Cache.prototype = {
// code :-)
function BasicModelRest(path, options) {
"use strict";
options = options || {};
path = path || '';
// Requests paths
@ -85,34 +90,70 @@ function BasicModelRest(path, options) {
}
BasicModelRest.prototype = {
// options:
// cacheKey: '.' --> do not cache
// undefined -- > use path as key
// success: success fnc to execute in case of success
_requestPath: function(path, options) {
"use strict";
options = options || {};
var success_fnc = options.success || function(){api.doLog('success not provided for '+path);};
var cacheKey = options.cacheKey || path;
if( path == '.' ) {
success_fnc({});
return;
}
if (cacheKey != '.' && this.cache.get(cacheKey)) {
success_fnc(this.cache.get(cacheKey));
} else {
var $this = this;
api.getJson(path, {
success: function(data) {
if( cacheKey != '.' ) {
$this.cache.put(cacheKey, data);
}
success_fnc(data);
},
});
}
},
get : function(options) {
"use strict";
options = options || {};
var path = this.getPath;
if (options.id !== undefined)
path += '/' + options.id;
api.getJson(path, options.success);
return this._requestPath(path, {
cacheKey: '.', // Right now, do not cache this
success: options.success,
});
},
types : function(success_fnc) {
// Cache types locally, will not change unless new broker version
sucess_fnc = success_fnc || function(data){};
if( this.typesPath == '.' ) {
success_fnc({});
return;
}
if (this.cache.get('types')) {
success_fnc(this.cache.get('types'));
} else {
var $this = this;
var path = this.typesPath;
api.getJson(path, function(data) {
$this.cache.put('types', data);
success_fnc(data);
});
}
types : function(options) {
"use strict";
options = options || {};
return this._requestPath(this.typesPath, {
cacheKey: 'type',
success: options.success,
});
},
tableInfo : function(success_fnc) {
gui: function(typeName, options) {
"use strict";
options = options || {};
var path = [this.typesPath, typeName, 'gui'].join('/');
return this._requestPath(path, {
cacheKey: typeName + '-gui',
success: options.success,
});
},
tableInfo : function(options) {
"use strict";
options = options || {};
var success_fnc = options.success || function(){api.doLog('success not provided for tableInfo');};
var path = this.tableInfoPath;
// Cache types locally, will not change unless new broker version
if( this.cache.get(path) ) {
@ -123,14 +164,17 @@ BasicModelRest.prototype = {
}
var $this = this;
api.getJson(path, function(data) {
$this.cache.put(path, data);
success_fnc(data);
api.getJson(path, {
success: function(data) {
$this.cache.put(path, data);
success_fnc(data);
},
});
},
detail: function(id, child) {
"use strict";
return new DetailModelRestApi(this, id, child);
}
@ -138,6 +182,7 @@ BasicModelRest.prototype = {
// For REST of type /auth/[id]/users, /services/[id]/users, ...
function DetailModelRestApi(parentApi, parentId, model) {
"use strict";
this.base = new BasicModelRest(undefined, {
getPath: [parentApi.path, parentId, model].join('/'),
typesPath: '.', // We do not has this on details
@ -148,13 +193,16 @@ function DetailModelRestApi(parentApi, parentId, model) {
DetailModelRestApi.prototype = {
// Generates a basic model with fixed methods for "detail" models
get: function(options) {
"use strict";
return this.base.get(options);
},
types: function(success_fnc) {
return this.base.types(success_fnc);
types: function(options) {
"use strict";
return this.base.types(options);
},
tableInfo: function(success_fnc) {
return this.base.tableInfo(success_fnc);
tableInfo: function(options) {
"use strict";
return this.base.tableInfo(options);
},
};

View File

@ -1,31 +0,0 @@
(function(api, $, undefined) {
api.cache = function(cacheName) {
return new Cache(cacheName);
};
}(window.api = window.api || {}, jQuery));
function Cache(cacheName) {
api.cacheTable = api.cacheTable || {};
api.cacheTable[cacheName] = api.cacheTable[cacheName] || {};
this.name = cacheName;
this.cache = api.cacheTable[cacheName];
}
Cache.prototype = {
get: function(key, not_found_fnc){
not_found_fnc = not_found_fnc || function() { return undefined; };
if( this.cache[key] === undefined ) {
this.cache[key] = not_found_fnc();
}
return this.cache[key];
},
put: function(key, value) {
this.cache[key] = value;
},
};

View File

@ -136,24 +136,26 @@ GuiElement.prototype = {
"use strict";
gui.doLog('Initializing ' + this.name);
var $this = this;
this.rest.types(function(data) {
var styles = '';
$.each(data, function(index, value) {
var className = $this.name + '-' + value.type;
$this.types[value.type] = {
css : className,
name : value.name || '',
description : value.description || ''
};
gui.doLog('Creating style for ' + className);
var style = '.' + className + ' { display:inline-block; background: url(data:image/png;base64,' +
value.icon + '); ' + 'width: 16px; height: 16px; vertical-align: middle; } ';
styles += style;
});
if (styles !== '') {
styles = '<style media="screen">' + styles + '</style>';
$(styles).appendTo('head');
}
this.rest.types({
success: function(data) {
var styles = '';
$.each(data, function(index, value) {
var className = $this.name + '-' + value.type;
$this.types[value.type] = {
css : className,
name : value.name || '',
description : value.description || ''
};
gui.doLog('Creating style for ' + className);
var style = '.' + className + ' { display:inline-block; background: url(data:image/png;base64,' +
value.icon + '); ' + 'width: 16px; height: 16px; vertical-align: middle; } ';
styles += style;
});
if (styles !== '') {
styles = '<style media="screen">' + styles + '</style>';
$(styles).appendTo('head');
}
},
});
},
table : function(options) {
@ -211,287 +213,267 @@ GuiElement.prototype = {
};
};
this.rest.tableInfo(function(data) {
var title = data.title;
var columns = [];
$.each(data.fields, function(index, value) {
for ( var v in value) {
var options = value[v];
var column = {
mData : v,
};
column.sTitle = options.title;
column.mRender = renderEmptyCell;
if (options.type !== undefined) {
switch(options.type) {
case 'date':
column.sType = 'date';
column.mRender = renderDate(djangoFormat(get_format('SHORT_DATE_FORMAT')));
break;
case 'datetime':
column.sType = 'date';
column.mRender = renderDate(djangoFormat(get_format('SHORT_DATETIME_FORMAT')));
break;
case 'time':
column.mRender = renderDate(djangoFormat(get_format('TIME_FORMAT')));
break;
case 'iconType':
//columnt.sType = 'html'; // html is default, so this is not needed
column.mRender = renderTypeIcon;
break;
case 'icon':
if( options.icon !== undefined ) {
column.mRender = renderIcon(options.icon);
}
break;
case 'dict':
if( options.dict !== undefined ) {
column.mRender = renderTextTransform(options.dict);
}
break;
default:
column.sType = options.type;
this.rest.tableInfo({
success: function(data) {
var title = data.title;
var columns = [];
$.each(data.fields, function(index, value) {
for ( var v in value) {
var options = value[v];
var column = {
mData : v,
};
column.sTitle = options.title;
column.mRender = renderEmptyCell;
if (options.type !== undefined) {
switch(options.type) {
case 'date':
column.sType = 'date';
column.mRender = renderDate(djangoFormat(get_format('SHORT_DATE_FORMAT')));
break;
case 'datetime':
column.sType = 'date';
column.mRender = renderDate(djangoFormat(get_format('SHORT_DATETIME_FORMAT')));
break;
case 'time':
column.mRender = renderDate(djangoFormat(get_format('TIME_FORMAT')));
break;
case 'iconType':
//columnt.sType = 'html'; // html is default, so this is not needed
column.mRender = renderTypeIcon;
break;
case 'icon':
if( options.icon !== undefined ) {
column.mRender = renderIcon(options.icon);
}
break;
case 'dict':
if( options.dict !== undefined ) {
column.mRender = renderTextTransform(options.dict);
}
break;
default:
column.sType = options.type;
}
}
if (options.width)
column.sWidth = options.width;
if (options.visible !== undefined)
column.bVisible = options.visible;
if (options.sortable !== undefined)
column.bSortable = options.sortable;
if (options.searchable !== undefined)
column.bSearchable = options.searchable;
columns.push(column);
}
if (options.width)
column.sWidth = options.width;
if (options.visible !== undefined)
column.bVisible = options.visible;
if (options.sortable !== undefined)
column.bSortable = options.sortable;
if (options.searchable !== undefined)
column.bSearchable = options.searchable;
columns.push(column);
}
});
// Generate styles for responsibe table, just the name of fields
var respStyles = [];
var counter = 0;
$.each(columns, function(col, value) {
if( value.bVisible === false )
return;
counter += 1;
respStyles.push('#' + tableId + ' td:nth-of-type(' + counter + '):before { content: "' +
(value.sTitle || '') + '";}\n');
respStyles.push('#' + tableId + ' td:nth-of-type(' + counter + '):empty { background-color: red ;}\n');
});
// If styles already exists, remove them before adding new ones
$('style-' + tableId).remove();
$('<style id="style-' + tableId + '" media="screen">@media (max-width: 979px) { ' + respStyles.join('') + '};</style>').appendTo('head');
$this.rest.get({
success : function(data) {
var table = gui.table(title, tableId);
if (options.container === undefined) {
gui.appendToWorkspace('<div class="row"><div class="col-lg-12">' + table + '</div></div>');
} else {
$('#' + options.container).empty();
$('#' + options.container).append(table);
}
var btns = [];
if (options.buttons) {
// methods for buttons click
var editFnc = function() {
gui.doLog('Edit');
gui.doLog(this);
};
var deleteFnc = function() {
gui.doLog('Delete');
gui.doLog(this);
};
// What execute on refresh button push
var onRefresh = options.onRefresh || function(){};
var refreshFnc = function(btn) {
// Refreshes table content
var tbl = $('#' + tableId).dataTable();
/*var width = $(btn).width();
var saved = $(btn).html();
$(btn).addClass('disabled').html('<span class="fa fa-spinner fa-spin"></span>')
.width(width);*/
if( data.length > 1000 )
api.tools.blockUI();
});
// Generate styles for responsibe table, just the name of fields
var respStyles = [];
var counter = 0;
$.each(columns, function(col, value) {
if( value.bVisible === false )
return;
counter += 1;
respStyles.push('#' + tableId + ' td:nth-of-type(' + counter + '):before { content: "' +
(value.sTitle || '') + '";}\n');
respStyles.push('#' + tableId + ' td:nth-of-type(' + counter + '):empty { background-color: red ;}\n');
});
// If styles already exists, remove them before adding new ones
$('style-' + tableId).remove();
$('<style id="style-' + tableId + '" media="screen">@media (max-width: 979px) { ' + respStyles.join('') + '};</style>').appendTo('head');
$this.rest.get({
success : function(data) {
var table = gui.table(title, tableId);
if (options.container === undefined) {
gui.appendToWorkspace('<div class="row"><div class="col-lg-12">' + table + '</div></div>');
} else {
$('#' + options.container).empty();
$('#' + options.container).append(table);
}
var btns = [];
if (options.buttons) {
// methods for buttons click
var editFnc = function() {
gui.doLog('Edit');
gui.doLog(this);
};
var deleteFnc = function() {
gui.doLog('Delete');
gui.doLog(this);
};
onRefresh($this);
$this.rest.get({
success : function(data) {
/*$(btn).removeClass('disabled').width('').html(saved);*/
setTimeout( function() {
tbl.fnClearTable();
tbl.fnAddData(data);
api.tools.unblockUI();
}, 0);
// What execute on refresh button push
var onRefresh = options.onRefresh || function(){};
var refreshFnc = function(btn) {
// Refreshes table content
var tbl = $('#' + tableId).dataTable();
/*var width = $(btn).width();
var saved = $(btn).html();
$(btn).addClass('disabled').html('<span class="fa fa-spinner fa-spin"></span>')
.width(width);*/
if( data.length > 1000 )
api.tools.blockUI();
onRefresh($this);
$this.rest.get({
success : function(data) {
/*$(btn).removeClass('disabled').width('').html(saved);*/
setTimeout( function() {
tbl.fnClearTable();
tbl.fnAddData(data);
api.tools.unblockUI();
}, 0);
}
});
};
// methods for buttons on row select
var editSelected = function(btn, obj, node) {
var sel = this.fnGetSelectedData();
if (sel.length == 1) {
$(btn).removeClass('disabled').addClass('btn3d-success');
} else {
$(btn).removeClass('btn3d-success').addClass('disabled');
}
});
};
// methods for buttons on row select
var editSelected = function(btn, obj, node) {
var sel = this.fnGetSelectedData();
if (sel.length == 1) {
$(btn).removeClass('disabled').addClass('btn3d-success');
} else {
$(btn).removeClass('btn3d-success').addClass('disabled');
}
};
var deleteSelected = function(btn, obj, node) {
var sel = this.fnGetSelectedData();
if (sel.length > 0) {
$(btn).removeClass('disabled').addClass('btn3d-warning');
} else {
$(btn).removeClass('btn3d-warning').addClass('disabled');
}
};
$.each(options.buttons, function(index, value) {
var btn;
switch (value) {
case 'edit':
btn = {
"sExtends" : "text",
"sButtonText" : gettext('Edit'),
"fnSelect" : editSelected,
"fnClick" : editFnc,
"sButtonClass" : "disabled btn3d btn3d-tables"
};
break;
case 'delete':
btn = {
"sExtends" : "text",
"sButtonText" : gettext('Delete'),
"fnSelect" : deleteSelected,
"fnClick" : deleteFnc,
"sButtonClass" : "disabled btn3d btn3d-tables"
};
break;
case 'refresh':
btn = {
"sExtends" : "text",
"sButtonText" : gettext('Refresh'),
"fnClick" : refreshFnc,
"sButtonClass" : "btn3d-primary btn3d btn3d-tables"
};
break;
case 'xls':
btn = {
"sExtends" : "text",
"sButtonText" : 'xls',
"fnClick" : function(){
api.templates.get('spreadsheet', function(tmpl) {
var styles = { 'bold': 's21', };
var uri = 'data:application/vnd.ms-excel;base64,',
base64 = function(s) { return window.btoa(unescape(encodeURIComponent(s))); };
var headings = [], rows = [];
$.each(columns, function(index, heading){
if( heading.bVisible === false ) {
return;
}
headings.push(api.spreadsheet.cell(heading.sTitle, 'String', styles.bold));
});
rows.push(api.spreadsheet.row(headings));
$.each(data, function(index, row) {
var cells = [];
$.each(columns, function(index, col){
if( col.bVisible === false ) {
};
var deleteSelected = function(btn, obj, node) {
var sel = this.fnGetSelectedData();
if (sel.length > 0) {
$(btn).removeClass('disabled').addClass('btn3d-warning');
} else {
$(btn).removeClass('btn3d-warning').addClass('disabled');
}
};
$.each(options.buttons, function(index, value) {
var btn;
switch (value) {
case 'edit':
btn = {
"sExtends" : "text",
"sButtonText" : gettext('Edit'),
"fnSelect" : editSelected,
"fnClick" : editFnc,
"sButtonClass" : "disabled btn3d btn3d-tables"
};
break;
case 'delete':
btn = {
"sExtends" : "text",
"sButtonText" : gettext('Delete'),
"fnSelect" : deleteSelected,
"fnClick" : deleteFnc,
"sButtonClass" : "disabled btn3d btn3d-tables"
};
break;
case 'refresh':
btn = {
"sExtends" : "text",
"sButtonText" : gettext('Refresh'),
"fnClick" : refreshFnc,
"sButtonClass" : "btn3d-primary btn3d btn3d-tables"
};
break;
case 'xls':
btn = {
"sExtends" : "text",
"sButtonText" : 'xls',
"fnClick" : function(){
api.templates.get('spreadsheet', function(tmpl) {
var styles = { 'bold': 's21', };
var uri = 'data:application/vnd.ms-excel;base64,',
base64 = function(s) { return window.btoa(unescape(encodeURIComponent(s))); };
var headings = [], rows = [];
$.each(columns, function(index, heading){
if( heading.bVisible === false ) {
return;
}
var type = col.sType == 'numeric' ? 'Number':'String';
cells.push(api.spreadsheet.cell(row[col.mData], type));
headings.push(api.spreadsheet.cell(heading.sTitle, 'String', styles.bold));
});
rows.push(api.spreadsheet.row(cells));
rows.push(api.spreadsheet.row(headings));
$.each(data, function(index, row) {
var cells = [];
$.each(columns, function(index, col){
if( col.bVisible === false ) {
return;
}
var type = col.sType == 'numeric' ? 'Number':'String';
cells.push(api.spreadsheet.cell(row[col.mData], type));
});
rows.push(api.spreadsheet.row(cells));
});
var ctx = {
creation_date: (new Date()).toISOString(),
worksheet: title,
columns_count: headings.length,
rows_count: rows.length,
rows: rows.join('\n')
};
// window.location.href = uri + base64(api.templates.evaluate(tmpl, ctx));
setTimeout( function() {
saveAs(new Blob([api.templates.evaluate(tmpl, ctx)],
{type: 'application/vnd.ms-excel'} ), title + '.xls');
}, 20);
});
var ctx = {
creation_date: (new Date()).toISOString(),
worksheet: title,
columns_count: headings.length,
rows_count: rows.length,
rows: rows.join('\n')
};
// window.location.href = uri + base64(api.templates.evaluate(tmpl, ctx));
setTimeout( function() {
saveAs(new Blob([api.templates.evaluate(tmpl, ctx)],
{type: 'application/vnd.ms-excel'} ), title + '.xls')
}, 20);
});
},
"sButtonClass" : "btn3d-info btn3d btn3d-tables"
};
/*case 'csv':
btn = {
"sExtends" : "csv",
"sTitle" : title,
"sFileName" : title + '.csv',
};
break;*/
/*case 'pdf':
btn = {
"sExtends" : "pdf",
"sTitle" : title,
"sPdfMessage" : "Summary Info",
"fnCellRender": function(value, col, node, dattaIndex) {
// All tables handled by this needs an "id" on col 0
// So, we return empty values for col 0
if(col === 0)
return '';
return value.toString().replace(/(<([^>]+)>)/ig, '');
},
"sFileName" : title + '.pdf',
"sPdfOrientation" : "portrait"
};
break;*/
}
if (btn !== undefined)
btns.push(btn);
},
"sButtonClass" : "btn3d-info btn3d btn3d-tables"
};
}
if (btn !== undefined)
btns.push(btn);
});
}
// Initializes oTableTools
var oTableTools = {
"aButtons" : btns
};
if (options.rowSelect) {
oTableTools.sRowSelect = options.rowSelect;
}
if (options.onRowSelect) {
oTableTools.fnRowSelected = options.onRowSelect;
}
if (options.onRowDeselect) {
oTableTools.fnRowDeselected = options.onRowDeselect;
}
$('#' + tableId).dataTable({
"aaData" : data,
"aoColumns" : columns,
"oLanguage" : gui.dataTablesLanguage,
"oTableTools" : oTableTools,
// First is upper row,
// second row is lower
// (pagination) row
"sDom" : "<'row'<'col-xs-8'T><'col-xs-4'f>r>t<'row'<'col-xs-5'i><'col-xs-7'p>>",
});
// Fix 3dbuttons
api.tools.fix3dButtons('#' + tableId + '_wrapper .btn-group-3d');
// Fix form
//$('#' + tableId + '_filter input').addClass('form-control');
if (options.scroll !== undefined ) {
var tableTop = $('#' + tableId).offset().top;
$('html, body').scrollTop(tableTop);
}
// if table rendered event
if( options.onLoad ) {
options.onLoad($this);
}
}
// Initializes oTableTools
var oTableTools = {
"aButtons" : btns
};
if (options.rowSelect) {
oTableTools.sRowSelect = options.rowSelect;
}
if (options.onRowSelect) {
oTableTools.fnRowSelected = options.onRowSelect;
}
if (options.onRowDeselect) {
oTableTools.fnRowDeselected = options.onRowDeselect;
}
$('#' + tableId).dataTable({
"aaData" : data,
"aoColumns" : columns,
"oLanguage" : gui.dataTablesLanguage,
"oTableTools" : oTableTools,
// First is upper row,
// second row is lower
// (pagination) row
"sDom" : "<'row'<'col-xs-8'T><'col-xs-4'f>r>t<'row'<'col-xs-5'i><'col-xs-7'p>>",
});
// Fix 3dbuttons
api.tools.fix3dButtons('#' + tableId + '_wrapper .btn-group-3d');
// Fix form
//$('#' + tableId + '_filter input').addClass('form-control');
if (options.scroll !== undefined ) {
var tableTop = $('#' + tableId).offset().top;
$('html, body').scrollTop(tableTop);
}
// if table rendered event
if( options.onLoad ) {
options.onLoad($this);
}
}
});
});
},
});
return '#' + tableId;
}

View File

@ -43,7 +43,7 @@
};
tools.blockUI = function(message) {
message = message || '<h1><span class="fa fa-spinner fa-spin"></span> ' + gettext('Just a moment...') + '</h1>'
message = message || '<h1><span class="fa fa-spinner fa-spin"></span> ' + gettext('Just a moment...') + '</h1>';
$.blockUI({ message: message });
};