Repository: comic/grand-challenge.org

Issue:
ChallengeList page should use pagination
This takes a while to load with many challenges and the Automated Evaluation boolean no longer works.



Discussion:

Resolving patch:
diff --git a/app/grandchallenge/challenges/views.py b/app/grandchallenge/challenges/views.py
--- a/app/grandchallenge/challenges/views.py
+++ b/app/grandchallenge/challenges/views.py
@@ -27,6 +27,7 @@
     UserIsStaffMixin,
 )
 from grandchallenge.core.templatetags.random_encode import random_encode
+from grandchallenge.datatables.views import Column, PaginatedTableListView
 from grandchallenge.subdomains.mixins import ChallengeSubdomainObjectMixin
 from grandchallenge.subdomains.utils import reverse
 
@@ -117,12 +118,33 @@ def get_context_data(self, *, object_list=None, **kwargs):
         return context
 
 
-class UsersChallengeList(UserIsNotAnonMixin, ListView):
+class UsersChallengeList(UserIsNotAnonMixin, PaginatedTableListView):
     model = Challenge
     template_name = "challenges/challenge_users_list.html"
+    row_template = "challenges/challenge_users_row.html"
+    search_fields = [
+        "title",
+        "short_name",
+        "description",
+    ]
+    columns = [
+        Column(title="Name", sort_field="short_name"),
+        Column(title="Created", sort_field="created"),
+        Column(title="Admins", sort_field="created"),
+        Column(title="Description", sort_field="description"),
+        Column(title="Automated Evaluation", sort_field="use_evaluation"),
+    ]
+    default_sort_column = 1
 
     def get_queryset(self):
-        queryset = super().get_queryset()
+        queryset = (
+            super()
+            .get_queryset()
+            .prefetch_related(
+                "admins_group__user_set__user_profile",
+                "admins_group__user_set__verification",
+            )
+        )
         if not self.request.user.is_superuser:
             queryset = queryset.filter(
                 Q(participants_group__in=self.request.user.groups.all())


Test patch:
diff --git a/app/tests/challenges_tests/test_filters.py b/app/tests/challenges_tests/test_filters.py
--- a/app/tests/challenges_tests/test_filters.py
+++ b/app/tests/challenges_tests/test_filters.py
@@ -6,28 +6,25 @@
 
 @pytest.mark.django_db
 def test_challenge_list_is_filtered(client, two_challenge_sets):
-    c1 = two_challenge_sets.challenge_set_1.challenge.short_name
-    c2 = two_challenge_sets.challenge_set_2.challenge.short_name
+    c1 = two_challenge_sets.challenge_set_1.challenge
+    c2 = two_challenge_sets.challenge_set_2.challenge
     tests = [
-        ([], [c1, c2], two_challenge_sets.challenge_set_1.non_participant),
-        ([c1], [c2], two_challenge_sets.challenge_set_1.participant),
-        ([c1], [c2], two_challenge_sets.challenge_set_1.participant1),
-        ([c1], [c2], two_challenge_sets.challenge_set_1.creator),
-        ([c1], [c2], two_challenge_sets.challenge_set_1.admin),
-        ([], [c1, c2], two_challenge_sets.challenge_set_2.non_participant),
-        ([c2], [c1], two_challenge_sets.challenge_set_2.participant),
-        ([c2], [c1], two_challenge_sets.challenge_set_2.participant1),
-        ([c2], [c1], two_challenge_sets.challenge_set_2.creator),
-        ([c2], [c1], two_challenge_sets.challenge_set_2.admin),
-        ([c1, c2], [], two_challenge_sets.admin12),
-        ([c1, c2], [], two_challenge_sets.participant12),
-        ([c1, c2], [], two_challenge_sets.admin1participant2),
+        (set(), two_challenge_sets.challenge_set_1.non_participant),
+        ({c1}, two_challenge_sets.challenge_set_1.participant),
+        ({c1}, two_challenge_sets.challenge_set_1.participant1),
+        ({c1}, two_challenge_sets.challenge_set_1.creator),
+        ({c1}, two_challenge_sets.challenge_set_1.admin),
+        (set(), two_challenge_sets.challenge_set_2.non_participant),
+        ({c2}, two_challenge_sets.challenge_set_2.participant),
+        ({c2}, two_challenge_sets.challenge_set_2.participant1),
+        ({c2}, two_challenge_sets.challenge_set_2.creator),
+        ({c2}, two_challenge_sets.challenge_set_2.admin),
+        ({c1, c2}, two_challenge_sets.admin12),
+        ({c1, c2}, two_challenge_sets.participant12),
+        ({c1, c2}, two_challenge_sets.admin1participant2),
     ]
-    for test in tests:
+    for expected_challenges, user in tests:
         response = get_view_for_user(
-            url=reverse("challenges:users-list"), client=client, user=test[2]
+            url=reverse("challenges:users-list"), client=client, user=user
         )
-        for short_name in test[0]:
-            assert short_name in response.rendered_content
-        for short_name in test[1]:
-            assert short_name not in response.rendered_content
+        assert expected_challenges == {*response.context[-1]["object_list"]}