Repository: wagtail/wagtail

Issue:
One click to view changes diff between revision submitted to moderation queue and live revision
We have been using the moderation queue workflows and it takes a lot of time to get to the history diff view to see the actual changes compared against the live revision - also, I could be mistaken but I believe the history view only shows against the previous revision instead of the live revision.  Often times this is easier to use the diff than directly jumping to the preview - or for spelling corrections and other one word fixes the diff is just more useful.  It would be very helpful if there was a one click "view changes" button to the "Awaiting your review" section that pulled up this visual diff against the live revision.

Currently, you have to click "edit", wait for the page to load, "history", wait for the page to load, find the correct draft, click "compare with previous version", wait for the page to load, then you have to click "edit this page", wait for the page to load, click "preview" to verify the change, wait for the page to load, then "approve and publish".

We are using Wagtail 2.11 but I didn't see any improvements here in the 2.12 notes.  This really adds a lot of time to the moderation process.  Anything to simplify it would be a big bonus


Discussion:
Hi @thenewguy , thanks for raising this! This sounds like a really good idea, and I'd be happy to review a PR that adds this, if you'd be up for making one. Alternatively I can look into adding this at some point.
Hello folks, this same concern has come up at WRDS and we would love to see this issue move forward. @jacobtoppm , can you please let me know if there's anything that we can do to help with this?
This has been improved in the new workflow information dialog that you can access by clicking the "View details" from the status side panel:

<img width="1199" alt="image" src="https://user-images.githubusercontent.com/6379424/224366596-90a0458c-a74e-4c98-937d-832070a07dda.png">

I suppose it can still be useful to add the link on the dashboard's moderation list, though.
Hi Sage, that's great and I'll share this with out content moderators!

Since we can have the links there, do you think it'd be possible to also add them to the listings on the CMS landing page?
![image](https://user-images.githubusercontent.com/482540/224369102-44a9b72d-f294-408c-9682-5a575f6fdbf3.png)

My team has also discussed wanting this feature recently, specifically on the page's history to compare revisions with the live version of a page. I created [this PR](https://github.com/wagtail/wagtail/pull/6701) a long time ago but then closed it because I realized you could get the diff by editing the URL; but, my team has recently also been mentioning that a button would be good. This might be off topic because this is more about the moderation flow, though.

Resolving patch:
diff --git a/wagtail/admin/views/home.py b/wagtail/admin/views/home.py
--- a/wagtail/admin/views/home.py
+++ b/wagtail/admin/views/home.py
@@ -177,6 +177,11 @@ def get_context_data(self, parent_context):
                 "task",
                 "revision__user",
             )
+            .prefetch_related(
+                "revision__content_object",
+                "revision__content_object__latest_revision",
+                "revision__content_object__live_revision",
+            )
             .order_by("-started_at")
         )
         for state in states:
@@ -186,24 +191,35 @@ def get_context_data(self, parent_context):
 
             workflow_action_url_name = "wagtailadmin_pages:workflow_action"
             workflow_preview_url_name = "wagtailadmin_pages:workflow_preview"
+            revisions_compare_url_name = "wagtailadmin_pages:revisions_compare"
 
             # Snippets can also have workflows
             if not isinstance(obj, Page):
                 viewset = obj.snippet_viewset
                 workflow_action_url_name = viewset.get_url_name("workflow_action")
                 workflow_preview_url_name = viewset.get_url_name("workflow_preview")
+                revisions_compare_url_name = viewset.get_url_name("revisions_compare")
 
             if not getattr(obj, "is_previewable", False):
                 workflow_preview_url_name = None
 
+            try:
+                previous_revision = state.revision.get_previous()
+            except Revision.DoesNotExist:
+                previous_revision = None
+
             context["states"].append(
                 {
                     "obj": obj,
+                    "revision": state.revision,
+                    "previous_revision": previous_revision,
+                    "live_revision": obj.live_revision,
                     "task_state": state,
                     "actions": actions,
                     "workflow_tasks": workflow_tasks,
                     "workflow_action_url_name": workflow_action_url_name,
                     "workflow_preview_url_name": workflow_preview_url_name,
+                    "revisions_compare_url_name": revisions_compare_url_name,
                 }
             )
 


Test patch:
diff --git a/wagtail/admin/tests/test_workflows.py b/wagtail/admin/tests/test_workflows.py
--- a/wagtail/admin/tests/test_workflows.py
+++ b/wagtail/admin/tests/test_workflows.py
@@ -3513,7 +3513,7 @@ def test_workflow_edit_locked_message(self):
         self.assertContains(response, "Save draft")
 
 
-class TestDashboardWithSnippets(BaseSnippetWorkflowTests):
+class TestDashboardWithPages(BasePageWorkflowTests):
     def setUp(self):
         super().setUp()
         # Ensure that the presence of private pages doesn't break the dashboard -
@@ -3539,3 +3539,52 @@ def test_dashboard_for_moderator(self):
         response = self.client.get(reverse("wagtailadmin_home"))
         self.assertEqual(response.status_code, 200)
         self.assertContains(response, "Awaiting your review")
+
+        # object had no previous revisions
+        self.assertNotContains(response, "Compare with live version")
+        self.assertNotContains(response, "Compare with previous version")
+
+    def test_dashboard_for_moderator_with_previous_revisions(self):
+        live_revision = self.object.save_revision()
+        self.object.publish(live_revision)
+        previous_revision = self.object.save_revision()
+
+        self.login(self.submitter)
+        self.post("submit")
+        self.object.refresh_from_db()
+        latest_revision = self.object.latest_revision
+
+        self.login(self.moderator)
+        response = self.client.get(reverse("wagtailadmin_home"))
+        self.assertEqual(response.status_code, 200)
+        self.assertContains(response, "Awaiting your review")
+
+        soup = self.get_soup(response.content)
+        compare_with_live_url = self.get_url(
+            "revisions_compare",
+            args=(self.object.pk, "live", latest_revision.id),
+        )
+        compare_with_previous_url = self.get_url(
+            "revisions_compare",
+            args=(self.object.pk, previous_revision.id, latest_revision.id),
+        )
+
+        compare_with_live_link = soup.select_one(f"a[href='{compare_with_live_url}']")
+        self.assertIsNotNone(compare_with_live_link)
+        self.assertEqual(
+            compare_with_live_link.text.strip(),
+            "Compare with live version",
+        )
+
+        compare_with_previous_link = soup.select_one(
+            f"a[href='{compare_with_previous_url}']"
+        )
+        self.assertIsNotNone(compare_with_previous_link)
+        self.assertEqual(
+            compare_with_previous_link.text.strip(),
+            "Compare with previous version",
+        )
+
+
+class TestDashboardWithSnippets(TestDashboardWithPages, BaseSnippetWorkflowTests):
+    pass