diff --git a/tailbone/templates/master/view.mako b/tailbone/templates/master/view.mako index 2f340e2d..cfd1b925 100644 --- a/tailbone/templates/master/view.mako +++ b/tailbone/templates/master/view.mako @@ -50,6 +50,9 @@ % if master.cloneable and request.has_perm('{}.clone'.format(permission_prefix)):
  • ${h.link_to("Clone this as new {}".format(model_title), url('{}.clone'.format(route_prefix), uuid=instance.uuid))}
  • % endif + % if master.touchable and request.has_perm('{}.touch'.format(permission_prefix)): +
  • ${h.link_to("\"Touch\" this {}".format(model_title), url('{}.touch'.format(route_prefix), uuid=instance.uuid))}
  • + % endif % if master.has_rows and master.rows_downloadable_csv and request.has_perm('{}.row_results_csv'.format(permission_prefix)):
  • ${h.link_to("Download row results as CSV", url('{}.row_results_csv'.format(route_prefix), uuid=instance.uuid))}
  • % endif diff --git a/tailbone/views/master.py b/tailbone/views/master.py index a11311ff..be0a9fc3 100644 --- a/tailbone/views/master.py +++ b/tailbone/views/master.py @@ -89,6 +89,7 @@ class MasterView(View): mergeable = False downloadable = False cloneable = False + touchable = False executable = False execute_progress_template = None execute_progress_initial_msg = None @@ -1041,6 +1042,30 @@ class MasterView(View): def clone_instance(self, instance): raise NotImplementedError + def touch(self): + """ + View for "touching" an object so as to trigger datasync logic for it. + Useful instead of actually "editing" the object, which is generally the + alternative. + """ + obj = self.get_instance() + change = self.touch_instance(obj) + self.request.session.flash("{} has been touched: {}".format( + self.get_model_title(), self.get_instance_title(obj))) + return self.redirect(self.get_action_url('view', obj)) + + def touch_instance(self, obj): + """ + Perform actual "touch" logic for the given object. Must return the + :class:`rattail:~rattail.db.model.Change` record involved. + """ + change = model.Change() + change.class_name = obj.__class__.__name__ + change.instance_uuid = obj.uuid + change = self.Session.merge(change) + change.deleted = False + return change + def versions(self): """ View to list version history for an object. @@ -3429,6 +3454,14 @@ class MasterView(View): config.add_view(cls, attr='clone', route_name='{}.clone'.format(route_prefix), permission='{}.clone'.format(permission_prefix)) + # touch + if cls.touchable: + config.add_tailbone_permission(permission_prefix, '{}.touch'.format(permission_prefix), + "\"Touch\" a {} to trigger datasync for it".format(model_title)) + config.add_route('{}.touch'.format(route_prefix), '{}/{{{}}}/touch'.format(url_prefix, model_key)) + config.add_view(cls, attr='touch', route_name='{}.touch'.format(route_prefix), + permission='{}.touch'.format(permission_prefix)) + # download if cls.downloadable: config.add_route('{}.download'.format(route_prefix), '{}/{{{}}}/download'.format(url_prefix, model_key))