Add initial support for mobile receiving views

This commit is contained in:
Lance Edgar 2017-05-24 00:04:56 -05:00
parent d68bf6b012
commit 5eca2347d5
11 changed files with 712 additions and 14 deletions

View file

@ -60,6 +60,7 @@ class MasterView(View):
downloadable = False
supports_mobile = False
mobile_creatable = False
listing = False
creating = False
@ -87,6 +88,8 @@ class MasterView(View):
rows_deletable_speedbump = False
rows_bulk_deletable = False
mobile_rows_viewable = False
@property
def Session(self):
"""
@ -238,6 +241,24 @@ class MasterView(View):
return ListItemRenderer
def mobile_row_listitem_renderer(self):
"""
Must return a FormAlchemy field renderer callable for the mobile row
grid's list item field.
"""
master = self
class ListItemRenderer(fa.FieldRenderer):
def render_readonly(self, **kwargs):
return master.render_mobile_row_listitem(self.raw_value, **kwargs)
return ListItemRenderer
def render_mobile_row_listitem(self, row, **kwargs):
if row is None:
return ''
return tags.link_to(row, '#')
def create(self):
"""
View for creating a new model record.
@ -316,6 +337,9 @@ class MasterView(View):
# '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, **kwargs):
@ -331,6 +355,25 @@ class MasterView(View):
form.readonly = self.viewing
return form
def preconfigure_mobile_row_fieldset(self, fieldset):
self._preconfigure_row_fieldset(fieldset)
def configure_mobile_row_fieldset(self, fieldset):
self.configure_row_fieldset(fieldset)
def make_mobile_row_form(self, row, **kwargs):
"""
Make a form for use with mobile CRUD views, for the given row object.
"""
fieldset = self.make_fieldset(row)
self.preconfigure_mobile_row_fieldset(fieldset)
self.configure_mobile_row_fieldset(fieldset)
kwargs.setdefault('action_url', self.request.current_route_url(_query=None))
factory = kwargs.pop('factory', forms.AlchemyForm)
form = factory(self.request, fieldset, **kwargs)
form.readonly = self.viewing
return form
def preconfigure_mobile_fieldset(self, fieldset):
self._preconfigure_fieldset(fieldset)
@ -340,6 +383,66 @@ class MasterView(View):
"""
self.configure_fieldset(fieldset)
def get_mobile_row_data(self, parent):
return self.get_row_data(parent)
def make_mobile_row_grid_kwargs(self, **kwargs):
defaults = {
'pageable': True,
'sortable': True,
}
defaults.update(kwargs)
return defaults
def make_mobile_row_grid(self, **kwargs):
"""
Make a new (configured) rows grid instance for mobile.
"""
parent = kwargs.pop('instance', self.get_instance())
kwargs['instance'] = parent
kwargs['data'] = self.get_mobile_row_data(parent)
kwargs['key'] = 'mobile.{}.{}'.format(self.get_grid_key(), self.request.matchdict[self.get_model_key()])
kwargs.setdefault('request', self.request)
kwargs.setdefault('model_class', self.model_row_class)
kwargs = self.make_mobile_row_grid_kwargs(**kwargs)
factory = self.get_grid_factory()
grid = factory(**kwargs)
self.configure_mobile_row_grid(grid)
grid.load_settings()
return grid
def mobile_row_listitem_field(self):
"""
Must return a FormAlchemy field to be appended to row grid, or ``None``
if none is desired.
"""
return fa.Field('listitem', value=lambda obj: obj,
renderer=self.mobile_row_listitem_renderer())
def configure_mobile_row_grid(self, grid):
listitem = self.mobile_row_listitem_field()
if listitem:
grid.append(listitem)
grid.configure(include=[grid.listitem])
else:
grid.configure()
def mobile_view_row(self):
"""
Mobile view for row items
"""
self.viewing = True
row = self.get_row_instance()
form = self.make_mobile_row_form(row)
context = {
'row': row,
'instance': row,
'instance_title': self.get_row_instance_title(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()),
@ -1476,12 +1579,17 @@ class MasterView(View):
permission='{}.list'.format(permission_prefix))
# create
if cls.creatable or cls.mobile_creatable:
config.add_tailbone_permission(permission_prefix, '{}.create'.format(permission_prefix),
"Create new {}".format(model_title))
if cls.creatable:
config.add_route('{0}.create'.format(route_prefix), '{0}/new'.format(url_prefix))
config.add_view(cls, attr='create', route_name='{0}.create'.format(route_prefix),
permission='{0}.create'.format(permission_prefix))
config.add_tailbone_permission(permission_prefix, '{0}.create'.format(permission_prefix),
"Create new {0}".format(model_title))
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 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))
# bulk delete
if cls.bulk_deletable:
@ -1556,10 +1664,15 @@ class MasterView(View):
"Create new {} rows".format(model_title))
# view row
if cls.has_rows and cls.rows_viewable:
config.add_route('{}.view'.format(row_route_prefix), '{}/{{uuid}}'.format(row_url_prefix))
config.add_view(cls, attr='view_row', route_name='{}.view'.format(row_route_prefix),
permission='{}.view'.format(permission_prefix))
if cls.has_rows:
if cls.rows_viewable:
config.add_route('{}.view'.format(row_route_prefix), '{}/{{uuid}}'.format(row_url_prefix))
config.add_view(cls, attr='view_row', route_name='{}.view'.format(row_route_prefix),
permission='{}.view'.format(permission_prefix))
if cls.mobile_rows_viewable:
config.add_route('mobile.{}.view'.format(row_route_prefix), '/mobile{}/{{uuid}}'.format(row_url_prefix))
config.add_view(cls, attr='mobile_view_row', route_name='mobile.{}.view'.format(row_route_prefix),
permission='{}.view'.format(permission_prefix))
# edit row
if cls.has_rows and cls.rows_editable: