Add option for list filter quick remove. #183

* add option for list filter quick remove

* move transform from css to python

* make template tag more resilient for unusual filters

* fix tests

* rename field, move rendering to template, change style

* fix tests
master
Éric 2022-10-11 12:15:21 -04:00 committed by GitHub
parent de2979219e
commit f8ace75f36
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 101 additions and 16 deletions

View File

@ -163,8 +163,10 @@ class ThemeAdmin(admin.ModelAdmin):
{
"classes": ("wide",),
"fields": (
"list_filter_highlight",
"list_filter_dropdown",
"list_filter_sticky",
"list_filter_removal_links",
),
},
),

View File

@ -0,0 +1,18 @@
# Generated by Django 4.0.7 on 2022-10-10 21:46
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('admin_interface', '0026_theme_list_filter_highlight'),
]
operations = [
migrations.AddField(
model_name='theme',
name='list_filter_removal_links',
field=models.BooleanField(default=False, verbose_name='quick remove links for active filters at top of sidebar'),
),
]

View File

@ -340,6 +340,10 @@ class Theme(models.Model):
list_filter_sticky = models.BooleanField(
default=True, verbose_name=_("sticky position")
)
list_filter_removal_links = models.BooleanField(
default=False, verbose_name=_(
"quick remove links for active filters at top of sidebar")
)
foldable_apps = models.BooleanField(default=True, verbose_name=_("foldable apps"))

View File

@ -376,12 +376,24 @@
border-radius: var(--admin-interface-module-border-radius);
}
.admin-interface .module.filtered #changelist-filter .changelist-filter-clear a {
font-size: 13px;
margin: .3em 0;
padding: 0 15px;
}
.admin-interface .module.filtered #changelist-filter .changelist-filter-clear a:focus,
.admin-interface .module.filtered #changelist-filter .changelist-filter-clear a:hover,
.admin-interface .module.filtered #changelist-filter #changelist-filter-clear a:focus,
.admin-interface .module.filtered #changelist-filter #changelist-filter-clear a:hover {
color: #666;
text-decoration: none;
}
.admin-interface .module.filtered #changelist-filter .changelist-filter-clear a span {
font-weight: bold;
}
.admin-interface .module.filtered #changelist-filter li a:focus,
.admin-interface .module.filtered #changelist-filter li a:hover {
color: #666;

View File

@ -0,0 +1,25 @@
{% extends "admin/change_list.html" %}
{% load i18n admin_list admin_interface_tags %}
{# copied from django 4.0.7 #}
{% block filters %}
{% if cl.has_filters %}
<div id="changelist-filter">
<h2>{% translate 'Filter' %}</h2>
{% if cl.has_active_filters %}
{% get_admin_interface_setting "list_filter_removal_links" as list_filter_removal_links %}
{% if list_filter_removal_links %}
{% for spec in cl.filter_specs %}{% admin_interface_filter_removal_link cl spec %}{% endfor %}
<h3 id="changelist-filter-clear">
<a href="{{ cl.clear_all_filters_qs }}">{% translate "Clear all filters" %} &#10006;</a>
</h3>
{% else %}
<h3 id="changelist-filter-clear">
<a href="{{ cl.clear_all_filters_qs }}">&#10006; {% translate "Clear all filters" %}</a>
</h3>
{% endif %}
{% endif %}
{% for spec in cl.filter_specs %}{% admin_list_filter cl spec %}{% endfor %}
</div>
{% endif %}
{% endblock %}

View File

@ -0,0 +1,6 @@
{% load admin_interface_tags %}
{% if spec.lookup_val or spec.value %}
<div class="changelist-filter-clear"><a href="{% admin_interface_clear_filter_qs cl spec %}">
{{ title|capfirst }}: <span>{{ selected_value }}</span> &#10006;
</a></div>
{% endif %}

View File

@ -6,6 +6,7 @@ import re
from django import template
from django.conf import settings
from django.template.loader import get_template
from django.utils import translation
from admin_interface.cache import get_cached_active_theme, set_cached_active_theme
@ -65,8 +66,8 @@ def get_admin_interface_languages(context):
return langs_data
@simple_tag(takes_context=True)
def get_admin_interface_theme(context):
@simple_tag()
def get_admin_interface_theme():
theme = get_cached_active_theme()
if not theme:
theme = Theme.get_active_theme()
@ -74,6 +75,12 @@ def get_admin_interface_theme(context):
return theme
@simple_tag()
def get_admin_interface_setting(setting):
theme = get_admin_interface_theme()
return getattr(theme, setting)
@simple_tag(takes_context=False)
def get_admin_interface_version():
return __version__
@ -88,3 +95,27 @@ def hash_string(text):
@simple_tag(takes_context=False)
def get_admin_interface_nocache():
return hash_string(__version__)
@simple_tag()
def admin_interface_clear_filter_qs(changelist, list_filter):
return changelist.get_query_string(remove=list_filter.expected_parameters())
@simple_tag()
def admin_interface_filter_removal_link(changelist, list_filter):
tpl = get_template('admin_interface/list_filter_removal_link.html')
title = list_filter.title
choices = [c for c in list_filter.choices(changelist) if c['selected']]
try:
value = choices[0]['display']
except (IndexError, KeyError):
value = '...'
return tpl.render({
'cl': changelist,
'spec': list_filter,
'selected_value': value,
'title': title,
})

View File

@ -102,20 +102,7 @@ class AdminInterfaceTemplateTagsTestCase(TestCase):
def test_get_theme(self):
Theme.objects.all().delete()
context = Context({})
theme = templatetags.get_admin_interface_theme(context)
self.assertEqual(theme.name, "Django")
rendered = self.__render_template(
"{% load admin_interface_tags %}"
"{% get_admin_interface_theme as theme %}"
"{{ theme.name }}",
context,
)
self.assertEqual(rendered, "Django")
def test_get_theme_with_request(self):
Theme.objects.all().delete()
context = Context({"request": self.request_factory.get("/")})
theme = templatetags.get_admin_interface_theme(context)
theme = templatetags.get_admin_interface_theme()
self.assertEqual(theme.name, "Django")
rendered = self.__render_template(
"{% load admin_interface_tags %}"