From d6aef973d64a5f84699cc63dd0725909947f9356 Mon Sep 17 00:00:00 2001
From: George Hickman <george@ghickman.co.uk>
Date: Fri, 26 Jul 2019 10:24:05 +0100
Subject: [PATCH] Add filters to the Leaderboard table

---
 hypha/apply/funds/tables.py          | 46 +++++++++++++++++++++++++++-
 hypha/apply/funds/views.py           |  2 ++
 hypha/apply/users/tests/factories.py |  2 +-
 3 files changed, 48 insertions(+), 2 deletions(-)

diff --git a/hypha/apply/funds/tables.py b/hypha/apply/funds/tables.py
index 7b83b3b45..b9824e848 100644
--- a/hypha/apply/funds/tables.py
+++ b/hypha/apply/funds/tables.py
@@ -23,7 +23,6 @@ from hypha.images.models import CustomImage
 
 from .widgets import Select2MultiCheckboxesWidget
 
-
 User = get_user_model()
 
 
@@ -363,6 +362,51 @@ class RoundsFilter(filters.FilterSet):
     round_state = OpenRoundFilter(label='Open')
 
 
+class LeaderboardFilterForm(forms.ModelForm):
+    """
+    Form to "clean" a list of User objects to their PKs.
+
+    The Leaderboard table is a list of User objects, however we also want the
+    ability to filter down to N Users (reviewers).  Django filter is converting
+    the selected PKs to User objects, however we can't filter a User QuerySet
+    with User objects.  So this form converts back to a list of User PKs using
+    the clean_reviewer method.
+    """
+    class Meta:
+        fields = ["id"]
+        model = User
+
+    def clean_reviewer(self):
+        return [u.id for u in self.cleaned_data['reviewer']]
+
+
+class LeaderboardFilter(filters.FilterSet):
+    reviewer = Select2ModelMultipleChoiceFilter(
+        field_name='pk',
+        label='Reviewers',
+        queryset=get_reviewers,
+    )
+    funds = Select2ModelMultipleChoiceFilter(
+        field_name='submission__page',
+        label='Funds',
+        queryset=get_used_funds,
+    )
+    rounds = Select2ModelMultipleChoiceFilter(
+        field_name='submission__round',
+        label='Rounds',
+        queryset=get_used_rounds,
+    )
+
+    class Meta:
+        fields = [
+            'reviewer',
+            'funds',
+            'rounds',
+        ]
+        form = LeaderboardFilterForm
+        model = User
+
+
 class LeaderboardTable(tables.Table):
     full_name = tables.Column(verbose_name="Reviewer")
     most_recent = tables.Column(orderable=False)
diff --git a/hypha/apply/funds/views.py b/hypha/apply/funds/views.py
index d77ab9755..2061a89bf 100644
--- a/hypha/apply/funds/views.py
+++ b/hypha/apply/funds/views.py
@@ -79,6 +79,7 @@ from .models import (
 from .permissions import is_user_has_access_to_view_submission
 from .tables import (
     AdminSubmissionsTable,
+    LeaderboardFilter,
     LeaderboardTable,
     ReviewerSubmissionsTable,
     RoundsFilter,
@@ -1187,6 +1188,7 @@ class SubmissionResultView(FilterView):
 
 @method_decorator(login_required, name='dispatch')
 class ReviewLeaderboard(SingleTableMixin, FilterView):
+    filterset_class = LeaderboardFilter
     table_class = LeaderboardTable
     table_pagination = False
     template_name = 'funds/review_leaderboard.html'
diff --git a/hypha/apply/users/tests/factories.py b/hypha/apply/users/tests/factories.py
index f1c46e42e..59fb93094 100644
--- a/hypha/apply/users/tests/factories.py
+++ b/hypha/apply/users/tests/factories.py
@@ -11,7 +11,7 @@ from ..groups import (
     COMMUNITY_REVIEWER_GROUP_NAME,
     PARTNER_GROUP_NAME,
     REVIEWER_GROUP_NAME,
-    STAFF_GROUP_NAME
+    STAFF_GROUP_NAME,
 )
 
 
-- 
GitLab