diff --git a/src/c3nav/control/templates/control/fragment_pagination.html b/src/c3nav/control/templates/control/fragment_pagination.html
new file mode 100644
index 00000000..6f095077
--- /dev/null
+++ b/src/c3nav/control/templates/control/fragment_pagination.html
@@ -0,0 +1,24 @@
+{% load i18n %}
+
+ {% if objects.has_previous %}
+
+ « {% trans 'first' %}
+ ·
+
+ ‹ {% trans 'previous' %}
+ ·
+ {% endif %}
+ {% with page_number=objects.number num_pages=objects.paginator.num_pages %}
+ {% blocktrans %}
+ Page {{ page_number }} of {{ num_pages }}
+ {% endblocktrans %}
+ {% endwith %}
+ {% if objects.has_next %}
+ ·
+ {% trans 'next' %} ›
+
+ ·
+ {% trans 'last' %} »
+
+ {% endif %}
+
diff --git a/src/c3nav/control/templates/control/users.html b/src/c3nav/control/templates/control/users.html
new file mode 100644
index 00000000..3f27bf7d
--- /dev/null
+++ b/src/c3nav/control/templates/control/users.html
@@ -0,0 +1,27 @@
+{% extends 'control/base.html' %}
+{% load i18n %}
+
+{% block subcontent %}
+ {% trans 'Users' %}
+
+
+
+ {% include 'control/fragment_pagination.html' with objects=users %}
+
+
+
+ {% trans 'ID' %} |
+ {% trans 'Username' %} |
+
+ {% for user in users %}
+
+ {{ user.id }} |
+ {{ user.username }} |
+
+ {% endfor %}
+
+
+ {% include 'control/fragment_pagination.html' with objects=users %}
+{% endblock %}
diff --git a/src/c3nav/control/urls.py b/src/c3nav/control/urls.py
index 7058385a..c0896ad8 100644
--- a/src/c3nav/control/urls.py
+++ b/src/c3nav/control/urls.py
@@ -1,7 +1,8 @@
from django.conf.urls import url
-from c3nav.control.views import main_index
+from c3nav.control.views import main_index, user_list
urlpatterns = [
+ url(r'^users/$', user_list, name='control.users'),
url(r'^$', main_index, name='control.index'),
]
diff --git a/src/c3nav/control/views.py b/src/c3nav/control/views.py
index dce8792e..f62b265f 100644
--- a/src/c3nav/control/views.py
+++ b/src/c3nav/control/views.py
@@ -1,19 +1,40 @@
from functools import wraps
from django.contrib.auth.decorators import login_required
+from django.contrib.auth.models import User
from django.core.exceptions import PermissionDenied
+from django.core.paginator import Paginator
from django.shortcuts import render
def control_panel_view(func):
@wraps(func)
- def wrapped_func(self, request, *args, **kwargs):
+ def wrapped_func(request, *args, **kwargs):
if not request.user_permissions.control_panel:
raise PermissionDenied
- return func(self, request, *args, **kwargs)
+ return func(request, *args, **kwargs)
return login_required(login_url='site.login')(wrapped_func)
+@login_required
@control_panel_view
def main_index(request):
return render(request, 'control/index.html', {})
+
+
+@login_required
+@control_panel_view
+def user_list(request):
+ search = request.GET.get('s')
+ page = request.GET.get('page', 1)
+
+ queryset = User.objects.order_by('id')
+ if search:
+ queryset = queryset.filter(username__icontains=search.strip())
+
+ paginator = Paginator(queryset, 20)
+ users = paginator.page(page)
+
+ return render(request, 'control/users.html', {
+ 'users': users,
+ })
diff --git a/src/c3nav/site/static/site/css/c3nav.css b/src/c3nav/site/static/site/css/c3nav.css
index 59c3d286..5d79b1d8 100644
--- a/src/c3nav/site/static/site/css/c3nav.css
+++ b/src/c3nav/site/static/site/css/c3nav.css
@@ -685,3 +685,8 @@ ul.messages li.alert-danger {
border-color: #CC0000;
background-color:#FFEEEE;
}
+
+.search-form input {
+ max-width: 400px;
+ vertical-align: top;
+}