diff --git a/reviewers/templates/reviewers/components/review_list_item.html b/reviewers/templates/reviewers/components/review_list_item.html
index 24595f5f..cf9b15b4 100644
--- a/reviewers/templates/reviewers/components/review_list_item.html
+++ b/reviewers/templates/reviewers/components/review_list_item.html
@@ -6,27 +6,25 @@
{{ extension.name }}
-
- {% if extension.authors.count %}
- {% include "extensions/components/authors.html" %}
- {% endif %}
- |
+ {% include "extensions/components/authors.html" %} |
{{ extension.date_created|naturaltime_compact }} |
- {{ extension.review_activity.all|length }}
+ {{ stats.count }}
-
- {% if extension.review_activity.all %}
-
- {{ extension.review_activity.all.last.date_created|naturaltime_compact }}
+
+ {{ stats.last_activity.date_created|naturaltime_compact }}
- {% endif %}
{% include "files/components/scan_details_flag.html" with suspicious_files=extension.suspicious_files %}
|
- {% include "common/components/status.html" with object=extension class="d-block" %}
+ {% with last_type=stats.last_type_display|default:"Awaiting Review" %}
+
+
+ {{ last_type }}
+
+ {% endwith %}
|
diff --git a/reviewers/templates/reviewers/extensions_review_detail.html b/reviewers/templates/reviewers/extensions_review_detail.html
index f3975e91..71d46216 100644
--- a/reviewers/templates/reviewers/extensions_review_detail.html
+++ b/reviewers/templates/reviewers/extensions_review_detail.html
@@ -101,8 +101,7 @@
{% for activity in extension.review_activity.all %}
- {# All activities except comments. #}
- {% if activity.type != 'COM' %}
+ {% if activity.type in status_change_types %}
diff --git a/reviewers/templates/reviewers/extensions_review_list.html b/reviewers/templates/reviewers/extensions_review_list.html
index 64f5e080..3912d605 100644
--- a/reviewers/templates/reviewers/extensions_review_list.html
+++ b/reviewers/templates/reviewers/extensions_review_list.html
@@ -34,12 +34,10 @@
- {% for extension in object_list %}
- {% if user.is_moderator %}
- {% include 'reviewers/components/review_list_item.html' %}
- {% elif extension.status_slug == 'awaiting-review' %}
- {% include 'reviewers/components/review_list_item.html' %}
- {% endif %}
+ {% for stats in object_list %}
+ {% with extension=stats.extension %}
+ {% include 'reviewers/components/review_list_item.html' with extension=extension stats=stats %}
+ {% endwith %}
{% endfor %}
diff --git a/reviewers/tests/test_views.py b/reviewers/tests/test_views.py
index dd80c1ff..7edf2cd3 100644
--- a/reviewers/tests/test_views.py
+++ b/reviewers/tests/test_views.py
@@ -3,13 +3,21 @@ from django.shortcuts import reverse
from common.tests.factories.extensions import create_version
from files.models import File
+from reviewers.models import ApprovalActivity
class CommentsViewTest(TestCase):
fixtures = ['licenses']
def setUp(self):
- self.default_version = create_version(file__status=File.STATUSES.AWAITING_REVIEW)
+ version = create_version(file__status=File.STATUSES.AWAITING_REVIEW)
+ self.default_version = version
+ ApprovalActivity(
+ type=ApprovalActivity.ActivityType.COMMENT,
+ user=version.file.user,
+ extension=version.extension,
+ message='test comment',
+ ).save()
# List of extensions under review does not require authentication
def test_list_visibility(self):
diff --git a/reviewers/views.py b/reviewers/views.py
index 7d2c9be0..cae0df7e 100644
--- a/reviewers/views.py
+++ b/reviewers/views.py
@@ -13,15 +13,51 @@ from reviewers.models import ApprovalActivity
log = logging.getLogger(__name__)
+STATUS_CHANGE_TYPES = [
+ ApprovalActivity.ActivityType.APPROVED,
+ ApprovalActivity.ActivityType.AWAITING_CHANGES,
+ ApprovalActivity.ActivityType.AWAITING_REVIEW,
+]
+
class ApprovalQueueView(ListView):
model = Extension
paginate_by = 100
def get_queryset(self):
- return Extension.objects.exclude(status=Extension.STATUSES.APPROVED).order_by(
- '-date_created'
+ qs = (
+ ApprovalActivity.objects.prefetch_related(
+ 'extension',
+ 'extension__authors',
+ 'extension__versions',
+ 'extension__versions__file',
+ 'extension__versions__file__validation',
+ )
+ .order_by('-date_created')
+ .all()
)
+ by_extension = {}
+ result = []
+ for item in qs:
+ extension = item.extension
+ stats = by_extension.get(extension, None)
+ if not stats:
+ # this check guarantees that we add a record only once per extension,
+ # and iterating over qs we get result also ordered by item.date_created
+ stats = {
+ 'count': 0,
+ 'extension': extension,
+ 'last_activity': None,
+ 'last_type_display': None,
+ }
+ by_extension[extension] = stats
+ result.append(stats)
+ stats['count'] += 1
+ if not stats.get('last_activity', None):
+ stats['last_activity'] = item
+ if not stats.get('last_type_display', None) and item.type in STATUS_CHANGE_TYPES:
+ stats['last_type_display'] = item.get_type_display
+ return result
template_name = 'reviewers/extensions_review_list.html'
@@ -36,33 +72,31 @@ class ExtensionsApprovalDetailView(DetailView):
ctx['pending_previews'] = self.object.preview_set.exclude(
file__status=File.STATUSES.APPROVED
)
+ ctx['status_change_types'] = STATUS_CHANGE_TYPES
if self.request.user.is_authenticated:
form = ctx['comment_form'] = CommentForm()
- # Remove 'Approved' status from dropdown it not moderator
- filtered_activity_types = ApprovalActivity.ActivityType.choices
+ # anyone can comment
+ filtered_activity_types = {ApprovalActivity.ActivityType.COMMENT}
user = self.request.user
- if not (user.is_moderator or user.is_superuser):
- filtered_activity_types = [
- t
- for t in ApprovalActivity.ActivityType.choices
- if t[0]
- not in [
+ if self.object.has_maintainer(user):
+ filtered_activity_types.add(ApprovalActivity.ActivityType.AWAITING_REVIEW)
+ if user.is_moderator or user.is_superuser:
+ filtered_activity_types.update(
+ [
ApprovalActivity.ActivityType.APPROVED,
ApprovalActivity.ActivityType.AWAITING_CHANGES,
]
- ]
- if not self.object.has_maintainer(user):
- # Other accounts can only comment
- filtered_activity_types = [
- t
- for t in ApprovalActivity.ActivityType.choices
- if t[0] == ApprovalActivity.ActivityType.COMMENT
- ]
- form.fields['type'].choices = filtered_activity_types
- form.fields['type'].widget.choices = filtered_activity_types
- if len(filtered_activity_types) == 1:
- form.fields['type'].widget = django.forms.HiddenInput()
+ )
+ choices = list(
+ filter(
+ lambda c: c[0] in filtered_activity_types, ApprovalActivity.ActivityType.choices
+ )
+ )
+ form.fields['type'].choices = choices
+ form.fields['type'].widget.choices = choices
+ if len(choices) == 1:
+ form.fields['type'].widget = django.forms.HiddenInput()
return ctx