diff --git a/tailbone/grids/core.py b/tailbone/grids/core.py index 92452b31..969be50a 100644 --- a/tailbone/grids/core.py +++ b/tailbone/grids/core.py @@ -196,9 +196,6 @@ class Grid(WuttaGrid): raw_renderers={}, extra_row_class=None, url='#', - joiners={}, - filterable=False, - filters={}, use_byte_string_filters=False, checkboxes=False, checked=None, @@ -263,6 +260,8 @@ class Grid(WuttaGrid): # reference grid.vue_component etc. kwargs.setdefault('vue_tagname', 'tailbone-grid') + self.use_byte_string_filters = use_byte_string_filters + kwargs['key'] = key kwargs['data'] = data super().__init__(request, **kwargs) @@ -286,11 +285,6 @@ class Grid(WuttaGrid): self.invisible = invisible or [] self.extra_row_class = extra_row_class self.url = url - self.joiners = joiners or {} - - self.filterable = filterable - self.use_byte_string_filters = use_byte_string_filters - self.filters = self.make_filters(filters) self.checkboxes = checkboxes self.checked = checked @@ -446,10 +440,14 @@ class Grid(WuttaGrid): self.remove(oldfield) def set_joiner(self, key, joiner): + """ """ if joiner is None: - self.joiners.pop(key, None) + warnings.warn("specifying None is deprecated for Grid.set_joiner(); " + "please use Grid.remove_joiner() instead", + DeprecationWarning, stacklevel=2) + self.remove_joiner(key) else: - self.joiners[key] = joiner + super().set_joiner(key, joiner) def set_sorter(self, key, *args, **kwargs): """ """ @@ -477,33 +475,27 @@ class Grid(WuttaGrid): self.sorters[key] = self.make_sorter(*args, **kwargs) def set_filter(self, key, *args, **kwargs): - if len(args) == 1 and args[0] is None: - self.remove_filter(key) + """ """ + + if len(args) == 1: + if args[0] is None: + warnings.warn("specifying None is deprecated for Grid.set_filter(); " + "please use Grid.remove_filter() instead", + DeprecationWarning, stacklevel=2) + self.remove_filter(key) + else: + super().set_filter(key, args[0], **kwargs) + + elif len(args) == 0: + super().set_filter(key, **kwargs) + else: - if 'label' not in kwargs and key in self.labels: - kwargs['label'] = self.labels[key] + warnings.warn("multiple args are deprecated for Grid.set_filter(); " + "please refactor your code accordingly", + DeprecationWarning, stacklevel=2) + kwargs.setdefault('label', self.get_label(key)) self.filters[key] = self.make_filter(key, *args, **kwargs) - def remove_filter(self, key): - self.filters.pop(key, None) - - def set_label(self, key, label, column_only=False): - """ - 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 set_click_handler(self, key, handler): if handler: self.click_handlers[key] = handler @@ -702,6 +694,14 @@ class Grid(WuttaGrid): def actions_column_format(self, column_number, row_number, item): return HTML.td(self.render_actions(item, row_number), class_='actions') + # TODO: upstream should handle this.. + def make_backend_filters(self, filters=None): + """ """ + final = self.get_default_filters() + if filters: + final.update(filters) + return final + def get_default_filters(self): """ Returns the default set of filters provided by the grid. @@ -726,16 +726,6 @@ class Grid(WuttaGrid): filters[prop.key] = self.make_filter(prop.key, column) return filters - def make_filters(self, filters=None): - """ - Returns an initial set of filters which will be available to the grid. - The grid itself may or may not provide some default filters, and the - ``filters`` kwarg may contain additions and/or overrides. - """ - if filters: - return filters - return self.get_default_filters() - def make_filter(self, key, column, **kwargs): """ Make a filter suitable for use with the given column. @@ -888,8 +878,8 @@ class Grid(WuttaGrid): # If request has filter settings, grab those, then grab sort/pager # settings from request or session. - elif self.filterable and self.request_has_settings('filter'): - self.update_filter_settings(settings, 'request') + elif self.request_has_settings('filter'): + self.update_filter_settings(settings, src='request') if self.request_has_settings('sort'): self.update_sort_settings(settings, src='request') else: @@ -901,7 +891,7 @@ class Grid(WuttaGrid): # settings from request or session. elif self.request_has_settings('sort'): self.update_sort_settings(settings, src='request') - self.update_filter_settings(settings, 'session') + self.update_filter_settings(settings, src='session') self.update_page_settings(settings) # NOTE: These next two are functionally equivalent, but are kept @@ -911,12 +901,12 @@ class Grid(WuttaGrid): # grab those, then grab filter/sort settings from session. elif self.request_has_settings('page'): self.update_page_settings(settings) - self.update_filter_settings(settings, 'session') + self.update_filter_settings(settings, src='session') self.update_sort_settings(settings, src='session') # If request has no settings, grab all from session. elif self.session_has_settings(): - self.update_filter_settings(settings, 'session') + self.update_filter_settings(settings, src='session') self.update_sort_settings(settings, src='session') self.update_page_settings(settings) @@ -1056,18 +1046,11 @@ class Grid(WuttaGrid): merge('page', int) def request_has_settings(self, type_): - """ - Determine if the current request (GET query string) contains any - filter/sort settings for the grid. - """ - if type_ == 'filter': - for filtr in self.iter_filters(): - if filtr.key in self.request.GET: - return True - if 'filter' in self.request.GET: # user may be applying empty filters - return True + """ """ + if super().request_has_settings(type_): + return True - elif type_ == 'sort': + if type_ == 'sort': # TODO: remove this eventually, but some links in the wild # may still include these params, so leave it for now @@ -1075,14 +1058,6 @@ class Grid(WuttaGrid): if key in self.request.GET: return True - if 'sort1key' in self.request.GET: - return True - - elif type_ == 'page': - for key in ['pagesize', 'page']: - if key in self.request.GET: - return True - return False def session_has_settings(self): @@ -1098,72 +1073,6 @@ class Grid(WuttaGrid): return any([key.startswith(f'{prefix}.filter') for key in self.request.session]) - def update_filter_settings(self, settings, source): - """ - Updates a settings dictionary according to filter settings data found - in either the GET query string, or session storage. - - :param settings: Dictionary of initial settings, which is to be updated. - - :param source: String identifying the source to consult for settings - data. Must be one of: ``('request', 'session')``. - """ - if not self.filterable: - return - - for filtr in self.iter_filters(): - prefix = 'filter.{}'.format(filtr.key) - - if source == 'request': - # consider filter active if query string contains a value for it - settings['{}.active'.format(prefix)] = filtr.key in self.request.GET - settings['{}.verb'.format(prefix)] = self.get_setting( - settings, f'{filtr.key}.verb', src='request', default='') - settings['{}.value'.format(prefix)] = self.get_setting( - settings, filtr.key, src='request', default='') - - else: # source = session - settings['{}.active'.format(prefix)] = self.get_setting( - settings, f'{prefix}.active', src='session', - normalize=lambda v: str(v).lower() == 'true', default=False) - settings['{}.verb'.format(prefix)] = self.get_setting( - settings, f'{prefix}.verb', src='session', default='') - settings['{}.value'.format(prefix)] = self.get_setting( - settings, f'{prefix}.value', src='session', default='') - - def update_page_settings(self, settings): - """ - Updates a settings dictionary according to pager settings data found in - either the GET query string, or session storage. - - Note that due to how the actual pager functions, the effective settings - will often come from *both* the request and session. This is so that - e.g. the page size will remain constant (coming from the session) while - the user jumps between pages (which only provides the single setting). - - :param settings: Dictionary of initial settings, which is to be updated. - """ - if not self.paginated: - return - - pagesize = self.request.GET.get('pagesize') - if pagesize is not None: - if pagesize.isdigit(): - settings['pagesize'] = int(pagesize) - else: - pagesize = self.request.session.get('grid.{}.pagesize'.format(self.key)) - if pagesize is not None: - settings['pagesize'] = pagesize - - page = self.request.GET.get('page') - if page is not None: - if page.isdigit(): - settings['page'] = int(page) - else: - page = self.request.session.get('grid.{}.page'.format(self.key)) - if page is not None: - settings['page'] = int(page) - def persist_settings(self, settings, dest='session'): """ """ if dest not in ('defaults', 'session'): @@ -1251,89 +1160,12 @@ class Grid(WuttaGrid): return data - def sort_data(self, data, sorters=None): - """ """ - if sorters is None: - sorters = self.active_sorters - if not sorters: - return data - - # nb. when data is a query, we want to apply sorters in the - # requested order, so the final query has order_by() in the - # correct "as-is" sequence. however when data is a list we - # must do the opposite, applying in the reverse order, so the - # final list has the most "important" sort(s) applied last. - if not isinstance(data, orm.Query): - sorters = reversed(sorters) - - for sorter in sorters: - sortkey = sorter['key'] - sortdir = sorter['dir'] - - # cannot sort unless we have a sorter callable - sortfunc = self.sorters.get(sortkey) - if not sortfunc: - return data - - # join appropriate model if needed - if sortkey in self.joiners and sortkey not in self.joined: - data = self.joiners[sortkey](data) - self.joined.add(sortkey) - - # invoke the sorter - data = sortfunc(data, sortdir) - - return data - - def paginate_data(self, data): - """ - Paginate the given data set according to current settings, and return - the result. - """ - # we of course assume our current page is correct, at first - pager = self.make_pager(data) - - # if pager has detected that our current page is outside the valid - # range, we must re-orient ourself around the "new" (valid) page - if pager.page != self.page: - self.page = pager.page - self.request.session['grid.{}.page'.format(self.key)] = self.page - pager = self.make_pager(data) - - return pager - - def make_pager(self, data): - - # TODO: this seems hacky..normally we expect `data` to be a - # query of course, but in some cases it may be a list instead. - # if so then we can't use ORM pager - if isinstance(data, list): - import paginate - return paginate.Page(data, - items_per_page=self.pagesize, - page=self.page) - - return SqlalchemyOrmPage(data, - items_per_page=self.pagesize, - page=self.page, - url_maker=URLMaker(self.request)) - def make_visible_data(self): - """ - Apply various settings to the raw data set, to produce a final data - set. This will page / sort / filter as necessary, according to the - grid's defaults and the current request etc. - """ - self.joined = set() - data = self.data - if self.filterable: - data = self.filter_data(data) - if self.sortable: - data = self.sort_data(data) - if self.paginated: - self.pager = self.paginate_data(data) - data = self.pager - return data + """ """ + warnings.warn("grid.make_visible_data() method is deprecated; " + "please use grid.get_visible_data() instead", + DeprecationWarning, stacklevel=2) + return self.get_visible_data() def render_vue_tag(self, master=None, **kwargs): """ """ @@ -1356,7 +1188,7 @@ class Grid(WuttaGrid): includes the context menu items and grid tools. """ if 'grid_columns' not in kwargs: - kwargs['grid_columns'] = self.get_table_columns() + kwargs['grid_columns'] = self.get_vue_columns() if 'grid_data' not in kwargs: kwargs['grid_data'] = self.get_table_data() @@ -1379,6 +1211,7 @@ class Grid(WuttaGrid): return HTML.literal(html) def render_buefy(self, **kwargs): + """ """ warnings.warn("Grid.render_buefy() is deprecated; " "please use Grid.render_complete() instead", DeprecationWarning, stacklevel=2) @@ -1568,23 +1401,19 @@ class Grid(WuttaGrid): def get_vue_columns(self): """ """ - return self.get_table_columns() + columns = super().get_vue_columns() + + for column in columns: + column['visible'] = column['field'] not in self.invisible + + return columns def get_table_columns(self): - """ - Return a list of dicts representing all grid columns. Meant - for use with the client-side JS table. - """ - columns = [] - for name in self.columns: - columns.append({ - 'field': name, - 'label': self.get_label(name), - 'sortable': self.is_sortable(name), - 'searchable': self.is_searchable(name), - 'visible': name not in self.invisible, - }) - return columns + """ """ + warnings.warn("grid.get_table_columns() method is deprecated; " + "please use grid.get_vue_columns() instead", + DeprecationWarning, stacklevel=2) + return self.get_vue_columns() def get_uuid_for_row(self, rowobj): @@ -1610,7 +1439,7 @@ class Grid(WuttaGrid): return self._table_data # filter / sort / paginate to get "visible" data - raw_data = self.make_visible_data() + raw_data = self.get_visible_data() data = [] status_map = {} checked = []