diff --git a/wagtail/admin/templates/wagtailadmin/pages/workflow_history/detail.html b/wagtail/admin/templates/wagtailadmin/pages/workflow_history/detail.html
index 89ca57697d..5d064d7ed3 100644
--- a/wagtail/admin/templates/wagtailadmin/pages/workflow_history/detail.html
+++ b/wagtail/admin/templates/wagtailadmin/pages/workflow_history/detail.html
@@ -70,9 +70,15 @@
{% for task_state in task_states %}
{% if task_state.status == 'approved' or task_state.status == 'rejected' %}
- {% blocktrans with action=' '|add:task_state.get_status_display|add:' '|safe at=task_state.finished_at %}
- {{ action }} at {{ at }}
- {% endblocktrans %}
+ {% if task_state.finished_by %}
+ {% blocktrans with action=''|add:task_state.get_status_display|add:' '|safe who=task_state.finished_by.get_full_name|default:task_state.finished_by.get_username at=task_state.finished_at %}
+ {{ action }} by {{ who }} at {{ at }}
+ {% endblocktrans %}
+ {% else %}
+ {% blocktrans with action=''|add:task_state.get_status_display|add:' '|safe at=task_state.finished_at %}
+ {{ action }} at {{ at }}
+ {% endblocktrans %}
+ {% endif %}
{% else %}
{{ task_state.get_status_display }}
{% endif %}
@@ -113,7 +119,13 @@
{% elif timeline_item.action == 'task_completed' %}
{{ timeline_item.task_state.task }}
- {{ timeline_item.task_state.get_status_display }}
+ {% if timeline_item.task_state.finished_by %}
+ {% blocktrans with action=''|add:timeline_item.task_state.get_status_display|add:' '|safe who=timeline_item.task_state.finished_by.get_full_name|default:timeline_item.task_state.finished_by.get_username %}
+ {{ action }} by {{ who }}
+ {% endblocktrans %}
+ {% else %}
+ {{ timeline_item.task_state.get_status_display }}
+ {% endif %}
{% endif %}
|
diff --git a/wagtail/core/migrations/0049_taskstate_finished_by.py b/wagtail/core/migrations/0049_taskstate_finished_by.py
new file mode 100644
index 0000000000..6fa4cd5a45
--- /dev/null
+++ b/wagtail/core/migrations/0049_taskstate_finished_by.py
@@ -0,0 +1,21 @@
+# Generated by Django 3.0.3 on 2020-03-10 11:01
+
+from django.conf import settings
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+ ('wagtailcore', '0048_add_default_workflows'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='taskstate',
+ name='finished_by',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='finished_task_states', to=settings.AUTH_USER_MODEL, verbose_name='finished by'),
+ ),
+ ]
diff --git a/wagtail/core/models.py b/wagtail/core/models.py
index 397bbdc69c..bb0b1e9326 100644
--- a/wagtail/core/models.py
+++ b/wagtail/core/models.py
@@ -2955,6 +2955,14 @@ class TaskState(MultiTableCopyMixin, models.Model):
status = models.fields.CharField(choices=STATUS_CHOICES, verbose_name=_("status"), max_length=50, default=STATUS_IN_PROGRESS)
started_at = models.DateTimeField(verbose_name=_('started at'), auto_now_add=True)
finished_at = models.DateTimeField(verbose_name=_('finished at'), blank=True, null=True)
+ finished_by = models.ForeignKey(
+ settings.AUTH_USER_MODEL,
+ verbose_name=_('finished by'),
+ null=True,
+ blank=True,
+ on_delete=models.SET_NULL,
+ related_name='finished_task_states'
+ )
content_type = models.ForeignKey(
ContentType,
verbose_name=_('content type'),