feat: inherit most logic from wuttaweb, for GridAction
This commit is contained in:
parent
09612b1921
commit
1b78bd617c
|
@ -38,6 +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 . import filters as gridfilters
|
||||
from tailbone.db import Session
|
||||
from tailbone.util import raw_datetime
|
||||
|
@ -1801,18 +1802,20 @@ class Grid:
|
|||
return False
|
||||
|
||||
|
||||
class GridAction(object):
|
||||
class GridAction(WuttaGridAction):
|
||||
"""
|
||||
Represents an action available to a grid. This is used to construct the
|
||||
'actions' column when rendering the grid.
|
||||
Represents a "row action" hyperlink within a grid context.
|
||||
|
||||
:param key: Key for the action (e.g. ``'edit'``), unique within
|
||||
the grid.
|
||||
This is a subclass of
|
||||
:class:`wuttaweb:wuttaweb.grids.base.GridAction`.
|
||||
|
||||
:param label: Label to be displayed for the action. If not set,
|
||||
will be a capitalized version of ``key``.
|
||||
.. warning::
|
||||
|
||||
:param icon: Icon name for the action.
|
||||
This class remains for now, to retain compatibility with
|
||||
existing code. But at some point the WuttaWeb class will
|
||||
supersede this one entirely.
|
||||
|
||||
:param target: HTML "target" attribute for the ``<a>`` tag.
|
||||
|
||||
:param click_handler: Optional JS click handler for the action.
|
||||
This value will be rendered as-is within the final grid
|
||||
|
@ -1824,41 +1827,23 @@ class GridAction(object):
|
|||
* ``$emit('do-something', props.row)``
|
||||
"""
|
||||
|
||||
def __init__(self, key, label=None, url='#', icon=None, target=None,
|
||||
link_class=None, click_handler=None):
|
||||
self.key = key
|
||||
self.label = label or prettify(key)
|
||||
self.icon = icon
|
||||
self.url = url
|
||||
def __init__(
|
||||
self,
|
||||
request,
|
||||
key,
|
||||
target=None,
|
||||
click_handler=None,
|
||||
**kwargs,
|
||||
):
|
||||
# TODO: previously url default was '#' - but i don't think we
|
||||
# need that anymore? guess we'll see..
|
||||
#kwargs.setdefault('url', '#')
|
||||
|
||||
super().__init__(request, key, **kwargs)
|
||||
|
||||
self.target = target
|
||||
self.link_class = link_class
|
||||
self.click_handler = click_handler
|
||||
|
||||
def get_url(self, row, i):
|
||||
"""
|
||||
Returns an action URL for the given row.
|
||||
"""
|
||||
if callable(self.url):
|
||||
return self.url(row, i)
|
||||
return self.url
|
||||
|
||||
def render_icon(self):
|
||||
"""
|
||||
Render the HTML snippet for the action link icon.
|
||||
"""
|
||||
return HTML.tag('i', class_='fas fa-{}'.format(self.icon))
|
||||
|
||||
def render_label(self):
|
||||
"""
|
||||
Render the label "text" within the actions column of a grid
|
||||
row. Most actions have a static label that never varies, but
|
||||
you can override this to add e.g. HTML content. Note that the
|
||||
return value will be treated / rendered as HTML whether or not
|
||||
it contains any, so perhaps be careful that it is trusted
|
||||
content.
|
||||
"""
|
||||
return self.label
|
||||
|
||||
|
||||
class URLMaker(object):
|
||||
"""
|
||||
|
|
|
@ -53,11 +53,11 @@
|
|||
</${b}-table-column>
|
||||
% endfor
|
||||
|
||||
% if grid.main_actions or grid.more_actions:
|
||||
% if grid.actions:
|
||||
<${b}-table-column field="actions"
|
||||
label="Actions"
|
||||
v-slot="props">
|
||||
% for action in grid.main_actions:
|
||||
% for action in grid.actions:
|
||||
<a :href="props.row._action_url_${action.key}"
|
||||
% if action.link_class:
|
||||
class="${action.link_class}"
|
||||
|
@ -68,12 +68,7 @@
|
|||
@click.prevent="${action.click_handler}"
|
||||
% endif
|
||||
>
|
||||
% if request.use_oruga:
|
||||
<o-icon icon="${action.icon}" />
|
||||
% else:
|
||||
<i class="fas fa-${action.icon}"></i>
|
||||
% endif
|
||||
${action.label}
|
||||
${action.render_icon_and_label()}
|
||||
</a>
|
||||
|
||||
% endfor
|
||||
|
|
|
@ -163,13 +163,7 @@
|
|||
target="${action.target}"
|
||||
% endif
|
||||
>
|
||||
% if request.use_oruga:
|
||||
<o-icon icon="${action.icon}" />
|
||||
<span>${action.render_label()|n}</span>
|
||||
% else:
|
||||
${action.render_icon()|n}
|
||||
${action.render_label()|n}
|
||||
% endif
|
||||
${action.render_icon_and_label()}
|
||||
</a>
|
||||
|
||||
% endfor
|
||||
|
|
|
@ -3220,14 +3220,18 @@ class MasterView(View):
|
|||
|
||||
def make_action(self, key, url=None, factory=None, **kwargs):
|
||||
"""
|
||||
Make a new :class:`GridAction` instance for the current grid.
|
||||
Make and return a new :class:`~tailbone.grids.core.GridAction`
|
||||
instance.
|
||||
|
||||
This can be called to make actions for any grid, not just the
|
||||
one from :meth:`index()`.
|
||||
"""
|
||||
if url is None:
|
||||
route = '{}.{}'.format(self.get_route_prefix(), key)
|
||||
url = lambda r, i: self.request.route_url(route, **self.get_action_route_kwargs(r))
|
||||
if not factory:
|
||||
factory = grids.GridAction
|
||||
return factory(key, url=url, **kwargs)
|
||||
return factory(self.request, key, url=url, **kwargs)
|
||||
|
||||
def get_action_route_kwargs(self, obj):
|
||||
"""
|
||||
|
|
|
@ -552,7 +552,7 @@ class PersonView(MasterView):
|
|||
if self.request.has_perm('trainwreck.transactions.view'):
|
||||
url = lambda row, i: self.request.route_url('trainwreck.transactions.view',
|
||||
uuid=row.uuid)
|
||||
g.main_actions.append(grids.GridAction('view', icon='eye', url=url))
|
||||
g.main_actions.append(self.make_action('view', icon='eye', url=url))
|
||||
g.load_settings()
|
||||
|
||||
g.set_enum('system', self.enum.TRAINWRECK_SYSTEM)
|
||||
|
|
|
@ -40,7 +40,7 @@ from webhelpers2.html import tags, HTML
|
|||
|
||||
from wuttaweb.util import get_form_data
|
||||
|
||||
from tailbone import forms, grids
|
||||
from tailbone import forms
|
||||
from tailbone.views.purchasing import PurchasingBatchView
|
||||
|
||||
|
||||
|
@ -1031,7 +1031,7 @@ class ReceivingBatchView(PurchasingBatchView):
|
|||
if batch.is_truck_dump_parent():
|
||||
permission_prefix = self.get_permission_prefix()
|
||||
if self.request.has_perm('{}.edit_row'.format(permission_prefix)):
|
||||
transform = grids.GridAction('transform',
|
||||
transform = self.make_action('transform',
|
||||
icon='shuffle',
|
||||
label="Transform to Unit",
|
||||
url=self.transform_unit_url)
|
||||
|
|
|
@ -363,7 +363,7 @@ class RoleView(PrincipalMasterView):
|
|||
if role.users:
|
||||
users = sorted(role.users, key=lambda u: u.username)
|
||||
actions = [
|
||||
grids.GridAction('view', icon='zoomin',
|
||||
self.make_action('view', icon='zoomin',
|
||||
url=lambda r, i: self.request.route_url('users.view', uuid=r.uuid))
|
||||
]
|
||||
kwargs['users'] = grids.Grid(None, users, ['username', 'active'],
|
||||
|
|
|
@ -137,3 +137,20 @@ class TestGrid(WebTestCase):
|
|||
# calling again returns same data
|
||||
data2 = grid.get_vue_data()
|
||||
self.assertIs(data2, data)
|
||||
|
||||
|
||||
class TestGridAction(WebTestCase):
|
||||
|
||||
def test_constructor(self):
|
||||
|
||||
# null by default
|
||||
action = mod.GridAction(self.request, 'view')
|
||||
self.assertIsNone(action.target)
|
||||
self.assertIsNone(action.click_handler)
|
||||
|
||||
# but can set them
|
||||
action = mod.GridAction(self.request, 'view',
|
||||
target='_blank',
|
||||
click_handler='doSomething(props.row)')
|
||||
self.assertEqual(action.target, '_blank')
|
||||
self.assertEqual(action.click_handler, 'doSomething(props.row)')
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
from unittest.mock import patch
|
||||
|
||||
from tailbone.views import master as mod
|
||||
from wuttaweb.grids import GridAction
|
||||
from tests.util import WebTestCase
|
||||
|
||||
|
||||
|
@ -24,3 +25,11 @@ class TestMasterView(WebTestCase):
|
|||
# sanity / coverage check
|
||||
kw = view.make_form_kwargs(model_instance=setting)
|
||||
self.assertIsNotNone(kw['action_url'])
|
||||
|
||||
def test_make_action(self):
|
||||
model = self.app.model
|
||||
with patch.multiple(mod.MasterView, create=True,
|
||||
model_class=model.Setting):
|
||||
view = self.make_view()
|
||||
action = view.make_action('view')
|
||||
self.assertIsInstance(action, GridAction)
|
||||
|
|
Loading…
Reference in a new issue