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