mirror of
https://github.com/dkmstr/openuds.git
synced 2025-01-11 05:17:55 +03:00
Finished based model/detail methods
This commit is contained in:
parent
043b28cfb4
commit
888f125dc6
@ -37,7 +37,7 @@ from uds.models import Provider
|
||||
from services import Services
|
||||
from uds.core import services
|
||||
|
||||
from uds.REST import NotFound
|
||||
from uds.REST import NotFound, RequestError
|
||||
from uds.REST.model import ModelHandler
|
||||
|
||||
import logging
|
||||
@ -77,6 +77,10 @@ class Providers(ModelHandler):
|
||||
'comments': provider.comments,
|
||||
}
|
||||
|
||||
def checkDelete(self, item):
|
||||
if item.services.count() > 0:
|
||||
raise RequestError('Can\'t delete providers with services already associated')
|
||||
|
||||
# Types related
|
||||
def enum_types(self):
|
||||
return services.factory().providers().values()
|
||||
|
@ -37,7 +37,8 @@ from django.utils.translation import ugettext as _
|
||||
from uds.core.Environment import Environment
|
||||
|
||||
from uds.REST.model import DetailHandler
|
||||
from uds.REST import NotFound, ResponseError
|
||||
from uds.REST import NotFound, ResponseError, RequestError
|
||||
from django.db import IntegrityError
|
||||
|
||||
import logging
|
||||
|
||||
@ -59,19 +60,51 @@ class Services(DetailHandler):
|
||||
'deployed_services_count' : k.deployedServices.count(),
|
||||
} for k in parent.services.all() ]
|
||||
else:
|
||||
with parent.get(pk=item) as k:
|
||||
return {
|
||||
'id':k.id,
|
||||
'name': k.name,
|
||||
'comments': k.comments,
|
||||
'type': k.data_type,
|
||||
'typeName' : _(k.getType().name()),
|
||||
'deployed_services_count' : k.deployedServices.count(),
|
||||
}
|
||||
k = parent.services.get(pk=item)
|
||||
return {
|
||||
'id':k.id,
|
||||
'name': k.name,
|
||||
'comments': k.comments,
|
||||
'type': k.data_type,
|
||||
'typeName' : _(k.getType().name()),
|
||||
'deployed_services_count' : k.deployedServices.count(),
|
||||
}
|
||||
except:
|
||||
logger.exception('En services')
|
||||
return { 'error': 'not found' }
|
||||
|
||||
def saveItem(self, parent, item):
|
||||
# Extract item db fields
|
||||
# We need this fields for all
|
||||
fields = self.readFieldsFromParams(['name', 'comments', 'data_type'])
|
||||
try:
|
||||
if item is None: # Create new
|
||||
service = parent.services.create(**fields)
|
||||
else:
|
||||
service = parent.services.get(pk=item)
|
||||
service.__dict__.update(fields)
|
||||
service.save()
|
||||
except self.model.DoesNotExist:
|
||||
raise NotFound('Item not found')
|
||||
except IntegrityError: # Duplicate key probably
|
||||
raise RequestError('Element already exists (duplicate key error)')
|
||||
except Exception:
|
||||
raise RequestError('incorrect invocation to PUT')
|
||||
|
||||
return self.getItems(parent, service.id)
|
||||
|
||||
def deleteItem(self, parent, item):
|
||||
try:
|
||||
service = parent.services.get(pk=item)
|
||||
|
||||
if service.deployedServices.count() != 0:
|
||||
raise RequestError('Item has associated deployed services')
|
||||
|
||||
service.delete()
|
||||
except:
|
||||
raise NotFound('service not found')
|
||||
|
||||
return 'deleted'
|
||||
|
||||
def getTitle(self, parent):
|
||||
try:
|
||||
return _('Services of {0}').format(parent.name)
|
||||
|
@ -111,32 +111,51 @@ class BaseModelHandler(Handler):
|
||||
processedFields.append({k1: dct})
|
||||
return { 'title': unicode(title), 'fields': processedFields };
|
||||
|
||||
def readFieldsFromParams(self, fldList):
|
||||
args = {}
|
||||
try:
|
||||
for key in fldList:
|
||||
args[key] = self._params[key]
|
||||
del self._params[key]
|
||||
except KeyError as e:
|
||||
raise RequestError('needed parameter not found in data {0}'.format(unicode(e)))
|
||||
|
||||
return args
|
||||
|
||||
# Exceptions
|
||||
def invalidRequestException(self):
|
||||
raise RequestError('Invalid Request')
|
||||
|
||||
# Details do not have types at all
|
||||
# so, right now, we only process details petitions for Handling & tables info
|
||||
class DetailHandler(BaseModelHandler):
|
||||
'''
|
||||
Detail handler (for relations such as provider-->services, authenticators-->users,groups, deployed services-->cache,assigned, groups, transports
|
||||
Urls treated are:
|
||||
Urls recognized for GET are:
|
||||
[path] --> get Items (all hopefully, this call is delegated to getItems)
|
||||
[path]/overview
|
||||
[path]/ID
|
||||
[path]/gui
|
||||
[path]/TYPE/gui
|
||||
[path]/gui/TYPE
|
||||
[path]/types
|
||||
[path]/types/TYPE
|
||||
[path]/tableinfo
|
||||
[path].... -->
|
||||
[path]/tableinfo
|
||||
For PUT:
|
||||
[path] --> create NEW item
|
||||
[path]/ID --> Modify existing item
|
||||
For DELETE:
|
||||
[path]/ID
|
||||
'''
|
||||
def __init__(self, parentHandler, path, *args, **kwargs):
|
||||
def __init__(self, parentHandler, path, params, *args, **kwargs):
|
||||
self._parent = parentHandler
|
||||
self._path = path
|
||||
self._params = params
|
||||
self._args = args
|
||||
self._kwargs = kwargs
|
||||
|
||||
def get(self):
|
||||
# Process args
|
||||
logger.debug("Detail args: {0}".format(self._args))
|
||||
logger.debug("Detail args for GET: {0}".format(self._args))
|
||||
nArgs = len(self._args)
|
||||
parent = self._kwargs['parent']
|
||||
if nArgs == 0:
|
||||
@ -163,15 +182,54 @@ class DetailHandler(BaseModelHandler):
|
||||
|
||||
return self.fallbackGet()
|
||||
|
||||
def put(self):
|
||||
'''
|
||||
Put is delegated to specific implementation
|
||||
'''
|
||||
logger.debug("Detail args for PUT: {0}, {1}".format(self._args, self._params))
|
||||
|
||||
parent = self._kwargs['parent']
|
||||
|
||||
if len(self._args) == 0:
|
||||
# Create new
|
||||
item = None
|
||||
elif len(self._args) == 1:
|
||||
item = self._args[0]
|
||||
else:
|
||||
self.invalidRequestException()
|
||||
|
||||
return self.saveItem(parent, item)
|
||||
|
||||
def delete(self):
|
||||
'''
|
||||
Put is delegated to specific implementation
|
||||
'''
|
||||
logger.debug("Detail args for DELETE: {0}".format(self._args))
|
||||
|
||||
parent = self._kwargs['parent']
|
||||
|
||||
if len(self._args) != 1:
|
||||
self.invalidRequestException()
|
||||
|
||||
return self.deleteItem(parent, self._args[0])
|
||||
|
||||
# Invoked if default get can't process request
|
||||
def fallbackGet(self):
|
||||
raise RequestError('Invalid request')
|
||||
raise self.invalidRequestException()
|
||||
|
||||
# Default (as sample) getItems
|
||||
def getItems(self, parent, item):
|
||||
if item is None:
|
||||
if item is None: # Returns ALL detail items
|
||||
return []
|
||||
return {}
|
||||
return {} # Returns one item
|
||||
|
||||
# Default save
|
||||
def saveItem(self, parent, item):
|
||||
self.invalidRequestException()
|
||||
|
||||
# Default delete
|
||||
def deleteItem(self, parent, item):
|
||||
self.invalidRequestException()
|
||||
|
||||
# A detail handler must also return title & fields for tables
|
||||
def getTitle(self, parent):
|
||||
@ -181,7 +239,7 @@ class DetailHandler(BaseModelHandler):
|
||||
return []
|
||||
|
||||
def getGui(self, parent, forType):
|
||||
raise RequestError('Gui not provided')
|
||||
raise RequestError('Gui not provided for this type of object')
|
||||
|
||||
def getTypes(self, parent, forType):
|
||||
return [] # Default is that details do not have types
|
||||
@ -214,24 +272,12 @@ class ModelHandler(BaseModelHandler):
|
||||
table_fields = []
|
||||
table_title = ''
|
||||
|
||||
def __fillIntanceFields(self, item, res):
|
||||
if hasattr(item, 'getInstance'):
|
||||
for key, value in item.getInstance().valuesDict().iteritems():
|
||||
value = {"true":True, "false":False}.get(value, value)
|
||||
logger.debug('{0} = {1}'.format(key, value))
|
||||
res[key] = value
|
||||
|
||||
# This method must be override, depending on what is provided
|
||||
|
||||
# Data related
|
||||
def item_as_dict(self, item):
|
||||
pass
|
||||
|
||||
def getItems(self, *args, **kwargs):
|
||||
for item in self.model.objects.filter(*args, **kwargs):
|
||||
try:
|
||||
yield self.item_as_dict(item)
|
||||
except:
|
||||
logger.exception('Exception getting item from {0}'.format(self.model))
|
||||
|
||||
# types related
|
||||
def enum_types(self): # override this
|
||||
return []
|
||||
@ -255,7 +301,14 @@ class ModelHandler(BaseModelHandler):
|
||||
|
||||
# gui related
|
||||
def getGui(self, type_):
|
||||
raise RequestError('invalid request')
|
||||
self.invalidRequestException()
|
||||
|
||||
# Delete related, checks if the item can be deleted
|
||||
# If it can't be so, raises an exception
|
||||
def checkDelete(self, item):
|
||||
pass
|
||||
|
||||
# End overridable
|
||||
|
||||
# Helper to process detail
|
||||
def processDetail(self):
|
||||
@ -265,11 +318,25 @@ class ModelHandler(BaseModelHandler):
|
||||
detailCls = self.detail[self._args[1]]
|
||||
args = list(self._args[2:])
|
||||
path = self._path + '/'.join(args[:2])
|
||||
detail = detailCls(self, path, *args, parent = item)
|
||||
detail = detailCls(self, path, self._params, *args, parent = item)
|
||||
return getattr(detail, self._operation)()
|
||||
except AttributeError:
|
||||
raise NotFound('method not found')
|
||||
|
||||
|
||||
def getItems(self, *args, **kwargs):
|
||||
for item in self.model.objects.filter(*args, **kwargs):
|
||||
try:
|
||||
yield self.item_as_dict(item)
|
||||
except:
|
||||
logger.exception('Exception getting item from {0}'.format(self.model))
|
||||
|
||||
def fillIntanceFields(self, item, res):
|
||||
if hasattr(item, 'getInstance'):
|
||||
for key, value in item.getInstance().valuesDict().iteritems():
|
||||
value = {"true":True, "false":False}.get(value, value)
|
||||
logger.debug('{0} = {1}'.format(key, value))
|
||||
res[key] = value
|
||||
|
||||
def get(self):
|
||||
logger.debug('method GET for {0}, {1}'.format(self.__class__.__name__, self._args))
|
||||
nArgs = len(self._args)
|
||||
@ -277,7 +344,7 @@ class ModelHandler(BaseModelHandler):
|
||||
result = []
|
||||
for val in self.model.objects.all():
|
||||
res = self.item_as_dict(val)
|
||||
self.__fillIntanceFields(val, res)
|
||||
self.fillIntanceFields(val, res)
|
||||
result.append(res)
|
||||
return result
|
||||
|
||||
@ -293,7 +360,7 @@ class ModelHandler(BaseModelHandler):
|
||||
try:
|
||||
val = self.model.objects.get(pk=self._args[0])
|
||||
res = self.item_as_dict(val)
|
||||
self.__fillIntanceFields(val, res)
|
||||
self.fillIntanceFields(val, res)
|
||||
return res
|
||||
except:
|
||||
raise NotFound('item not found')
|
||||
@ -318,59 +385,56 @@ class ModelHandler(BaseModelHandler):
|
||||
|
||||
def put(self):
|
||||
logger.debug('method PUT for {0}, {1}'.format(self.__class__.__name__, self._args))
|
||||
args = {}
|
||||
try:
|
||||
for key in self.save_fields:
|
||||
args[key] = self._params[key]
|
||||
del self._params[key]
|
||||
except KeyError as e:
|
||||
raise RequestError('needed parameter not found in data {0}'.format(unicode(e)))
|
||||
|
||||
|
||||
if len(self._args) > 1: # Detail?
|
||||
return self.processDetail()
|
||||
try:
|
||||
# Extract fields
|
||||
args = self.readFieldsFromParams(self.save_fields)
|
||||
deleteOnError = False
|
||||
if len(self._args) == 0: # create new
|
||||
item = self.model.objects.create(**args);
|
||||
elif len(self._args) == 1:
|
||||
item = self.model.objects.create(**args)
|
||||
deleteOnError = True
|
||||
else: # Must have 1 arg
|
||||
# We have to take care with this case, update will efectively update records on db
|
||||
item = self.model.objects.get(pk=self._args[0]);
|
||||
item.__dict__.update(args) # Update fields from args
|
||||
else: # TODO: Maybe a detail put request
|
||||
raise Exception() # Incorrect invocation
|
||||
except self.model.DoesNotExist:
|
||||
raise NotFound('Element do not exists')
|
||||
raise NotFound('Item not found')
|
||||
except IntegrityError: # Duplicate key probably
|
||||
raise RequestError('Element already exists (duplicate key error)')
|
||||
except Exception as e:
|
||||
except Exception:
|
||||
raise RequestError('incorrect invocation to PUT')
|
||||
|
||||
# Store associated object if needed
|
||||
if self._params.has_key('data_type'): # Needs to store instance
|
||||
item.data_type = self._params['data_type']
|
||||
item.data = item.getInstance(self._params).serialize()
|
||||
|
||||
item.save()
|
||||
|
||||
res = self.item_as_dict(item)
|
||||
|
||||
self.__fillIntanceFields(item, res)
|
||||
|
||||
item.save()
|
||||
try:
|
||||
if self._params.has_key('data_type'): # Needs to store instance
|
||||
item.data_type = self._params['data_type']
|
||||
item.data = item.getInstance(self._params).serialize()
|
||||
|
||||
item.save()
|
||||
|
||||
res = self.item_as_dict(item)
|
||||
self.fillIntanceFields(item, res)
|
||||
except:
|
||||
if deleteOnError:
|
||||
item.delete()
|
||||
raise
|
||||
|
||||
return res
|
||||
|
||||
def delete(self):
|
||||
logger.debug('method DELETE for {0}, {1}'.format(self.__class__.__name__, self._args))
|
||||
if len(self._args) == 2: # TODO: Detail request
|
||||
raise Exception()
|
||||
if len(self._args) > 1:
|
||||
return self.processDetail()
|
||||
|
||||
if len(self._args) != 1:
|
||||
raise RequestError('Delete need one and only one argument')
|
||||
try:
|
||||
item = self.model.objects.get(pk=self._args[0]);
|
||||
self.checkDelete(item)
|
||||
item.delete()
|
||||
except self.model.DoesNotExist:
|
||||
raise NotFound('Element do not exists')
|
||||
except Exception:
|
||||
logger.exception('delete')
|
||||
raise RequestError('incorrect invocation to DELETE')
|
||||
|
||||
return 'deleted'
|
||||
|
||||
|
@ -43,7 +43,7 @@
|
||||
api.templates.get = function(name, success_fnc) {
|
||||
var $this = this;
|
||||
success_fnc = success_fnc || function(){};
|
||||
api.doLog('Getting tempkate ' + name);
|
||||
api.doLog('Getting template ' + name);
|
||||
if (name.indexOf('?') == -1) {
|
||||
if ($this.cache.get(name) ) {
|
||||
success_fnc($this.cache.get(name));
|
||||
@ -64,7 +64,6 @@
|
||||
$this.cache.put('_' + cachedId, $this.evaluate(data));
|
||||
$this.cache.put(name, cachedId);
|
||||
api.doLog('Success getting template "' + name + '".');
|
||||
api.doLog('Received: ' + data);
|
||||
success_fnc(cachedId);
|
||||
},
|
||||
fail: function( jqXHR, textStatus, errorThrown ) {
|
||||
|
@ -359,6 +359,34 @@ DetailModelRestApi.prototype = {
|
||||
"use strict";
|
||||
return this.base.get(success_fnc, fail_fnc);
|
||||
},
|
||||
put: function(data, options) {
|
||||
"use strict";
|
||||
return this.base.put(data, options);
|
||||
},
|
||||
create: function(data, success_fnc, fail_fnc) {
|
||||
"use strict";
|
||||
|
||||
return this.put(data, {
|
||||
success: success_fnc,
|
||||
fail: fail_fnc
|
||||
});
|
||||
},
|
||||
save: function(data, success_fnc, fail_fnc) {
|
||||
"use strict";
|
||||
|
||||
return this.put(data, {
|
||||
id: data.id,
|
||||
success: success_fnc,
|
||||
fail: fail_fnc
|
||||
});
|
||||
},
|
||||
// --------------
|
||||
// Delete
|
||||
// --------------
|
||||
del: function(id, success_fnc, fail_fnc) {
|
||||
"use strict";
|
||||
return this.base.del(id, success_fnc, fail_fnc);
|
||||
},
|
||||
tableInfo: function(success_fnc, fail_fnc) {
|
||||
"use strict";
|
||||
return this.base.tableInfo(success_fnc, fail_fnc);
|
||||
|
@ -41,13 +41,13 @@ gui.providers.link = function(event) {
|
||||
container : 'providers-placeholder',
|
||||
rowSelect : 'single',
|
||||
onCheck : function(check, items) { // Check if item can be deleted
|
||||
if( check == 'delete' ) {
|
||||
/*if( check == 'delete' ) {
|
||||
for( var i in items ) {
|
||||
if( items[i].services_count > 0)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}*/
|
||||
return true;
|
||||
},
|
||||
onRowSelect : function(selected) {
|
||||
@ -71,7 +71,9 @@ gui.providers.link = function(event) {
|
||||
return true;
|
||||
},
|
||||
buttons : [ 'new', 'edit', 'delete', 'xls' ],
|
||||
onEdit : services.typedEdit(gettext('Edit service'), gettext('Error processing service')),
|
||||
onEdit : gui.methods.typedEdit(services, gettext('Edit service'), gettext('Error processing service')),
|
||||
onNew : gui.methods.typedNew(services, gettext('New service'), gettext('Error creating service')),
|
||||
onDelete: gui.methods.del(services, gettext('Delete service'), gettext('Error deleting service')),
|
||||
scrollToTable : false,
|
||||
onLoad: function(k) {
|
||||
api.tools.unblockUI();
|
||||
@ -80,7 +82,9 @@ gui.providers.link = function(event) {
|
||||
return false;
|
||||
},
|
||||
buttons : [ 'new', 'edit', 'delete', 'xls' ],
|
||||
onEdit: gui.providers.typedEdit(gettext('Edit provider'), gettext('Error processing provider')),
|
||||
onNew : gui.methods.typedNew(gui.providers, gettext('New provider'), gettext('Error creating provider')),
|
||||
onEdit: gui.methods.typedEdit(gui.providers, gettext('Edit provider'), gettext('Error processing provider')),
|
||||
onDelete: gui.methods.del(gui.providers, gettext('Delete provider'), gettext('Error deleting provider')),
|
||||
});
|
||||
});
|
||||
|
||||
@ -107,7 +111,7 @@ gui.authenticators.link = function(event) {
|
||||
gui.authenticators.table({
|
||||
container : 'auths-placeholder',
|
||||
rowSelect : 'single',
|
||||
buttons : [ 'edit', 'delete', 'xls' ],
|
||||
buttons : [ 'new', 'edit', 'delete', 'xls' ],
|
||||
onRowSelect : function(selected) {
|
||||
api.tools.blockUI();
|
||||
var id = selected[0].id;
|
||||
@ -135,7 +139,9 @@ gui.authenticators.link = function(event) {
|
||||
onRefresh : function() {
|
||||
$('#users-placeholder').empty(); // Remove detail on parent refresh
|
||||
},
|
||||
onEdit: gui.authenticators.typedEdit(gettext('Edit authenticator'), gettext('Error processing authenticator')),
|
||||
onNew : gui.methods.typedNew(gui.authenticators, gettext('New authenticator'), gettext('Error creating authenticator')),
|
||||
onEdit: gui.methods.typedEdit(gui.authenticators, gettext('Edit authenticator'), gettext('Error processing authenticator')),
|
||||
onDelete: gui.methods.del(gui.authenticators, gettext('Delete authenticator'), gettext('Error deleting authenticator')),
|
||||
|
||||
});
|
||||
});
|
||||
@ -241,8 +247,7 @@ gui.connectivity.link = function(event) {
|
||||
// TODO: Add confirmation to deletion
|
||||
gui.connectivity.transports.rest.del(value.id, function(){
|
||||
refreshFnc();
|
||||
}, gui.failRequestModalFnc(gettext('Error removing transport'))
|
||||
);
|
||||
}, gui.failRequestModalFnc(gettext('Error removing transport')) );
|
||||
},
|
||||
});
|
||||
gui.connectivity.networks.table({
|
||||
|
@ -352,9 +352,9 @@ GuiElement.prototype = {
|
||||
headings.push(api.spreadsheet.cell(heading.sTitle, 'String', styles.bold));
|
||||
});
|
||||
rows.push(api.spreadsheet.row(headings));
|
||||
$.each(data, function(index, row) {
|
||||
$.each(data, function(index1, row) {
|
||||
var cells = [];
|
||||
$.each(columns, function(index, col){
|
||||
$.each(columns, function(index2, col){
|
||||
if( col.bVisible === false ) {
|
||||
return;
|
||||
}
|
||||
@ -363,7 +363,6 @@ GuiElement.prototype = {
|
||||
});
|
||||
rows.push(api.spreadsheet.row(cells));
|
||||
});
|
||||
|
||||
var ctx = {
|
||||
creation_date: (new Date()).toISOString(),
|
||||
worksheet: title,
|
||||
@ -371,6 +370,7 @@ GuiElement.prototype = {
|
||||
rows_count: rows.length,
|
||||
rows: rows.join('\n')
|
||||
};
|
||||
gui.doLog(ctx);
|
||||
setTimeout( function() {
|
||||
saveAs(new Blob([api.templates.evaluate(tmpl, ctx)],
|
||||
{type: 'application/vnd.ms-excel'} ), title + '.xls');
|
||||
@ -446,28 +446,4 @@ GuiElement.prototype = {
|
||||
}); // End Tableinfo data
|
||||
return '#' + tableId;
|
||||
},
|
||||
// "Generic" edit method to set onEdit table
|
||||
typedEdit: function(modalTitle, modalErrorMsg, guiProcessor, fieldsProcessor) {
|
||||
"use strict";
|
||||
var self = this;
|
||||
return function(value, event, table, refreshFnc) {
|
||||
self.rest.gui(value.type, function(guiDefinition) {
|
||||
var tabs = guiProcessor ? guiProcessor(guiDefinition) : guiDefinition;
|
||||
self.rest.item(value.id, function(item) {
|
||||
gui.forms.launchModal(modalTitle+' <b>'+value.name+'</b>', tabs, item, function(form_selector, closeFnc) {
|
||||
var fields = gui.forms.read(form_selector);
|
||||
fields.data_type = value.type;
|
||||
fields = fieldsProcessor ? fieldsProcessor(fields) : fields; // Preprocess fields (probably generate tabs...)
|
||||
self.rest.save(fields, function(data) { // Success on put
|
||||
closeFnc();
|
||||
refreshFnc();
|
||||
}, gui.failRequestModalFnc(modalErrorMsg)); // Fail on put, show modal message
|
||||
return false;
|
||||
});
|
||||
});
|
||||
|
||||
}, gui.failRequestModalFnc(modalErrorMsg));
|
||||
};
|
||||
},
|
||||
|
||||
};
|
||||
|
@ -116,8 +116,17 @@
|
||||
.on('hidden.bs.modal', function () {
|
||||
$(id).remove();
|
||||
});
|
||||
return id;
|
||||
};
|
||||
|
||||
gui.alert = function(message, type) {
|
||||
api.templates.get('alert', function(tmpl) {
|
||||
$(api.templates.evaluate(tmpl, {
|
||||
type: type,
|
||||
message: message
|
||||
})).appendTo('#alerts');
|
||||
});
|
||||
};
|
||||
|
||||
gui.failRequestMessageFnc = function(jqXHR, textStatus, errorThrown) {
|
||||
api.templates.get('request_failed', function(tmpl) {
|
||||
@ -209,7 +218,71 @@
|
||||
gui.setLinksEvents();
|
||||
gui.dashboard.link();
|
||||
};
|
||||
|
||||
// Generic "methods" for editing, creating, etc...
|
||||
|
||||
gui.methods = {};
|
||||
|
||||
// "Generic" edit method to set onEdit table
|
||||
gui.methods.typedEdit = function(parent, modalTitle, modalErrorMsg, guiProcessor, fieldsProcessor) {
|
||||
var self = parent;
|
||||
return function(value, event, table, refreshFnc) {
|
||||
self.rest.gui(value.type, function(guiDefinition) {
|
||||
var tabs = guiProcessor ? guiProcessor(guiDefinition) : guiDefinition; // Preprocess fields (probably generate tabs...)
|
||||
self.rest.item(value.id, function(item) {
|
||||
gui.forms.launchModal(modalTitle+' <b>'+value.name+'</b>', tabs, item, function(form_selector, closeFnc) {
|
||||
var fields = gui.forms.read(form_selector);
|
||||
fields.data_type = value.type;
|
||||
fields = fieldsProcessor ? fieldsProcessor(fields) : fields;
|
||||
self.rest.save(fields, function(data) { // Success on put
|
||||
closeFnc();
|
||||
refreshFnc();
|
||||
gui.alert(gettext('Edition successfully done'), 'success');
|
||||
}, gui.failRequestModalFnc(modalErrorMsg)); // Fail on put, show modal message
|
||||
return false;
|
||||
});
|
||||
});
|
||||
|
||||
}, gui.failRequestModalFnc(modalErrorMsg));
|
||||
};
|
||||
};
|
||||
|
||||
// "Generic" new method to set onNew table
|
||||
gui.methods.typedNew = function(parent, modalTitle, modalErrorMsg, guiProcessor, fieldsProcessor) {
|
||||
var self = parent;
|
||||
return function(type, table, refreshFnc) {
|
||||
self.rest.gui(type, function(guiDefinition) {
|
||||
var tabs = guiProcessor ? guiProcessor(guiDefinition) : guiDefinition; // Preprocess fields (probably generate tabs...)
|
||||
gui.forms.launchModal(modalTitle, tabs, undefined, function(form_selector, closeFnc) {
|
||||
var fields = gui.forms.read(form_selector);
|
||||
fields.data_type = type;
|
||||
fields = fieldsProcessor ? fieldsProcessor(fields) : fields; // P
|
||||
self.rest.create(fields, function(data) { // Success on put
|
||||
closeFnc();
|
||||
refreshFnc();
|
||||
gui.alert(gettext('Creation successfully done'), 'success');
|
||||
}, gui.failRequestModalFnc(modalErrorMsg) // Fail on put, show modal message
|
||||
);
|
||||
});
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
gui.methods.del = function(parent, modalTitle, modalErrorMsg) {
|
||||
var self = parent;
|
||||
return function(value, event, table, refreshFnc) {
|
||||
var content = gettext('Are you sure do you want to delete ') + '<b>' + value.name + '</b>';
|
||||
var modalId = gui.launchModal(modalTitle, content, '<button type="button" class="btn btn-danger button-accept">' + gettext('Delete') + '</button>');
|
||||
$(modalId + ' .button-accept').click(function(){
|
||||
$(modalId).modal('hide');
|
||||
self.rest.del(value.id, function(){
|
||||
refreshFnc();
|
||||
gui.alert(gettext('Deletion successfully done'), 'success');
|
||||
}, gui.failRequestModalFnc(modalErrorMsg) );
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
// Public attributes
|
||||
gui.debug = true;
|
||||
}(window.gui = window.gui || {}, jQuery));
|
||||
|
@ -35,8 +35,9 @@
|
||||
<!-- End of menu -->
|
||||
<!-- Content -->
|
||||
<div id="page-wrapper">
|
||||
<div id="alerts">
|
||||
</div>
|
||||
<div id="content">
|
||||
{% block body %}{% endblock %}
|
||||
</div>
|
||||
<div class="row">
|
||||
<div id="minimized" class="col-lg-12">
|
||||
@ -124,6 +125,7 @@
|
||||
{% js_template 'table' %}
|
||||
{% js_template 'modal' %}
|
||||
{% js_template 'responsive_table' %}
|
||||
{% js_template 'alert' %}
|
||||
<!-- fields -->
|
||||
{% js_template 'fld/checkbox' %}
|
||||
{% js_template 'fld/choice' %}
|
||||
|
6
server/src/uds/templates/uds/admin/tmpl/alert.html
Normal file
6
server/src/uds/templates/uds/admin/tmpl/alert.html
Normal file
@ -0,0 +1,6 @@
|
||||
{% verbatim %}
|
||||
<div class="alert alert-dismissable alert-{{ type }}">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
|
||||
{{ message }}
|
||||
</div>
|
||||
{% endverbatim %}
|
Loading…
Reference in New Issue
Block a user