kopia lustrzana https://github.com/wagtail/wagtail
Use Task.get_template_for_action() in workflow modal views (#12926)
rodzic
e86fdb1899
commit
32e1366534
|
@ -16,6 +16,7 @@ Changelog
|
|||
* Add better support and documentation for overriding or extending icons used in the in the userbar (Sébastien Corbin)
|
||||
* List the comments action, if comments are enabled, within the admin keyboard shortcuts dialog (Dhruvi Patel)
|
||||
* Add better support and documentation for overriding the default field widgets used within form pages (Baptiste Mispelon)
|
||||
* Allow workflow tasks to specify a template for the action modal via `get_template_for_action` (Sage Abdullah)
|
||||
* Fix: Take preferred language into account for translatable strings in client-side code (Bernhard Bliem, Sage Abdullah)
|
||||
* Fix: Do not show the content type column as sortable when searching pages (Srishti Jaiswal, Sage Abdullah)
|
||||
* Fix: Support simple subqueries for `in` and `exact` lookup on Elasticsearch (Sage Abdullah)
|
||||
|
|
|
@ -30,6 +30,7 @@ This version adds formal support for Django 5.2.
|
|||
* Add better support and documentation for overriding or extending [icons used in the in the userbar](custom_icons_userbar) (Sébastien Corbin)
|
||||
* List the comments action, if comments are enabled, within the admin keyboard shortcuts dialog (Dhruvi Patel)
|
||||
* Add better support and documentation for [overriding the default field widgets](custom_form_field_type_widgets) used within form pages (Baptiste Mispelon)
|
||||
* Allow workflow tasks to specify a template for the action modal via `get_template_for_action` (Sage Abdullah)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@ from wagtail.test.testapp.models import (
|
|||
MultiPreviewModesPage,
|
||||
SimplePage,
|
||||
SimpleTask,
|
||||
UserApprovalTask,
|
||||
)
|
||||
from wagtail.test.utils import WagtailTestUtils
|
||||
from wagtail.test.utils.template_tests import AdminTemplateTestUtils
|
||||
|
@ -2705,6 +2706,62 @@ class TestApproveRejectPageWorkflow(BasePageWorkflowTests):
|
|||
)
|
||||
self.assertIn("Comment", html)
|
||||
|
||||
def test_workflow_action_get_custom_template(self):
|
||||
"""
|
||||
https://github.com/wagtail/wagtail/issues/12222
|
||||
Custom tasks can override Task.get_template_for_action() to use a custom
|
||||
template for the workflow action modal.
|
||||
"""
|
||||
# Add a custom task to the workflow
|
||||
custom_task = UserApprovalTask.objects.create(
|
||||
name="user_approval_1",
|
||||
user=self.moderator,
|
||||
)
|
||||
WorkflowTask.objects.create(
|
||||
workflow=self.workflow,
|
||||
task=custom_task,
|
||||
sort_order=2,
|
||||
)
|
||||
self.approve() # Approve the GroupApprovalTask
|
||||
|
||||
# Refresh from DB
|
||||
self.object = self.object_class.objects.get(pk=self.object.pk)
|
||||
|
||||
response = self.client.get(
|
||||
self.get_url(
|
||||
"workflow_action",
|
||||
args=(
|
||||
quote(self.object.pk),
|
||||
"approve",
|
||||
self.object.current_workflow_task_state.id,
|
||||
),
|
||||
),
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertTemplateUsed(response, "tests/workflows/approve_with_style.html")
|
||||
self.assertTemplateNotUsed(
|
||||
response, "wagtailadmin/shared/workflow_action_modal.html"
|
||||
)
|
||||
html = json.loads(response.content)["html"]
|
||||
soup = self.get_soup(html)
|
||||
form = soup.select_one("form")
|
||||
self.assertIsNotNone(form)
|
||||
self.assertEqual(
|
||||
form["action"],
|
||||
self.get_url(
|
||||
"workflow_action",
|
||||
args=(
|
||||
quote(self.object.pk),
|
||||
"approve",
|
||||
self.object.current_workflow_task_state.id,
|
||||
),
|
||||
),
|
||||
)
|
||||
submit = form.select_one("button[type=submit]")
|
||||
self.assertIsNotNone(submit)
|
||||
self.assertEqual(submit.text.strip(), "Ship it!")
|
||||
self.assertNotIn("Comment", html)
|
||||
|
||||
def test_workflow_action_view_bad_id(self):
|
||||
"""
|
||||
This tests that the workflow action view handles invalid object ids correctly
|
||||
|
@ -2935,6 +2992,62 @@ class TestApproveRejectPageWorkflow(BasePageWorkflowTests):
|
|||
)
|
||||
self.assertIn("Comment", html)
|
||||
|
||||
def test_collect_workflow_action_data_get_custom_template(self):
|
||||
"""
|
||||
https://github.com/wagtail/wagtail/issues/12222
|
||||
Custom tasks can override Task.get_template_for_action() to use a custom
|
||||
template for the workflow action modal.
|
||||
"""
|
||||
# Add a custom task to the workflow
|
||||
custom_task = UserApprovalTask.objects.create(
|
||||
name="user_approval_1",
|
||||
user=self.moderator,
|
||||
)
|
||||
WorkflowTask.objects.create(
|
||||
workflow=self.workflow,
|
||||
task=custom_task,
|
||||
sort_order=2,
|
||||
)
|
||||
self.approve() # Approve the GroupApprovalTask
|
||||
|
||||
# Refresh from DB
|
||||
self.object = self.object_class.objects.get(pk=self.object.pk)
|
||||
|
||||
response = self.client.get(
|
||||
self.get_url(
|
||||
"collect_workflow_action_data",
|
||||
args=(
|
||||
quote(self.object.pk),
|
||||
"approve",
|
||||
self.object.current_workflow_task_state.id,
|
||||
),
|
||||
),
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertTemplateUsed(response, "tests/workflows/approve_with_style.html")
|
||||
self.assertTemplateNotUsed(
|
||||
response, "wagtailadmin/shared/workflow_action_modal.html"
|
||||
)
|
||||
html = json.loads(response.content)["html"]
|
||||
soup = self.get_soup(html)
|
||||
form = soup.select_one("form")
|
||||
self.assertIsNotNone(form)
|
||||
self.assertEqual(
|
||||
form["action"],
|
||||
self.get_url(
|
||||
"collect_workflow_action_data",
|
||||
args=(
|
||||
quote(self.object.pk),
|
||||
"approve",
|
||||
self.object.current_workflow_task_state.id,
|
||||
),
|
||||
),
|
||||
)
|
||||
submit = form.select_one("button[type=submit]")
|
||||
self.assertIsNotNone(submit)
|
||||
self.assertEqual(submit.text.strip(), "Ship it!")
|
||||
self.assertNotIn("Comment", html)
|
||||
|
||||
def test_collect_workflow_action_data_post(self):
|
||||
"""
|
||||
This tests that a POST request to the collect_workflow_action_data view (for the approve action) returns a modal response with the validated data
|
||||
|
|
|
@ -47,6 +47,11 @@ class BaseWorkflowFormView(BaseObjectMixin, View):
|
|||
def get_form_class(self):
|
||||
return self.task.get_form_for_action(self.action_name)
|
||||
|
||||
def get_template_names(self):
|
||||
if template := self.task.get_template_for_action(self.action_name):
|
||||
return [template]
|
||||
return [self.template_name]
|
||||
|
||||
def add_not_in_moderation_error(self):
|
||||
messages.error(
|
||||
self.request,
|
||||
|
@ -103,7 +108,7 @@ class BaseWorkflowFormView(BaseObjectMixin, View):
|
|||
def render_modal_form(self, request, form):
|
||||
return render_modal_workflow(
|
||||
request,
|
||||
self.template_name,
|
||||
self.get_template_names(),
|
||||
None,
|
||||
self.get_context_data(form=form),
|
||||
json_data={"step": "action"},
|
||||
|
@ -195,6 +200,11 @@ class ConfirmWorkflowCancellation(BaseObjectMixin, View):
|
|||
json_data={"step": "no_confirmation_needed"},
|
||||
)
|
||||
|
||||
# This confirmation step is specific to the
|
||||
# `WAGTAIL_WORKFLOW_CANCEL_ON_PUBLISH` setting that happens when a user
|
||||
# publishes a page with a workflow in progress, which is different from
|
||||
# a "cancel" action on the task. So, we use `self.template_name`
|
||||
# directly and not make it customisable.
|
||||
return render_modal_workflow(
|
||||
request,
|
||||
self.template_name,
|
||||
|
|
|
@ -780,6 +780,9 @@ class Task(SpecificMixin, models.Model):
|
|||
return TaskStateCommentForm
|
||||
|
||||
def get_template_for_action(self, action):
|
||||
"""
|
||||
Specifies a template for the workflow action modal.
|
||||
"""
|
||||
return ""
|
||||
|
||||
def get_task_states_user_can_moderate(self, user, **kwargs):
|
||||
|
|
|
@ -8,7 +8,7 @@ from django.db import migrations, models
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("tests", "0047_advertwithcustomuuidprimarykey_page"),
|
||||
("tests", "0050_headcountrelatedmodelusingpk_related_page"),
|
||||
("wagtailcore", "0094_alter_page_locale"),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
|
@ -2375,12 +2375,21 @@ class UserApprovalTask(Task):
|
|||
if user == self.user:
|
||||
return [
|
||||
("approve", "Approve", False),
|
||||
("approve", "Approve with style", True),
|
||||
("reject", "Reject", False),
|
||||
("cancel", "Cancel", False),
|
||||
]
|
||||
else:
|
||||
return []
|
||||
|
||||
def get_template_for_action(self, action):
|
||||
# https://github.com/wagtail/wagtail/issues/12222
|
||||
# This will be used for "Approve with style" which has the third value
|
||||
# (action_requires_additional_data_from_modal) set to True.
|
||||
if action == "approve":
|
||||
return "tests/workflows/approve_with_style.html"
|
||||
return super().get_template_for_action(action)
|
||||
|
||||
def on_action(self, task_state, user, action_name, **kwargs):
|
||||
if action_name == "cancel":
|
||||
return task_state.workflow_state.cancel(user=user)
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
{% include "wagtailadmin/shared/header.html" with title=action_verbose icon="clipboard-list" %}
|
||||
|
||||
<form class="nice-padding" action="{{ submit_url }}" method="POST" novalidate>
|
||||
{% csrf_token %}
|
||||
<button class="button" type="submit">Ship it!</button>
|
||||
</form>
|
Ładowanie…
Reference in New Issue