Browse Source

Move filters to be inside the search form and use AJAX to submit the form

Also make the search form optional. The <form> element may still be
rendered as if there is either the search form or the filters, or both.
Sage Abdullah 1 năm trước cách đây
mục cha
commit
d792346752

+ 4 - 4
client/scss/components/_header.scss

@@ -171,11 +171,11 @@
 
 .w-slim-header {
   &__search-form {
-    @apply w-mx-2;
+    @apply w-mx-2 w-flex w-items-center w-gap-2;
+  }
 
-    .w-field__wrapper {
-      @apply w-mb-0;
-    }
+  .w-field__wrapper:not(.w-dialog .w-field__wrapper) {
+    @apply w-mb-0;
 
     .w-field__input {
       @apply w-mt-0;

+ 21 - 16
wagtail/admin/templates/wagtailadmin/shared/headers/slim_header.html

@@ -58,21 +58,37 @@
             </div>
 
             {% block search_form %}
-                {% if search_url and search_form %}
+                {% if not search_url %}
+                {% elif search_form or filters %}
                     <form
                         action="{{ search_url }}"
                         method="get"
                         class="w-slim-header__search-form"
                         novalidate
                         role="search"
+                        data-search-form
                         data-controller="w-swap"
-                        data-action="change->w-swap#searchLazy input->w-swap#searchLazy"
+                        data-action="change->w-swap#submitLazy input->w-swap#submitLazy"
                         data-w-swap-src-value="{{ search_url }}"
                         data-w-swap-target-value="#listing-results"
                     >
-                        {% for field in search_form %}
-                            {% formattedfield field=field sr_only_label=True icon="search" %}
-                        {% endfor %}
+                        {% if search_form %}
+                            {% for field in search_form %}
+                                {% formattedfield field=field sr_only_label=True icon="search" %}
+                            {% endfor %}
+                        {% endif %}
+
+                        {% if filters %}
+                            {% fragment as filters_icon %}{% icon name="sliders" title=_("Show filters") %}{% endfragment %}
+                            {% dialog_toggle classname="w-filter-button" dialog_id="filters-dialog" text=filters_icon %}
+
+                            {% dialog theme="floating" id="filters-dialog" title=_("Filters") dialog_root_selector="[data-search-form]" %}
+                                {% for field in filters.form %}
+                                    {% formattedfield field %}
+                                {% endfor %}
+                            {% enddialog %}
+                        {% endif %}
+
                         {% comment %}
                             Add an initial disabled & hidden submit button so that
                             pressing 'Enter' will not submit form. Reload is not
@@ -83,17 +99,6 @@
                 {% endif %}
             {% endblock %}
 
-            {% block filters %}
-                {% if filters %}
-                    {% fragment as filters_icon %}{% icon name="sliders" title=_("Show filters") %}{% endfragment %}
-                    {% dialog_toggle classname="w-filter-button" dialog_id="filters-dialog" text=filters_icon %}
-
-                    {% dialog theme="floating" id="filters-dialog" title=_("Filters") %}
-                        {% include "wagtailadmin/shared/filters.html" %}
-                    {% enddialog %}
-                {% endif %}
-            {% endblock %}
-
             <div class="w-w-full sm:w-w-min w-flex sm:w-flex-nowrap sm:w-flex-row w-items-center w-p-0 sm:w-py-0 sm:w-pr-4 sm:w-justify-end">
                 {% block toggles %}
                     {% if side_panels %}

+ 0 - 5
wagtail/admin/tests/viewsets/test_model_viewset.py

@@ -250,7 +250,6 @@ class TestListFilter(WagtailTestUtils, TestCase):
         for case, (url_namespace, lookup, label_text) in self.cases.items():
             with self.subTest(case=case):
                 response = self.get(url_namespace)
-                self.assertTemplateUsed(response, "wagtailadmin/shared/filters.html")
                 self.assertContains(
                     response,
                     "There are no feature complete toys to display",
@@ -273,7 +272,6 @@ class TestListFilter(WagtailTestUtils, TestCase):
         for case, (url_namespace, lookup, label_text) in self.cases.items():
             with self.subTest(case=case):
                 response = self.get(url_namespace)
-                self.assertTemplateUsed(response, "wagtailadmin/shared/filters.html")
                 self.assertContains(response, "Buzz Lightyear")
                 self.assertContains(response, "Forky")
                 self.assertNotContains(response, "There are 2 matches")
@@ -297,7 +295,6 @@ class TestListFilter(WagtailTestUtils, TestCase):
         for case, (url_namespace, lookup, label_text) in self.cases.items():
             with self.subTest(case=case):
                 response = self.get(url_namespace, {lookup: ""})
-                self.assertTemplateUsed(response, "wagtailadmin/shared/filters.html")
                 self.assertContains(response, "Buzz Lightyear")
                 self.assertContains(response, "Forky")
                 self.assertNotContains(response, "There are 2 matches")
@@ -324,7 +321,6 @@ class TestListFilter(WagtailTestUtils, TestCase):
             with self.subTest(case=case):
                 value = lookup_values[lookup]
                 response = self.get(url_namespace, {lookup: value})
-                self.assertTemplateUsed(response, "wagtailadmin/shared/filters.html")
                 self.assertContains(
                     response,
                     "No feature complete toys match your query",
@@ -351,7 +347,6 @@ class TestListFilter(WagtailTestUtils, TestCase):
             with self.subTest(case=case):
                 value = lookup_values[lookup]
                 response = self.get(url_namespace, {lookup: value})
-                self.assertTemplateUsed(response, "wagtailadmin/shared/filters.html")
                 self.assertContains(response, "Buzz Lightyear")
                 self.assertContains(response, "There is 1 match")
                 self.assertNotContains(response, "Forky")

+ 1 - 1
wagtail/admin/views/generic/models.py

@@ -150,7 +150,7 @@ class IndexView(
         return self.index_url_name
 
     def get_search_form(self):
-        if self.model is None:
+        if self.model is None or not self.is_searchable:
             return None
 
         if self.is_searchable and self.search_kwarg in self.request.GET:

+ 0 - 13
wagtail/snippets/tests/test_viewset.py

@@ -443,12 +443,10 @@ class TestFilterSetClass(BaseSnippetViewSetTests):
             '<label for="id_country_code_0"><input type="radio" name="country_code" value="" id="id_country_code_0" checked>All</label>',
             html=True,
         )
-        self.assertTemplateUsed(response, "wagtailadmin/shared/filters.html")
 
     def test_unfiltered_with_results(self):
         self.create_test_snippets()
         response = self.get()
-        self.assertTemplateUsed(response, "wagtailadmin/shared/filters.html")
         self.assertContains(response, "Nasi goreng from Indonesia")
         self.assertContains(response, "Fish and chips from the UK")
         self.assertNotContains(response, "There are 2 matches")
@@ -461,7 +459,6 @@ class TestFilterSetClass(BaseSnippetViewSetTests):
     def test_empty_filter_with_results(self):
         self.create_test_snippets()
         response = self.get({"country_code": ""})
-        self.assertTemplateUsed(response, "wagtailadmin/shared/filters.html")
         self.assertContains(response, "Nasi goreng from Indonesia")
         self.assertContains(response, "Fish and chips from the UK")
         self.assertNotContains(response, "There are 2 matches")
@@ -474,7 +471,6 @@ class TestFilterSetClass(BaseSnippetViewSetTests):
     def test_filtered_no_results(self):
         self.create_test_snippets()
         response = self.get({"country_code": "PH"})
-        self.assertTemplateUsed(response, "wagtailadmin/shared/filters.html")
         self.assertContains(
             response, "Sorry, no full-featured snippets match your query"
         )
@@ -487,7 +483,6 @@ class TestFilterSetClass(BaseSnippetViewSetTests):
     def test_filtered_with_results(self):
         self.create_test_snippets()
         response = self.get({"country_code": "ID"})
-        self.assertTemplateUsed(response, "wagtailadmin/shared/filters.html")
         self.assertContains(response, "Nasi goreng from Indonesia")
         self.assertContains(response, "There is 1 match")
         self.assertContains(
@@ -522,7 +517,6 @@ class TestFilterSetClassSearch(WagtailTestUtils, TransactionTestCase):
     def test_filtered_searched_no_results(self):
         self.create_test_snippets()
         response = self.get({"country_code": "ID", "q": "chips"})
-        self.assertTemplateUsed(response, "wagtailadmin/shared/filters.html")
         self.assertContains(
             response, "Sorry, no full-featured snippets match your query"
         )
@@ -535,7 +529,6 @@ class TestFilterSetClassSearch(WagtailTestUtils, TransactionTestCase):
     def test_filtered_searched_with_results(self):
         self.create_test_snippets()
         response = self.get({"country_code": "UK", "q": "chips"})
-        self.assertTemplateUsed(response, "wagtailadmin/shared/filters.html")
         self.assertContains(response, "Fish and chips from the UK")
         self.assertContains(response, "There is 1 match")
         self.assertContains(
@@ -588,12 +581,10 @@ class TestListFilterWithList(BaseSnippetViewSetTests):
             '<input type="text" name="first_published_at" autocomplete="off" id="id_first_published_at">',
             html=True,
         )
-        self.assertTemplateUsed(response, "wagtailadmin/shared/filters.html")
 
     def test_unfiltered_with_results(self):
         self.create_test_snippets()
         response = self.get()
-        self.assertTemplateUsed(response, "wagtailadmin/shared/filters.html")
         self.assertContains(response, "The first created object")
         self.assertContains(response, "A second one after that")
         self.assertNotContains(response, "There are 2 matches")
@@ -611,7 +602,6 @@ class TestListFilterWithList(BaseSnippetViewSetTests):
     def test_empty_filter_with_results(self):
         self.create_test_snippets()
         response = self.get({"first_published_at": ""})
-        self.assertTemplateUsed(response, "wagtailadmin/shared/filters.html")
         self.assertContains(response, "The first created object")
         self.assertContains(response, "A second one after that")
         self.assertNotContains(response, "There are 2 matches")
@@ -629,7 +619,6 @@ class TestListFilterWithList(BaseSnippetViewSetTests):
     def test_filtered_no_results(self):
         self.create_test_snippets()
         response = self.get({"first_published_at": "1970-01-01"})
-        self.assertTemplateUsed(response, "wagtailadmin/shared/filters.html")
         self.assertContains(
             response,
             f"Sorry, no {self.model._meta.verbose_name_plural} match your query",
@@ -648,7 +637,6 @@ class TestListFilterWithList(BaseSnippetViewSetTests):
     def test_filtered_with_results(self):
         self.create_test_snippets()
         response = self.get({"first_published_at": self.date_str})
-        self.assertTemplateUsed(response, "wagtailadmin/shared/filters.html")
         self.assertContains(response, "A second one after that")
         self.assertContains(response, "There is 1 match")
         self.assertContains(
@@ -669,7 +657,6 @@ class TestListFilterWithDict(TestListFilterWithList):
     def test_filtered_contains_with_results(self):
         self.create_test_snippets()
         response = self.get({"text__contains": "second one"})
-        self.assertTemplateUsed(response, "wagtailadmin/shared/filters.html")
         self.assertContains(response, "A second one after that")
         self.assertContains(response, "There is 1 match")
         self.assertContains(