Implement filtering on reports

pull/5959/head
Karl Hobley 2020-03-19 13:59:22 +00:00 zatwierdzone przez Matt Westcott
rodzic a11de58a63
commit 92c2cedb67
9 zmienionych plików z 145 dodań i 4 usunięć

Wyświetl plik

@ -0,0 +1,21 @@
.button-select {
&__option {
display: block;
width: 100%;
margin-bottom: 10px;
background-color: #fff;
border-color: $color-teal;
color: #262626;
&--selected {
background-color: $color-teal;
color: #fff;
}
}
}
.button-select .button-select__option {
/* override default margin from horizontally-aligned buttons */
margin-left: 0;
}

Wyświetl plik

@ -128,6 +128,7 @@ These are classes for components.
@import 'components/link.legacy';
@import 'components/privacy-indicator';
@import 'components/status-tag';
@import 'components/button-select';
/* OVERRIDES

Wyświetl plik

@ -0,0 +1,31 @@
import django_filters
from django import forms
from django.utils.translation import gettext_lazy as _
from wagtail.core.models import Page
class ButtonSelect(forms.Select):
input_type = 'hidden'
template_name = 'wagtailadmin/widgets/button_select.html'
option_template_name = 'wagtailadmin/widgets/button_select_option.html'
class WagtailFilterSet(django_filters.FilterSet):
@classmethod
def filter_for_lookup(cls, field, lookup_type):
filter_class, params = super().filter_for_lookup(field, lookup_type)
if filter_class == django_filters.ChoiceFilter:
params.setdefault('widget', ButtonSelect)
params.setdefault('empty_label', _("All"))
return filter_class, params
class LockedPagesReportFilterSet(WagtailFilterSet):
class Meta:
model = Page
fields = ['title', 'locked_by', 'locked_at']

Wyświetl plik

@ -538,6 +538,28 @@ wagtail = (function(document, window, wagtail) {
$(document).ready(initDropDowns);
wagtail.ui.initDropDowns = initDropDowns;
wagtail.ui.DropDownController = DropDownController;
// Initialise button selectors
function initButtonSelects() {
document.querySelectorAll('.button-select').forEach(function(element) {
var inputElement = element.querySelector('input[type="hidden"]');
element.querySelectorAll('.button-select__option').forEach(function(buttonElement) {
buttonElement.addEventListener('click', function(e) {
e.preventDefault();
inputElement.value = buttonElement.value;
element.querySelectorAll('.button-select__option--selected').forEach(function(selectedButtonElement) {
selectedButtonElement.classList.remove('button-select__option--selected');
});
buttonElement.classList.add('button-select__option--selected');
});
});
});
}
$(document).ready(initButtonSelects);
return wagtail;
})(document, window, wagtail);

Wyświetl plik

@ -0,0 +1,23 @@
.report {
display: grid;
grid-template-columns: auto;
grid-column-gap: 50px;
margin-left: 50px;
margin-right: 50px;
&--has-filters {
grid-template-columns: auto 300px;
}
&__results {
grid-column-start: col-start 1 col-end 2;
}
&__filters {
grid-column-start: col-start -2 col-end -1;
button[type='submit'] {
margin-top: 20px;
}
}
}

Wyświetl plik

@ -27,8 +27,27 @@
</div>
</header>
<div class="nice-padding">
{% block results %}
{% endblock %}
<div class="report{% if filters %} report--has-filters{% endif %}">
<div class="report__results">
{% block results %}
{% endblock %}
</div>
{% if filters %}
<div class="report__filters">
<h2>{% trans 'Filter' %}</h2>
<form method="get">
{% for filter in filters.form %}
{{ filter.label_tag }}
{{ filter }}
{{ filter.errors }}
{% endfor %}
<button class="button button-longrunning" type="submit">{% trans 'Apply filters' %}</button>
</form>
</div>
{% endif %}
</div>
{% endblock %}
{% block extra_css %}
<link rel="stylesheet" href="{% versioned_static 'wagtailadmin/css/layouts/report.css' %}" type="text/css" />
{% endblock %}

Wyświetl plik

@ -0,0 +1,12 @@
<div class="button-select">
<input type="hidden" name="{{ widget.name }}" value="{{ widget.value.0 }}" {% include "django/forms/widgets/attrs.html" %}>
{% for group_name, group_choices, group_index in widget.optgroups %}
{% if group_name %}
<h4>{{ group_name }}</h4>
{% endif %}
{% for option in group_choices %}
{% include option.template_name with widget=option %}
{% endfor %}
{% endfor %}
</div>

Wyświetl plik

@ -0,0 +1 @@
<button class="button button-select__option{% if widget.attrs.selected %} button-select__option--selected{% endif %}" value="{{ widget.value|stringformat:'s' }}">{{ widget.label }}</button>

Wyświetl plik

@ -11,6 +11,7 @@ from django.views.generic.list import BaseListView
from xlsxwriter.workbook import Workbook
from wagtail.admin.auth import permission_denied
from wagtail.admin.filters import LockedPagesReportFilterSet
from wagtail.core.models import UserPagePermissionsProxy
@ -186,6 +187,7 @@ class ReportView(SpreadsheetExportMixin, TemplateResponseMixin, BaseListView):
template_name = "wagtailadmin/reports/base_report.html"
title = ""
paginate_by = 50
filterset_class = None
def dispatch(self, request, *args, **kwargs):
self.is_export = self.request.GET.get("export") in self.FORMATS
@ -195,9 +197,17 @@ class ReportView(SpreadsheetExportMixin, TemplateResponseMixin, BaseListView):
return super().dispatch(request, *args, **kwargs)
def get_context_data(self, *args, object_list=None, **kwargs):
context = super().get_context_data(*args, object_list=object_list, **kwargs)
filters = None
queryset = object_list if object_list is not None else self.object_list
if self.filterset_class:
filters = self.filterset_class(self.request.GET, queryset=queryset)
queryset = filters.qs
context = super().get_context_data(*args, object_list=queryset, **kwargs)
context["title"] = self.title
context["header_icon"] = self.header_icon
context["filters"] = filters
return context
@ -224,6 +234,7 @@ class LockedPagesView(PageReportView):
"locked_at",
"locked_by",
]
filterset_class = LockedPagesReportFilterSet
def get_filename(self):
return "locked-pages-report-{}".format(