From 36fc9615ae33ad6116fdd276cda1fe0263147fdb Mon Sep 17 00:00:00 2001
From: Sage Abdullah <sage.abdullah@torchbox.com>
Date: Fri, 30 Aug 2024 12:50:20 +0100
Subject: [PATCH] Enable breadcrumbs in documents multiple upload view

---
 .../templates/wagtaildocs/multiple/add.html   | 65 +++++++++----------
 wagtail/documents/tests/test_admin_views.py   | 14 +++-
 wagtail/documents/views/multiple.py           | 20 +++++-
 3 files changed, 62 insertions(+), 37 deletions(-)

diff --git a/wagtail/documents/templates/wagtaildocs/multiple/add.html b/wagtail/documents/templates/wagtaildocs/multiple/add.html
index 9f88b2880f..b4fb2e1cce 100644
--- a/wagtail/documents/templates/wagtaildocs/multiple/add.html
+++ b/wagtail/documents/templates/wagtaildocs/multiple/add.html
@@ -1,4 +1,4 @@
-{% extends "wagtailadmin/base.html" %}
+{% extends "wagtailadmin/generic/base.html" %}
 {% load i18n %}
 {% load l10n %}
 {% load wagtailadmin_tags %}
@@ -9,43 +9,38 @@
     {{ form_media.css }}
 {% endblock %}
 
-{% block content %}
-    {% trans "Add documents" as add_str %}
-    {% include "wagtailadmin/shared/header.html" with title=add_str icon="doc-full-inverse" %}
+{% block main_content %}
+    <div class="drop-zone w-mt-8">
+        <p>{% trans "Drag and drop documents into this area to upload immediately." %}</p>
+        <p>{{ help_text }}</p>
 
-    <div class="nice-padding">
-        <div class="drop-zone">
-            <p>{% trans "Drag and drop documents into this area to upload immediately." %}</p>
-            <p>{{ help_text }}</p>
-
-            <form action="{% url 'wagtaildocs:add_multiple' %}" method="POST" enctype="multipart/form-data">
-                <div class="replace-file-input">
-                    <button class="button bicolor button--icon">{% icon name="plus" wrapped=1 %}{% trans "Or choose from your computer" %}</button>
-                    <input id="fileupload" type="file" name="files[]" data-url="{% url 'wagtaildocs:add_multiple' %}" multiple>
-                </div>
-                {% csrf_token %}
-                {% if collections %}
-                    {% trans "Add to collection:" as label_text %}
-                    {% rawformattedfield label_text=label_text id_for_label="id_adddocument_collection" classname="w-mx-auto w-mt-4 w-grid w-justify-center"  %}
-                        <select id="id_adddocument_collection" name="collection">
-                            {% for pk, display_name in collections.get_indented_choices %}
-                                <option value="{{ pk|unlocalize }}"{% if pk|unlocalize == selected_collection_id %} selected{% endif %}>
-                                    {{ display_name }}
-                                </option>
-                            {% endfor %}
-                        </select>
-                    {% endrawformattedfield %}
-                {% endif %}
-            </form>
-        </div>
-
-        <div id="overall-progress" class="progress progress-secondary">
-            <div class="bar" style="width: 0%;">0%</div>
-        </div>
-
-        <ul id="upload-list" class="upload-list multiple"></ul>
+        <form action="{% url 'wagtaildocs:add_multiple' %}" method="POST" enctype="multipart/form-data">
+            <div class="replace-file-input">
+                <button class="button bicolor button--icon">{% icon name="plus" wrapped=1 %}{% trans "Or choose from your computer" %}</button>
+                <input id="fileupload" type="file" name="files[]" data-url="{% url 'wagtaildocs:add_multiple' %}" multiple>
+            </div>
+            {% csrf_token %}
+            {% if collections %}
+                {% trans "Add to collection:" as label_text %}
+                {% rawformattedfield label_text=label_text id_for_label="id_adddocument_collection" classname="w-mx-auto w-mt-4 w-grid w-justify-center"  %}
+                    <select id="id_adddocument_collection" name="collection">
+                        {% for pk, display_name in collections.get_indented_choices %}
+                            <option value="{{ pk|unlocalize }}"{% if pk|unlocalize == selected_collection_id %} selected{% endif %}>
+                                {{ display_name }}
+                            </option>
+                        {% endfor %}
+                    </select>
+                {% endrawformattedfield %}
+            {% endif %}
+        </form>
     </div>
 
+    <div id="overall-progress" class="progress progress-secondary">
+        <div class="bar" style="width: 0%;">0%</div>
+    </div>
+
+    <ul id="upload-list" class="upload-list multiple"></ul>
+
     <template id="upload-list-item">
         <li class="row">
             <div class="left col3">
diff --git a/wagtail/documents/tests/test_admin_views.py b/wagtail/documents/tests/test_admin_views.py
index e93cc88f9f..aedd6052e1 100644
--- a/wagtail/documents/tests/test_admin_views.py
+++ b/wagtail/documents/tests/test_admin_views.py
@@ -9,6 +9,7 @@ from django.test.utils import override_settings
 from django.urls import reverse
 from django.utils.html import escape
 from django.utils.http import urlencode
+from django.utils.text import capfirst
 
 from wagtail.admin.admin_url_finder import AdminURLFinder
 from wagtail.documents import get_document_model, models
@@ -1025,7 +1026,7 @@ class TestDocumentDeleteView(WagtailTestUtils, TestCase):
         self.assertContains(response, "This document is referenced 0 times")
 
 
-class TestMultipleDocumentUploader(WagtailTestUtils, TestCase):
+class TestMultipleDocumentUploader(AdminTemplateTestUtils, WagtailTestUtils, TestCase):
     """
     This tests the multiple document upload views located in wagtaildocs/views/multiple.py
     """
@@ -1064,6 +1065,17 @@ class TestMultipleDocumentUploader(WagtailTestUtils, TestCase):
         self.assertEqual(response.status_code, 200)
         self.assertTemplateUsed(response, "wagtaildocs/multiple/add.html")
 
+        self.assertBreadcrumbsItemsRendered(
+            [
+                {
+                    "url": reverse("wagtaildocs:index"),
+                    "label": capfirst(self.doc._meta.verbose_name_plural),
+                },
+                {"url": "", "label": "Add documents"},
+            ],
+            response.content,
+        )
+
         # no collection chooser when only one collection exists
         self.assertNotContains(response, "id_adddocument_collection")
 
diff --git a/wagtail/documents/views/multiple.py b/wagtail/documents/views/multiple.py
index 4d7b2fd457..09591de15e 100644
--- a/wagtail/documents/views/multiple.py
+++ b/wagtail/documents/views/multiple.py
@@ -1,5 +1,10 @@
 import os.path
 
+from django.urls import reverse
+from django.utils.text import capfirst
+from django.utils.translation import gettext_lazy
+
+from wagtail.admin.views.generic.base import WagtailAdminTemplateMixin
 from wagtail.admin.views.generic.multiple_upload import AddView as BaseAddView
 from wagtail.admin.views.generic.multiple_upload import (
     CreateFromUploadView as BaseCreateFromUploadView,
@@ -15,10 +20,14 @@ from ..forms import get_document_form, get_document_multi_form
 from ..permissions import permission_policy
 
 
-class AddView(BaseAddView):
+class AddView(WagtailAdminTemplateMixin, BaseAddView):
     permission_policy = permission_policy
     template_name = "wagtaildocs/multiple/add.html"
+    header_icon = "doc-full-inverse"
+    page_title = gettext_lazy("Add documents")
+    _show_breadcrumbs = True
 
+    index_url_name = "wagtaildocs:index"
     edit_object_url_name = "wagtaildocs:edit_multiple"
     delete_object_url_name = "wagtaildocs:delete_multiple"
     edit_object_form_prefix = "doc"
@@ -31,6 +40,15 @@ class AddView(BaseAddView):
     context_upload_name = "uploaded_document"
     context_upload_id_name = "uploaded_file_id"
 
+    def get_breadcrumbs_items(self):
+        return self.breadcrumbs_items + [
+            {
+                "url": reverse(self.index_url_name),
+                "label": capfirst(self.model._meta.verbose_name_plural),
+            },
+            {"url": "", "label": self.get_page_title()},
+        ]
+
     def get_model(self):
         return get_document_model()