Kaynağa Gözat

Re-label approve/reject

Dan Braghis 4 yıl önce
ebeveyn
işleme
982fb07d90

+ 11 - 5
wagtail/admin/action_menu.py

@@ -5,6 +5,7 @@ from django.forms import Media, MediaDefiningClass
 from django.template.loader import render_to_string
 from django.urls import reverse
 from django.utils.functional import cached_property
+from django.utils.text import format_lazy
 from django.utils.translation import gettext_lazy as _
 
 from wagtail.core import hooks
@@ -224,8 +225,8 @@ def _get_base_page_action_menu_items():
             UnpublishMenuItem(order=10),
             DeleteMenuItem(order=20),
             PublishMenuItem(order=30),
-            RestartWorkflowMenuItem(order=40),
-            CancelWorkflowMenuItem(order=50),
+            CancelWorkflowMenuItem(order=40),
+            RestartWorkflowMenuItem(order=50),
             SubmitForModerationMenuItem(order=60),
             PageLockedMenuItem(order=10000),
         ]
@@ -248,10 +249,16 @@ class PageActionMenu:
         page = self.context.get('page')
         if page:
             task = page.current_workflow_task
+            is_final_task = page.current_workflow_state and page.current_workflow_state.is_at_final_task
             if task:
                 actions = task.get_actions(page, request.user)
-                workflow_menu_items = [WorkflowMenuItem(name, label, launch_modal) for name, label, launch_modal in actions]
-                workflow_menu_items = [item for item in workflow_menu_items if item.is_shown(self.request, self.context)]
+                workflow_menu_items = []
+                for name, label, launch_modal in actions:
+                    if name == "approve" and is_final_task:
+                        label = format_lazy(_("{label} and Publish"), label=label)
+                    item = WorkflowMenuItem(name, label, launch_modal)
+                    if item.is_shown(self.request, self.context):
+                        workflow_menu_items.append(item)
                 self.menu_items.extend(workflow_menu_items)
 
         self.menu_items.extend([
@@ -265,7 +272,6 @@ class PageActionMenu:
         for hook in hooks.get_hooks('construct_page_action_menu'):
             hook(self.menu_items, self.request, self.context)
 
-
         try:
             self.default_item = self.menu_items.pop(0)
         except IndexError:

+ 27 - 8
wagtail/core/models.py

@@ -2993,8 +2993,11 @@ class Task(models.Model):
         return False
 
     def get_actions(self, page, user):
-        """Get the list of action strings (name, verbose_name, whether the action requires additional data - see ``get_form_for_action``)
-        for actions the current user can perform for this task on the given page. These strings should be the same as those able to be passed to ``on_action``"""
+        """
+        Get the list of action strings (name, verbose_name, whether the action requires additional data - see
+        ``get_form_for_action``) for actions the current user can perform for this task on the given page.
+        These strings should be the same as those able to be passed to ``on_action``
+        """
         return []
 
     def get_form_for_action(self, action):
@@ -3137,12 +3140,12 @@ class GroupApprovalTask(Task):
     def get_actions(self, page, user):
         if self.groups.filter(id__in=user.groups.all()).exists() or user.is_superuser:
             return [
+                ('reject', _("Request changes"), True),
                 ('approve', _("Approve"), False),
                 ('approve', _("Approve with comment"), True),
-                ('reject', _("Reject"), True)
             ]
-        else:
-            return []
+
+        return []
 
     def get_task_states_user_can_moderate(self, user, **kwargs):
         if self.groups.filter(id__in=user.groups.all()).exists() or user.is_superuser:
@@ -3280,17 +3283,23 @@ class WorkflowState(models.Model):
                 # if there is no uncompleted task, finish the workflow.
                 self.finish(user=user)
 
-    def get_next_task(self):
-        """Returns the next active task, which has not been either approved or skipped"""
+    @property
+    def successful_task_states(self):
         successful_task_states = self.task_states.filter(
             Q(status=TaskState.STATUS_APPROVED) | Q(status=TaskState.STATUS_SKIPPED)
         )
         if getattr(settings, "WAGTAIL_WORKFLOW_REQUIRE_REAPPROVAL_ON_EDIT", False):
             successful_task_states = successful_task_states.filter(page_revision=self.page.get_latest_revision())
+
+        return successful_task_states
+
+    def get_next_task(self):
+        """Returns the next active task, which has not been either approved or skipped"""
+
         return (
             Task.objects.filter(workflow_tasks__workflow=self.workflow, active=True)
             .exclude(
-                task_states__in=successful_task_states
+                task_states__in=self.successful_task_states
             ).order_by('workflow_tasks__sort_order').first()
         )
 
@@ -3388,6 +3397,16 @@ class WorkflowState(models.Model):
     def is_active(self):
         return self.status not in [self.STATUS_APPROVED, self.STATUS_CANCELLED]
 
+    @property
+    def is_at_final_task(self):
+        """Returns the next active task, which has not been either approved or skipped"""
+
+        last_task = Task.objects.filter(workflow_tasks__workflow=self.workflow, active=True)\
+            .exclude(task_states__in=self.successful_task_states)\
+            .order_by('workflow_tasks__sort_order').last()
+
+        return self.get_next_task() == last_task
+
     class Meta:
         verbose_name = _('Workflow state')
         verbose_name_plural = _('Workflow states')

+ 10 - 0
wagtail/core/tests/test_workflow.py

@@ -259,3 +259,13 @@ class TestWorkflows(TestCase):
         self.assertEqual(
             list(task.active_workflows), [workflow]
         )
+
+    def test_is_at_final_task(self):
+        # test that a Workflow rejected on its second Task can be resumed on the second task
+        data = self.start_workflow_on_homepage()
+        workflow_state = data['workflow_state']
+
+        self.assertFalse(workflow_state.is_at_final_task)
+        workflow_state.current_task_state.approve(user=None)
+        workflow_state.refresh_from_db()
+        self.assertTrue(workflow_state.is_at_final_task)