From 2e08285ed95c7a6b808f6c6ed9862cdc0ca76e50 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Bedna=C5=99=C3=ADk?= <jan.bednarik@gmail.com>
Date: Thu, 9 Sep 2021 22:45:32 +0200
Subject: [PATCH] elections2021: Program search

---
 elections2021/models.py                       | 33 +++++++++++++++----
 .../templates/elections2021/_pagination.html  |  8 ++---
 .../elections2021_program_page.html           | 29 +++++++++++++++-
 3 files changed, 58 insertions(+), 12 deletions(-)

diff --git a/elections2021/models.py b/elections2021/models.py
index 46654b9b..ead2809f 100644
--- a/elections2021/models.py
+++ b/elections2021/models.py
@@ -32,6 +32,7 @@ from wagtail.core.models import Page
 from wagtail.documents.blocks import DocumentChooserBlock
 from wagtail.images.blocks import ImageChooserBlock
 from wagtail.images.edit_handlers import ImageChooserPanel
+from wagtail.search import index
 from wagtailmetadata.models import MetadataPageMixin
 
 from calendar_utils.models import CalendarMixin
@@ -1238,15 +1239,21 @@ class Elections2021ProgramPage(
 
     @route(r"^$")
     def plan_all(self, request):
-        points = (
-            Elections2021ProgramPointPage.objects.live()
-            .specific()
-            .order_by("-default_order")
-        )
+        query = request.GET.get("q", None)
+        context = {"query": query, "show_app_banner": not query}
+        if query:
+            points = Elections2021ProgramPointPage.objects.search(query)
+        else:
+            points = (
+                Elections2021ProgramPointPage.objects.live()
+                .specific()
+                .order_by("-default_order")
+            )
+
         points = Paginator(points, PROGRAM_POINTS_PER_PAGE).get_page(
             request.GET.get("page")
         )
-        context = {"points": points}
+        context["points"] = points
         return self.render(request, context_overrides=context)
 
     @route(r"^plan/([a-z-]+)/$")
@@ -1497,7 +1504,9 @@ class BenefitBlock(blocks.StructBlock):
         template = "elections2021/_benefit_block.html"
 
 
-class Elections2021ProgramPointPage(SubpageMixin, MetadataPageMixin, Page):
+class Elections2021ProgramPointPage(
+    SubpageMixin, MetadataPageMixin, Page, index.Indexed
+):
     ### FIELDS
 
     annotation = RichTextField(
@@ -1772,6 +1781,16 @@ class Elections2021ProgramPointPage(SubpageMixin, MetadataPageMixin, Page):
     parent_page_types = ["elections2021.Elections2021ProgramPage"]
     subpage_types = []
 
+    ### SEARCH
+
+    search_fields = Page.search_fields + [
+        index.SearchField("annotation", boost=1.6),
+        index.SearchField("problem"),
+        index.SearchField("context"),
+        index.SearchField("ideal"),
+        index.SearchField("proposal"),
+    ]
+
     ### OTHERS
 
     base_form_class = ProgramPointPageForm
diff --git a/elections2021/templates/elections2021/_pagination.html b/elections2021/templates/elections2021/_pagination.html
index 97ff3613..4855e96b 100644
--- a/elections2021/templates/elections2021/_pagination.html
+++ b/elections2021/templates/elections2021/_pagination.html
@@ -4,7 +4,7 @@
   <nav class="pagination space-x-1">
 
     {% if paginator.has_previous %}
-    <a href="?page={{ paginator.previous_page_number }}" class="btn btn--icon btn--grey-125 btn--hoveractive btn--to-black btn--condensed btn--inverted-icon">
+    <a href="?page={{ paginator.previous_page_number }}{% if query %}&amp;q={{ query }}{% endif %}" class="btn btn--icon btn--grey-125 btn--hoveractive btn--to-black btn--condensed btn--inverted-icon">
       <div class="btn__body-wrap">
         <div class="btn__body ">předchozí</div>
         <div class="btn__icon ">
@@ -17,9 +17,9 @@
     {% if paginator.paginator.num_pages > 1 %}
       {% for i in paginator.paginator.page_range %}
         {% if i == paginator.number %}
-        <a href="?page={{ i }}" class="btn btn--grey-500 btn--condensed hidden md:inline-block">
+        <a href="?page={{ i }}{% if query %}&amp;q={{ query }}{% endif %}" class="btn btn--grey-500 btn--condensed hidden md:inline-block">
         {% else %}
-        <a href="?page={{ i }}" class="btn btn--grey-125 btn--hoveractive btn--to-black btn--condensed hidden md:inline-block">
+        <a href="?page={{ i }}{% if query %}&amp;q={{ query }}{% endif %}" class="btn btn--grey-125 btn--hoveractive btn--to-black btn--condensed hidden md:inline-block">
         {% endif %}
           <div class="btn__body ">{{ i }}</div>
         </a>
@@ -27,7 +27,7 @@
     {% endif %}
 
     {% if paginator.has_next %}
-    <a href="?page={{ paginator.next_page_number }}" class="btn btn--icon btn--grey-125 btn--hoveractive btn--to-black btn--condensed">
+    <a href="?page={{ paginator.next_page_number }}{% if query %}&amp;q={{ query }}{% endif %}" class="btn btn--icon btn--grey-125 btn--hoveractive btn--to-black btn--condensed">
       <div class="btn__body-wrap">
         <div class="btn__body ">další</div>
         <div class="btn__icon ">
diff --git a/elections2021/templates/elections2021/elections2021_program_page.html b/elections2021/templates/elections2021/elections2021_program_page.html
index 06f6394e..245aefdc 100644
--- a/elections2021/templates/elections2021/elections2021_program_page.html
+++ b/elections2021/templates/elections2021/elections2021_program_page.html
@@ -45,11 +45,32 @@
 <div class="container container--default pt-8 pb-16 lg:py-24">
   <div class="text-center">
 
+    <div>
+      <div class="mb-8 relative">
+        <form action="{{ page.root_page.program_page_url }}" method="get">
+          <label id="searchlabel" class="cursor-text block elevation-8 relative w-full bg-white shadow-sm px-8 py-7 text-left cursor-default focus:outline-none focus:ring-1 focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" aria-haspopup="listbox" aria-expanded="true" aria-labelledby="listbox-label">
+            <span class="flex items-center">
+              <i class="text-2xl ico--search"></i>
+              <input type="text" name="q" value="{{ query|default:"" }}" class="w-full ml-3 block truncate focus:outline-none" placeholder="Co Vás zajímá?">
+            </span>
+            <div href="#" class="mx-3 absolute inset-y-0 right-0 flex items-center py-8 no-underline hover:no-underline">
+              <button class="btn ">
+                <div class="btn__body bg-fxactivecolor text-black text-lg p-4">Zobrazit</div>
+              </button>
+            </div>
+          </label>
+        </form>
+      </div>
+    </div>
+
     {% if has_my_program %}
       <div id="progamswitch" class="switch mb-4">
         {% if active_my_program %}
           <span class="switch__item switch__item--active">Program pro mě</span>
           <a href="{% pageurl page %}" class="switch__item">Úplný program</a>
+        {% elif query %}
+          <a href="{% routablepageurl page "my_program" %}" class="switch__item">Program pro mě</a>
+          <a href="{% pageurl page %}" class="switch__item">Úplný program</a>
         {% else %}
           <a href="{% routablepageurl page "my_program" %}" class="switch__item">Program pro mě</a>
           <cpan class="switch__item switch__item--active">Úplný program</span>
@@ -118,9 +139,15 @@
 
   </div>
 
+  {% if query and not points %}
+    <div class="text-center mt-8">
+      <p class="para"><i>Žádný relevantní programový bod nenalezen. Zkuste vyhledat něco jiného.</i></p>
+    </div>
+  {% endif %}
+
   {% if show_pagination %}
     <div class="text-center mt-16">
-      {% include "elections2021/_pagination.html" with paginator=points %}
+      {% include "elections2021/_pagination.html" with paginator=points query=query %}
     </div>
   {% endif %}
 </div>
-- 
GitLab