diff --git a/tailbone/templates/master/index.mako b/tailbone/templates/master/index.mako index d2215abe..b0ee17d6 100644 --- a/tailbone/templates/master/index.mako +++ b/tailbone/templates/master/index.mako @@ -28,6 +28,19 @@ <%def name="grid_tools()"> + ## grid totals + % if master.supports_grid_totals: + + {{ gridTotalsFetching ? "Working, please wait..." : "Show Totals" }} + +
+ Totals: {{ gridTotalsDisplay }} +
+ % endif + ## download search results % if master.results_downloadable and master.has_perm('download_results'): + % if master.supports_grid_totals: + ${grid.component_studly}Data.gridTotalsDisplay = null + ${grid.component_studly}Data.gridTotalsFetching = false + + ${grid.component_studly}.methods.gridTotalsFetch = function() { + this.gridTotalsFetching = true + + let url = '${url(f'{route_prefix}.fetch_grid_totals')}' + this.simpleGET(url, {}, response => { + this.gridTotalsDisplay = response.data.totals_display + this.gridTotalsFetching = false + }, response => { + this.gridTotalsFetching = false + }) + } + + ${grid.component_studly}.methods.appliedFiltersHook = function() { + this.gridTotalsDisplay = null + this.gridTotalsFetching = false + } + % endif + ## maybe auto-redirect to download latest results file % if download_results_path: ThisPage.methods.downloadResultsRedirect = function() { diff --git a/tailbone/views/master.py b/tailbone/views/master.py index c515da7b..04262124 100644 --- a/tailbone/views/master.py +++ b/tailbone/views/master.py @@ -107,6 +107,7 @@ class MasterView(View): set_deletable = False supports_autocomplete = False supports_set_enabled_toggle = False + supports_grid_totals = False populatable = False mergeable = False merge_handler = None @@ -1837,6 +1838,9 @@ class MasterView(View): self.request.session.flash("Deleted {} {}".format(len(objects), model_title_plural)) return self.redirect(self.get_index_url()) + def fetch_grid_totals(self): + return {'totals_display': "TODO: totals go here"} + def oneoff_import(self, importer, host_object=None): """ Basic helper method, to do a one-off import (or export, depending on @@ -5198,6 +5202,15 @@ class MasterView(View): config.add_view(cls, attr='download_results_rows', route_name='{}.download_results_rows'.format(route_prefix), permission='{}.download_results_rows'.format(permission_prefix)) + # fetch total hours + if cls.supports_grid_totals: + config.add_route(f'{route_prefix}.fetch_grid_totals', + f'{url_prefix}/fetch-grid-totals') + config.add_view(cls, attr='fetch_grid_totals', + route_name=f'{route_prefix}.fetch_grid_totals', + permission=f'{permission_prefix}.list', + renderer='json') + # configure if cls.configurable: config.add_tailbone_permission(permission_prefix, diff --git a/tailbone/views/members.py b/tailbone/views/members.py index d2a0e455..61b190c2 100644 --- a/tailbone/views/members.py +++ b/tailbone/views/members.py @@ -406,6 +406,7 @@ class MemberEquityPaymentView(MasterView): model_class = model.MemberEquityPayment route_prefix = 'member_equity_payments' url_prefix = '/member-equity-payments' + supports_grid_totals = True has_versions = True grid_columns = [ @@ -470,6 +471,12 @@ class MemberEquityPaymentView(MasterView): key = getattr(payment.member, field) return key + def fetch_grid_totals(self): + app = self.get_rattail_app() + results = self.get_effective_data() + total = sum([payment.amount for payment in results]) + return {'totals_display': app.render_currency(total)} + def configure_form(self, f): super().configure_form(f) model = self.model