From 214f3d9b1e0d83890755a81610f223c4ca07e8bf Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Sun, 18 Jun 2023 18:50:01 -0500 Subject: [PATCH] Improve merge support for records with no uuid for now we "pretend" they have a uuid still, custom view is responsible for determining the value for each row if needed --- tailbone/grids/core.py | 33 +++++++++++++++-- tailbone/templates/grids/buefy.mako | 2 +- tailbone/templates/master/merge.mako | 4 +-- tailbone/views/master.py | 53 +++++++++++++++++++++------- 4 files changed, 74 insertions(+), 18 deletions(-) diff --git a/tailbone/grids/core.py b/tailbone/grids/core.py index 230bd061..abbac793 100644 --- a/tailbone/grids/core.py +++ b/tailbone/grids/core.py @@ -170,6 +170,21 @@ class Grid(object): 'myfield': myrender, }, ) + + .. attribute row_uuid_getter:: + + Optional callable to obtain the "UUID" (sic) value for each + data row. The default assumption as that each row object has a + ``uuid`` attribute, but when that isn't the case, *and* the + grid needs to support checkboxes, we must "pretend" by + injecting some custom value to the ``uuid`` of the row data. + + If necssary, set this to a callable like so:: + + def fake_uuid(row): + return row.some_custom_key + + grid.row_uuid_getter = fake_uuid """ def __init__(self, key, data, columns=None, width='auto', request=None, @@ -182,7 +197,7 @@ class Grid(object): 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, + 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', @@ -243,6 +258,7 @@ class Grid(object): self.check_handler = check_handler self.check_all_handler = check_all_handler self.checkable = checkable + self.row_uuid_getter = row_uuid_getter self.clicking_row_checks_box = clicking_row_checks_box self.click_handlers = click_handlers or {} @@ -1425,6 +1441,16 @@ class Grid(object): }) return columns + def get_uuid_for_row(self, rowobj): + + # use custom getter if set + if self.row_uuid_getter: + return self.row_uuid_getter(rowobj) + + # otherwise fallback to normal uuid, if present + if hasattr(rowobj, 'uuid'): + return rowobj.uuid + def get_buefy_data(self): """ Returns a list of data rows for the grid, for use with Buefy table. @@ -1481,8 +1507,9 @@ class Grid(object): # maybe add UUID for convenience if 'uuid' not in self.columns: - if hasattr(rowobj, 'uuid'): - row['uuid'] = rowobj.uuid + uuid = self.get_uuid_for_row(rowobj) + if uuid: + row['uuid'] = uuid # set action URL(s) for row, as needed self.set_action_urls(row, rowobj, i) diff --git a/tailbone/templates/grids/buefy.mako b/tailbone/templates/grids/buefy.mako index 48c3a081..d96358d5 100644 --- a/tailbone/templates/grids/buefy.mako +++ b/tailbone/templates/grids/buefy.mako @@ -192,7 +192,7 @@ % if grid.check_all_handler: @check-all="${grid.check_all_handler}" % endif - % if isinstance(grid.checkable, six.string_types): + % if isinstance(grid.checkable, str): :is-row-checkable="${grid.row_checkable}" % elif grid.checkable: :is-row-checkable="row => row._checkable" diff --git a/tailbone/templates/master/merge.mako b/tailbone/templates/master/merge.mako index 565dece3..6727dc5c 100644 --- a/tailbone/templates/master/merge.mako +++ b/tailbone/templates/master/merge.mako @@ -123,7 +123,7 @@
${h.form(request.current_route_url(), **{'@submit': 'submitSwapForm'})} ${h.csrf_token(request)} - ${h.hidden('uuids', value='{},{}'.format(object_to_keep.uuid, object_to_remove.uuid))} + ${h.hidden('uuids', value=f'{keeping_uuid},{removing_uuid}')} {{ swapFormButtonText }} @@ -134,7 +134,7 @@
${h.form(request.current_route_url(), **{'@submit': 'submitMergeForm'})} ${h.csrf_token(request)} - ${h.hidden('uuids', value='{},{}'.format(object_to_remove.uuid, object_to_keep.uuid))} + ${h.hidden('uuids', value=f'{removing_uuid},{keeping_uuid}')} ${h.hidden('commit-merge', value='yes')}