Skip to content

Commit

Permalink
Add new user list for administrators
Browse files Browse the repository at this point in the history
  • Loading branch information
rixx committed Apr 15, 2024
1 parent 171c478 commit 06d76a0
Show file tree
Hide file tree
Showing 8 changed files with 366 additions and 7 deletions.
1 change: 1 addition & 0 deletions doc/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
Release Notes
=============

- :feature:`orga` Administrators (i.e. instance owners) can now search a list of all users, which includes their teams and permissions, and links to trigger account deletion and password resets.
- :bug:`orga:review` Assigning reviewers could lead to incorrect assignments when browsers cached the form, but new reviewers were added to the team, shifting the overall order of input fields.
- :feature:`cfp` Choice and multiple choice questions now use a drop-down with typeahead (search for options) when they have a lot of options.
- :feature:`orga,1079` All images in forms in the organiser area now include a preview of the saved image, and open a lightbox instead of the image file when clicked.
Expand Down
File renamed without changes.
19 changes: 19 additions & 0 deletions src/pretalx/orga/templates/orga/admin/user_delete.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{% extends "orga/base.html" %}
{% load i18n %}
{% block content %}
<h2>
{% translate "Do you really want to delete this user?" %}
</h2>
<strong>{{ quotation_close }}{{ object.name }}{{ quotation_open }}</strong> – {{ object.text }}<p>
<form method="post">
{% csrf_token %}
<div class="submit-group">
<a href="/orga/admin/users/{{ object.code }}/" class="btn btn-lg btn-danger">
{% translate "Back" %}
</a>
<button type="submit" class="btn btn-lg btn-success">
{% translate "Yes" %}
</button>
</div>
</form>
{% endblock %}
119 changes: 119 additions & 0 deletions src/pretalx/orga/templates/orga/admin/user_detail.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
{% extends "orga/base.html" %}
{% load bootstrap4 %}
{% load copyable %}
{% load i18n %}
{% load url_replace %}

{% block title %}{{ user.name }}{% endblock %}

{% block content %}
<h2 class="d-flex">{{ user.name }}
<form method="post">
{% csrf_token %}
<button class="btn btn-warning btn-sm ml-2 mr-2" type="submit" name="action" value="pw-reset">
<i class="fa fa-key"></i>
{% translate "Reset password" %}
</button>
<a href="delete" class="btn btn-danger btn-sm"><i class="fa fa-trash"></i></a>
</form>
</h2>

<div class="d-flex justify-content-between">
<table class="table table-sm table-flip col-4">
<tr>
<th>{% translate "Email" %}</th>
<td>{{ user.email|copyable }}</td>
</tr>
<tr>
<th>{% translate "Last login" %}</th>
<td>{{ user.last_login|default:'-' }}</td>
</tr>
<tr>
<th>{% translate "Password reset time" %}</th>
<td>{{ user.pw_reset_time|default:'-' }}</td>
</tr>
<tr>
<th>{% translate "Language" %}</th>
<td>{{ user.locale }}</td>
</tr>
<tr>
<th>{% translate "Timezone" %}</th>
<td>{{ user.timezone }}</td>
</tr>
</table>
<div class="ml-auto">
<img height=160 class="" src="https://www.gravatar.com/avatar/{{ user.gravatar_parameter }}?s=512">
</div>
</div>

<h4>{% translate "Teams" %}</h4>
<div class="table-responsive">
<table class="table table-sm table-hover table-flip">
<thead>
<tr>
<th>{% translate "Team" %}</th>
<th>{% translate "Organiser" %}</th>
<th>{% translate "Events" %}</th>
<th>{% translate "Permissions" %}</th>
</tr>
</thead>
<tbody>
{% for team in user.teams.all %}
<tr>
<td><a href="{{ team.urls.base }}">{{ team.name }}</a></td>
<td><a href="{{ team.organiser.orga_urls.base }}">{{ team.organiser.name }}</a></td>
<td>
{% if team.limit_events.all %}
{% for event in team.limit_events.all %}
<a href="{{ event.orga_urls.base }}">{{ event.name }}</a>{% if not forloop.last %},{% endif %}
{% endfor %}
{% else %}
{% translate "All events" %}:
{% for event in team.organiser.events.all %}
<a href="{{ event.orga_urls.base }}">{{ event.name }}</a>{% if not forloop.last %},{% endif %}
{% endfor %}
{% endif %}

<td>{{ team.permission_set }}</td>
</tr>
{% empty %}
<tr>
<td colspan="4">{% translate "User isn't in any teams" %}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>

<hr>

<h4>{% translate "Proposals" %}</h4>

<div class="table-responsive">
<table class="table table-sm table-hover table-flip">
<thead>
<tr>
<th>{% translate "Title" %}</th>
<th>{% translate "Event" %}</th>
<th>{% translate "State" %}</th>
<th>{% translate "Submitted" %}</th>
</tr>
</thead>
<tbody>
{% for submission in submissions %}
<tr>
<td><a href="{{ submission.orga_urls.base }}">{{ submission.title }}</a></td>
<td><a href="{{ submission.event.orga_urls.base }}">{{ submission.event.name }}</a></td>
<td>{% include "cfp/event/fragment_state.html" with state=submission.state %}</td>
<td>{{ submission.created | date:"SHORT_DATE_FORMAT" }}</td>
</tr>
{% empty %}
<tr>
<td colspan="4">{% translate "User hasn't submitted any proposals" %}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>

{% endblock %}
89 changes: 89 additions & 0 deletions src/pretalx/orga/templates/orga/admin/user_list.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
{% extends "orga/base.html" %}
{% load bootstrap4 %}
{% load copyable %}
{% load i18n %}
{% load url_replace %}

{% block title %}{% translate "Users" %}{% endblock %}

{% block content %}
<h2>{% translate "Users" %}</h2>

<form>
<input name="q" type="text" {% if request.GET.q %} value="{{ request.GET.q }}" {% endif %}>
</form>

<form method="post">{% csrf_token %}
<div class="table-responsive">
<table class="table table-sm table-hover table-flip">
<thead>
<tr>
<th>
{% translate "Name" %}
</th>
<th>
{% translate "Email" %}
</th>
<th>
{% translate "Language" %}
</th>
<th>
{% translate "Teams" %}
</th>
<th>
{% translate "Events" %}
</th>
<th class="numeric">
{% translate "Submissions" %}
</th>
<th class="numeric">
{% translate "Last login" %}
</th>
<th class="numeric">
{% translate "Password reset time" %}
</th>
<th></th>
</tr>
</thead>
<tbody>
{% for user in users %}
<tr>
<td>
<a href="/orga/admin/users/{{ user.code }}/">{{ user.name }}</a>
</td>
<td>{{ user.email|copyable }}</td>
<td>{{ user.locale }}</td>
<td>
<ul>
{% for team in user.teams.all %}
<li><a href="{{ team.urls.base }}">{{ team.name }}</li>
{% endfor %}
</ul>
</td>
<td>
<ul>
{% for event in user.get_events_with_any_permission %}
<li><a href="{{ event.orga_urls.base }}">{{ event.name }}</li>
{% endfor %}
</ul>
</td>
<td class="numeric">{{ user.submission_count }}</td>
<td class="numeric-left">{{ user.last_login|timesince }} {% if user.last_login %}ago{% endif %}</td>
<td class="numeric-left">{{ user.pw_reset_time|timesince }}{% if user.pw_reset_time %} ago{% endif %}</td>
<td>
<div class="d-flex mb-2">
<a href="/orga/admin/users/{{ user.code }}/" class="btn btn-xs btn-info mr-2"> <i class="fa fa-edit"></i> </a>
<button name="action" value="delete-{{ user.id }}" class="btn btn-xs btn-danger"><i class="fa fa-trash"></i></button>
</div>
<button name="action" value="reset-{{ user.id }}" class="btn btn-xs btn-warning mr-2">{% translate "Reset password" %}</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</form>
</div>
{% include "orga/includes/pagination.html" %}
{% endblock %}


25 changes: 21 additions & 4 deletions src/pretalx/orga/templates/orga/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -405,10 +405,27 @@
</a>
{% endif %}
{% if request.user.is_administrator %}
<a class="nav-link {% if "/orga/admin/" in request.path %} active{% endif %}" href="/orga/admin/">
<i class="fa fa-users"></i>
<span>{% translate "Admin information" %}</span>
</a>
<div class="nav-fold">
<span class="has-children">
<a class="nav-link nav-link-inner" href="/orga/admin/">
<i class="fa fa-cogs"></i>
<span class="sidebar-text">
{% translate "Administration" %}
</span>
</a>
<a class="arrow nav-link" data-toggle="collapse" href="#collapseAdmin" aria-controls="collapseAdmin">
<i class="fa fa-angle-down"></i>
</a>
</span>
<div class="collapse in{% if "/orga/admin/" in request.path %} show{% endif %}" aria-expand="true" id="collapseAdmin">
<a class="nav-link nav-link-second-level {% if "/orga/admin/" == request.path %} active{% endif %}" href="/orga/admin/">
<span>{% translate "Admin information" %}</span>
</a>
<a href="/orga/admin/users/" class="nav-link nav-link-second-level{% if "/orga/admin/users" in request.path %} active{% endif %}">
<span>{% translate "Users" %}</span>
</a>
</div>
</div>
{% endif %}
{% for nav_element in nav_global %}
{% include "orga/includes/sidebar_nav.html" %}
Expand Down
11 changes: 11 additions & 0 deletions src/pretalx/orga/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,17 @@
path("", RedirectView.as_view(url="event", permanent=False)),
path("admin/", admin.AdminDashboard.as_view(), name="admin.dashboard"),
path("admin/update/", admin.UpdateCheckView.as_view(), name="admin.update"),
path(
"admin/users/<slug:code>/",
admin.AdminUserDetail.as_view(),
name="admin.user.view",
),
path(
"admin/users/<slug:code>/delete/",
admin.AdminUserDelete.as_view(),
name="admin.user.delete",
),
path("admin/users/", admin.AdminUserList.as_view(), name="admin.user.list"),
path("me", event.UserSettings.as_view(), name="user.view"),
path("me/subuser", person.SubuserView.as_view(), name="user.subuser"),
path(
Expand Down
Loading

0 comments on commit 06d76a0

Please sign in to comment.