feat: inherit from wutta base class for Grid
This commit is contained in:
parent
f7641218cb
commit
2a0b6da2f9
23 changed files with 317 additions and 274 deletions
|
@ -38,7 +38,7 @@ from pyramid.renderers import render
|
|||
from webhelpers2.html import HTML, tags
|
||||
from paginate_sqlalchemy import SqlalchemyOrmPage
|
||||
|
||||
from wuttaweb.grids import GridAction as WuttaGridAction
|
||||
from wuttaweb.grids import Grid as WuttaGrid, GridAction as WuttaGridAction
|
||||
from . import filters as gridfilters
|
||||
from tailbone.db import Session
|
||||
from tailbone.util import raw_datetime
|
||||
|
@ -61,7 +61,7 @@ class FieldList(list):
|
|||
self.insert(i + 1, newfield)
|
||||
|
||||
|
||||
class Grid:
|
||||
class Grid(WuttaGrid):
|
||||
"""
|
||||
Core grid class. In sore need of documentation.
|
||||
|
||||
|
@ -186,32 +186,59 @@ class Grid:
|
|||
grid.row_uuid_getter = fake_uuid
|
||||
"""
|
||||
|
||||
def __init__(self, key, data, columns=None, width='auto', request=None,
|
||||
model_class=None, model_title=None, model_title_plural=None,
|
||||
enums={}, labels={}, assume_local_times=False, renderers={}, invisible=[],
|
||||
raw_renderers={},
|
||||
extra_row_class=None, linked_columns=[], url='#',
|
||||
joiners={}, filterable=False, filters={}, use_byte_string_filters=False,
|
||||
searchable={},
|
||||
sortable=False, sorters={}, default_sortkey=None, default_sortdir='asc',
|
||||
pageable=False, default_pagesize=None, default_page=1,
|
||||
checkboxes=False, checked=None, check_handler=None, check_all_handler=None,
|
||||
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,
|
||||
vue_tagname=None,
|
||||
expose_direct_link=False,
|
||||
**kwargs):
|
||||
def __init__(
|
||||
self,
|
||||
request,
|
||||
key=None,
|
||||
data=None,
|
||||
width='auto',
|
||||
model_title=None,
|
||||
model_title_plural=None,
|
||||
enums={},
|
||||
assume_local_times=False,
|
||||
invisible=[],
|
||||
raw_renderers={},
|
||||
extra_row_class=None,
|
||||
url='#',
|
||||
joiners={},
|
||||
filterable=False,
|
||||
filters={},
|
||||
use_byte_string_filters=False,
|
||||
searchable={},
|
||||
sortable=False,
|
||||
sorters={},
|
||||
default_sortkey=None,
|
||||
default_sortdir='asc',
|
||||
pageable=False,
|
||||
default_pagesize=None,
|
||||
default_page=1,
|
||||
checkboxes=False,
|
||||
checked=None,
|
||||
check_handler=None,
|
||||
check_all_handler=None,
|
||||
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,
|
||||
expose_direct_link=False,
|
||||
**kwargs,
|
||||
):
|
||||
if kwargs.get('component'):
|
||||
warnings.warn("component param is deprecated for Grid(); "
|
||||
"please use vue_tagname param instead",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
kwargs.setdefault('vue_tagname', kwargs.pop('component'))
|
||||
|
||||
self.key = key
|
||||
self.data = data
|
||||
self.columns = FieldList(columns) if columns is not None else None
|
||||
self.width = width
|
||||
self.request = request
|
||||
self.model_class = model_class
|
||||
if self.model_class and self.columns is None:
|
||||
self.columns = self.make_columns()
|
||||
# TODO: pretty sure this should go away?
|
||||
kwargs.setdefault('vue_tagname', 'tailbone-grid')
|
||||
|
||||
kwargs['key'] = key
|
||||
kwargs['data'] = data
|
||||
super().__init__(request, **kwargs)
|
||||
|
||||
self.model_title = model_title
|
||||
if not self.model_title and self.model_class and hasattr(self.model_class, 'get_model_title'):
|
||||
|
@ -224,15 +251,13 @@ class Grid:
|
|||
if not self.model_title_plural:
|
||||
self.model_title_plural = '{}s'.format(self.model_title)
|
||||
|
||||
self.width = width
|
||||
self.enums = enums or {}
|
||||
|
||||
self.labels = labels or {}
|
||||
self.assume_local_times = assume_local_times
|
||||
self.renderers = self.make_default_renderers(renderers or {})
|
||||
self.renderers = self.make_default_renderers(self.renderers)
|
||||
self.raw_renderers = raw_renderers or {}
|
||||
self.invisible = invisible or []
|
||||
self.extra_row_class = extra_row_class
|
||||
self.linked_columns = linked_columns or []
|
||||
self.url = url
|
||||
self.joiners = joiners or {}
|
||||
|
||||
|
@ -263,8 +288,6 @@ class Grid:
|
|||
|
||||
self.click_handlers = click_handlers or {}
|
||||
|
||||
self.main_actions = main_actions or []
|
||||
self.more_actions = more_actions or []
|
||||
self.delete_speedbump = delete_speedbump
|
||||
|
||||
if ajax_data_url:
|
||||
|
@ -274,29 +297,22 @@ class Grid:
|
|||
else:
|
||||
self.ajax_data_url = ''
|
||||
|
||||
# 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",
|
||||
self.main_actions = main_actions or []
|
||||
if self.main_actions:
|
||||
warnings.warn("main_actions param is deprecated for Grdi(); "
|
||||
"please use actions param instead",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
self.vue_tagname = kwargs['component']
|
||||
if not self.vue_tagname:
|
||||
self.vue_tagname = 'tailbone-grid'
|
||||
self.actions.extend(self.main_actions)
|
||||
self.more_actions = more_actions or []
|
||||
if self.more_actions:
|
||||
warnings.warn("more_actions param is deprecated for Grdi(); "
|
||||
"please use actions param instead",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
self.actions.extend(self.more_actions)
|
||||
|
||||
self.expose_direct_link = expose_direct_link
|
||||
self._whgrid_kwargs = kwargs
|
||||
|
||||
@property
|
||||
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):
|
||||
"""
|
||||
|
@ -317,34 +333,6 @@ class Grid:
|
|||
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`.
|
||||
"""
|
||||
if not self.model_class:
|
||||
raise ValueError("Must define model_class to use make_columns()")
|
||||
|
||||
mapper = orm.class_mapper(self.model_class)
|
||||
return [prop.key for prop in mapper.iterate_properties]
|
||||
|
||||
def remove(self, *keys):
|
||||
"""
|
||||
This *removes* some column(s) from the grid, altogether.
|
||||
"""
|
||||
for key in keys:
|
||||
if key in self.columns:
|
||||
self.columns.remove(key)
|
||||
|
||||
def hide_column(self, key):
|
||||
"""
|
||||
This *removes* a column from the grid, altogether.
|
||||
|
@ -377,9 +365,6 @@ class Grid:
|
|||
if key in self.invisible:
|
||||
self.invisible.remove(key)
|
||||
|
||||
def append(self, field):
|
||||
self.columns.append(field)
|
||||
|
||||
def insert_before(self, field, newfield):
|
||||
self.columns.insert_before(field, newfield)
|
||||
|
||||
|
@ -430,24 +415,22 @@ class Grid:
|
|||
self.filters.pop(key, None)
|
||||
|
||||
def set_label(self, key, label, column_only=False):
|
||||
self.labels[key] = label
|
||||
"""
|
||||
Set/override the label for a column.
|
||||
|
||||
This overrides
|
||||
:meth:`~wuttaweb:wuttaweb.grids.base.Grid.set_label()` to add
|
||||
the following params:
|
||||
|
||||
:param column_only: Boolean indicating whether the label
|
||||
should be applied *only* to the column header (if
|
||||
``True``), vs. applying also to the filter (if ``False``).
|
||||
"""
|
||||
super().set_label(key, label)
|
||||
|
||||
if not column_only and key in self.filters:
|
||||
self.filters[key].label = label
|
||||
|
||||
def get_label(self, key):
|
||||
"""
|
||||
Returns the label text for given field key.
|
||||
"""
|
||||
return self.labels.get(key, prettify(key))
|
||||
|
||||
def set_link(self, key, link=True):
|
||||
if link:
|
||||
if key not in self.linked_columns:
|
||||
self.linked_columns.append(key)
|
||||
else: # unlink
|
||||
if self.linked_columns and key in self.linked_columns:
|
||||
self.linked_columns.remove(key)
|
||||
|
||||
def set_click_handler(self, key, handler):
|
||||
if handler:
|
||||
self.click_handlers[key] = handler
|
||||
|
@ -457,9 +440,6 @@ class Grid:
|
|||
def has_click_handler(self, key):
|
||||
return key in self.click_handlers
|
||||
|
||||
def set_renderer(self, key, renderer):
|
||||
self.renderers[key] = renderer
|
||||
|
||||
def set_raw_renderer(self, key, renderer):
|
||||
"""
|
||||
Set or remove the "raw" renderer for the given field.
|
||||
|
@ -1450,22 +1430,13 @@ class Grid:
|
|||
return render(template, context)
|
||||
|
||||
def get_view_click_handler(self):
|
||||
|
||||
""" """
|
||||
# locate the 'view' action
|
||||
# TODO: this should be easier, and/or moved elsewhere?
|
||||
view = None
|
||||
for action in self.main_actions:
|
||||
for action in self.actions:
|
||||
if action.key == 'view':
|
||||
view = action
|
||||
break
|
||||
if not view:
|
||||
for action in self.more_actions:
|
||||
if action.key == 'view':
|
||||
view = action
|
||||
break
|
||||
|
||||
if view:
|
||||
return view.click_handler
|
||||
return action.click_handler
|
||||
|
||||
def set_filters_sequence(self, filters, only=False):
|
||||
"""
|
||||
|
@ -1561,26 +1532,21 @@ class Grid:
|
|||
kwargs['form'] = form
|
||||
return render(template, kwargs)
|
||||
|
||||
def render_actions(self, row, i):
|
||||
"""
|
||||
Returns the rendered contents of the 'actions' column for a given row.
|
||||
"""
|
||||
main_actions = [self.render_action(a, row, i)
|
||||
for a in self.main_actions]
|
||||
main_actions = [a for a in main_actions if a]
|
||||
more_actions = [self.render_action(a, row, i)
|
||||
for a in self.more_actions]
|
||||
more_actions = [a for a in more_actions if a]
|
||||
if more_actions:
|
||||
icon = HTML.tag('span', class_='ui-icon ui-icon-carat-1-e')
|
||||
link = tags.link_to("More" + icon, '#', class_='more')
|
||||
main_actions.append(HTML.literal(' ') + link + HTML.tag('div', class_='more', c=more_actions))
|
||||
return HTML.literal('').join(main_actions)
|
||||
def render_actions(self, row, i): # pragma: no cover
|
||||
""" """
|
||||
warnings.warn("grid.render_actions() is deprecated!",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
|
||||
actions = [self.render_action(a, row, i)
|
||||
for a in self.actions]
|
||||
actions = [a for a in actions if a]
|
||||
return HTML.literal('').join(actions)
|
||||
|
||||
def render_action(self, action, row, i): # pragma: no cover
|
||||
""" """
|
||||
warnings.warn("grid.render_action() is deprecated!",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
|
||||
def render_action(self, action, row, i):
|
||||
"""
|
||||
Renders an action menu item (link) for the given row.
|
||||
"""
|
||||
url = action.get_url(row, i)
|
||||
if url:
|
||||
kwargs = {'class_': action.key, 'target': action.target}
|
||||
|
@ -1786,21 +1752,10 @@ class Grid:
|
|||
Pre-generate all action URLs for the given data row. Meant for use
|
||||
with client-side table, since we can't generate URLs from JS.
|
||||
"""
|
||||
for action in (self.main_actions + self.more_actions):
|
||||
for action in self.actions:
|
||||
url = action.get_url(rowobj, i)
|
||||
row['_action_url_{}'.format(action.key)] = url
|
||||
|
||||
def is_linked(self, name):
|
||||
"""
|
||||
Should return ``True`` if the given column name is configured to be
|
||||
"linked" (i.e. table cell should contain a link to "view object"),
|
||||
otherwise ``False``.
|
||||
"""
|
||||
if self.linked_columns:
|
||||
if name in self.linked_columns:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class GridAction(WuttaGridAction):
|
||||
"""
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue