From 8d6ecc3ec7d61675a2f13df712c055d800e60576 Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Sun, 24 Mar 2019 17:24:43 -0500 Subject: [PATCH] Add basic "Buefy" support for grids (master index view) still pretty experimental at this point, but making progress --- tailbone/grids/core.py | 105 ++++++++++++++- tailbone/templates/grids/buefy.mako | 142 ++++++++++++++++++++ tailbone/templates/master/index.mako | 12 +- tailbone/templates/themes/falafel/base.mako | 4 + tailbone/views/datasync.py | 4 +- tailbone/views/email.py | 1 + tailbone/views/master.py | 39 ++++-- tailbone/views/tables.py | 3 +- tailbone/views/upgrades.py | 1 + 9 files changed, 296 insertions(+), 15 deletions(-) create mode 100644 tailbone/templates/grids/buefy.mako diff --git a/tailbone/grids/core.py b/tailbone/grids/core.py index 4398b05b..17fadcf0 100644 --- a/tailbone/grids/core.py +++ b/tailbone/grids/core.py @@ -2,7 +2,7 @@ ################################################################################ # # Rattail -- Retail Software Framework -# Copyright © 2010-2018 Lance Edgar +# Copyright © 2010-2019 Lance Edgar # # This file is part of Rattail. # @@ -176,6 +176,12 @@ class Grid(object): if 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: @@ -900,9 +906,16 @@ class Grid(object): """ context = kwargs context['grid'] = self + context['request'] = self.request context.setdefault('allow_save_defaults', True) return render(template, context) + def render_buefy(self, template='/grids/buefy.mako', **kwargs): + """ + Render the Buefy grid, including filters. + """ + return self.render_complete(template=template, **kwargs) + def render_filters(self, template='/grids/filters.mako', **kwargs): """ Render the filters to a Unicode string, using the specified template. @@ -982,6 +995,96 @@ class Grid(object): # TODO: Make configurable or something... return [5, 10, 20, 50, 100, 200] + def has_static_data(self): + """ + Should return ``True`` if the grid data can be considered "static" + (i.e. a list of values). Will return ``False`` otherwise, e.g. if the + data is represented as a SQLAlchemy query. + """ + # TODO: should make this smarter? + if isinstance(self.data, list): + return True + return False + + def get_buefy_columns(self): + """ + Return a list of dicts representing all grid columns. Meant for use + with Buefy table. + """ + columns = [] + for name in self.columns: + columns.append({ + 'field': name, + 'label': self.get_label(name), + 'sortable': self.sortable and name in self.sorters, + }) + return columns + + def get_buefy_data(self): + """ + Returns a list of data rows for the grid, for use with Buefy table. + """ + # filter / sort / paginate to get "visible" data + raw_data = self.make_visible_data() + data = [] + + # iterate over data rows + for i in range(len(raw_data)): + rowobj = raw_data[i] + row = {} + + # iterate over data fields + for name in self.columns: + + # leverage configured rendering logic where applicable; + # otherwise use "raw" data value as string + if self.renderers and name in self.renderers: + row[name] = self.renderers[name](rowobj, name) + else: + value = self.obtain_value(rowobj, name) + if value is None: + value = "" + row[name] = six.text_type(value) + + # set action URL(s) for row, as needed + self.set_action_urls(row, rowobj, i) + + data.append(row) + + results = { + 'data': data, + } + + if self.pageable and self.pager is not None: + results['total_items'] = self.pager.item_count + results['per_page'] = self.pager.items_per_page + results['page'] = self.pager.page + results['pages'] = self.pager.page_count + results['first_item'] = self.pager.first_item + results['last_item'] = self.pager.last_item + + return results + + def set_action_urls(self, row, rowobj, i): + """ + Pre-generate all action URLs for the given data row. Meant for use + with Buefy table, since we can't generate URLs from JS. + """ + for action in (self.main_actions + self.more_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 CustomWebhelpersGrid(webhelpers2_grid.Grid): """ diff --git a/tailbone/templates/grids/buefy.mako b/tailbone/templates/grids/buefy.mako new file mode 100644 index 00000000..01219a76 --- /dev/null +++ b/tailbone/templates/grids/buefy.mako @@ -0,0 +1,142 @@ +## -*- coding: utf-8; -*- + +
+ + + + + + + % if grid.pageable and grid.pager: + + % endif + + +
+ + diff --git a/tailbone/templates/master/index.mako b/tailbone/templates/master/index.mako index 85252961..9a502a67 100644 --- a/tailbone/templates/master/index.mako +++ b/tailbone/templates/master/index.mako @@ -17,7 +17,9 @@