feat: refactor forms/grids/views/templates per wuttaweb compat

this starts to get things more aligned between wuttaweb and tailbone.
the use case in mind so far is for a wuttaweb view to be included in a
tailbone app.

form and grid classes now have some new methods to match wuttaweb, so
templates call the shared method names where possible.

templates can no longer assume they have tailbone-native master view,
form, grid etc. so must inspect context more closely in some cases.
This commit is contained in:
Lance Edgar 2024-08-15 14:34:20 -05:00
parent b53479f8e4
commit a6ce5eb21d
39 changed files with 1037 additions and 300 deletions
tailbone/grids

View file

@ -198,7 +198,8 @@ class Grid:
checkable=None, row_uuid_getter=None,
clicking_row_checks_box=False, click_handlers=None,
main_actions=[], more_actions=[], delete_speedbump=False,
ajax_data_url=None, component='tailbone-grid',
ajax_data_url=None,
vue_tagname=None,
expose_direct_link=False,
**kwargs):
@ -268,19 +269,63 @@ class Grid:
if ajax_data_url:
self.ajax_data_url = ajax_data_url
elif self.request:
self.ajax_data_url = self.request.current_route_url(_query=None)
self.ajax_data_url = self.request.path_url
else:
self.ajax_data_url = ''
self.component = component
# vue_tagname
self.vue_tagname = vue_tagname
if not self.vue_tagname and kwargs.get('component'):
warnings.warn("component kwarg is deprecated for Grid(); "
"please use vue_tagname param instead",
DeprecationWarning, stacklevel=2)
self.vue_tagname = kwargs['component']
if not self.vue_tagname:
self.vue_tagname = 'tailbone-grid'
self.expose_direct_link = expose_direct_link
self._whgrid_kwargs = kwargs
@property
def component_studly(self):
words = self.component.split('-')
def vue_component(self):
"""
String name for the Vue component, e.g. ``'TailboneGrid'``.
This is a generated value based on :attr:`vue_tagname`.
"""
words = self.vue_tagname.split('-')
return ''.join([word.capitalize() for word in words])
@property
def component(self):
"""
DEPRECATED - use :attr:`vue_tagname` instead.
"""
warnings.warn("Grid.component is deprecated; "
"please use vue_tagname instead",
DeprecationWarning, stacklevel=2)
return self.vue_tagname
@property
def component_studly(self):
"""
DEPRECATED - use :attr:`vue_component` instead.
"""
warnings.warn("Grid.component_studly is deprecated; "
"please use vue_component instead",
DeprecationWarning, stacklevel=2)
return self.vue_component
@property
def actions(self):
""" """
actions = []
if self.main_actions:
actions.extend(self.main_actions)
if self.more_actions:
actions.extend(self.more_actions)
return actions
def make_columns(self):
"""
Return a default list of columns, based on :attr:`model_class`.
@ -1334,6 +1379,21 @@ class Grid:
data = self.pager
return data
def render_vue_tag(self, master=None, **kwargs):
""" """
kwargs.setdefault('ref', 'grid')
kwargs.setdefault(':csrftoken', 'csrftoken')
if (master and master.deletable and master.has_perm('delete')
and master.delete_confirm == 'simple'):
kwargs.setdefault('@deleteActionClicked', 'deleteObject')
return HTML.tag(self.vue_tagname, **kwargs)
def render_vue_template(self, template='/grids/complete.mako', **context):
""" """
return self.render_complete(template=template, **context)
def render_complete(self, template='/grids/complete.mako', **kwargs):
"""
Render the grid, complete with filters. Note that this also
@ -1359,7 +1419,8 @@ class Grid:
context['request'] = self.request
context.setdefault('allow_save_defaults', True)
context.setdefault('view_click_handler', self.get_view_click_handler())
return render(template, context)
html = render(template, context)
return HTML.literal(html)
def render_buefy(self, **kwargs):
warnings.warn("Grid.render_buefy() is deprecated; "
@ -1575,6 +1636,10 @@ class Grid:
return True
return False
def get_vue_columns(self):
""" """
return self.get_table_columns()
def get_table_columns(self):
"""
Return a list of dicts representing all grid columns. Meant
@ -1600,11 +1665,19 @@ class Grid:
if hasattr(rowobj, 'uuid'):
return rowobj.uuid
def get_vue_data(self):
""" """
table_data = self.get_table_data()
return table_data['data']
def get_table_data(self):
"""
Returns a list of data rows for the grid, for use with
client-side JS table.
"""
if hasattr(self, '_table_data'):
return self._table_data
# filter / sort / paginate to get "visible" data
raw_data = self.make_visible_data()
data = []
@ -1704,7 +1777,8 @@ class Grid:
else:
results['total_items'] = count
return results
self._table_data = results
return self._table_data
def set_action_urls(self, row, rowobj, i):
"""