Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix #1333 #1667

Merged
merged 14 commits into from
Apr 22, 2022
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 2 additions & 10 deletions evap/evaluation/templates/navbar.html
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,8 @@
<li class="nav-item"><a class="nav-link" href="{% url 'results:index' %}">{% trans 'Results' %}</a></li>
{% endif %}
{% if user.is_manager %}
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarUsersDropdownMenuLink" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">{% trans 'Users' %}</a>
<div class="dropdown-menu" aria-labelledby="navbarUsersDropdownMenuLink">
<a class="dropdown-item" href="{% url 'staff:user_index' %}">{% trans 'User list' %}</a>
<a class="dropdown-item" href="{% url 'staff:user_create' %}">{% trans 'Create' %}</a>
<a class="dropdown-item" href="{% url 'staff:user_import' %}">{% trans 'Import' %}</a>
<a class="dropdown-item" href="{% url 'staff:user_merge_selection' %}">{% trans 'Merge' %}</a>
<a class="dropdown-item" href="{% url 'staff:user_bulk_update' %}">{% trans 'Update' %}</a>
</div>
</li>

<li class="nav-item"><a class="nav-link" href="{% url 'staff:user_index' %}">{% trans 'Users' %}</a></li>
<li class="nav-item"><a class="nav-link" href="{% url 'staff:questionnaire_index' %}">{% trans 'Questionnaires' %}</a></li>
{% endif %}
{% if user.is_grade_publisher %}
Expand Down
2 changes: 2 additions & 0 deletions evap/staff/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -913,6 +913,8 @@ class UserMergeSelectionForm(forms.Form):
main_user = UserModelChoiceField(UserProfile.objects.all())
other_user = UserModelChoiceField(UserProfile.objects.all())

class UserEditSelectionForm(forms.Form):
user = UserModelChoiceField(UserProfile.objects.all())

class EmailTemplateForm(forms.ModelForm):
class Meta:
Expand Down
2 changes: 1 addition & 1 deletion evap/staff/templates/staff_index.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ <h4 class="card-title">{% trans 'Questionnaires' %}</h4>
<div class="card-body">
<h4 class="card-title">{% trans 'Users' %}</h4>
<ul>
<li><a href="{% url 'staff:user_index' %}">{% trans 'All users' %}</a></li>
<li><a href="{% url 'staff:user_list' %}">{% trans 'All users' %}</a></li>
<li><a href="{% url 'staff:user_import' %}">{% trans 'Import users' %}</a></li>
<li><a href="{% url 'staff:user_merge_selection' %}">{% trans 'Merge users' %}</a></li>
<li><a href="{% url 'staff:user_bulk_update' %}">{% trans 'Update users' %}</a></li>
Expand Down
29 changes: 29 additions & 0 deletions evap/staff/templates/staff_user_form.html
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,36 @@ <h5 class="card-title me-auto">{% trans 'Export evaluation results' %}</h5>
<div class="card card-submit-area text-center mb-3">
<div class="card-body">
<button type="submit" class="btn btn-primary">{% trans 'Save user' %}</button>
{% if form.instance and form.instance.can_be_deleted_by_manager %}
<button type="button" class="btn btn-danger" onclick="deleteModalShow({{ form.instance.id }}, '{{ form.instance.full_name|escapejs }}');">
{% trans 'Delete user' %}
</button>
{% else %}
<span tabindex="0" data-bs-toggle="tooltip" title="{% blocktrans %}This user contributes to an evaluation, participates in an evaluation whose participations haven't been archived yet or has special rights and as such cannot be deleted.{% endblocktrans %}">
<button type="button" disabled class="btn btn-danger">
{% trans 'Delete user' %}
</button>
{% endif %}
</div>
</div>
</form>
{% endblock %}

{% block modals %}
{{ block.super }}
{% trans 'Delete user' as title %}
{% trans 'Do you really want to delete the user <strong data-label=""></strong>?<br/>This person will also be removed from every other user having this person as a delegated or CC-user.' as question %}
{% trans 'Delete user' as action_text %}
{% include 'confirmation_modal.html' with modal_id='deleteModal' title=title question=question action_text=action_text btn_type='danger' %}
<script type="text/javascript">
function deleteModalAction(dataId) {
$.ajax({
type: "POST",
url: "{% url 'staff:user_delete' %}",
data: {"user_id": dataId},
success: function(){window.location="{% url 'staff:user_index' %}"},
janno42 marked this conversation as resolved.
Show resolved Hide resolved
error: function(){ window.alert("{% trans 'The server is not responding.' %}"); }
});
};
</script>
{% endblock %}
116 changes: 24 additions & 92 deletions evap/staff/templates/staff_user_index.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,102 +9,34 @@

{% block content %}
{{ block.super }}
<div class="row mb-3 align-items-center">
janno42 marked this conversation as resolved.
Show resolved Hide resolved
<div class="col btn-area">
<a href="{% url 'staff:user_import' %}" class="btn btn-sm btn-light">{% trans 'Import users' %}</a>
<a href="{% url 'staff:user_merge_selection' %}" class="btn btn-sm btn-light">{% trans 'Merge users' %}</a>
<a href="{% url 'staff:user_bulk_update' %}" class="btn btn-sm btn-light">{% trans 'Bulk update users' %}</a>
<a href="{% url 'staff:user_create' %}" class="btn btn-sm btn-dark">{% trans 'Create new user' %}</a>
</div>
<div class="col-auto">
<div class="btn-switch btn-switch-light">
<div class="btn-switch-label">{% trans 'Inactive users' %}</div>
<div class="btn-switch btn-group">
<a href="{% url 'staff:user_index' %}?filter_users=false" role="button" class="btn btn-sm btn-light{% if not filter_users %} active{% endif %}">
{% trans 'Show' %}
</a>
<a href="{% url 'staff:user_index' %}?filter_users=true" role="button" class="btn btn-sm btn-light{% if filter_users %} active{% endif %}">
{% trans 'Hide' %}
</a>

<div class="row row-cols-1 row-cols-md-2">
<div class="col">
<div class="card h-100">
<div class="card-body">
<ul>
<li><a href="{% url 'staff:user_list' %}" class="">{% trans 'User list' %}</a></li>
<li><a href="{% url 'staff:user_import' %}" class="">{% trans 'Import users' %}</a></li>
<li><a href="{% url 'staff:user_merge_selection' %}" class="">{% trans 'Merge users' %}</a></li>
<li><a href="{% url 'staff:user_bulk_update' %}" class="">{% trans 'Bulk update users' %}</a></li>
</ul>
<a href="{% url 'staff:user_create' %}" class="btn btn-sm btn-dark mt-2">{% trans 'Create new user' %}</a>
</div>
</div>
</div>
<div class="col-3">
<div class="input-group">
<input type="search" name="search" class="form-control" placeholder="{% trans 'Search...' %}" />
<button class="btn btn-light text-secondary" type="button" data-reset="search" data-bs-toggle="tooltip" data-bs-placement="top" title="{% trans 'Clear search filter' %}">
<span class="fas fa-backspace"></span>
</button>
<div class="col">
<div class="card h-100">
<div class="card-body">
<form id="user-edit-form" method="POST" class="form-horizontal">
{% csrf_token %}
<h4 class="card-title">{% trans 'Edit user' %}</h4>
{% include 'bootstrap_form_field_widget.html' with field=form.user %}
</form>
richardebeling marked this conversation as resolved.
Show resolved Hide resolved
</div>
<div class="card-footer text-center card-submit-area d-flex">
<button type="submit" form="user-edit-form" class="btn btn-primary mx-auto my-auto">{% trans 'Edit' %}</button>
</div>
</div>
</div>
</div>

<div class="card mb-3">
<div class="card-body">
<table class="table table-striped table-vertically-aligned user-table">
<thead>
<tr>
<th style="width: 25%">{% trans 'Name' %}</th>
<th style="width: 35%">{% trans 'Email' %}</th>
<th style="width: 30%">{% trans 'Information' %}</th>
<th style="width: 10%">{% trans 'Actions' %}</th>
</tr>
</thead>
<tbody>
{% for user in users %}
<tr id="user-row-{{ user.id }}">
<td>{{ user.full_name }}</td>
<td>{% if user.email %}{{ user.email }}{% endif %}</td>
<td>{% include 'staff_user_badges.html' with user=user %}</td>
<td>
<a href="{% url 'staff:user_edit' user.id %}" class="btn btn-secondary btn-sm"><span class="fas fa-pencil-alt"></span></a>
{% if user.can_be_deleted_by_manager %}
<button type="button" class="btn btn-danger btn-sm" onclick="deleteModalShow({{ user.id }}, '{{ user.full_name|escapejs }}');">
<span class="fas fa-trash"></span
></button>
{% else %}
<button type="button" disabled class="btn btn-sm btn-danger" data-bs-toggle="tooltip" data-bs-placement="left"
title="{% blocktrans %}This user contributes to an evaluation, participates in an evaluation whose participations
haven't been archived yet or has special rights and as such cannot be deleted.{% endblocktrans %}">
<span class="fas fa-trash"></span>
</button>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
{% endblock %}

{% block modals %}
{{ block.super }}
{% trans 'Delete user' as title %}
{% trans 'Do you really want to delete the user <strong data-label=""></strong>?<br/>This person will also be removed from every other user having this person as a delegated or CC-user.' as question %}
{% trans 'Delete user' as action_text %}
{% include 'confirmation_modal.html' with modal_id='deleteModal' title=title question=question action_text=action_text btn_type='danger' %}
<script type="text/javascript">
function deleteModalAction(dataId) {
$.ajax({
type: "POST",
url: "{% url 'staff:user_delete' %}",
data: {"user_id": dataId},
success: function(){ $('#user-row-'+dataId).hide('slow', function(){ $('#user-row-'+dataId).remove(); }); },
error: function(){ window.alert("{% trans 'The server is not responding.' %}"); }
});
};
</script>
{% endblock %}

{% block additional_javascript %}
<script type="module">
import {TableGrid} from "{% static 'js/datagrid.js' %}";
new TableGrid({
storageKey: "user-index-data-grid",
table: document.querySelector(".user-table"),
searchInput: document.querySelector("input[name=search]"),
resetSearch: document.querySelector("[data-reset=search]"),
}).init();
</script>
{% endblock %}
77 changes: 77 additions & 0 deletions evap/staff/templates/staff_user_list.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
{% extends 'staff_base.html' %}

{% load static %}

{% block breadcrumb %}
{{ block.super }}
<li class="breadcrumb-item"><a href="{% url 'staff:user_index' %}">{% trans 'Users' %}</a></li>
<li class="breadcrumb-item">{% trans 'User list' %}</li>
{% endblock %}

{% block content %}
{{ block.super }}
<div class="row mb-3 align-items-center">
<div class="col-auto">
<div class="btn-switch btn-switch-light">
<div class="btn-switch-label">{% trans 'Inactive users' %}</div>
<div class="btn-switch btn-group">
<a href="{% url 'staff:user_list' %}?filter_users=false" role="button" class="btn btn-sm btn-light{% if not filter_users %} active{% endif %}">
{% trans 'Show' %}
</a>
<a href="{% url 'staff:user_list' %}?filter_users=true" role="button" class="btn btn-sm btn-light{% if filter_users %} active{% endif %}">
{% trans 'Hide' %}
</a>
</div>
</div>
</div>
<div class="col-3 ms-auto">
<div class="input-group">
<input type="search" name="search" class="form-control" placeholder="{% trans 'Search...' %}" />
<div class="input-group-append">
<button class="btn btn-light text-secondary" type="button" data-reset="search" data-toggle="tooltip" data-placement="top" title="{% trans 'Clear search filter' %}">
<span class="fas fa-backspace"></span>
</button>
</div>
</div>
</div>
</div>

<div class="card mb-3">
<div class="card-body">
<table class="table table-vertically-aligned table-seamless-links user-table">
<thead>
<tr>
<th style="width: 25%">{% trans 'Name' %}</th>
<th style="width: 35%">{% trans 'Email' %}</th>
<th style="width: 30%">{% trans 'Information' %}</th>
<th style="width: 10%"></th>
</tr>
</thead>
<tbody>
{% for user in users %}
<tr id="user-row-{{ user.id }}" class="hover-row hover-row-info" data-url="{% url 'staff:user_edit' user.id %}">
<td>{{ user.full_name }}</td>
<td>{% if user.email %}{{ user.email }}{% endif %}</td>
<td>{% include 'staff_user_badges.html' with user=user %}</td>
<td class="text-end">
<a href="{% url 'staff:user_edit' user.id %}" class="btn btn-primary btn-sm btn-row-hover"><span class="fas fa-pencil-alt"></span></a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
{% endblock %}

{% block additional_javascript %}
<script type="module">
import {TableGrid} from "{% static 'js/datagrid.js' %}";
new TableGrid({
storageKey: "user-index-data-grid",
table: document.querySelector(".user-table"),
searchInput: document.querySelector("input[name=search]"),
resetSearch: document.querySelector("[data-reset=search]"),
}).init();
</script>
{% endblock %}
4 changes: 2 additions & 2 deletions evap/staff/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,8 @@ def setUpTestData(cls):
baker.make(FaqQuestion, section=section)


class TestUserIndexView(WebTestStaffMode):
url = "/staff/user/"
class TestUserListView(WebTestStaffMode):
url = "/staff/user/list"

@classmethod
def setUpTestData(cls):
Expand Down
1 change: 1 addition & 0 deletions evap/staff/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,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"),
Expand Down
18 changes: 17 additions & 1 deletion evap/staff/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
from evap.rewards.models import RewardPointGranting
from evap.rewards.tools import can_reward_points_be_used_by, is_semester_activated
from evap.staff import staff_mode

niklasmohrin marked this conversation as resolved.
Show resolved Hide resolved
from evap.staff.forms import (
AtLeastOneFormSet,
ContributionCopyForm,
Expand Down Expand Up @@ -82,6 +83,7 @@
UserForm,
UserImportForm,
UserMergeSelectionForm,
UserEditSelectionForm,
)
from evap.staff.importers import EnrollmentImporter, PersonImporter, UserImporter, sorted_messages
from evap.staff.tools import (
Expand All @@ -96,6 +98,9 @@
merge_users,
save_import_file,
)



niklasmohrin marked this conversation as resolved.
Show resolved Hide resolved
from evap.student.forms import QuestionnaireVotingForm
from evap.student.models import TextAnswerWarning
from evap.student.views import get_valid_form_groups_or_render_vote_page
Expand Down Expand Up @@ -1893,6 +1898,16 @@ def text_answer_warnings_index(request):

@manager_required
def user_index(request):
richardebeling marked this conversation as resolved.
Show resolved Hide resolved
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()
Expand Down Expand Up @@ -1925,7 +1940,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))
richardebeling marked this conversation as resolved.
Show resolved Hide resolved


@manager_required
Expand Down Expand Up @@ -2033,6 +2048,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


Expand Down