diff --git a/patchwork/models.py b/patchwork/models.py
index a05db7f9..8055ca5f 100644
--- a/patchwork/models.py
+++ b/patchwork/models.py
@@ -880,6 +880,25 @@ def received_total(self):
def received_all(self):
return self.total <= self.received_total
+ @property
+ def check_count(self):
+ """Generate a list of unique checks for all patchs in the series.
+
+ Compile a list of checks associated with this series patches for each
+ type of check. Only "unique" checks are considered, identified by their
+ 'context' field. This means, given n checks with the same 'context', the
+ newest check is the only one counted regardless of its value. The end
+ result will be a association of types to number of unique checks for
+ said type.
+ """
+ counts = {key: 0 for key, _ in Check.STATE_CHOICES}
+
+ for p in self.patches.all():
+ for check in p.checks:
+ counts[check.state] += 1
+
+ return counts
+
def add_cover_letter(self, cover):
"""Add a cover letter to the series.
diff --git a/patchwork/templates/patchwork/series-list.html b/patchwork/templates/patchwork/series-list.html
index bd23c252..2f6f2217 100644
--- a/patchwork/templates/patchwork/series-list.html
+++ b/patchwork/templates/patchwork/series-list.html
@@ -11,6 +11,7 @@
{% load person %}
{% load listurl %}
{% load patch %}
+{% load series %}
{% load project %}
{% load static %}
@@ -37,7 +38,11 @@
-
+ {% project_tags %}
+ |
+
+
+
|
@@ -83,13 +88,8 @@
{{ series.version|default:"-"}}
- |
- {% if series.cover_letter.content %}
- ✓
- {% else %}
- -
- {% endif %}
- |
+ {{ series|series_tags }} |
+ {{ series|series_checks }} |
{{ series.received_total}} |
{{ series.date|date:"Y-m-d" }} |
{{ series.submitter|personify:project }} |
diff --git a/patchwork/templatetags/series.py b/patchwork/templatetags/series.py
new file mode 100644
index 00000000..2c255330
--- /dev/null
+++ b/patchwork/templatetags/series.py
@@ -0,0 +1,61 @@
+# Patchwork - automated patch tracking system
+# Copyright (C) 2008 Jeremy Kerr
+# Copyright (C) 2015 Intel Corporation
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+from django import template
+from django.utils.safestring import mark_safe
+
+from patchwork.models import Check
+
+
+register = template.Library()
+
+
+@register.filter(name='series_tags')
+def series_tags(series):
+ counts = []
+ titles = []
+
+ for tag in [t for t in series.project.tags if t.show_column]:
+ count = 0
+ for patch in series.patches.with_tag_counts(series.project).all():
+ count += getattr(patch, tag.attr_name)
+
+ titles.append('%d %s' % (count, tag.name))
+ if count == 0:
+ counts.append('-')
+ else:
+ counts.append(str(count))
+
+ return mark_safe(
+ '%s' % (' / '.join(titles), ' '.join(counts))
+ )
+
+
+@register.filter(name='series_checks')
+def series_checks(series):
+ required = [Check.STATE_SUCCESS, Check.STATE_WARNING, Check.STATE_FAIL]
+ titles = ['Success', 'Warning', 'Fail']
+ counts = series.check_count
+
+ check_elements = []
+ for state in required[::-1]:
+ if counts[state]:
+ color = dict(Check.STATE_CHOICES).get(state)
+ count = str(counts[state])
+ else:
+ color = ''
+ count = '-'
+
+ check_elements.append(
+ f'{count}'
+ )
+
+ check_elements.reverse()
+
+ return mark_safe(
+ '%s'
+ % (' / '.join(titles), ''.join(check_elements))
+ )