Add generic support for "enable/disable selection" of grid records

This commit is contained in:
Lance Edgar 2019-02-05 10:49:54 -06:00
parent 05bb8a2df0
commit 13ec46b145
2 changed files with 120 additions and 18 deletions

View file

@ -57,6 +57,38 @@
% endif % endif
% if master.supports_set_enabled_toggle and request.has_perm('{}.enable_disable_set'.format(permission_prefix)):
$('form[name="enable-set"] button').click(function() {
var form = $(this).parents('form');
var uuids = $('.grid').gridcore('selected_uuids');
if (! uuids.length) {
alert("You must first select one or more objects to enable.");
return false;
}
if (! confirm("Are you sure you wish to ENABLE the " + uuids.length + " selected objects?")) {
return false;
}
form.find('[name="uuids"]').val(uuids.toString());
disable_button(this);
form.submit();
});
$('form[name="disable-set"] button').click(function() {
var form = $(this).parents('form');
var uuids = $('.grid').gridcore('selected_uuids');
if (! uuids.length) {
alert("You must first select one or more objects to disable.");
return false;
}
if (! confirm("Are you sure you wish to DISABLE the " + uuids.length + " selected objects?")) {
return false;
}
form.find('[name="uuids"]').val(uuids.toString());
disable_button(this);
form.submit();
});
% endif
% if master.set_deletable and request.has_perm('{}.delete_set'.format(permission_prefix)): % if master.set_deletable and request.has_perm('{}.delete_set'.format(permission_prefix)):
$('form[name="delete-set"] button').click(function() { $('form[name="delete-set"] button').click(function() {
var form = $(this).parents('form'); var form = $(this).parents('form');
@ -65,7 +97,7 @@
alert("You must first select one or more objects to delete."); alert("You must first select one or more objects to delete.");
return false; return false;
} }
if (! confirm("Are you sure you wish to delete the " + uuids.length + " selected objects?")) { if (! confirm("Are you sure you wish to DELETE the " + uuids.length + " selected objects?")) {
return false; return false;
} }
form.find('[name="uuids"]').val(uuids.toString()); form.find('[name="uuids"]').val(uuids.toString());
@ -104,11 +136,18 @@
${h.end_form()} ${h.end_form()}
% endif % endif
## delete search results ## enable / disable selected objects
% if master.bulk_deletable and request.has_perm('{}.bulk_delete'.format(permission_prefix)): % if master.supports_set_enabled_toggle and request.has_perm('{}.enable_disable_set'.format(permission_prefix)):
${h.form(url('{}.bulk_delete'.format(route_prefix)), name='bulk-delete')} ${h.form(url('{}.enable_set'.format(route_prefix)), name='enable-set')}
${h.csrf_token(request)} ${h.csrf_token(request)}
<button type="button">Delete Results</button> ${h.hidden('uuids')}
<button type="button">Enable Selected</button>
${h.end_form()}
${h.form(url('{}.disable_set'.format(route_prefix)), name='disable-set')}
${h.csrf_token(request)}
${h.hidden('uuids')}
<button type="button">Disable Selected</button>
${h.end_form()} ${h.end_form()}
% endif % endif
@ -121,6 +160,14 @@
${h.end_form()} ${h.end_form()}
% endif % endif
## delete search results
% if master.bulk_deletable and request.has_perm('{}.bulk_delete'.format(permission_prefix)):
${h.form(url('{}.bulk_delete'.format(route_prefix)), name='bulk-delete')}
${h.csrf_token(request)}
<button type="button">Delete Results</button>
${h.end_form()}
% endif
</%def> </%def>
${grid.render_complete(tools=capture(self.grid_tools).strip(), context_menu=capture(self.context_menu_items).strip())|n} ${grid.render_complete(tools=capture(self.grid_tools).strip(), context_menu=capture(self.context_menu_items).strip())|n}

View file

@ -83,6 +83,7 @@ class MasterView(View):
deletable = True deletable = True
bulk_deletable = False bulk_deletable = False
set_deletable = False set_deletable = False
supports_set_enabled_toggle = False
populatable = False populatable = False
mergeable = False mergeable = False
downloadable = False downloadable = False
@ -332,6 +333,8 @@ class MasterView(View):
checkboxes = self.checkboxes checkboxes = self.checkboxes
if not checkboxes and self.mergeable and self.request.has_perm('{}.merge'.format(permission_prefix)): if not checkboxes and self.mergeable and self.request.has_perm('{}.merge'.format(permission_prefix)):
checkboxes = True checkboxes = True
if not checkboxes and self.supports_set_enabled_toggle and self.request.has_perm('{}.enable_disable_set'.format(permission_prefix)):
checkboxes = True
if not checkboxes and self.set_deletable and self.request.has_perm('{}.delete_set'.format(permission_prefix)): if not checkboxes and self.set_deletable and self.request.has_perm('{}.delete_set'.format(permission_prefix)):
checkboxes = True checkboxes = True
@ -1630,9 +1633,9 @@ class MasterView(View):
progress.session['success_url'] = self.get_index_url() progress.session['success_url'] = self.get_index_url()
progress.session.save() progress.session.save()
def delete_set(self): def obtain_set(self):
""" """
View which can delete a specific set of records. Obtain the effective "set" (selection) of records from POST data.
""" """
# TODO: should have a cleaner way to parse object uuids? # TODO: should have a cleaner way to parse object uuids?
uuids = self.request.POST.get('uuids') uuids = self.request.POST.get('uuids')
@ -1640,14 +1643,53 @@ class MasterView(View):
uuids = uuids.split(',') uuids = uuids.split(',')
# TODO: probably need to allow override of fetcher callable # TODO: probably need to allow override of fetcher callable
fetcher = lambda uuid: self.Session.query(self.model_class).get(uuid) fetcher = lambda uuid: self.Session.query(self.model_class).get(uuid)
deleted = 0 objects = []
for uuid in uuids: for uuid in uuids:
obj = fetcher(uuid) obj = fetcher(uuid)
if obj: if obj:
self.delete_instance(obj) objects.append(obj)
deleted += 1 return objects
def enable_set(self):
"""
View which can turn ON the 'enabled' flag for a specific set of records.
"""
objects = self.obtain_set()
if objects:
enabled = 0
for obj in objects:
if not obj.enabled:
obj.enabled = True
enabled += 1
model_title_plural = self.get_model_title_plural() model_title_plural = self.get_model_title_plural()
self.request.session.flash("Deleted {} {}".format(deleted, model_title_plural)) self.request.session.flash("Enabled {} {}".format(enabled, model_title_plural))
return self.redirect(self.get_index_url())
def disable_set(self):
"""
View which can turn OFF the 'enabled' flag for a specific set of records.
"""
objects = self.obtain_set()
if objects:
disabled = 0
for obj in objects:
if obj.enabled:
obj.enabled = False
disabled += 1
model_title_plural = self.get_model_title_plural()
self.request.session.flash("Disabled {} {}".format(disabled, model_title_plural))
return self.redirect(self.get_index_url())
def delete_set(self):
"""
View which can delete a specific set of records.
"""
objects = self.obtain_set()
if objects:
for obj in objects:
self.delete_instance(obj)
model_title_plural = self.get_model_title_plural()
self.request.session.flash("Deleted {} {}".format(len(objects), model_title_plural))
return self.redirect(self.get_index_url()) return self.redirect(self.get_index_url())
def oneoff_import(self, importer, host_object=None): def oneoff_import(self, importer, host_object=None):
@ -3079,14 +3121,18 @@ class MasterView(View):
config.add_view(cls, attr='populate', route_name='{}.populate'.format(route_prefix), config.add_view(cls, attr='populate', route_name='{}.populate'.format(route_prefix),
permission='{}.create'.format(permission_prefix)) permission='{}.create'.format(permission_prefix))
# bulk delete # enable/disable set
if cls.bulk_deletable: if cls.supports_set_enabled_toggle:
config.add_route('{}.bulk_delete'.format(route_prefix), '{}/bulk-delete'.format(url_prefix), config.add_tailbone_permission(permission_prefix, '{}.enable_disable_set'.format(permission_prefix),
"Enable / disable set (selection) of {}".format(model_title_plural))
config.add_route('{}.enable_set'.format(route_prefix), '{}/enable-set'.format(url_prefix),
request_method='POST') request_method='POST')
config.add_view(cls, attr='bulk_delete', route_name='{}.bulk_delete'.format(route_prefix), config.add_view(cls, attr='enable_set', route_name='{}.enable_set'.format(route_prefix),
permission='{}.bulk_delete'.format(permission_prefix)) permission='{}.enable_disable_set'.format(permission_prefix))
config.add_tailbone_permission(permission_prefix, '{}.bulk_delete'.format(permission_prefix), config.add_route('{}.disable_set'.format(route_prefix), '{}/disable-set'.format(url_prefix),
"Bulk delete {}".format(model_title_plural)) request_method='POST')
config.add_view(cls, attr='disable_set', route_name='{}.disable_set'.format(route_prefix),
permission='{}.enable_disable_set'.format(permission_prefix))
# delete set # delete set
if cls.set_deletable: if cls.set_deletable:
@ -3097,6 +3143,15 @@ class MasterView(View):
config.add_view(cls, attr='delete_set', route_name='{}.delete_set'.format(route_prefix), config.add_view(cls, attr='delete_set', route_name='{}.delete_set'.format(route_prefix),
permission='{}.delete_set'.format(permission_prefix)) permission='{}.delete_set'.format(permission_prefix))
# bulk delete
if cls.bulk_deletable:
config.add_route('{}.bulk_delete'.format(route_prefix), '{}/bulk-delete'.format(url_prefix),
request_method='POST')
config.add_view(cls, attr='bulk_delete', route_name='{}.bulk_delete'.format(route_prefix),
permission='{}.bulk_delete'.format(permission_prefix))
config.add_tailbone_permission(permission_prefix, '{}.bulk_delete'.format(permission_prefix),
"Bulk delete {}".format(model_title_plural))
# merge # merge
if cls.mergeable: if cls.mergeable:
config.add_route('{}.merge'.format(route_prefix), '{}/merge'.format(url_prefix)) config.add_route('{}.merge'.format(route_prefix), '{}/merge'.format(url_prefix))