Repository: e-valuation/EvaP

Issue:
Redesign user index
The user index page loads quite slowly. This could probably be improved be removing badges that are not really needed ("Contributor", "Responsible", "External", "No email") and postponing the `can_be_deleted_by_manager` check to be run only after clicking the button and returning an error message if not possible
It should be investigated if further improvements to the loading time are possible.


Discussion:
In an offline discussion, @janno42 realized that the delete button could simply be moved to the user edit form.

(edited, see discussion below)

In most cases we don't need a complete list of all users at all. So the user index page should be changed to a new overview page like the staff index giving access to:
- user import
- user adding
- user merge
- user bulk update
- the complete user list as it is now ~but extended by filters for proxy users, managers, grade publishers, and reviewers~
- a new search field where all users (including inactive and proxy users) can be found via a user selection field which then allows to open the respective user's edit form for a specific user

And in addition:
- the user edit form needs to get a delete button as stated above
to avoid any confusion, you want to *keep* the full list but extend it with more filters, and add buttons to import/merge etc at the top?

and your last bullet point I didn't understand. What does it do differently than the current search field?
the full list with additional filters is for the rare cases where you might want to see all reviewers when the student representative group changes or something like that. but it needs to be an extra page instead of the index, so that for all other use cases the loading time of the list doesn't matter anymore.

the search field should be placed on the (new) user index page and could work just like the contributor selection fields but with a button next to it opening the selected profile.
ooooh i see. So it's a completely new page with a button leading to the old one.

i would suggest leaving out the additional filters to the old page for the first PR to make this issue more accessible. maybe add the delete button to the user edit form instead, so the new page can cover more use cases. maybe the old page really becomes irrelevant then (or irrelevant enough that typing 'reviewer' into the search field is sufficient for your "see all reviewers" use case)
ah right, i had searching like that in mind and somehow forgot it on the way writing the requirement above. you are right: additional filters are not required. i'll update the list above and add the delete button thing.
@lill28 do you still want to work on this issue?

Resolving patch:
diff --git a/evap/staff/forms.py b/evap/staff/forms.py
--- a/evap/staff/forms.py
+++ b/evap/staff/forms.py
@@ -1015,6 +1015,10 @@ class UserMergeSelectionForm(forms.Form):
     other_user = UserModelChoiceField(UserProfile.objects.all())
 
 
+class UserEditSelectionForm(forms.Form):
+    user = UserModelChoiceField(UserProfile.objects.all())
+
+
 class EmailTemplateForm(forms.ModelForm):
     class Meta:
         model = EmailTemplate
diff --git a/evap/staff/urls.py b/evap/staff/urls.py
--- a/evap/staff/urls.py
+++ b/evap/staff/urls.py
@@ -69,6 +69,7 @@
     path("user/create", views.user_create, name="user_create"),
     path("user/import", views.user_import, name="user_import"),
     path("user/<int:user_id>/edit", views.user_edit, name="user_edit"),
+    path("user/list", views.user_list, name="user_list"),
 
     path("user/delete", views.user_delete, name="user_delete"),
     path("user/bulk_update", views.user_bulk_update, name="user_bulk_update"),
diff --git a/evap/staff/views.py b/evap/staff/views.py
--- a/evap/staff/views.py
+++ b/evap/staff/views.py
@@ -84,6 +84,7 @@
     TextAnswerForm,
     TextAnswerWarningForm,
     UserBulkUpdateForm,
+    UserEditSelectionForm,
     UserForm,
     UserImportForm,
     UserMergeSelectionForm,
@@ -1944,6 +1945,17 @@ def text_answer_warnings_index(request):
 
 @manager_required
 def user_index(request):
+    form = UserEditSelectionForm(request.POST or None)
+
+    if form.is_valid():
+        user = form.cleaned_data["user"]
+        return redirect("staff:user_edit", user.id)
+
+    return render(request, "staff_user_index.html", dict(form=form))
+
+
+@manager_required
+def user_list(request):
     filter_users = get_parameter_from_url_or_session(request, "filter_users")
 
     users = UserProfile.objects.all()
@@ -1976,7 +1988,7 @@ def user_index(request):
         .order_by("last_name", "first_name", "email")
     )
 
-    return render(request, "staff_user_index.html", dict(users=users, filter_users=filter_users))
+    return render(request, "staff_user_list.html", dict(users=users, filter_users=filter_users))
 
 
 @manager_required
@@ -2083,6 +2095,7 @@ def user_delete(request):
     if not user.can_be_deleted_by_manager:
         raise SuspiciousOperation("Deleting user not allowed")
     user.delete()
+    messages.success(request, _("Successfully deleted user."))
     return HttpResponse()  # 200 OK
 
 


Test patch:
diff --git a/evap/staff/tests/test_views.py b/evap/staff/tests/test_views.py
--- a/evap/staff/tests/test_views.py
+++ b/evap/staff/tests/test_views.py
@@ -144,6 +144,22 @@ def setUpTestData(cls):
 class TestUserIndexView(WebTestStaffMode):
     url = "/staff/user/"
 
+    @classmethod
+    def setUpTestData(cls):
+        cls.manager = make_manager()
+        cls.some_user = baker.make(UserProfile)
+
+    def test_redirect(self):
+        page = self.app.get(self.url, user=self.manager, status=200)
+        form = page.forms["user-edit-form"]
+        form["user"] = self.some_user.pk
+        response = form.submit(status=302)
+        self.assertEqual(response.location, f"/staff/user/{self.some_user.pk}/edit")
+
+
+class TestUserListView(WebTestStaffMode):
+    url = "/staff/user/list"
+
     @classmethod
     def setUpTestData(cls):
         cls.manager = make_manager()