kopia lustrzana https://github.com/wagtail/wagtail
				
				
				
			Add breadcrumbs and new Page Editor side panels to Snippets views (#8623)
							rodzic
							
								
									bc0f561240
								
							
						
					
					
						commit
						952edd84c7
					
				| 
						 | 
				
			
			@ -10,7 +10,7 @@
 | 
			
		|||
 | 
			
		||||
    <div class="w-sticky w-top-0 w-z-header">
 | 
			
		||||
        {% include 'wagtailadmin/shared/headers/page_create_header.html' %}
 | 
			
		||||
        {% include "wagtailadmin/shared/page_side_panels.html" %}
 | 
			
		||||
        {% include "wagtailadmin/shared/side_panels.html" %}
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <form id="page-edit-form" action="{% url 'wagtailadmin_pages:add' content_type.app_label content_type.model parent_page.id %}" method="POST" novalidate{% if form.is_multipart %} enctype="multipart/form-data"{% endif %}>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,7 +11,7 @@
 | 
			
		|||
 | 
			
		||||
    <div class="w-sticky w-top-0 w-z-header">
 | 
			
		||||
        {% include 'wagtailadmin/shared/headers/page_edit_header.html' %}
 | 
			
		||||
        {% include "wagtailadmin/shared/page_side_panels.html" %}
 | 
			
		||||
        {% include "wagtailadmin/shared/side_panels.html" %}
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    {% block form %}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,6 +12,6 @@
 | 
			
		|||
 | 
			
		||||
{% block actions %}
 | 
			
		||||
    {% with nav_icon_classes='w-w-4 w-h-4' nav_icon_button_classes='w-h-[50px] w-bg-transparent w-box-border w-py-3 w-px-3 w-flex w-justify-center w-items-center w-outline-offset-inside w-text-grey-400 w-transition hover:w-transform hover:w-scale-110 hover:w-text-primary focus:w-text-primary' %}
 | 
			
		||||
        {% include "wagtailadmin/shared/page_side_panel_toggles.html" %}
 | 
			
		||||
        {% include "wagtailadmin/shared/side_panel_toggles.html" %}
 | 
			
		||||
    {% endwith %}
 | 
			
		||||
{% endblock %}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,7 +16,7 @@
 | 
			
		|||
 | 
			
		||||
{% block actions %}
 | 
			
		||||
    {% with nav_icon_classes='w-w-4 w-h-4' nav_icon_button_classes='w-h-[50px] w-bg-transparent w-box-border w-py-3 w-px-3 w-flex w-justify-center w-items-center w-outline-offset-inside w-text-grey-400 w-transition hover:w-transform hover:w-scale-110 hover:w-text-primary focus:w-text-primary' %}
 | 
			
		||||
        {% include "wagtailadmin/shared/page_side_panel_toggles.html" %}
 | 
			
		||||
        {% include "wagtailadmin/shared/side_panel_toggles.html" %}
 | 
			
		||||
 | 
			
		||||
        {# Page history #}
 | 
			
		||||
        {% if page.get_latest_revision %}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,7 +8,7 @@
 | 
			
		|||
        {% trans 'Locale: ' as screen_reader_title_prefix %}
 | 
			
		||||
    {% endif %}
 | 
			
		||||
 | 
			
		||||
    {% if translations %}
 | 
			
		||||
    {% if object.pk and translations %}
 | 
			
		||||
        {% blocktrans trimmed asvar help_text %}
 | 
			
		||||
            Available in {{ translations_total }} locales
 | 
			
		||||
        {% endblocktrans %}
 | 
			
		||||
| 
						 | 
				
			
			@ -16,7 +16,7 @@
 | 
			
		|||
        {% trans 'No other translations' as help_text %}
 | 
			
		||||
    {% endif %}
 | 
			
		||||
 | 
			
		||||
    {% with icon_name='globe' title=object.locale.get_display_name %}
 | 
			
		||||
    {% with icon_name='globe' title=locale.get_display_name %}
 | 
			
		||||
        {{ block.super }}
 | 
			
		||||
    {% endwith %}
 | 
			
		||||
{% endblock %}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -31,9 +31,12 @@ class BaseStatusSidePanel(BaseSidePanel):
 | 
			
		|||
    toggle_icon_name = "info-circle"
 | 
			
		||||
 | 
			
		||||
    def get_status_templates(self, context):
 | 
			
		||||
        templates = [
 | 
			
		||||
            "wagtailadmin/shared/side_panels/includes/status/workflow.html",
 | 
			
		||||
        ]
 | 
			
		||||
        templates = []
 | 
			
		||||
 | 
			
		||||
        if self.object.pk:
 | 
			
		||||
            templates += [
 | 
			
		||||
                "wagtailadmin/shared/side_panels/includes/status/workflow.html",
 | 
			
		||||
            ]
 | 
			
		||||
 | 
			
		||||
        if context.get("locale"):
 | 
			
		||||
            templates += ["wagtailadmin/shared/side_panels/includes/status/locale.html"]
 | 
			
		||||
| 
						 | 
				
			
			@ -50,7 +53,7 @@ class BaseStatusSidePanel(BaseSidePanel):
 | 
			
		|||
class PageStatusSidePanel(BaseStatusSidePanel):
 | 
			
		||||
    def get_status_templates(self, context):
 | 
			
		||||
        templates = super().get_status_templates(context)
 | 
			
		||||
        if self.object.id:
 | 
			
		||||
        if self.object.pk:
 | 
			
		||||
            templates += ["wagtailadmin/shared/side_panels/includes/status/locked.html"]
 | 
			
		||||
        templates += ["wagtailadmin/shared/side_panels/includes/status/privacy.html"]
 | 
			
		||||
        return templates
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,9 +18,11 @@ from django.views.generic.list import BaseListView
 | 
			
		|||
from wagtail.admin import messages
 | 
			
		||||
from wagtail.admin.forms.search import SearchForm
 | 
			
		||||
from wagtail.admin.panels import get_edit_handler
 | 
			
		||||
from wagtail.admin.templatetags.wagtailadmin_tags import user_display_name
 | 
			
		||||
from wagtail.admin.ui.tables import Table, TitleColumn
 | 
			
		||||
from wagtail.log_actions import log
 | 
			
		||||
from wagtail.models import RevisionMixin
 | 
			
		||||
from wagtail.log_actions import registry as log_registry
 | 
			
		||||
from wagtail.models import DraftStateMixin, RevisionMixin
 | 
			
		||||
from wagtail.search.index import class_is_indexed
 | 
			
		||||
 | 
			
		||||
from .base import WagtailAdminTemplateMixin
 | 
			
		||||
| 
						 | 
				
			
			@ -105,7 +107,7 @@ class IndexView(
 | 
			
		|||
    def get_search_url(self):
 | 
			
		||||
        if not self.is_searchable:
 | 
			
		||||
            return None
 | 
			
		||||
        return self.get_index_url()
 | 
			
		||||
        return self.index_url_name
 | 
			
		||||
 | 
			
		||||
    def get_search_form(self):
 | 
			
		||||
        if self.model is None:
 | 
			
		||||
| 
						 | 
				
			
			@ -314,6 +316,11 @@ class EditView(
 | 
			
		|||
    error_message = None
 | 
			
		||||
    submit_button_label = gettext_lazy("Save")
 | 
			
		||||
 | 
			
		||||
    def setup(self, request, *args, **kwargs):
 | 
			
		||||
        super().setup(request, *args, **kwargs)
 | 
			
		||||
        self.revision_enabled = self.model and issubclass(self.model, RevisionMixin)
 | 
			
		||||
        self.draftstate_enabled = self.model and issubclass(self.model, DraftStateMixin)
 | 
			
		||||
 | 
			
		||||
    def get_object(self, queryset=None):
 | 
			
		||||
        if "pk" not in self.kwargs:
 | 
			
		||||
            self.kwargs["pk"] = self.args[0]
 | 
			
		||||
| 
						 | 
				
			
			@ -353,7 +360,7 @@ class EditView(
 | 
			
		|||
        self.has_content_changes = self.form.has_changed()
 | 
			
		||||
 | 
			
		||||
        # Save revision if the model inherits from RevisionMixin
 | 
			
		||||
        if isinstance(instance, RevisionMixin):
 | 
			
		||||
        if self.revision_enabled:
 | 
			
		||||
            revision = instance.save_revision(
 | 
			
		||||
                user=self.request.user,
 | 
			
		||||
                changed=self.has_content_changes,
 | 
			
		||||
| 
						 | 
				
			
			@ -385,6 +392,38 @@ class EditView(
 | 
			
		|||
            return None
 | 
			
		||||
        return self.error_message
 | 
			
		||||
 | 
			
		||||
    def get_live_last_updated_info(self):
 | 
			
		||||
        # DraftStateMixin is applied but object is not live
 | 
			
		||||
        if self.draftstate_enabled and not self.object.live:
 | 
			
		||||
            return None
 | 
			
		||||
 | 
			
		||||
        revision = None
 | 
			
		||||
        # DraftStateMixin is applied and object is live
 | 
			
		||||
        if self.draftstate_enabled and self.object.live_revision:
 | 
			
		||||
            revision = self.object.live_revision
 | 
			
		||||
        # RevisionMixin is applied, so object is assumed to be live
 | 
			
		||||
        elif self.revision_enabled and self.object.latest_revision:
 | 
			
		||||
            revision = self.object.latest_revision
 | 
			
		||||
 | 
			
		||||
        # No mixin is applied or no revision exists, fall back to latest log entry
 | 
			
		||||
        if not revision:
 | 
			
		||||
            return log_registry.get_logs_for_instance(self.object).first()
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            "timestamp": revision.created_at,
 | 
			
		||||
            "user_display_name": user_display_name(revision.user),
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    def get_draft_last_updated_info(self):
 | 
			
		||||
        if not (self.draftstate_enabled and self.object.has_unpublished_changes):
 | 
			
		||||
            return None
 | 
			
		||||
 | 
			
		||||
        revision = self.object.latest_revision
 | 
			
		||||
        return {
 | 
			
		||||
            "timestamp": revision.created_at,
 | 
			
		||||
            "user_display_name": user_display_name(revision.user),
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    def form_valid(self, form):
 | 
			
		||||
        self.form = form
 | 
			
		||||
        with transaction.atomic():
 | 
			
		||||
| 
						 | 
				
			
			@ -420,6 +459,12 @@ class EditView(
 | 
			
		|||
        if context["can_delete"]:
 | 
			
		||||
            context["delete_url"] = self.get_delete_url()
 | 
			
		||||
            context["delete_item_label"] = self.delete_item_label
 | 
			
		||||
 | 
			
		||||
        context["revision_enabled"] = self.revision_enabled
 | 
			
		||||
        context["draftstate_enabled"] = self.draftstate_enabled
 | 
			
		||||
 | 
			
		||||
        context["live_last_updated_info"] = self.get_live_last_updated_info()
 | 
			
		||||
        context["draft_last_updated_info"] = self.get_draft_last_updated_info()
 | 
			
		||||
        return context
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,43 @@
 | 
			
		|||
from wagtail.admin.ui.side_panels import BaseSidePanels, BaseStatusSidePanel
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class SnippetStatusSidePanel(BaseStatusSidePanel):
 | 
			
		||||
    def get_status_templates(self, context):
 | 
			
		||||
        templates = []
 | 
			
		||||
 | 
			
		||||
        if self.object.pk:
 | 
			
		||||
            templates += [
 | 
			
		||||
                "wagtailsnippets/snippets/side_panels/includes/status/workflow.html",
 | 
			
		||||
            ]
 | 
			
		||||
 | 
			
		||||
        if context.get("locale"):
 | 
			
		||||
            templates += ["wagtailadmin/shared/side_panels/includes/status/locale.html"]
 | 
			
		||||
 | 
			
		||||
        return templates
 | 
			
		||||
 | 
			
		||||
    def get_context_data(self, parent_context):
 | 
			
		||||
        context = super().get_context_data(parent_context)
 | 
			
		||||
        inherit = [
 | 
			
		||||
            "view",
 | 
			
		||||
            "revision_enabled",
 | 
			
		||||
            "draftstate_enabled",
 | 
			
		||||
            "live_last_updated_info",
 | 
			
		||||
            "draft_last_updated_info",
 | 
			
		||||
            "locale",
 | 
			
		||||
            "translations",
 | 
			
		||||
        ]
 | 
			
		||||
        context.update({k: parent_context.get(k) for k in inherit})
 | 
			
		||||
 | 
			
		||||
        translations = context.get("translations")
 | 
			
		||||
        if translations:
 | 
			
		||||
            context["translations_total"] = len(context["translations"]) + 1
 | 
			
		||||
 | 
			
		||||
        context["status_templates"] = self.get_status_templates(context)
 | 
			
		||||
        return context
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class SnippetSidePanels(BaseSidePanels):
 | 
			
		||||
    def __init__(self, request, object):
 | 
			
		||||
        self.side_panels = [
 | 
			
		||||
            SnippetStatusSidePanel(object, request),
 | 
			
		||||
        ]
 | 
			
		||||
| 
						 | 
				
			
			@ -1,9 +1,15 @@
 | 
			
		|||
{% extends "wagtailadmin/base.html" %}
 | 
			
		||||
{% load i18n wagtailadmin_tags %}
 | 
			
		||||
{% block titletag %}{% blocktrans trimmed with snippet_type_name=model_opts.verbose_name %}New  {{ snippet_type_name }}{% endblocktrans %}{% endblock %}
 | 
			
		||||
{% block bodyclass %}page-editor create model-{{ model_opts.model_name }}{% endblock %}
 | 
			
		||||
{% block content %}
 | 
			
		||||
    <div class="w-sticky w-top-0 w-z-header">
 | 
			
		||||
        {% include 'wagtailsnippets/snippets/headers/create_header.html' %}
 | 
			
		||||
        {% include "wagtailadmin/shared/side_panels.html" %}
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    {% trans "New" as new_str %}
 | 
			
		||||
    {% include "wagtailadmin/shared/header_with_locale_selector.html" with title=new_str subtitle=model_opts.verbose_name icon="snippet" merged=1 locale=locale translations=translations only %}
 | 
			
		||||
    {% include "wagtailadmin/shared/header.html" with title=new_str subtitle=model_opts.verbose_name icon="snippet" merged=1 only %}
 | 
			
		||||
 | 
			
		||||
    <form action="{{ action_url }}" method="POST" novalidate{% if form.is_multipart %} enctype="multipart/form-data"{% endif %}>
 | 
			
		||||
        {% csrf_token %}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,9 +1,14 @@
 | 
			
		|||
{% extends "wagtailadmin/base.html" %}
 | 
			
		||||
{% load wagtailadmin_tags i18n %}
 | 
			
		||||
{% block titletag %}{% blocktrans trimmed with snippet_type_name=model_opts.verbose_name %}Editing {{ snippet_type_name }} - {{ instance }}{% endblocktrans %}{% endblock %}
 | 
			
		||||
{% block titletag %}{% blocktrans trimmed with snippet_type_name=model_opts.verbose_name %}Editing {{ snippet_type_name }} - {{ object }}{% endblocktrans %}{% endblock %}
 | 
			
		||||
{% block bodyclass %}page-editor model-{{ model_opts.model_name }} {% endblock %}
 | 
			
		||||
{% block content %}
 | 
			
		||||
    {% trans "Editing" as editing_str %}
 | 
			
		||||
    {% include "wagtailsnippets/snippets/_header_with_history.html" with title=editing_str subtitle=instance icon="snippet" merged=1 locale=locale translations=translations latest_log_entry=latest_log_entry history_url=history_url model_opts=model_opts instance=instance only %}
 | 
			
		||||
    <div class="w-sticky w-top-0 w-z-header">
 | 
			
		||||
        {% include 'wagtailsnippets/snippets/headers/edit_header.html' %}
 | 
			
		||||
        {% include "wagtailadmin/shared/side_panels.html" %}
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    {% include "wagtailadmin/shared/header.html" with title=object icon="snippet" merged=1 only %}
 | 
			
		||||
 | 
			
		||||
    <div class="row row-flush">
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -31,7 +36,7 @@
 | 
			
		|||
                <dl>
 | 
			
		||||
                    <dt>{% trans "Usage" %}</dt>
 | 
			
		||||
                    <dd>
 | 
			
		||||
                        <a href="{{ instance.usage_url }}">{% blocktrans trimmed count usage_count=instance.get_usage.count %}Used {{ usage_count }} time{% plural %}Used {{ usage_count }} times{% endblocktrans %}</a>
 | 
			
		||||
                        <a href="{{ object.usage_url }}">{% blocktrans trimmed count usage_count=object.get_usage.count %}Used {{ usage_count }} time{% plural %}Used {{ usage_count }} times{% endblocktrans %}</a>
 | 
			
		||||
                    </dd>
 | 
			
		||||
                </dl>
 | 
			
		||||
            </div>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,43 @@
 | 
			
		|||
{% extends 'wagtailadmin/shared/headers/slim_header.html' %}
 | 
			
		||||
{% load wagtailadmin_tags i18n %}
 | 
			
		||||
 | 
			
		||||
{# TODO: Replace this with wagtailadmin/shared/breadcrumbs.html once it's possible #}
 | 
			
		||||
 | 
			
		||||
{% block header_content %}
 | 
			
		||||
    {% with breadcrumb_link_classes='w-flex w-items-center w-h-full w-text-primary w-px-0.5 w-no-underline w-outline-offset-inside hover:w-underline hover:w-text-primary w-h-full' breadcrumb_item_classes='w-h-full w-flex w-items-center w-overflow-hidden w-transition w-duration-300 w-whitespace-nowrap w-flex-shrink-0 w-font-bold w-text-14' icon_classes='w-w-4 w-h-4 w-ml-3' %}
 | 
			
		||||
        {# Breadcrumbs are visible on mobile by default but hidden on desktop #}
 | 
			
		||||
        <div class="w-breadcrumb w-flex w-flex-row w-items-center w-overflow-x-auto w-overflow-y-hidden w-scrollbar-thin" data-breadcrumb-next>
 | 
			
		||||
            <button
 | 
			
		||||
                type="button"
 | 
			
		||||
                data-toggle-breadcrumbs
 | 
			
		||||
                class="w-flex w-items-center w-justify-center w-box-border w-ml-0 w-p-4 w-w-[50px] w-h-full w-bg-transparent w-text-grey-400 w-transition hover:w-scale-110 hover:w-text-primary w-outline-offset-inside"
 | 
			
		||||
                aria-label="{% trans 'Toggle breadcrumbs' %}"
 | 
			
		||||
                aria-expanded="false"
 | 
			
		||||
            >
 | 
			
		||||
                {% icon name="breadcrumb-expand" class_name="w-w-4 w-h-4" %}
 | 
			
		||||
            </button>
 | 
			
		||||
 | 
			
		||||
            <div class="w-relative w-h-[50px] w-mr-4 w-top-0 w-z-20 w-flex w-items-center w-flex-row w-flex-1 sm:w-flex-none w-transition w-duration-300">
 | 
			
		||||
                <nav class="w-flex w-items-center w-flex-row w-h-full"
 | 
			
		||||
                    aria-label="{% trans 'Breadcrumb' %}">
 | 
			
		||||
                    <ol class="w-flex w-flex-row w-justify-start w-items-center w-h-full w-pl-0 w-my-0 w-gap-2 sm:w-gap-0 sm:w-space-x-2">
 | 
			
		||||
                        {% block breadcrumb_items %}
 | 
			
		||||
                            <li class="{{ breadcrumb_item_classes }} w-max-w-0" data-breadcrumb-item hidden>
 | 
			
		||||
                                <a class="{{ breadcrumb_link_classes }}" href="{% url 'wagtailsnippets:index' %}">
 | 
			
		||||
                                    {% trans "Snippets" %}
 | 
			
		||||
                                </a>
 | 
			
		||||
                                {% icon name="arrow-right" class_name=icon_classes %}
 | 
			
		||||
                            </li>
 | 
			
		||||
                            <li class="{{ breadcrumb_item_classes }} w-max-w-0" data-breadcrumb-item hidden>
 | 
			
		||||
                                <a class="{{ breadcrumb_link_classes }}" href="{% url view.index_url_name %}">
 | 
			
		||||
                                    {{ model_opts.verbose_name_plural|capfirst }}
 | 
			
		||||
                                </a>
 | 
			
		||||
                                {% icon name="arrow-right" class_name=icon_classes %}
 | 
			
		||||
                            </li>
 | 
			
		||||
                        {% endblock %}
 | 
			
		||||
                    </ol>
 | 
			
		||||
                </nav>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    {% endwith %}
 | 
			
		||||
{% endblock %}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,28 @@
 | 
			
		|||
{% extends 'wagtailsnippets/snippets/headers/_base_header.html' %}
 | 
			
		||||
{% load wagtailadmin_tags i18n %}
 | 
			
		||||
 | 
			
		||||
{% block breadcrumb_items %}
 | 
			
		||||
    {{ block.super }}
 | 
			
		||||
    <li class="{{ breadcrumb_item_classes }}">
 | 
			
		||||
        <div class="w-flex w-justify-start w-items-center">
 | 
			
		||||
            {{ title }}
 | 
			
		||||
        </div>
 | 
			
		||||
    </li>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block header_content %}
 | 
			
		||||
    {% with model_opts.verbose_name|capfirst as model_name %}
 | 
			
		||||
        {% trans 'New: '|add:model_name as title %}
 | 
			
		||||
        {{ block.super }}
 | 
			
		||||
 | 
			
		||||
        <h1 class="w-sr-only">
 | 
			
		||||
            {{ title }}
 | 
			
		||||
        </h1>
 | 
			
		||||
    {% endwith %}
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block actions %}
 | 
			
		||||
    {% with nav_icon_classes='w-w-4 w-h-4' nav_icon_button_classes='w-h-[50px] w-bg-transparent w-box-border w-py-3 w-px-3 w-flex w-justify-center w-items-center w-outline-offset-inside w-text-grey-400 w-transition hover:w-transform hover:w-scale-110 hover:w-text-primary focus:w-text-primary' %}
 | 
			
		||||
        {% include "wagtailadmin/shared/side_panel_toggles.html" %}
 | 
			
		||||
    {% endwith %}
 | 
			
		||||
{% endblock %}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,36 @@
 | 
			
		|||
{% extends 'wagtailsnippets/snippets/headers/_base_header.html' %}
 | 
			
		||||
{% load wagtailadmin_tags i18n %}
 | 
			
		||||
 | 
			
		||||
{% block breadcrumb_items %}
 | 
			
		||||
    {{ block.super }}
 | 
			
		||||
    <li class="{{ breadcrumb_item_classes }}">
 | 
			
		||||
        <a class="{{ breadcrumb_link_classes }}" href="{% url view.edit_url_name object.pk|admin_urlquote %}">
 | 
			
		||||
            {{ object }}
 | 
			
		||||
        </a>
 | 
			
		||||
    </li>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block header_content %}
 | 
			
		||||
    {{ block.super }}
 | 
			
		||||
 | 
			
		||||
    <h1 class="w-sr-only">
 | 
			
		||||
        {% blocktrans trimmed with title=object snippet_type=model_opts.verbose_name %}Editing {{ snippet_type }} {{ title }}{% endblocktrans %}
 | 
			
		||||
    </h1>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block actions %}
 | 
			
		||||
    {% with nav_icon_classes='w-w-4 w-h-4' nav_icon_button_classes='w-h-[50px] w-bg-transparent w-box-border w-py-3 w-px-3 w-flex w-justify-center w-items-center w-outline-offset-inside w-text-grey-400 w-transition hover:w-transform hover:w-scale-110 hover:w-text-primary focus:w-text-primary' %}
 | 
			
		||||
        {% include "wagtailadmin/shared/side_panel_toggles.html" %}
 | 
			
		||||
 | 
			
		||||
        {# Object history #}
 | 
			
		||||
        <a href="{{ history_url }}"
 | 
			
		||||
            class="{{ nav_icon_button_classes }}"
 | 
			
		||||
            data-tippy-content="{% trans 'History' %}"
 | 
			
		||||
            data-tippy-offset="[0, 0]"
 | 
			
		||||
            data-tippy-placement="bottom"
 | 
			
		||||
            aria-label="{% trans 'History' %}"
 | 
			
		||||
        >
 | 
			
		||||
            {% icon name="history" class_name=nav_icon_classes %}
 | 
			
		||||
        </a>
 | 
			
		||||
    {% endwith %}
 | 
			
		||||
{% endblock %}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,17 @@
 | 
			
		|||
{% extends 'wagtailsnippets/snippets/headers/_base_header.html' %}
 | 
			
		||||
{% load wagtailadmin_tags i18n %}
 | 
			
		||||
 | 
			
		||||
{% block breadcrumb_items %}
 | 
			
		||||
    {{ block.super }}
 | 
			
		||||
    <li class="{{ breadcrumb_item_classes }} w-max-w-0" data-breadcrumb-item hidden>
 | 
			
		||||
        <a class="{{ breadcrumb_link_classes }}" href="{% url view.edit_url_name object.pk|admin_urlquote %}">
 | 
			
		||||
            {{ object }}
 | 
			
		||||
        </a>
 | 
			
		||||
        {% icon name="arrow-right" class_name=icon_classes %}
 | 
			
		||||
    </li>
 | 
			
		||||
    <li class="{{ breadcrumb_item_classes }}">
 | 
			
		||||
        <div class="w-flex w-justify-start w-items-center">
 | 
			
		||||
            {% trans "History" %}
 | 
			
		||||
        </div>
 | 
			
		||||
    </li>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,16 @@
 | 
			
		|||
{% extends 'wagtailsnippets/snippets/headers/_base_header.html' %}
 | 
			
		||||
{% load wagtailadmin_tags i18n %}
 | 
			
		||||
 | 
			
		||||
{% block breadcrumb_items %}
 | 
			
		||||
    <li class="{{ breadcrumb_item_classes }} w-max-w-0" data-breadcrumb-item hidden>
 | 
			
		||||
        <a class="{{ breadcrumb_link_classes }}" href="{% url 'wagtailsnippets:index' %}">
 | 
			
		||||
            {% trans "Snippets" %}
 | 
			
		||||
        </a>
 | 
			
		||||
        {% icon name="arrow-right" class_name=icon_classes %}
 | 
			
		||||
    </li>
 | 
			
		||||
    <li class="{{ breadcrumb_item_classes }}">
 | 
			
		||||
        <a class="{{ breadcrumb_link_classes }}" href="{% url view.index_url_name %}">
 | 
			
		||||
            {{ model_opts.verbose_name_plural|capfirst }}
 | 
			
		||||
        </a>
 | 
			
		||||
    </li>
 | 
			
		||||
{% endblock breadcrumb_items %}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,17 @@
 | 
			
		|||
{% extends 'wagtailsnippets/snippets/headers/_base_header.html' %}
 | 
			
		||||
{% load wagtailadmin_tags i18n %}
 | 
			
		||||
 | 
			
		||||
{% block breadcrumb_items %}
 | 
			
		||||
    {{ block.super }}
 | 
			
		||||
    <li class="{{ breadcrumb_item_classes }} w-max-w-0" data-breadcrumb-item hidden>
 | 
			
		||||
        <a class="{{ breadcrumb_link_classes }}" href="{% url view.edit_url_name object.pk|admin_urlquote %}">
 | 
			
		||||
            {{ object }}
 | 
			
		||||
        </a>
 | 
			
		||||
        {% icon name="arrow-right" class_name=icon_classes %}
 | 
			
		||||
    </li>
 | 
			
		||||
    <li class="{{ breadcrumb_item_classes }}">
 | 
			
		||||
        <div class="w-flex w-justify-start w-items-center">
 | 
			
		||||
            {% trans "Usage" %}
 | 
			
		||||
        </div>
 | 
			
		||||
    </li>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
| 
						 | 
				
			
			@ -2,11 +2,18 @@
 | 
			
		|||
{% load i18n wagtailadmin_tags %}
 | 
			
		||||
 | 
			
		||||
{% block titletag %}{% blocktrans trimmed with title=subtitle %}Snippet history for {{ subtitle }}{% endblocktrans %}{% endblock %}
 | 
			
		||||
{% block bodyclass %}model-{{ model_opts.model_name }}{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block actions %}
 | 
			
		||||
    <a href="{% url view.edit_url_name object.pk|admin_urlquote %}" class="button bicolor icon icon-edit">{% trans "Edit this snippet" %}</a>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block content %}
 | 
			
		||||
    {% include 'wagtailsnippets/snippets/headers/history_header.html' %}
 | 
			
		||||
 | 
			
		||||
    {{ block.super }}
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block results %}
 | 
			
		||||
    {% if object_list %}
 | 
			
		||||
        {% component table %}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,61 @@
 | 
			
		|||
{% extends 'wagtailadmin/shared/side_panels/includes/action_list_item.html' %}
 | 
			
		||||
{% load wagtailadmin_tags i18n %}
 | 
			
		||||
 | 
			
		||||
{% comment %}
 | 
			
		||||
    This template is used to show Live, Draft, Live and Draft, In Moderation or Live and In Moderation.
 | 
			
		||||
    Sometimes {{ block.super }} will be called two times in the instances where the object is in multiple states eg. Live + Draft
 | 
			
		||||
{% endcomment %}
 | 
			
		||||
 | 
			
		||||
{% block content %}
 | 
			
		||||
    <div class="w-space-y-3">
 | 
			
		||||
        {% trans 'Status: ' as screen_reader_title_prefix %}
 | 
			
		||||
 | 
			
		||||
        {# Live section #}
 | 
			
		||||
        {% if live_last_updated_info %}
 | 
			
		||||
            {% trans 'Live' as title %}
 | 
			
		||||
            {% with icon_name='snippet' timestamp=live_last_updated_info.timestamp user_display_name=live_last_updated_info.user_display_name %}
 | 
			
		||||
                {% timesince_last_update timestamp user_display_name=user_display_name use_shorthand=True as help_text %}
 | 
			
		||||
                {% if draft_last_updated_info %}
 | 
			
		||||
                    {% with hide_action=True %}
 | 
			
		||||
                        {{ block.super }}
 | 
			
		||||
                    {% endwith %}
 | 
			
		||||
                {% else %}
 | 
			
		||||
                    {{ block.super }}
 | 
			
		||||
                {% endif %}
 | 
			
		||||
            {% endwith %}
 | 
			
		||||
        {% endif %}
 | 
			
		||||
 | 
			
		||||
        {# Draft section #}
 | 
			
		||||
        {% if draft_last_updated_info %}
 | 
			
		||||
            {% trans 'Draft' as title %}
 | 
			
		||||
            {% timesince_last_update draft_last_updated_info.timestamp user_display_name=draft_last_updated_info.user_display_name use_shorthand=True as help_text %}
 | 
			
		||||
 | 
			
		||||
            {# Icon #}
 | 
			
		||||
            {% with icon_name='draft' %}
 | 
			
		||||
                {{ block.super }}
 | 
			
		||||
            {% endwith %}
 | 
			
		||||
        {% endif %}
 | 
			
		||||
    </div>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block action %}
 | 
			
		||||
    {% with action_url=view.get_history_url %}
 | 
			
		||||
        {% trans 'View history' as action_text %}
 | 
			
		||||
        {{ block.super }}
 | 
			
		||||
    {% endwith %}
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block bottom %}
 | 
			
		||||
    {# Workflow Status #}
 | 
			
		||||
    {% with latest_revision=object.get_latest_revision %}
 | 
			
		||||
        {# Scheduled publishing #}
 | 
			
		||||
        {% if draftstate_enabled and latest_revision and latest_revision.approved_go_live_at %}
 | 
			
		||||
            <div class="w-flex w-space-x-3">
 | 
			
		||||
                {% icon name='info-circle' class_name='w-w-4 w-h-4 w-text-info-100 w-shrink-0' %}
 | 
			
		||||
                <div class="w-label-3 w-flex-1">
 | 
			
		||||
                    {% trans 'This will publish at ' %}{{ latest_revision.approved_go_live_at }}
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
        {% endif %}
 | 
			
		||||
    {% endwith %}
 | 
			
		||||
{% endblock %}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,9 +1,9 @@
 | 
			
		|||
{% extends "wagtailadmin/base.html" %}
 | 
			
		||||
{% load i18n wagtailadmin_tags %}
 | 
			
		||||
{% block titletag %}{% blocktrans trimmed with snippet_type_name_plural=model_opts.verbose_name_plural|capfirst %}Snippets {{ snippet_type_name_plural }}{% endblocktrans %}{% endblock %}
 | 
			
		||||
{% block bodyclass %}model-{{ model_opts.model_name }}{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block extra_js %}
 | 
			
		||||
    {{ block.super }}
 | 
			
		||||
    <script>
 | 
			
		||||
        window.headerSearch = {
 | 
			
		||||
            url: "{% url view.index_results_url_name %}",
 | 
			
		||||
| 
						 | 
				
			
			@ -17,17 +17,17 @@
 | 
			
		|||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block content %}
 | 
			
		||||
    {% include 'wagtailsnippets/snippets/headers/list_header.html' %}
 | 
			
		||||
 | 
			
		||||
    <header class="header">
 | 
			
		||||
        <div class="row">
 | 
			
		||||
            <div class="left">
 | 
			
		||||
                <div class="col">
 | 
			
		||||
                    <h1 class="header__title">
 | 
			
		||||
                        {% icon name="snippet" %}
 | 
			
		||||
                        {% blocktrans trimmed with snippet_type_name_plural=model_opts.verbose_name_plural|capfirst %}Snippets <span>{{ snippet_type_name_plural }}</span>{% endblocktrans %}
 | 
			
		||||
                        {% icon name="snippet" %} {{ model_opts.verbose_name_plural|capfirst }}
 | 
			
		||||
                    </h1>
 | 
			
		||||
                    {% if is_searchable and search_url %}
 | 
			
		||||
                        <form class="col search-form" action="{{ search_url }}" method="get" novalidate>
 | 
			
		||||
                        <form class="col search-form" action="{% url search_url %}" method="get" novalidate>
 | 
			
		||||
                            <ul class="fields">
 | 
			
		||||
                                {% for field in search_form %}
 | 
			
		||||
                                    {% include "wagtailadmin/shared/field_as_li.html" with field=field field_classes="field-small iconfield" icon="search" %}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,9 +1,13 @@
 | 
			
		|||
{% extends "wagtailadmin/base.html" %}
 | 
			
		||||
{% load i18n %}
 | 
			
		||||
{% block titletag %}{% blocktrans trimmed with title=instance %}Usage of {{ title }}{% endblocktrans %}{% endblock %}
 | 
			
		||||
{% load i18n wagtailadmin_tags %}
 | 
			
		||||
{% block titletag %}{% blocktrans trimmed with title=object %}Usage of {{ title }}{% endblocktrans %}{% endblock %}
 | 
			
		||||
{% block bodyclass %}model-{{ model_opts.model_name }}{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block content %}
 | 
			
		||||
    {% include 'wagtailsnippets/snippets/headers/usage_header.html' %}
 | 
			
		||||
 | 
			
		||||
    {% trans "Usage of" as usage_str %}
 | 
			
		||||
    {% include "wagtailadmin/shared/header.html" with title=usage_str subtitle=instance %}
 | 
			
		||||
    {% include "wagtailadmin/shared/header.html" with title=usage_str subtitle=object %}
 | 
			
		||||
 | 
			
		||||
    <div class="nice-padding">
 | 
			
		||||
        <table class="listing">
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -600,14 +600,7 @@ class TestLocaleSelectorOnCreate(TestCase, WagtailTestUtils):
 | 
			
		|||
            reverse("wagtailsnippets_snippetstests_translatablesnippet:add")
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        switch_to_french_url = (
 | 
			
		||||
            reverse("wagtailsnippets_snippetstests_translatablesnippet:add")
 | 
			
		||||
            + "?locale=fr"
 | 
			
		||||
        )
 | 
			
		||||
        self.assertContains(
 | 
			
		||||
            response,
 | 
			
		||||
            f'<a href="{switch_to_french_url}" aria-label="French" class="u-link is-live w-no-underline">',
 | 
			
		||||
        )
 | 
			
		||||
        self.assertContains(response, "Switch locales")
 | 
			
		||||
 | 
			
		||||
    @override_settings(WAGTAIL_I18N_ENABLED=False)
 | 
			
		||||
    def test_locale_selector_not_present_when_i18n_disabled(self):
 | 
			
		||||
| 
						 | 
				
			
			@ -615,25 +608,12 @@ class TestLocaleSelectorOnCreate(TestCase, WagtailTestUtils):
 | 
			
		|||
            reverse("wagtailsnippets_snippetstests_translatablesnippet:add")
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        switch_to_french_url = (
 | 
			
		||||
            reverse("wagtailsnippets_snippetstests_translatablesnippet:add")
 | 
			
		||||
            + "?locale=fr"
 | 
			
		||||
        )
 | 
			
		||||
        self.assertNotContains(
 | 
			
		||||
            response,
 | 
			
		||||
            f'<a href="{switch_to_french_url}" aria-label="French" class="u-link is-live w-no-underline">',
 | 
			
		||||
        )
 | 
			
		||||
        self.assertNotContains(response, "Switch locales")
 | 
			
		||||
 | 
			
		||||
    def test_locale_selector_not_present_on_non_translatable_snippet(self):
 | 
			
		||||
        response = self.client.get(reverse("wagtailsnippets_tests_advert:add"))
 | 
			
		||||
 | 
			
		||||
        switch_to_french_url = (
 | 
			
		||||
            reverse("wagtailsnippets_tests_advert:add") + "?locale=fr"
 | 
			
		||||
        )
 | 
			
		||||
        self.assertNotContains(
 | 
			
		||||
            response,
 | 
			
		||||
            f'<a href="{switch_to_french_url}" aria-label="French" class="u-link is-live w-no-underline">',
 | 
			
		||||
        )
 | 
			
		||||
        self.assertNotContains(response, "Switch locales")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class BaseTestSnippetEditView(TestCase, WagtailTestUtils):
 | 
			
		||||
| 
						 | 
				
			
			@ -692,10 +672,6 @@ class TestSnippetEditView(BaseTestSnippetEditView):
 | 
			
		|||
        self.assertTemplateUsed(response, "wagtailsnippets/snippets/edit.html")
 | 
			
		||||
        self.assertNotContains(response, 'role="tablist"')
 | 
			
		||||
 | 
			
		||||
        # "Last updated" timestamp should be present
 | 
			
		||||
        self.assertContains(
 | 
			
		||||
            response, 'data-wagtail-tooltip="Sept. 30, 2021, 10:01 a.m."'
 | 
			
		||||
        )
 | 
			
		||||
        # History link should be present
 | 
			
		||||
        self.assertContains(
 | 
			
		||||
            response,
 | 
			
		||||
| 
						 | 
				
			
			@ -928,8 +904,8 @@ class TestEditFileUploadSnippet(BaseTestSnippetEditView):
 | 
			
		|||
class TestLocaleSelectorOnEdit(BaseTestSnippetEditView):
 | 
			
		||||
    fixtures = ["test.json"]
 | 
			
		||||
 | 
			
		||||
    LOCALE_SELECTOR_HTML = '<a href="javascript:void(0)" aria-label="English" class="c-dropdown__button u-btn-current w-no-underline">'
 | 
			
		||||
    LOCALE_INDICATOR_HTML = '<use href="#icon-site"></use></svg>\n    English'
 | 
			
		||||
    LOCALE_SELECTOR_LABEL = "Switch locales"
 | 
			
		||||
    LOCALE_INDICATOR_HTML = '<h3 id="status-sidebar-english"'
 | 
			
		||||
 | 
			
		||||
    def setUp(self):
 | 
			
		||||
        super().setUp()
 | 
			
		||||
| 
						 | 
				
			
			@ -940,56 +916,29 @@ class TestLocaleSelectorOnEdit(BaseTestSnippetEditView):
 | 
			
		|||
 | 
			
		||||
    def test_locale_selector(self):
 | 
			
		||||
        response = self.get()
 | 
			
		||||
 | 
			
		||||
        self.assertContains(response, self.LOCALE_SELECTOR_HTML)
 | 
			
		||||
 | 
			
		||||
        switch_to_french_url = reverse(
 | 
			
		||||
            "wagtailsnippets_snippetstests_translatablesnippet:edit",
 | 
			
		||||
            args=[quote(self.test_snippet_fr.pk)],
 | 
			
		||||
        )
 | 
			
		||||
        self.assertContains(
 | 
			
		||||
            response,
 | 
			
		||||
            f'<a href="{switch_to_french_url}" aria-label="French" class="u-link is-live w-no-underline">',
 | 
			
		||||
        )
 | 
			
		||||
        self.assertContains(response, self.LOCALE_SELECTOR_LABEL)
 | 
			
		||||
        self.assertContains(response, self.LOCALE_INDICATOR_HTML)
 | 
			
		||||
 | 
			
		||||
    def test_locale_selector_without_translation(self):
 | 
			
		||||
        self.test_snippet_fr.delete()
 | 
			
		||||
 | 
			
		||||
        response = self.get()
 | 
			
		||||
 | 
			
		||||
        # The "Switch locale" button should not be shown
 | 
			
		||||
        self.assertNotContains(response, self.LOCALE_SELECTOR_LABEL)
 | 
			
		||||
        # Locale status still available and says "No other translations"
 | 
			
		||||
        self.assertContains(response, self.LOCALE_INDICATOR_HTML)
 | 
			
		||||
 | 
			
		||||
        switch_to_french_url = reverse(
 | 
			
		||||
            "wagtailsnippets_snippetstests_translatablesnippet:edit",
 | 
			
		||||
            args=[quote(self.test_snippet_fr.pk)],
 | 
			
		||||
        )
 | 
			
		||||
        self.assertNotContains(
 | 
			
		||||
            response,
 | 
			
		||||
            f'<a href="{switch_to_french_url}" aria-label="French" class="u-link is-live w-no-underline">',
 | 
			
		||||
        )
 | 
			
		||||
        self.assertContains(response, "No other translations")
 | 
			
		||||
 | 
			
		||||
    @override_settings(WAGTAIL_I18N_ENABLED=False)
 | 
			
		||||
    def test_locale_selector_not_present_when_i18n_disabled(self):
 | 
			
		||||
        response = self.get()
 | 
			
		||||
 | 
			
		||||
        self.assertNotContains(response, self.LOCALE_SELECTOR_HTML)
 | 
			
		||||
 | 
			
		||||
        switch_to_french_url = reverse(
 | 
			
		||||
            "wagtailsnippets_snippetstests_translatablesnippet:edit",
 | 
			
		||||
            args=[quote(self.test_snippet_fr.pk)],
 | 
			
		||||
        )
 | 
			
		||||
        self.assertNotContains(
 | 
			
		||||
            response,
 | 
			
		||||
            f'<a href="{switch_to_french_url}" aria-label="French" class="u-link is-live w-no-underline">',
 | 
			
		||||
        )
 | 
			
		||||
        self.assertNotContains(response, self.LOCALE_SELECTOR_LABEL)
 | 
			
		||||
        self.assertNotContains(response, self.LOCALE_INDICATOR_HTML)
 | 
			
		||||
 | 
			
		||||
    def test_locale_selector_not_present_on_non_translatable_snippet(self):
 | 
			
		||||
        self.test_snippet = Advert.objects.get(pk=1)
 | 
			
		||||
 | 
			
		||||
        response = self.get()
 | 
			
		||||
 | 
			
		||||
        self.assertNotContains(response, self.LOCALE_SELECTOR_HTML)
 | 
			
		||||
        self.assertNotContains(response, 'aria-label="French" class="u-link is-live">')
 | 
			
		||||
        self.assertNotContains(response, self.LOCALE_SELECTOR_LABEL)
 | 
			
		||||
        self.assertNotContains(response, self.LOCALE_INDICATOR_HTML)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestEditRevisionSnippet(BaseTestSnippetEditView):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,6 +34,7 @@ from wagtail.search.backends import get_search_backend
 | 
			
		|||
from wagtail.snippets.action_menu import SnippetActionMenu
 | 
			
		||||
from wagtail.snippets.models import get_snippet_models
 | 
			
		||||
from wagtail.snippets.permissions import user_can_edit_snippet_type
 | 
			
		||||
from wagtail.snippets.side_panels import SnippetSidePanels
 | 
			
		||||
from wagtail.utils.deprecation import RemovedInWagtail50Warning
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -236,14 +237,20 @@ class Create(CreateView):
 | 
			
		|||
    def get_context_data(self, **kwargs):
 | 
			
		||||
        context = super().get_context_data(**kwargs)
 | 
			
		||||
 | 
			
		||||
        media = context.get("media")
 | 
			
		||||
        action_menu = self._get_action_menu()
 | 
			
		||||
        media = context.get("media") + action_menu.media
 | 
			
		||||
 | 
			
		||||
        side_panels = None
 | 
			
		||||
        if self.locale:
 | 
			
		||||
            side_panels = SnippetSidePanels(self.request, self.model())
 | 
			
		||||
            media += side_panels.media
 | 
			
		||||
 | 
			
		||||
        context.update(
 | 
			
		||||
            {
 | 
			
		||||
                "model_opts": self.model._meta,
 | 
			
		||||
                "action_menu": action_menu,
 | 
			
		||||
                "media": media + action_menu.media,
 | 
			
		||||
                "side_panels": side_panels,
 | 
			
		||||
                "media": media,
 | 
			
		||||
            }
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -329,9 +336,6 @@ class Edit(EditView):
 | 
			
		|||
            self.request, view=self.view_name, instance=self.object
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def _get_latest_log_entry(self):
 | 
			
		||||
        return log_registry.get_logs_for_instance(self.object).first()
 | 
			
		||||
 | 
			
		||||
    def get_form_kwargs(self):
 | 
			
		||||
        return {**super().get_form_kwargs(), "for_user": self.request.user}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -340,16 +344,14 @@ class Edit(EditView):
 | 
			
		|||
 | 
			
		||||
        media = context.get("media")
 | 
			
		||||
        action_menu = self._get_action_menu()
 | 
			
		||||
        latest_log_entry = self._get_latest_log_entry()
 | 
			
		||||
        side_panels = SnippetSidePanels(self.request, self.object)
 | 
			
		||||
 | 
			
		||||
        context.update(
 | 
			
		||||
            {
 | 
			
		||||
                "model_opts": self.model._meta,
 | 
			
		||||
                "instance": self.object,
 | 
			
		||||
                "action_menu": action_menu,
 | 
			
		||||
                "latest_log_entry": latest_log_entry,
 | 
			
		||||
                "history_url": self.get_history_url(),
 | 
			
		||||
                "media": media + action_menu.media,
 | 
			
		||||
                "side_panels": side_panels,
 | 
			
		||||
                "media": media + action_menu.media + side_panels.media,
 | 
			
		||||
            }
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -455,17 +457,18 @@ class Usage(IndexView):
 | 
			
		|||
    template_name = "wagtailsnippets/snippets/usage.html"
 | 
			
		||||
    paginate_by = 20
 | 
			
		||||
    page_kwarg = "p"
 | 
			
		||||
    is_searchable = False
 | 
			
		||||
 | 
			
		||||
    def setup(self, request, *args, pk, **kwargs):
 | 
			
		||||
        super().setup(request, *args, **kwargs)
 | 
			
		||||
        self.pk = pk
 | 
			
		||||
        self.instance = self._get_instance()
 | 
			
		||||
        self.object = self.get_object()
 | 
			
		||||
 | 
			
		||||
    def _get_instance(self):
 | 
			
		||||
    def get_object(self):
 | 
			
		||||
        return get_object_or_404(self.model, pk=unquote(self.pk))
 | 
			
		||||
 | 
			
		||||
    def get_queryset(self):
 | 
			
		||||
        return self.instance.get_usage()
 | 
			
		||||
        return self.object.get_usage()
 | 
			
		||||
 | 
			
		||||
    def paginate_queryset(self, queryset, page_size):
 | 
			
		||||
        paginator = self.get_paginator(
 | 
			
		||||
| 
						 | 
				
			
			@ -481,7 +484,13 @@ class Usage(IndexView):
 | 
			
		|||
 | 
			
		||||
    def get_context_data(self, **kwargs):
 | 
			
		||||
        context = super().get_context_data(**kwargs)
 | 
			
		||||
        context.update({"instance": self.instance, "used_by": context.get("page_obj")})
 | 
			
		||||
        context.update(
 | 
			
		||||
            {
 | 
			
		||||
                "object": self.object,
 | 
			
		||||
                "used_by": context.get("page_obj"),
 | 
			
		||||
                "model_opts": self.model._meta,
 | 
			
		||||
            }
 | 
			
		||||
        )
 | 
			
		||||
        return context
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -536,6 +545,7 @@ class ActionColumn(Column):
 | 
			
		|||
 | 
			
		||||
class History(ReportView):
 | 
			
		||||
    view_name = "history"
 | 
			
		||||
    index_url_name = None
 | 
			
		||||
    edit_url_name = None
 | 
			
		||||
    revisions_revert_url_name = None
 | 
			
		||||
    revisions_compare_url_name = None
 | 
			
		||||
| 
						 | 
				
			
			@ -565,6 +575,7 @@ class History(ReportView):
 | 
			
		|||
        context = super().get_context_data(*args, object_list=object_list, **kwargs)
 | 
			
		||||
        context["object"] = self.object
 | 
			
		||||
        context["subtitle"] = self.get_page_subtitle()
 | 
			
		||||
        context["model_opts"] = self.model._meta
 | 
			
		||||
        return context
 | 
			
		||||
 | 
			
		||||
    def get_queryset(self):
 | 
			
		||||
| 
						 | 
				
			
			@ -672,6 +683,8 @@ class SnippetViewSet(ViewSet):
 | 
			
		|||
        return self.usage_view_class.as_view(
 | 
			
		||||
            model=self.model,
 | 
			
		||||
            permission_policy=self.permission_policy,
 | 
			
		||||
            index_url_name=self.get_url_name("list"),
 | 
			
		||||
            edit_url_name=self.get_url_name("edit"),
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
| 
						 | 
				
			
			@ -679,6 +692,7 @@ class SnippetViewSet(ViewSet):
 | 
			
		|||
        return self.history_view_class.as_view(
 | 
			
		||||
            model=self.model,
 | 
			
		||||
            permission_policy=self.permission_policy,
 | 
			
		||||
            index_url_name=self.get_url_name("list"),
 | 
			
		||||
            edit_url_name=self.get_url_name("edit"),
 | 
			
		||||
            revisions_revert_url_name=self.get_url_name("revisions_revert"),
 | 
			
		||||
            revisions_compare_url_name=self.get_url_name("revisions_compare"),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Ładowanie…
	
		Reference in New Issue