Adopt Stimulus `w-formset` attributes in Workflow pages basic formset

- Use the Wagtail admin formset mixin to adopt new data attributes on core form parts
- Update the edit/create templates to put the attributes on the remaining elements
- Add basic unit tests for smoke testing data attributes
- Remove CSP incompatible inline scripts approach
- Remove the now unused standalone static build/imports for the group edit view as this will not be needed
- Ensure that the edit workflow form does not render any JS or attributes when the pages are not actually editable (workflow disabled)
pull/12675/head
LB Johnston 2024-02-11 17:27:55 +10:00 zatwierdzone przez Matt Westcott
rodzic 3d6f1c366f
commit 585d3e3385
7 zmienionych plików z 87 dodań i 40 usunięć

Wyświetl plik

@ -10,6 +10,7 @@ from django.utils.translation import gettext_lazy
from wagtail.admin import widgets
from wagtail.admin.forms import WagtailAdminModelForm
from wagtail.admin.forms.formsets import BaseFormSetMixin
from wagtail.admin.panels import FieldPanel, InlinePanel, ObjectList
from wagtail.admin.widgets.workflows import AdminTaskChooser
from wagtail.coreutils import get_content_type_label, get_model_string
@ -121,19 +122,7 @@ class WorkflowPageForm(forms.ModelForm):
)
class BaseWorkflowPagesFormSet(forms.BaseInlineFormSet):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for form in self.forms:
form.fields["DELETE"].widget = forms.HiddenInput()
@property
def empty_form(self):
empty_form = super().empty_form
empty_form.fields["DELETE"].widget = forms.HiddenInput()
return empty_form
class BaseWorkflowPagesFormSet(BaseFormSetMixin, forms.BaseInlineFormSet):
def clean(self):
"""Checks that no two forms refer to the same page object"""
if any(self.errors):

Wyświetl plik

@ -5,7 +5,7 @@
{{ edit_handler.render_form_content }}
<div class="w-form-width">
{% panel id="workflow-pages" icon="doc-empty-inverse" heading=_("Assign your workflow to pages") %}
{% panel id="workflow-pages" icon="doc-empty-inverse" heading=_("Assign your workflow to pages") attrs=pages_formset.attrs %}
{% include "wagtailadmin/workflows/includes/workflow_pages_formset.html" with formset=pages_formset %}
{% endpanel %}

Wyświetl plik

@ -5,7 +5,7 @@
{{ edit_handler.render_form_content }}
<div class="w-form-width">
{% panel id="workflow-pages" icon="doc-empty-inverse" heading=_("Assign your workflow to pages") %}
{% panel id="workflow-pages" icon="doc-empty-inverse" heading=_("Assign your workflow to pages") attrs=pages_formset.attrs %}
{% if workflow.active %}
<p class="help-block help-info">
{% icon name='help' %}

Wyświetl plik

@ -5,5 +5,5 @@
</td>
<td>
<button class="button button-small no" type="button" id="{{ form.DELETE.id_for_label }}-button">{% trans "Delete" %}</button>
<button class="button button-small no" type="button" id="{{ form.DELETE.id_for_label }}-button" data-action="w-formset#delete">{% trans "Delete" %}</button>
</td>

Wyświetl plik

@ -20,9 +20,9 @@
<th aria-label="{% trans 'Action' %}"></th>
</tr>
</thead>
<tbody id="id_{{ formset.prefix }}-FORMS">
<tbody id="id_{{ formset.prefix }}-FORMS" data-w-formset-target="forms">
{% for form in formset.forms %}
<tr id="inline_child_{{ form.prefix }}"{% if form.DELETE.value %} style="display: none;"{% endif %}>
<tr id="inline_child_{{ form.prefix }}"{% if form.DELETE.value %} hidden data-w-formset-target="deleted"{% else %} data-w-formset-target="child"{% endif %}>
{% if form.non_field_errors %}
<p class="error-message">
{% for error in form.non_field_errors %}
@ -36,29 +36,12 @@
</tbody>
</table>
<template id="id_{{ formset.prefix }}-EMPTY_FORM_TEMPLATE">
<tr id="inline_child_{{ formset.empty_form.prefix }}">
<template id="id_{{ formset.prefix }}-EMPTY_FORM_TEMPLATE" data-w-formset-target="template">
<tr id="inline_child_{{ formset.empty_form.prefix }}" data-w-formset-target="child">
{% include "wagtailadmin/workflows/includes/workflow_pages_form.html" with form=formset.empty_form only %}
</tr>
</template>
<p class="add">
<button class="button bicolor button--icon" id="id_{{ formset.prefix }}-ADD" value="Add" type="button">{% icon name="plus" wrapped=1 %}{% trans "Assign to another page" %}</button>
<button class="button bicolor button--icon" id="id_{{ formset.prefix }}-ADD" value="Add" type="button" data-action="w-formset#add">{% icon name="plus" wrapped=1 %}{% trans "Assign to another page" %}</button>
</p>
<script>
$(function() {
buildExpandingFormset('id_{{ formset.prefix|escapejs }}', {
onInit: function(index) {
var deleteInputId = 'id_{{ formset.prefix|escapejs }}-' + index + '-DELETE';
var childId = 'inline_child_{{ formset.prefix|escapejs }}-' + index;
$('#' + deleteInputId + '-button').on('click', function() {
/* set 'deleted' form field to true */
$('#' + deleteInputId).val('1');
$('#' + childId).fadeOut();
});
}
});
});
</script>

Wyświetl plik

@ -431,6 +431,40 @@ class TestWorkflowsCreateView(AdminTemplateTestUtils, WagtailTestUtils, TestCase
response.content,
)
# Check the correct data attributes have been set on the form
soup = self.get_soup(response.content)
workflow_pages_panel = soup.find(id="workflow-pages-section")
self.assertIn(
"w-formset",
workflow_pages_panel.attrs["data-controller"],
)
self.assertEqual(
"totalFormsInput",
workflow_pages_panel.find(id="id_pages-TOTAL_FORMS").attrs[
"data-w-formset-target"
],
)
self.assertEqual(
"template",
workflow_pages_panel.find("template").attrs["data-w-formset-target"],
)
tbody = workflow_pages_panel.find("table").find("tbody")
self.assertEqual(
"forms",
tbody.attrs["data-w-formset-target"],
)
row = tbody.find("tr")
self.assertEqual(
"child",
row.attrs["data-w-formset-target"],
)
self.assertEqual(
"deleteInput",
row.find(id="id_pages-0-DELETE").attrs["data-w-formset-target"],
)
def test_post(self):
response = self.post(
{
@ -663,6 +697,41 @@ class TestWorkflowsEditView(AdminTemplateTestUtils, WagtailTestUtils, TestCase):
# Check that the list of pages has the page to which this workflow is assigned
self.assertContains(response, self.page.title)
# Check the correct data attributes have been set on the form
soup = self.get_soup(response.content)
workflow_pages_panel = soup.find(id="workflow-pages-section")
self.assertIn(
"w-formset",
workflow_pages_panel.attrs["data-controller"],
)
self.assertEqual(
"totalFormsInput",
workflow_pages_panel.find(id="id_pages-TOTAL_FORMS").attrs[
"data-w-formset-target"
],
)
self.assertEqual(
"template",
workflow_pages_panel.find("template").attrs["data-w-formset-target"],
)
tbody = workflow_pages_panel.find("table").find("tbody")
self.assertEqual(
"forms",
tbody.attrs["data-w-formset-target"],
)
row = tbody.find("tr")
self.assertEqual(
"child",
row.attrs["data-w-formset-target"],
)
self.assertEqual(
"deleteInput",
row.find(id="id_pages-0-DELETE").attrs["data-w-formset-target"],
)
def test_post(self):
response = self.post(
{

Wyświetl plik

@ -304,7 +304,6 @@ class Edit(EditView):
pages_formset = self.get_pages_formset()
context["edit_handler"] = bound_panel
context["pages"] = self.get_paginated_pages()
context["pages_formset"] = pages_formset
context["has_workflow_enabled_models"] = bool(get_workflow_enabled_models())
context["content_type_form"] = self.get_content_type_form()
context["can_disable"] = (
@ -315,7 +314,14 @@ class Edit(EditView):
self.permission_policy is None
or self.permission_policy.user_has_permission(self.request.user, "add")
) and not self.object.active
context["media"] = bound_panel.media + form.media + pages_formset.media
context["media"] = bound_panel.media + form.media
# Only add the pages_formset if the workflow is active
if self.object.active:
pages_formset = self.get_pages_formset()
context["pages_formset"] = pages_formset
context["media"] += pages_formset.media
return context
@property