0
0
mirror of https://github.com/wagtail/wagtail.git synced 2024-11-25 05:02:57 +01:00

Render filter count by counting the active filters client-side

This commit is contained in:
Sage Abdullah 2024-01-23 20:32:27 +00:00 committed by Thibaud Colas
parent a8bf1ab868
commit 3cedd02994
5 changed files with 39 additions and 13 deletions

View File

@ -10,21 +10,44 @@ export class DrilldownController extends Controller<HTMLElement> {
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<HTMLElement> {
});
const queryString = `?${filteredParams.toString()}`;
window.history.replaceState(null, '', queryString);
// Update the drilldowns count badge based on remaining filter parameters.
this.countTarget.hidden = filteredParams.size === 0;
this.countTarget.textContent = filteredParams.size.toString();
}
this.updateCount();
}
open(e: MouseEvent) {

View File

@ -1,7 +1,7 @@
{% load i18n wagtailadmin_tags %}
<ul class="w-active-filters">
{% for filter in active_filters %}
<li class="w-pill">
<li class="w-pill" data-w-active-filter-name="{{ filter.field_name }}">
<div class="w-pill__content">
<span class="w-text-14">{{ filter.field_label }}:</span>
<b class="w-ml-1">{{ filter.value }}</b>

View File

@ -12,6 +12,7 @@
<button class="w-drilldown__toggle" type="button" aria-expanded="false" aria-controls="drilldown-{{ field.auto_id }}" data-w-drilldown-target="toggle" data-action="click->w-drilldown#open">
{{ field.label }}
<div class="w-flex w-items-center w-gap-2">
<span class="w-drilldown__count" data-w-drilldown-target="count" data-count-name="{{ field.name }}" hidden></span>
{% icon name="arrow-right" %}
</div>
</button>

View File

@ -79,7 +79,7 @@
{% endif %}
{% if filters %}
<div id="filters-drilldown" class="w-drilldown" data-controller="w-drilldown" data-action="w-swap:success@document->w-drilldown#updateParamsCount w-dropdown:hide->w-drilldown#delayedClose">
<div id="filters-drilldown" class="w-drilldown" data-controller="w-drilldown" data-action="w-swap:success@document->w-drilldown#updateParams w-dropdown:hide->w-drilldown#delayedClose" data-w-drilldown-count-attr-value="data-w-active-filter-name">
{% include "wagtailadmin/shared/headers/_filters.html" with filters=filters only %}
</div>
{% endif %}

View File

@ -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),