Purge things for legacy (jquery) mobile, and unused template themes
gosh it feels good to get rid of this stuff... fingers crossed that nothing was broken, but am thinking it's safe
This commit is contained in:
parent
fac00e6ecd
commit
708641a8f1
70 changed files with 196 additions and 4886 deletions
|
@ -115,14 +115,6 @@ class MasterView(View):
|
|||
# set to True to declare model as "contact"
|
||||
is_contact = False
|
||||
|
||||
supports_mobile = False
|
||||
mobile_creatable = False
|
||||
mobile_editable = False
|
||||
mobile_pageable = True
|
||||
mobile_filterable = False
|
||||
mobile_executable = False
|
||||
|
||||
mobile = False
|
||||
listing = False
|
||||
creating = False
|
||||
creates_multiple = False
|
||||
|
@ -170,14 +162,6 @@ class MasterView(View):
|
|||
rows_downloadable_csv = False
|
||||
rows_downloadable_xlsx = False
|
||||
|
||||
mobile_rows_creatable = False
|
||||
mobile_rows_creatable_via_browse = False
|
||||
mobile_rows_quickable = False
|
||||
mobile_rows_filterable = False
|
||||
mobile_rows_viewable = False
|
||||
mobile_rows_editable = False
|
||||
mobile_rows_deletable = False
|
||||
|
||||
row_labels = {}
|
||||
|
||||
@property
|
||||
|
@ -236,24 +220,6 @@ class MasterView(View):
|
|||
"""
|
||||
return getattr(cls, 'version_grid_factory', grids.Grid)
|
||||
|
||||
@classmethod
|
||||
def get_mobile_grid_factory(cls):
|
||||
"""
|
||||
Must return a callable to be used when creating new mobile grid
|
||||
instances. Instead of overriding this, you can set
|
||||
:attr:`mobile_grid_factory`. Default factory is :class:`MobileGrid`.
|
||||
"""
|
||||
return getattr(cls, 'mobile_grid_factory', grids.MobileGrid)
|
||||
|
||||
@classmethod
|
||||
def get_mobile_row_grid_factory(cls):
|
||||
"""
|
||||
Must return a callable to be used when creating new mobile row grid
|
||||
instances. Instead of overriding this, you can set
|
||||
:attr:`mobile_row_grid_factory`. Default factory is :class:`MobileGrid`.
|
||||
"""
|
||||
return getattr(cls, 'mobile_row_grid_factory', grids.MobileGrid)
|
||||
|
||||
def set_labels(self, obj):
|
||||
labels = self.collect_labels()
|
||||
for key, label in six.iteritems(labels):
|
||||
|
@ -624,163 +590,6 @@ class MasterView(View):
|
|||
def render_version_comment(self, transaction, column):
|
||||
return transaction.meta.get('comment', "")
|
||||
|
||||
def mobile_index(self):
|
||||
"""
|
||||
Mobile "home" page for the data model
|
||||
"""
|
||||
self.mobile = True
|
||||
self.listing = True
|
||||
grid = self.make_mobile_grid()
|
||||
return self.render_to_response('index', {'grid': grid}, mobile=True)
|
||||
|
||||
@classmethod
|
||||
def get_mobile_grid_key(cls):
|
||||
"""
|
||||
Must return a unique "config key" for the mobile grid, for sort/filter
|
||||
purposes etc. (It need only be unique among *mobile* grids.) Instead
|
||||
of overriding this, you can set :attr:`mobile_grid_key`. Default is
|
||||
the value returned by :meth:`get_route_prefix()`.
|
||||
"""
|
||||
if hasattr(cls, 'mobile_grid_key'):
|
||||
return cls.mobile_grid_key
|
||||
return 'mobile.{}'.format(cls.get_route_prefix())
|
||||
|
||||
def make_mobile_grid(self, factory=None, key=None, data=None, columns=None, **kwargs):
|
||||
"""
|
||||
Creates a new mobile grid instance
|
||||
"""
|
||||
if factory is None:
|
||||
factory = self.get_mobile_grid_factory()
|
||||
if key is None:
|
||||
key = self.get_mobile_grid_key()
|
||||
if data is None:
|
||||
data = self.get_mobile_data(session=kwargs.get('session'))
|
||||
if columns is None:
|
||||
columns = self.get_mobile_grid_columns()
|
||||
|
||||
kwargs.setdefault('request', self.request)
|
||||
kwargs.setdefault('mobile', True)
|
||||
kwargs = self.make_mobile_grid_kwargs(**kwargs)
|
||||
grid = factory(key, data, columns, **kwargs)
|
||||
self.configure_mobile_grid(grid)
|
||||
grid.load_settings()
|
||||
return grid
|
||||
|
||||
def get_mobile_grid_columns(self):
|
||||
if hasattr(self, 'mobile_grid_columns'):
|
||||
return self.mobile_grid_columns
|
||||
# TODO
|
||||
return ['listitem']
|
||||
|
||||
def get_mobile_data(self, session=None):
|
||||
"""
|
||||
Must return the "raw" / full data set for the mobile grid. This data
|
||||
should *not* yet be sorted or filtered in any way; that happens later.
|
||||
Default is the value returned by :meth:`get_data()`, in which case all
|
||||
records visible in the traditional view, are visible in mobile too.
|
||||
"""
|
||||
return self.get_data(session=session)
|
||||
|
||||
def make_mobile_grid_kwargs(self, **kwargs):
|
||||
"""
|
||||
Must return a dictionary of kwargs to be passed to the factory when
|
||||
creating new mobile grid instances.
|
||||
"""
|
||||
defaults = {
|
||||
'model_class': getattr(self, 'model_class', None),
|
||||
'pageable': self.mobile_pageable,
|
||||
'sortable': False,
|
||||
'filterable': self.mobile_filterable,
|
||||
'renderers': self.make_mobile_grid_renderers(),
|
||||
'url': lambda obj: self.get_action_url('view', obj, mobile=True),
|
||||
}
|
||||
# TODO: this seems wrong..
|
||||
if self.mobile_filterable:
|
||||
defaults['filters'] = self.make_mobile_filters()
|
||||
defaults.update(kwargs)
|
||||
return defaults
|
||||
|
||||
def make_mobile_grid_renderers(self):
|
||||
return {
|
||||
'listitem': self.render_mobile_listitem,
|
||||
}
|
||||
|
||||
def render_mobile_listitem(self, obj, i):
|
||||
return obj
|
||||
|
||||
def configure_mobile_grid(self, grid):
|
||||
pass
|
||||
|
||||
def make_mobile_row_grid(self, factory=None, key=None, data=None, columns=None, **kwargs):
|
||||
"""
|
||||
Make a new (configured) rows grid instance for mobile.
|
||||
"""
|
||||
instance = kwargs.pop('instance', self.get_instance())
|
||||
|
||||
if factory is None:
|
||||
factory = self.get_mobile_row_grid_factory()
|
||||
if key is None:
|
||||
key = 'mobile.{}.{}'.format(self.get_grid_key(), self.request.matchdict[self.get_model_key()])
|
||||
if data is None:
|
||||
data = self.get_mobile_row_data(instance)
|
||||
if columns is None:
|
||||
columns = self.get_mobile_row_grid_columns()
|
||||
|
||||
kwargs.setdefault('request', self.request)
|
||||
kwargs.setdefault('mobile', True)
|
||||
kwargs = self.make_mobile_row_grid_kwargs(**kwargs)
|
||||
grid = factory(key, data, columns, **kwargs)
|
||||
self.configure_mobile_row_grid(grid)
|
||||
grid.load_settings()
|
||||
return grid
|
||||
|
||||
def get_mobile_row_grid_columns(self):
|
||||
if hasattr(self, 'mobile_row_grid_columns'):
|
||||
return self.mobile_row_grid_columns
|
||||
# TODO
|
||||
return ['listitem']
|
||||
|
||||
def make_mobile_row_grid_kwargs(self, **kwargs):
|
||||
"""
|
||||
Must return a dictionary of kwargs to be passed to the factory when
|
||||
creating new mobile *row* grid instances.
|
||||
"""
|
||||
defaults = {
|
||||
'model_class': self.model_row_class,
|
||||
# TODO
|
||||
'pageable': self.pageable,
|
||||
'sortable': False,
|
||||
'filterable': self.mobile_rows_filterable,
|
||||
'renderers': self.make_mobile_row_grid_renderers(),
|
||||
'url': lambda obj: self.get_row_action_url('view', obj, mobile=True),
|
||||
}
|
||||
# TODO: this seems wrong..
|
||||
if self.mobile_rows_filterable:
|
||||
defaults['filters'] = self.make_mobile_row_filters()
|
||||
defaults.update(kwargs)
|
||||
return defaults
|
||||
|
||||
def make_mobile_row_grid_renderers(self):
|
||||
return {
|
||||
'listitem': self.render_mobile_row_listitem,
|
||||
}
|
||||
|
||||
def configure_mobile_row_grid(self, grid):
|
||||
pass
|
||||
|
||||
def make_mobile_filters(self):
|
||||
"""
|
||||
Returns a set of filters for the mobile grid, if applicable.
|
||||
"""
|
||||
|
||||
def make_mobile_row_filters(self):
|
||||
"""
|
||||
Returns a set of filters for the mobile row grid, if applicable.
|
||||
"""
|
||||
|
||||
def render_mobile_row_listitem(self, obj, i):
|
||||
return obj
|
||||
|
||||
def create(self, form=None, template='create'):
|
||||
"""
|
||||
View for creating a new model record.
|
||||
|
@ -800,22 +609,6 @@ class MasterView(View):
|
|||
context['dform'] = form.make_deform_form()
|
||||
return self.render_to_response(template, context)
|
||||
|
||||
def mobile_create(self):
|
||||
"""
|
||||
Mobile view for creating a new primary object
|
||||
"""
|
||||
self.mobile = True
|
||||
self.creating = True
|
||||
form = self.make_mobile_form(self.get_model_class())
|
||||
if self.request.method == 'POST':
|
||||
if self.validate_mobile_form(form):
|
||||
# let save_create_form() return alternate object if necessary
|
||||
obj = self.save_mobile_create_form(form)
|
||||
self.after_create(obj)
|
||||
self.flash_after_create(obj)
|
||||
return self.redirect_after_create(obj, mobile=True)
|
||||
return self.render_to_response('create', {'form': form}, mobile=True)
|
||||
|
||||
def save_create_form(self, form):
|
||||
uploads = self.normalize_uploads(form)
|
||||
self.before_create(form)
|
||||
|
@ -1044,19 +837,10 @@ class MasterView(View):
|
|||
self.request.session.flash("{} has been created: {}".format(
|
||||
self.get_model_title(), self.get_instance_title(obj)))
|
||||
|
||||
def save_mobile_create_form(self, form):
|
||||
self.before_create(form)
|
||||
with self.Session.no_autoflush:
|
||||
obj = self.objectify(form, self.form_deserialized)
|
||||
self.before_create_flush(obj, form)
|
||||
self.Session.add(obj)
|
||||
self.Session.flush()
|
||||
return obj
|
||||
|
||||
def redirect_after_create(self, instance, mobile=False):
|
||||
def redirect_after_create(self, instance, **kwargs):
|
||||
if self.populatable and self.should_populate(instance):
|
||||
return self.redirect(self.get_action_url('populate', instance, mobile=mobile))
|
||||
return self.redirect(self.get_action_url('view', instance, mobile=mobile))
|
||||
return self.redirect(self.get_action_url('populate', instance))
|
||||
return self.redirect(self.get_action_url('view', instance))
|
||||
|
||||
def should_populate(self, obj):
|
||||
return True
|
||||
|
@ -1249,8 +1033,8 @@ class MasterView(View):
|
|||
self.Session.flush()
|
||||
return cloned
|
||||
|
||||
def redirect_after_clone(self, instance, mobile=False):
|
||||
return self.redirect(self.get_action_url('view', instance, mobile=mobile))
|
||||
def redirect_after_clone(self, instance, **kwargs):
|
||||
return self.redirect(self.get_action_url('view', instance))
|
||||
|
||||
def touch(self):
|
||||
"""
|
||||
|
@ -1414,75 +1198,6 @@ class MasterView(View):
|
|||
versions.extend(query.all())
|
||||
return versions
|
||||
|
||||
def mobile_view(self):
|
||||
"""
|
||||
Mobile view for displaying a single object's details
|
||||
"""
|
||||
self.mobile = True
|
||||
self.viewing = True
|
||||
instance = self.get_instance()
|
||||
form = self.make_mobile_form(instance)
|
||||
|
||||
context = {
|
||||
'instance': instance,
|
||||
'instance_title': self.get_instance_title(instance),
|
||||
'instance_editable': self.editable_instance(instance),
|
||||
# 'instance_deletable': self.deletable_instance(instance),
|
||||
'form': form,
|
||||
}
|
||||
if self.has_rows:
|
||||
context['model_row_class'] = self.model_row_class
|
||||
context['grid'] = self.make_mobile_row_grid(instance=instance)
|
||||
return self.render_to_response('view', context, mobile=True)
|
||||
|
||||
def make_mobile_form(self, instance=None, factory=None, fields=None, schema=None, **kwargs):
|
||||
"""
|
||||
Creates a new mobile form for the given model class/instance.
|
||||
"""
|
||||
if factory is None:
|
||||
factory = self.get_mobile_form_factory()
|
||||
if fields is None:
|
||||
fields = self.get_mobile_form_fields()
|
||||
if schema is None:
|
||||
schema = self.make_mobile_form_schema()
|
||||
|
||||
if not self.creating:
|
||||
kwargs['model_instance'] = instance
|
||||
kwargs = self.make_mobile_form_kwargs(**kwargs)
|
||||
form = factory(fields, schema, **kwargs)
|
||||
self.configure_mobile_form(form)
|
||||
return form
|
||||
|
||||
def get_mobile_form_fields(self):
|
||||
if hasattr(self, 'mobile_form_fields'):
|
||||
return self.mobile_form_fields
|
||||
# TODO
|
||||
# raise NotImplementedError
|
||||
|
||||
def make_mobile_form_schema(self):
|
||||
if not self.model_class:
|
||||
# TODO
|
||||
raise NotImplementedError
|
||||
|
||||
def make_mobile_form_kwargs(self, **kwargs):
|
||||
"""
|
||||
Return a dictionary of kwargs to be passed to the factory when creating
|
||||
new mobile forms.
|
||||
"""
|
||||
defaults = {
|
||||
'request': self.request,
|
||||
'readonly': self.viewing,
|
||||
'model_class': getattr(self, 'model_class', None),
|
||||
'action_url': self.request.current_route_url(_query=None),
|
||||
}
|
||||
if self.creating:
|
||||
defaults['cancel_url'] = self.get_index_url(mobile=True)
|
||||
else:
|
||||
instance = kwargs['model_instance']
|
||||
defaults['cancel_url'] = self.get_action_url('view', instance, mobile=True)
|
||||
defaults.update(kwargs)
|
||||
return defaults
|
||||
|
||||
def configure_common_form(self, form):
|
||||
"""
|
||||
Configure the form in whatever way is deemed "common" - i.e. where
|
||||
|
@ -1491,6 +1206,8 @@ class MasterView(View):
|
|||
By default this removes the 'uuid' field (if present), sets any primary
|
||||
key fields to be readonly (if we have a :attr:`model_class` and are in
|
||||
edit mode), and sets labels as defined by the master class hierarchy.
|
||||
|
||||
TODO: this logic should be moved back into configure_form()
|
||||
"""
|
||||
form.remove_field('uuid')
|
||||
|
||||
|
@ -1516,62 +1233,29 @@ class MasterView(View):
|
|||
# is the safer option and would help prevent unwanted mistakes
|
||||
form.set_default('local_only', True)
|
||||
|
||||
def configure_mobile_form(self, form):
|
||||
"""
|
||||
Configure the main "mobile" form for the view's data model.
|
||||
"""
|
||||
self.configure_common_form(form)
|
||||
|
||||
def validate_mobile_form(self, form):
|
||||
if form.validate(newstyle=True):
|
||||
# TODO: deprecate / remove self.form_deserialized
|
||||
self.form_deserialized = form.validated
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def make_mobile_row_form(self, instance=None, factory=None, fields=None, schema=None, **kwargs):
|
||||
"""
|
||||
Creates a new mobile form for the given model class/instance.
|
||||
"""
|
||||
if factory is None:
|
||||
factory = self.get_mobile_row_form_factory()
|
||||
if fields is None:
|
||||
fields = self.get_mobile_row_form_fields()
|
||||
if schema is None:
|
||||
schema = self.make_mobile_row_form_schema()
|
||||
|
||||
if not self.creating:
|
||||
kwargs['model_instance'] = instance
|
||||
kwargs = self.make_mobile_row_form_kwargs(**kwargs)
|
||||
form = factory(fields, schema, **kwargs)
|
||||
self.configure_mobile_row_form(form)
|
||||
return form
|
||||
|
||||
def make_quick_row_form(self, instance=None, factory=None, fields=None, schema=None, mobile=False, **kwargs):
|
||||
def make_quick_row_form(self, instance=None, factory=None, fields=None, schema=None, **kwargs):
|
||||
"""
|
||||
Creates a "quick" form for adding a new row to the given instance.
|
||||
"""
|
||||
if factory is None:
|
||||
factory = self.get_quick_row_form_factory(mobile=mobile)
|
||||
factory = self.get_quick_row_form_factory()
|
||||
if fields is None:
|
||||
fields = self.get_quick_row_form_fields(mobile=mobile)
|
||||
fields = self.get_quick_row_form_fields()
|
||||
if schema is None:
|
||||
schema = self.make_quick_row_form_schema(mobile=mobile)
|
||||
schema = self.make_quick_row_form_schema()
|
||||
|
||||
kwargs['mobile'] = mobile
|
||||
kwargs = self.make_quick_row_form_kwargs(**kwargs)
|
||||
form = factory(fields, schema, **kwargs)
|
||||
self.configure_quick_row_form(form, mobile=mobile)
|
||||
self.configure_quick_row_form(form)
|
||||
return form
|
||||
|
||||
def get_quick_row_form_factory(self, mobile=False):
|
||||
def get_quick_row_form_factory(self, **kwargs):
|
||||
return forms.Form
|
||||
|
||||
def get_quick_row_form_fields(self, mobile=False):
|
||||
def get_quick_row_form_fields(self, **kwargs):
|
||||
pass
|
||||
|
||||
def make_quick_row_form_schema(self, mobile=False):
|
||||
def make_quick_row_form_schema(self, **kwargs):
|
||||
schema = colander.MappingSchema()
|
||||
schema.add(colander.SchemaNode(colander.String(), name='quick_entry'))
|
||||
return schema
|
||||
|
@ -1585,102 +1269,12 @@ class MasterView(View):
|
|||
defaults.update(kwargs)
|
||||
return defaults
|
||||
|
||||
def configure_quick_row_form(self, form, mobile=False):
|
||||
def configure_quick_row_form(self, form, **kwargs):
|
||||
pass
|
||||
|
||||
def get_mobile_row_form_fields(self):
|
||||
if hasattr(self, 'mobile_row_form_fields'):
|
||||
return self.mobile_row_form_fields
|
||||
# TODO
|
||||
# raise NotImplementedError
|
||||
|
||||
def make_mobile_row_form_schema(self):
|
||||
if not self.model_row_class:
|
||||
# TODO
|
||||
raise NotImplementedError
|
||||
|
||||
def make_mobile_row_form_kwargs(self, **kwargs):
|
||||
"""
|
||||
Return a dictionary of kwargs to be passed to the factory when creating
|
||||
new mobile row forms.
|
||||
"""
|
||||
defaults = {
|
||||
'request': self.request,
|
||||
'mobile': True,
|
||||
'readonly': self.viewing,
|
||||
'model_class': getattr(self, 'model_row_class', None),
|
||||
'action_url': self.request.current_route_url(_query=None),
|
||||
}
|
||||
if self.creating:
|
||||
defaults['cancel_url'] = self.request.get_referrer()
|
||||
else:
|
||||
instance = kwargs['model_instance']
|
||||
defaults['cancel_url'] = self.get_row_action_url('view', instance, mobile=True)
|
||||
defaults.update(kwargs)
|
||||
return defaults
|
||||
|
||||
def configure_mobile_row_form(self, form):
|
||||
"""
|
||||
Configure the mobile row form.
|
||||
"""
|
||||
# TODO: is any of this stuff from configure_form() needed?
|
||||
# if self.editing:
|
||||
# model_class = self.get_model_class(error=False)
|
||||
# if model_class:
|
||||
# mapper = orm.class_mapper(model_class)
|
||||
# for key in mapper.primary_key:
|
||||
# for field in form.fields:
|
||||
# if field == key.name:
|
||||
# form.set_readonly(field)
|
||||
# break
|
||||
# form.remove_field('uuid')
|
||||
|
||||
self.set_row_labels(form)
|
||||
|
||||
def validate_mobile_row_form(self, form):
|
||||
controls = self.request.POST.items()
|
||||
try:
|
||||
self.form_deserialized = form.validate(controls)
|
||||
except deform.ValidationFailure:
|
||||
return False
|
||||
return True
|
||||
|
||||
def validate_quick_row_form(self, form):
|
||||
return form.validate(newstyle=True)
|
||||
|
||||
def get_mobile_row_data(self, parent):
|
||||
query = self.get_row_data(parent)
|
||||
return self.sort_mobile_row_data(query)
|
||||
|
||||
def sort_mobile_row_data(self, query):
|
||||
return query
|
||||
|
||||
def mobile_row_route_url(self, route_name, **kwargs):
|
||||
route_name = 'mobile.{}.{}_row'.format(self.get_route_prefix(), route_name)
|
||||
return self.request.route_url(route_name, **kwargs)
|
||||
|
||||
def mobile_view_row(self):
|
||||
"""
|
||||
Mobile view for row items
|
||||
"""
|
||||
self.mobile = True
|
||||
self.viewing = True
|
||||
row = self.get_row_instance()
|
||||
parent = self.get_parent(row)
|
||||
form = self.make_mobile_row_form(row)
|
||||
context = {
|
||||
'row': row,
|
||||
'parent_instance': parent,
|
||||
'parent_title': self.get_instance_title(parent),
|
||||
'parent_url': self.get_action_url('view', parent, mobile=True),
|
||||
'instance': row,
|
||||
'instance_title': self.get_row_instance_title(row),
|
||||
'instance_editable': self.row_editable(row),
|
||||
'parent_model_title': self.get_model_title(),
|
||||
'form': form,
|
||||
}
|
||||
return self.render_to_response('view_row', context, mobile=True)
|
||||
|
||||
def make_default_row_grid_tools(self, obj):
|
||||
if self.rows_creatable:
|
||||
link = tags.link_to("Create a new {}".format(self.get_row_model_title()),
|
||||
|
@ -1851,61 +1445,16 @@ class MasterView(View):
|
|||
context['dform'] = form.make_deform_form()
|
||||
return self.render_to_response('edit', context)
|
||||
|
||||
def mobile_edit(self):
|
||||
"""
|
||||
Mobile view for editing an existing model record.
|
||||
"""
|
||||
self.mobile = True
|
||||
self.editing = True
|
||||
obj = self.get_instance()
|
||||
|
||||
if not self.editable_instance(obj):
|
||||
msg = "Edit is not permitted for {}: {}".format(
|
||||
self.get_model_title(),
|
||||
self.get_instance_title(obj))
|
||||
self.request.session.flash(msg, 'error')
|
||||
return self.redirect(self.get_action_url('view', obj))
|
||||
|
||||
form = self.make_mobile_form(obj)
|
||||
|
||||
if self.request.method == 'POST':
|
||||
if self.validate_mobile_form(form):
|
||||
|
||||
# note that save_form() may return alternate object
|
||||
obj = self.save_mobile_edit_form(form)
|
||||
|
||||
msg = "{} has been updated: {}".format(
|
||||
self.get_model_title(),
|
||||
self.get_instance_title(obj))
|
||||
self.request.session.flash(msg)
|
||||
return self.redirect_after_edit(obj, mobile=True)
|
||||
|
||||
context = {
|
||||
'instance': obj,
|
||||
'instance_title': self.get_instance_title(obj),
|
||||
'instance_deletable': self.deletable_instance(obj),
|
||||
'instance_url': self.get_action_url('view', obj, mobile=True),
|
||||
'form': form,
|
||||
}
|
||||
if hasattr(form, 'make_deform_form'):
|
||||
context['dform'] = form.make_deform_form()
|
||||
return self.render_to_response('edit', context, mobile=True)
|
||||
|
||||
def save_edit_form(self, form):
|
||||
if not self.mobile:
|
||||
uploads = self.normalize_uploads(form)
|
||||
uploads = self.normalize_uploads(form)
|
||||
obj = self.objectify(form)
|
||||
if not self.mobile:
|
||||
self.process_uploads(obj, form, uploads)
|
||||
self.process_uploads(obj, form, uploads)
|
||||
self.after_edit(obj)
|
||||
self.Session.flush()
|
||||
return obj
|
||||
|
||||
def save_mobile_edit_form(self, form):
|
||||
return self.save_edit_form(form)
|
||||
|
||||
def redirect_after_edit(self, instance, mobile=False):
|
||||
return self.redirect(self.get_action_url('view', instance, mobile=mobile))
|
||||
def redirect_after_edit(self, instance, **kwargs):
|
||||
return self.redirect(self.get_action_url('view', instance))
|
||||
|
||||
def delete(self):
|
||||
"""
|
||||
|
@ -2350,13 +1899,11 @@ class MasterView(View):
|
|||
"""
|
||||
return getattr(cls, 'permission_prefix', cls.get_route_prefix())
|
||||
|
||||
def get_index_url(self, mobile=False, **kwargs):
|
||||
def get_index_url(self, **kwargs):
|
||||
"""
|
||||
Returns the master view's index URL.
|
||||
"""
|
||||
route = self.get_route_prefix()
|
||||
if mobile:
|
||||
route = 'mobile.{}'.format(route)
|
||||
return self.request.route_url(route, **kwargs)
|
||||
|
||||
@classmethod
|
||||
|
@ -2366,15 +1913,13 @@ class MasterView(View):
|
|||
"""
|
||||
return getattr(cls, 'index_title', cls.get_model_title_plural())
|
||||
|
||||
def get_action_url(self, action, instance, mobile=False, **kwargs):
|
||||
def get_action_url(self, action, instance, **kwargs):
|
||||
"""
|
||||
Generate a URL for the given action on the given instance
|
||||
"""
|
||||
kw = self.get_action_route_kwargs(instance)
|
||||
kw.update(kwargs)
|
||||
route_prefix = self.get_route_prefix()
|
||||
if mobile:
|
||||
route_prefix = 'mobile.{}'.format(route_prefix)
|
||||
return self.request.route_url('{}.{}'.format(route_prefix, action), **kw)
|
||||
|
||||
def get_help_url(self):
|
||||
|
@ -2394,7 +1939,7 @@ class MasterView(View):
|
|||
|
||||
return global_help_url(self.rattail_config)
|
||||
|
||||
def render_to_response(self, template, data, mobile=False):
|
||||
def render_to_response(self, template, data, **kwargs):
|
||||
"""
|
||||
Return a response with the given template rendered with the given data.
|
||||
Note that ``template`` must only be a "key" (e.g. 'index' or 'view').
|
||||
|
@ -2405,13 +1950,12 @@ class MasterView(View):
|
|||
context = {
|
||||
'master': self,
|
||||
'use_buefy': self.get_use_buefy(),
|
||||
'mobile': mobile,
|
||||
'model_title': self.get_model_title(),
|
||||
'model_title_plural': self.get_model_title_plural(),
|
||||
'route_prefix': self.get_route_prefix(),
|
||||
'permission_prefix': self.get_permission_prefix(),
|
||||
'index_title': self.get_index_title(),
|
||||
'index_url': self.get_index_url(mobile=mobile),
|
||||
'index_url': self.get_index_url(),
|
||||
'action_url': self.get_action_url,
|
||||
'grid_index': self.grid_index,
|
||||
'help_url': self.get_help_url(),
|
||||
|
@ -2430,34 +1974,20 @@ class MasterView(View):
|
|||
context['row_model_title_plural'] = self.get_row_model_title_plural()
|
||||
context['row_action_url'] = self.get_row_action_url
|
||||
|
||||
if mobile and self.viewing and self.mobile_rows_quickable:
|
||||
|
||||
# quick row does *not* mimic keyboard wedge by default, but can
|
||||
context['quick_row_keyboard_wedge'] = False
|
||||
|
||||
# quick row does *not* use autocomplete by default, but can
|
||||
context['quick_row_autocomplete'] = False
|
||||
context['quick_row_autocomplete_url'] = '#'
|
||||
|
||||
context.update(data)
|
||||
context.update(self.template_kwargs(**context))
|
||||
if hasattr(self, 'template_kwargs_{}'.format(template)):
|
||||
context.update(getattr(self, 'template_kwargs_{}'.format(template))(**context))
|
||||
if mobile and hasattr(self, 'mobile_template_kwargs_{}'.format(template)):
|
||||
context.update(getattr(self, 'mobile_template_kwargs_{}'.format(template))(**context))
|
||||
|
||||
# First try the template path most specific to the view.
|
||||
if mobile:
|
||||
mako_path = '/mobile{}/{}.mako'.format(self.get_template_prefix(), template)
|
||||
else:
|
||||
mako_path = '{}/{}.mako'.format(self.get_template_prefix(), template)
|
||||
mako_path = '{}/{}.mako'.format(self.get_template_prefix(), template)
|
||||
try:
|
||||
return render_to_response(mako_path, context, request=self.request)
|
||||
|
||||
except IOError:
|
||||
|
||||
# Failing that, try one or more fallback templates.
|
||||
for fallback in self.get_fallback_templates(template, mobile=mobile):
|
||||
for fallback in self.get_fallback_templates(template):
|
||||
try:
|
||||
return render_to_response(fallback, context, request=self.request)
|
||||
except IOError:
|
||||
|
@ -2504,9 +2034,7 @@ class MasterView(View):
|
|||
return render('{}/{}.mako'.format(self.get_template_prefix(), template),
|
||||
context, request=self.request)
|
||||
|
||||
def get_fallback_templates(self, template, mobile=False):
|
||||
if mobile:
|
||||
return ['/mobile/master/{}.mako'.format(template)]
|
||||
def get_fallback_templates(self, template, **kwargs):
|
||||
return ['/master/{}.mako'.format(template)]
|
||||
|
||||
def get_default_engine_dbkey(self):
|
||||
|
@ -3736,14 +3264,6 @@ class MasterView(View):
|
|||
"""
|
||||
return getattr(cls, 'form_factory', forms.Form)
|
||||
|
||||
@classmethod
|
||||
def get_mobile_form_factory(cls):
|
||||
"""
|
||||
Returns the factory or class which is to be used when creating new
|
||||
mobile forms.
|
||||
"""
|
||||
return getattr(cls, 'mobile_form_factory', forms.Form)
|
||||
|
||||
@classmethod
|
||||
def get_row_form_factory(cls):
|
||||
"""
|
||||
|
@ -3752,14 +3272,6 @@ class MasterView(View):
|
|||
"""
|
||||
return getattr(cls, 'row_form_factory', forms.Form)
|
||||
|
||||
@classmethod
|
||||
def get_mobile_row_form_factory(cls):
|
||||
"""
|
||||
Returns the factory or class which is to be used when creating new
|
||||
mobile row forms.
|
||||
"""
|
||||
return getattr(cls, 'mobile_row_form_factory', forms.Form)
|
||||
|
||||
def download_path(self, obj, filename):
|
||||
"""
|
||||
Should return absolute path on disk, for the given object and filename.
|
||||
|
@ -4055,49 +3567,8 @@ class MasterView(View):
|
|||
def after_create_row(self, row_object):
|
||||
pass
|
||||
|
||||
def redirect_after_create_row(self, row, mobile=False):
|
||||
return self.redirect(self.get_row_action_url('view', row, mobile=mobile))
|
||||
|
||||
def mobile_create_row(self):
|
||||
"""
|
||||
Mobile view for creating a new row object
|
||||
"""
|
||||
self.mobile = True
|
||||
self.creating = True
|
||||
parent = self.get_instance()
|
||||
instance_url = self.get_action_url('view', parent, mobile=True)
|
||||
form = self.make_mobile_row_form(self.model_row_class, cancel_url=instance_url)
|
||||
if self.request.method == 'POST':
|
||||
if self.validate_mobile_row_form(form):
|
||||
self.before_create_row(form)
|
||||
# let save() return alternate object if necessary
|
||||
obj = self.save_create_row_form(form)
|
||||
self.after_create_row(obj)
|
||||
return self.redirect_after_create_row(obj, mobile=True)
|
||||
return self.render_to_response('create_row', {
|
||||
'instance_title': self.get_instance_title(parent),
|
||||
'instance_url': instance_url,
|
||||
'parent_object': parent,
|
||||
'form': form,
|
||||
}, mobile=True)
|
||||
|
||||
def mobile_quick_row(self):
|
||||
"""
|
||||
Mobile view for "quick" location or creation of a row object
|
||||
"""
|
||||
parent = self.get_instance()
|
||||
parent_url = self.get_action_url('view', parent, mobile=True)
|
||||
form = self.make_quick_row_form(self.model_row_class, mobile=True, cancel_url=parent_url)
|
||||
if self.request.method == 'POST':
|
||||
if self.validate_quick_row_form(form):
|
||||
row = self.save_quick_row_form(form)
|
||||
if not row:
|
||||
self.request.session.flash("Could not locate/create row for entry: "
|
||||
"{}".format(form.validated['quick_entry']),
|
||||
'error')
|
||||
return self.redirect(parent_url)
|
||||
return self.redirect_after_quick_row(row, mobile=True)
|
||||
return self.redirect(parent_url)
|
||||
def redirect_after_create_row(self, row, **kwargs):
|
||||
return self.redirect(self.get_row_action_url('view', row))
|
||||
|
||||
def save_quick_row_form(self, form):
|
||||
raise NotImplementedError("You must define `{}:{}.save_quick_row_form()` "
|
||||
|
@ -4105,8 +3576,8 @@ class MasterView(View):
|
|||
self.__class__.__module__,
|
||||
self.__class__.__name__))
|
||||
|
||||
def redirect_after_quick_row(self, row, mobile=False):
|
||||
return self.redirect(self.get_row_action_url('edit', row, mobile=mobile))
|
||||
def redirect_after_quick_row(self, row, **kwargs):
|
||||
return self.redirect(self.get_row_action_url('edit', row))
|
||||
|
||||
def view_row(self):
|
||||
"""
|
||||
|
@ -4182,34 +3653,6 @@ class MasterView(View):
|
|||
'dform': form.make_deform_form(),
|
||||
})
|
||||
|
||||
def mobile_edit_row(self):
|
||||
"""
|
||||
Mobile view for editing a row object
|
||||
"""
|
||||
self.mobile = True
|
||||
self.editing = True
|
||||
row = self.get_row_instance()
|
||||
instance_url = self.get_row_action_url('view', row, mobile=True)
|
||||
form = self.make_mobile_row_form(row)
|
||||
|
||||
if self.request.method == 'POST':
|
||||
if self.validate_mobile_row_form(form):
|
||||
self.save_edit_row_form(form)
|
||||
return self.redirect_after_edit_row(row, mobile=True)
|
||||
|
||||
parent = self.get_parent(row)
|
||||
return self.render_to_response('edit_row', {
|
||||
'row': row,
|
||||
'instance': row,
|
||||
'parent_instance': parent,
|
||||
'instance_title': self.get_row_instance_title(row),
|
||||
'instance_url': instance_url,
|
||||
'instance_deletable': self.row_deletable(row),
|
||||
'parent_title': self.get_instance_title(parent),
|
||||
'parent_url': self.get_action_url('view', parent, mobile=True),
|
||||
'form': form},
|
||||
mobile=True)
|
||||
|
||||
def save_edit_row_form(self, form):
|
||||
obj = self.objectify(form, self.form_deserialized)
|
||||
self.after_edit_row(obj)
|
||||
|
@ -4224,8 +3667,8 @@ class MasterView(View):
|
|||
Event hook, called just after an existing row object is saved.
|
||||
"""
|
||||
|
||||
def redirect_after_edit_row(self, row, mobile=False):
|
||||
return self.redirect(self.get_row_action_url('view', row, mobile=mobile))
|
||||
def redirect_after_edit_row(self, row, **kwargs):
|
||||
return self.redirect(self.get_row_action_url('view', row))
|
||||
|
||||
def row_deletable(self, row):
|
||||
"""
|
||||
|
@ -4252,22 +3695,6 @@ class MasterView(View):
|
|||
self.delete_row_object(row)
|
||||
return self.redirect(self.get_action_url('view', self.get_parent(row)))
|
||||
|
||||
def mobile_delete_row(self):
|
||||
"""
|
||||
Mobile view which can "delete" a sub-row from the parent.
|
||||
"""
|
||||
if self.request.method == 'POST':
|
||||
parent = self.get_instance()
|
||||
row = self.get_row_instance()
|
||||
if self.get_parent(row) is not parent:
|
||||
raise RuntimeError("Can only delete rows which belong to current object")
|
||||
|
||||
self.delete_row_object(row)
|
||||
return self.redirect(self.get_action_url('view', parent, mobile=True))
|
||||
|
||||
self.session.flash("Must POST to delete a row", 'error')
|
||||
return self.redirect(self.request.get_referrer(mobile=True))
|
||||
|
||||
def get_parent(self, row):
|
||||
raise NotImplementedError
|
||||
|
||||
|
@ -4357,13 +3784,11 @@ class MasterView(View):
|
|||
return True
|
||||
return False
|
||||
|
||||
def get_row_action_url(self, action, row, mobile=False):
|
||||
def get_row_action_url(self, action, row, **kwargs):
|
||||
"""
|
||||
Generate a URL for the given action on the given row.
|
||||
"""
|
||||
route_name = '{}.{}_row'.format(self.get_route_prefix(), action)
|
||||
if mobile:
|
||||
route_name = 'mobile.{}'.format(route_name)
|
||||
return self.request.route_url(route_name, **self.get_row_action_route_kwargs(row))
|
||||
|
||||
def get_row_action_route_kwargs(self, row):
|
||||
|
@ -4426,7 +3851,6 @@ class MasterView(View):
|
|||
model_title_plural = cls.get_model_title_plural()
|
||||
if cls.has_rows:
|
||||
row_model_title = cls.get_row_model_title()
|
||||
legacy_mobile = cls.legacy_mobile_enabled(rattail_config)
|
||||
|
||||
config.add_tailbone_permission_group(permission_prefix, model_title_plural, overwrite=False)
|
||||
|
||||
|
@ -4437,10 +3861,6 @@ class MasterView(View):
|
|||
config.add_route(route_prefix, '{}/'.format(url_prefix))
|
||||
config.add_view(cls, attr='index', route_name=route_prefix,
|
||||
permission='{}.list'.format(permission_prefix))
|
||||
if legacy_mobile and cls.supports_mobile:
|
||||
config.add_route('mobile.{}'.format(route_prefix), '/mobile{}/'.format(url_prefix))
|
||||
config.add_view(cls, attr='mobile_index', route_name='mobile.{}'.format(route_prefix),
|
||||
permission='{}.list'.format(permission_prefix))
|
||||
|
||||
# download results
|
||||
# this is the "new" more flexible approach, but we only want to
|
||||
|
@ -4495,17 +3915,12 @@ class MasterView(View):
|
|||
permission='{}.quickie'.format(permission_prefix))
|
||||
|
||||
# create
|
||||
if cls.creatable or (legacy_mobile and cls.mobile_creatable):
|
||||
if cls.creatable:
|
||||
config.add_tailbone_permission(permission_prefix, '{}.create'.format(permission_prefix),
|
||||
"Create new {}".format(model_title))
|
||||
if cls.creatable:
|
||||
config.add_route('{}.create'.format(route_prefix), '{}/new'.format(url_prefix))
|
||||
config.add_view(cls, attr='create', route_name='{}.create'.format(route_prefix),
|
||||
permission='{}.create'.format(permission_prefix))
|
||||
if legacy_mobile and cls.mobile_creatable:
|
||||
config.add_route('mobile.{}.create'.format(route_prefix), '/mobile{}/new'.format(url_prefix))
|
||||
config.add_view(cls, attr='mobile_create', route_name='mobile.{}.create'.format(route_prefix),
|
||||
permission='{}.create'.format(permission_prefix))
|
||||
|
||||
# populate new object
|
||||
if cls.populatable:
|
||||
|
@ -4572,10 +3987,6 @@ class MasterView(View):
|
|||
config.add_route('{}.view'.format(route_prefix), instance_url_prefix)
|
||||
config.add_view(cls, attr='view', route_name='{}.view'.format(route_prefix),
|
||||
permission='{}.view'.format(permission_prefix))
|
||||
if legacy_mobile and cls.supports_mobile:
|
||||
config.add_route('mobile.{}.view'.format(route_prefix), '/mobile{}'.format(instance_url_prefix))
|
||||
config.add_view(cls, attr='mobile_view', route_name='mobile.{}.view'.format(route_prefix),
|
||||
permission='{}.view'.format(permission_prefix))
|
||||
|
||||
# version history
|
||||
if cls.has_versions and rattail_config and rattail_config.versioning_enabled():
|
||||
|
@ -4625,30 +4036,20 @@ class MasterView(View):
|
|||
"Download associated data for {}".format(model_title))
|
||||
|
||||
# edit
|
||||
if cls.editable or (legacy_mobile and cls.mobile_editable):
|
||||
if cls.editable:
|
||||
config.add_tailbone_permission(permission_prefix, '{}.edit'.format(permission_prefix),
|
||||
"Edit {}".format(model_title))
|
||||
if cls.editable:
|
||||
config.add_route('{}.edit'.format(route_prefix), '{}/edit'.format(instance_url_prefix))
|
||||
config.add_view(cls, attr='edit', route_name='{}.edit'.format(route_prefix),
|
||||
permission='{}.edit'.format(permission_prefix))
|
||||
if legacy_mobile and cls.mobile_editable:
|
||||
config.add_route('mobile.{}.edit'.format(route_prefix), '/mobile{}/edit'.format(instance_url_prefix))
|
||||
config.add_view(cls, attr='mobile_edit', route_name='mobile.{}.edit'.format(route_prefix),
|
||||
permission='{}.edit'.format(permission_prefix))
|
||||
|
||||
# execute
|
||||
if cls.executable or (legacy_mobile and cls.mobile_executable):
|
||||
if cls.executable:
|
||||
config.add_tailbone_permission(permission_prefix, '{}.execute'.format(permission_prefix),
|
||||
"Execute {}".format(model_title))
|
||||
if cls.executable:
|
||||
config.add_route('{}.execute'.format(route_prefix), '{}/execute'.format(instance_url_prefix))
|
||||
config.add_view(cls, attr='execute', route_name='{}.execute'.format(route_prefix),
|
||||
permission='{}.execute'.format(permission_prefix))
|
||||
if legacy_mobile and cls.mobile_executable:
|
||||
config.add_route('mobile.{}.execute'.format(route_prefix), '/mobile{}/execute'.format(instance_url_prefix))
|
||||
config.add_view(cls, attr='mobile_execute', route_name='mobile.{}.execute'.format(route_prefix),
|
||||
permission='{}.execute'.format(permission_prefix))
|
||||
|
||||
# delete
|
||||
if cls.deletable:
|
||||
|
@ -4683,21 +4084,12 @@ class MasterView(View):
|
|||
|
||||
# create row
|
||||
if cls.has_rows:
|
||||
if cls.rows_creatable or (legacy_mobile and cls.mobile_rows_creatable):
|
||||
if cls.rows_creatable:
|
||||
config.add_tailbone_permission(permission_prefix, '{}.create_row'.format(permission_prefix),
|
||||
"Create new {} rows".format(model_title))
|
||||
if cls.rows_creatable:
|
||||
config.add_route('{}.create_row'.format(route_prefix), '{}/new-row'.format(instance_url_prefix))
|
||||
config.add_view(cls, attr='create_row', route_name='{}.create_row'.format(route_prefix),
|
||||
permission='{}.create_row'.format(permission_prefix))
|
||||
if legacy_mobile and cls.mobile_rows_creatable:
|
||||
config.add_route('mobile.{}.create_row'.format(route_prefix), '/mobile{}/new-row'.format(instance_url_prefix))
|
||||
config.add_view(cls, attr='mobile_create_row', route_name='mobile.{}.create_row'.format(route_prefix),
|
||||
permission='{}.create_row'.format(permission_prefix))
|
||||
if cls.mobile_rows_quickable:
|
||||
config.add_route('mobile.{}.quick_row'.format(route_prefix), '/mobile{}/quick-row'.format(instance_url_prefix))
|
||||
config.add_view(cls, attr='mobile_quick_row', route_name='mobile.{}.quick_row'.format(route_prefix),
|
||||
permission='{}.create_row'.format(permission_prefix))
|
||||
|
||||
# view row
|
||||
if cls.has_rows:
|
||||
|
@ -4705,35 +4097,21 @@ class MasterView(View):
|
|||
config.add_route('{}.view_row'.format(route_prefix), '{}/{{uuid}}/rows/{{row_uuid}}'.format(url_prefix))
|
||||
config.add_view(cls, attr='view_row', route_name='{}.view_row'.format(route_prefix),
|
||||
permission='{}.view'.format(permission_prefix))
|
||||
if legacy_mobile and cls.mobile_rows_viewable:
|
||||
config.add_route('mobile.{}.view_row'.format(route_prefix), '/mobile{}/{{uuid}}/rows/{{row_uuid}}'.format(url_prefix))
|
||||
config.add_view(cls, attr='mobile_view_row', route_name='mobile.{}.view_row'.format(route_prefix),
|
||||
permission='{}.view'.format(permission_prefix))
|
||||
|
||||
# edit row
|
||||
if cls.has_rows:
|
||||
if cls.rows_editable or (legacy_mobile and cls.mobile_rows_editable):
|
||||
if cls.rows_editable:
|
||||
config.add_tailbone_permission(permission_prefix, '{}.edit_row'.format(permission_prefix),
|
||||
"Edit individual {} rows".format(model_title))
|
||||
if cls.rows_editable:
|
||||
config.add_route('{}.edit_row'.format(route_prefix), '{}/{{uuid}}/rows/{{row_uuid}}/edit'.format(url_prefix))
|
||||
config.add_view(cls, attr='edit_row', route_name='{}.edit_row'.format(route_prefix),
|
||||
permission='{}.edit_row'.format(permission_prefix))
|
||||
if legacy_mobile and cls.mobile_rows_editable:
|
||||
config.add_route('mobile.{}.edit_row'.format(route_prefix), '/mobile{}/{{uuid}}/rows/{{row_uuid}}/edit'.format(url_prefix))
|
||||
config.add_view(cls, attr='mobile_edit_row', route_name='mobile.{}.edit_row'.format(route_prefix),
|
||||
permission='{}.edit_row'.format(permission_prefix))
|
||||
|
||||
# delete row
|
||||
if cls.has_rows:
|
||||
if cls.rows_deletable or (legacy_mobile and cls.mobile_rows_deletable):
|
||||
if cls.rows_deletable:
|
||||
config.add_tailbone_permission(permission_prefix, '{}.delete_row'.format(permission_prefix),
|
||||
"Delete individual {} rows".format(model_title))
|
||||
if cls.rows_deletable:
|
||||
config.add_route('{}.delete_row'.format(route_prefix), '{}/{{uuid}}/rows/{{row_uuid}}/delete'.format(url_prefix))
|
||||
config.add_view(cls, attr='delete_row', route_name='{}.delete_row'.format(route_prefix),
|
||||
permission='{}.delete_row'.format(permission_prefix))
|
||||
if legacy_mobile and cls.mobile_rows_deletable:
|
||||
config.add_route('mobile.{}.delete_row'.format(route_prefix), '/mobile{}/{{uuid}}/rows/{{row_uuid}}/delete'.format(url_prefix))
|
||||
config.add_view(cls, attr='mobile_delete_row', route_name='mobile.{}.delete_row'.format(route_prefix),
|
||||
permission='{}.delete_row'.format(permission_prefix))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue