From 3cedd02994ed13df5cf88f63fdabfb8c299b58f6 Mon Sep 17 00:00:00 2001 From: Sage Abdullah Date: Tue, 23 Jan 2024 20:32:27 +0000 Subject: [PATCH] Render filter count by counting the active filters client-side --- client/src/controllers/DrilldownController.ts | 40 ++++++++++++++----- .../wagtailadmin/shared/active_filters.html | 2 +- .../wagtailadmin/shared/headers/_filters.html | 1 + .../shared/headers/slim_header.html | 2 +- wagtail/admin/views/generic/base.py | 7 +++- 5 files changed, 39 insertions(+), 13 deletions(-) diff --git a/client/src/controllers/DrilldownController.ts b/client/src/controllers/DrilldownController.ts index ac1a8cf625..a227b03e7d 100644 --- a/client/src/controllers/DrilldownController.ts +++ b/client/src/controllers/DrilldownController.ts @@ -10,21 +10,44 @@ export class DrilldownController extends Controller { static values = { // Default: main menu. activeSubmenu: { default: '', type: String }, + countAttr: { default: '', type: String }, }; declare activeSubmenuValue: string; + declare countAttrValue: string; - declare readonly countTarget: HTMLElement; + declare readonly countTargets: HTMLElement[]; declare readonly menuTarget: HTMLElement; declare readonly toggleTargets: HTMLButtonElement[]; - connect() { - const filteredParams = new URLSearchParams(window.location.search); - this.countTarget.hidden = filteredParams.size === 0; - this.countTarget.textContent = filteredParams.size.toString(); + countTargetConnected() { + this.updateCount(); } - updateParamsCount(e: Event) { + /** + * Update the count of items in the menu. + * This is done by counting the number of elements with the data attribute + * specified by the countAttrValue value that have the same value as the + * data-count-name attribute of the countTarget. + * If the countTarget does not have a data-count-name attribute, then all + * elements with the data attribute specified by the countAttrValue value + * are counted. + */ + updateCount() { + const total = document.querySelectorAll(`[${this.countAttrValue}]`).length; + this.countTargets.forEach((countTarget) => { + const name = countTarget.dataset.countName; + const count = name + ? document.querySelectorAll(`[${this.countAttrValue}=${name}]`).length + : total; + // eslint-disable-next-line no-param-reassign + countTarget.hidden = count === 0; + // eslint-disable-next-line no-param-reassign + countTarget.textContent = count.toString(); + }); + } + + updateParams(e: Event) { const swapEvent = e as CustomEvent<{ requestUrl: string }>; if ((e.target as HTMLElement)?.id === 'listing-results') { const params = new URLSearchParams( @@ -39,11 +62,8 @@ export class DrilldownController extends Controller { }); const queryString = `?${filteredParams.toString()}`; window.history.replaceState(null, '', queryString); - - // Update the drilldown’s count badge based on remaining filter parameters. - this.countTarget.hidden = filteredParams.size === 0; - this.countTarget.textContent = filteredParams.size.toString(); } + this.updateCount(); } open(e: MouseEvent) { diff --git a/wagtail/admin/templates/wagtailadmin/shared/active_filters.html b/wagtail/admin/templates/wagtailadmin/shared/active_filters.html index 9aff1f72f4..9e372ac473 100644 --- a/wagtail/admin/templates/wagtailadmin/shared/active_filters.html +++ b/wagtail/admin/templates/wagtailadmin/shared/active_filters.html @@ -1,7 +1,7 @@ {% load i18n wagtailadmin_tags %}
    {% for filter in active_filters %} -
  • +
  • {{ filter.field_label }}: {{ filter.value }} diff --git a/wagtail/admin/templates/wagtailadmin/shared/headers/_filters.html b/wagtail/admin/templates/wagtailadmin/shared/headers/_filters.html index 54b3c03eb4..b7dd7723a4 100644 --- a/wagtail/admin/templates/wagtailadmin/shared/headers/_filters.html +++ b/wagtail/admin/templates/wagtailadmin/shared/headers/_filters.html @@ -12,6 +12,7 @@ diff --git a/wagtail/admin/templates/wagtailadmin/shared/headers/slim_header.html b/wagtail/admin/templates/wagtailadmin/shared/headers/slim_header.html index 7edb9936e9..8fc44b9cff 100644 --- a/wagtail/admin/templates/wagtailadmin/shared/headers/slim_header.html +++ b/wagtail/admin/templates/wagtailadmin/shared/headers/slim_header.html @@ -79,7 +79,7 @@ {% endif %} {% if filters %} -
    +
    {% include "wagtailadmin/shared/headers/_filters.html" with filters=filters only %}
    {% endif %} diff --git a/wagtail/admin/views/generic/base.py b/wagtail/admin/views/generic/base.py index 5780493f1f..3516e07521 100644 --- a/wagtail/admin/views/generic/base.py +++ b/wagtail/admin/views/generic/base.py @@ -173,7 +173,7 @@ class BaseOperationView(BaseObjectMixin, View): # Represents a django-filters filter that is currently in force on a listing queryset ActiveFilter = namedtuple( - "ActiveFilter", ["field_label", "value", "removed_filter_url"] + "ActiveFilter", ["field_name", "field_label", "value", "removed_filter_url"] ) @@ -263,6 +263,7 @@ class BaseListingView(WagtailAdminTemplateMixin, BaseListView): for item in value: filters.append( ActiveFilter( + field_name, filter_def.label, field.label_from_instance(item), self.get_url_without_filter_param_value( @@ -274,6 +275,7 @@ class BaseListingView(WagtailAdminTemplateMixin, BaseListView): field = filter_def.field filters.append( ActiveFilter( + field_name, filter_def.label, field.label_from_instance(value), self.get_url_without_filter_param(field_name), @@ -284,6 +286,7 @@ class BaseListingView(WagtailAdminTemplateMixin, BaseListView): end_date_display = date_format(value.stop) if value.stop else "" filters.append( ActiveFilter( + field_name, filter_def.label, "%s - %s" % (start_date_display, end_date_display), self.get_url_without_filter_param( @@ -295,6 +298,7 @@ class BaseListingView(WagtailAdminTemplateMixin, BaseListView): choices = {str(id): label for id, label in filter_def.field.choices} filters.append( ActiveFilter( + field_name, filter_def.label, choices.get(str(value), str(value)), self.get_url_without_filter_param(field_name), @@ -303,6 +307,7 @@ class BaseListingView(WagtailAdminTemplateMixin, BaseListView): else: filters.append( ActiveFilter( + field_name, filter_def.label, str(value), self.get_url_without_filter_param(field_name),