kopia lustrzana https://github.com/wagtail/wagtail
Add the ability to view users in a group
* adds users view to group view (users filtered by that group) * adds the ability to go to the users list for the group currently being edited (via header link) * fix issue where the link to add a new user (when no users found) was broken * resolves #5801pull/5977/head
rodzic
2055da6a3a
commit
7565248438
|
@ -7,6 +7,8 @@ Changelog
|
|||
* Removed support for Python 3.5
|
||||
* Reorganised Dockerfile in project template to follow best practices (Tomasz Knapik, Jannik Wempe)
|
||||
* Added filtering to locked pages report (Karl Hobley)
|
||||
* Adds ability to view a group's users via standalone admin URL and a link to this on the group edit view (Karran Besen)
|
||||
* Fix: Ensure link to add a new user works when no users are visible in the users list (LB (Ben Johnston))
|
||||
|
||||
|
||||
2.9 (xx.xx.xxxx) - IN DEVELOPMENT
|
||||
|
|
|
@ -146,7 +146,7 @@ header {
|
|||
@include column(3);
|
||||
}
|
||||
|
||||
.col3.addbutton {
|
||||
.col3.actionbutton {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,12 +16,13 @@ Other features
|
|||
|
||||
* Reorganised Dockerfile in project template to follow best practices (Tomasz Knapik, Jannik Wempe)
|
||||
* Added filtering to locked pages report (Karl Hobley)
|
||||
* Adds ability to view a group's users via standalone admin URL and a link to this on the group edit view (Karran Besen)
|
||||
|
||||
|
||||
Bug fixes
|
||||
~~~~~~~~~
|
||||
|
||||
* ...
|
||||
* Ensure link to add a new user works when no users are visible in the users list (LB (Ben Johnston))
|
||||
|
||||
|
||||
Upgrade considerations
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
{% block titletag %}{{ view.page_title }}{% endblock %}
|
||||
{% block content %}
|
||||
{% if can_add %}
|
||||
{% include "wagtailadmin/shared/header.html" with title=view.page_title add_link=view.add_url_name add_text=view.add_item_label icon=view.header_icon %}
|
||||
{% url view.add_url_name as add_link %}
|
||||
{% include "wagtailadmin/shared/header.html" with title=view.page_title action_url=add_link action_text=view.add_item_label icon=view.header_icon %}
|
||||
{% else %}
|
||||
{% include "wagtailadmin/shared/header.html" with title=view.page_title icon=view.header_icon %}
|
||||
{% endif %}
|
||||
|
|
|
@ -14,8 +14,10 @@
|
|||
tabbed - if true, add the classname 'tab-merged'
|
||||
merged - if true, add the classname 'merged'
|
||||
|
||||
add_link - if present, display an 'add' button. This is a URL route name (taking no parameters) to be used as the link URL for the button
|
||||
add_text - text for the 'add' button
|
||||
action_url - if present, display an 'action' button. This is the URL to be used as the link URL for the button
|
||||
action_text - text for the 'action' button
|
||||
action_icon - icon for the 'action' button, default is 'icon-plus'
|
||||
|
||||
{% endcomment %}
|
||||
<header class="{% if merged %}merged{% endif %} {% if tabbed %}tab-merged{% endif %} {% if search_form %}hasform{% endif %}">
|
||||
{% block breadcrumb %}{% endblock %}
|
||||
|
@ -37,9 +39,9 @@
|
|||
{% endif %}
|
||||
</div>
|
||||
<div class="right">
|
||||
{% if add_link %}
|
||||
<div class="addbutton">
|
||||
<a href="{% url add_link %}" class="button bicolor icon icon-plus">{{ add_text }}</a>
|
||||
{% if action_url %}
|
||||
<div class="actionbutton">
|
||||
<a href="{{ action_url }}" class="button bicolor icon {{ action_icon|default:'icon-plus' }}">{{ action_text }}</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
|
|
@ -26,9 +26,9 @@
|
|||
{% block header_extra %}
|
||||
<div class="right">
|
||||
{% if user_can_create %}
|
||||
<span class="addbutton">
|
||||
<div class="actionbutton">
|
||||
{% include 'modeladmin/includes/button.html' with button=view.button_helper.add_button %}
|
||||
</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if view.list_export %}
|
||||
<div class="dropdown dropdown-button match-width col">
|
||||
|
|
|
@ -17,7 +17,8 @@
|
|||
{% trans "Redirects" as redirects_str %}
|
||||
{% trans "Add redirect" as add_str %}
|
||||
{% if user_can_add %}
|
||||
{% include "wagtailadmin/shared/header.html" with title=redirects_str icon="redirect" add_link="wagtailredirects:add" add_text=add_str search_url="wagtailredirects:index" %}
|
||||
{% url "wagtailredirects:add" as add_link %}
|
||||
{% include "wagtailadmin/shared/header.html" with title=redirects_str icon="redirect" action_url=add_link action_text=add_str search_url="wagtailredirects:index" %}
|
||||
{% else %}
|
||||
{% include "wagtailadmin/shared/header.html" with title=redirects_str icon="redirect" search_url="wagtailredirects:index" %}
|
||||
{% endif %}
|
||||
|
|
|
@ -16,7 +16,9 @@
|
|||
{% block content %}
|
||||
{% trans "Promoted search results" as sp_title_str %}
|
||||
{% trans "Add new promoted result" as sp_text_str %}
|
||||
{% include "wagtailadmin/shared/header.html" with title=sp_title_str add_link="wagtailsearchpromotions:add" icon="pick" add_text=sp_text_str search_url="wagtailsearchpromotions:index" %}
|
||||
|
||||
{% url "wagtailsearchpromotions:add" as add_link %}
|
||||
{% include "wagtailadmin/shared/header.html" with title=sp_title_str action_url=add_link icon="pick" action_text=sp_text_str search_url="wagtailsearchpromotions:index" %}
|
||||
|
||||
<div class="nice-padding">
|
||||
<div id="editorspicks-results" class="redirects">
|
||||
|
|
|
@ -663,7 +663,8 @@
|
|||
|
||||
{% include "wagtailadmin/shared/header.html" with title=title_trans %}
|
||||
|
||||
{% include "wagtailadmin/shared/header.html" with title=title_trans add_link="wagtailstyleguide" icon="image" add_text="button" search_url="wagtailimages:index" %}
|
||||
{% url "wagtailstyleguide" as add_link %}
|
||||
{% include "wagtailadmin/shared/header.html" with title=title_trans action_url=add_link icon="image" action_text="button" search_url="wagtailimages:index" %}
|
||||
</section>
|
||||
|
||||
<section id="forms">
|
||||
|
|
|
@ -23,7 +23,8 @@
|
|||
|
||||
{% if user_can_add %}
|
||||
{% trans "Add a document" as add_doc_str %}
|
||||
{% include "wagtailadmin/shared/header.html" with title=doc_str add_link="wagtaildocs:add_multiple" icon="doc-full-inverse" add_text=add_doc_str search_url="wagtaildocs:index" %}
|
||||
{% url "wagtaildocs:add_multiple" as add_link %}
|
||||
{% include "wagtailadmin/shared/header.html" with title=doc_str action_url=add_link icon="doc-full-inverse" action_text=add_doc_str search_url="wagtaildocs:index" %}
|
||||
{% else %}
|
||||
{% include "wagtailadmin/shared/header.html" with title=doc_str icon="doc-full-inverse" search_url="wagtaildocs:index" %}
|
||||
{% endif %}
|
||||
|
|
|
@ -26,7 +26,8 @@
|
|||
|
||||
{% if user_can_add %}
|
||||
{% trans "Add an image" as add_img_str %}
|
||||
{% include "wagtailadmin/shared/header.html" with title=im_str add_link="wagtailimages:add_multiple" icon="image" add_text=add_img_str search_url="wagtailimages:index" %}
|
||||
{% url "wagtailimages:add_multiple" as add_link %}
|
||||
{% include "wagtailadmin/shared/header.html" with title=im_str action_url=add_link icon="image" action_text=add_img_str search_url="wagtailimages:index" %}
|
||||
{% else %}
|
||||
{% include "wagtailadmin/shared/header.html" with title=im_str icon="image" search_url="wagtailimages:index" %}
|
||||
{% endif %}
|
||||
|
|
|
@ -13,7 +13,9 @@
|
|||
{% block content %}
|
||||
|
||||
{% trans "Editing" as editing_str %}
|
||||
{% include "wagtailadmin/shared/header.html" with title=editing_str subtitle=group.name icon="group" %}
|
||||
{% trans "View users of this group" as users_str %}
|
||||
{% url 'wagtailusers_groups:users' group.id as group_users_url %}
|
||||
{% include "wagtailadmin/shared/header.html" with title=editing_str action_icon="icon-user" action_url=group_users_url action_text=users_str subtitle=group.name icon="group" %}
|
||||
|
||||
<div class="nice-padding">
|
||||
<form action="{% url 'wagtailusers_groups:edit' group.id %}" method="POST" novalidate>
|
||||
|
|
|
@ -15,7 +15,8 @@
|
|||
{% block content %}
|
||||
{% trans "groups" as groups_str %}
|
||||
{% trans "Add a group" as add_a_group_str %}
|
||||
{% include "wagtailadmin/shared/header.html" with title=groups_str add_link="wagtailusers_groups:add" add_text=add_a_group_str icon="group" search_url="wagtailusers_groups:index" %}
|
||||
{% url "wagtailusers_groups:add" as add_link %}
|
||||
{% include "wagtailadmin/shared/header.html" with title=groups_str action_url=add_link action_text=add_a_group_str icon="group" search_url="wagtailusers_groups:index" %}
|
||||
|
||||
<div class="nice-padding">
|
||||
<div id="group-results" class="groups">
|
||||
|
|
|
@ -5,7 +5,11 @@
|
|||
{{ block.super }}
|
||||
<script>
|
||||
window.headerSearch = {
|
||||
{% if group %}
|
||||
url: "{% url 'wagtailusers_groups:users' group.id %}",
|
||||
{% else %}
|
||||
url: "{% url 'wagtailusers_users:index' %}",
|
||||
{% endif %}
|
||||
termInput: "#id_q",
|
||||
targetOutput: "#user-results"
|
||||
}
|
||||
|
@ -15,7 +19,9 @@
|
|||
{% block content %}
|
||||
{% trans "Users" as users_str %}
|
||||
{% trans "Add a user" as add_a_user_str %}
|
||||
{% include "wagtailadmin/shared/header.html" with title=users_str add_link="wagtailusers_users:add" add_text=add_a_user_str icon="user" search_url="wagtailusers_users:index" %}
|
||||
|
||||
{% url "wagtailusers_users:add" as add_link %}
|
||||
{% include "wagtailadmin/shared/header.html" with subtitle=group.name title=users_str action_url=add_link action_text=add_a_user_str icon="user" search_url="wagtailusers_users:index" %}
|
||||
|
||||
<div class="nice-padding">
|
||||
<div id="user-results" class="users">
|
||||
|
|
|
@ -21,7 +21,13 @@
|
|||
|
||||
{% search_other %}
|
||||
{% else %}
|
||||
{% url 'wagtailusers_create' as wagtailusers_create_url %}
|
||||
<p>{% blocktrans %}There are no users configured. Why not <a href="{{ wagtailusers_create_url }}">add some</a>?{% endblocktrans %}</p>
|
||||
{% url 'wagtailusers_users:add' as wagtailusers_add_url %}
|
||||
{% if group %}
|
||||
{% with group.name as group_name %}
|
||||
<p>{% blocktrans %}The {{ group_name }} group has no users configured. Why not <a href="{{ wagtailusers_add_url }}">add some</a>?{% endblocktrans %}</p>
|
||||
{% endwith %}
|
||||
{% else %}
|
||||
<p>{% blocktrans %}There are no users configured. Why not <a href="{{ wagtailusers_add_url }}">add some</a>?{% endblocktrans %}</p>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
|
|
@ -70,6 +70,57 @@ class TestUserFormHelpers(TestCase):
|
|||
self.assertRaises(ImproperlyConfigured, get_user_edit_form)
|
||||
|
||||
|
||||
class TestGroupUsersView(TestCase, WagtailTestUtils):
|
||||
def setUp(self):
|
||||
# create a user that should be visible in the listing
|
||||
self.test_user = get_user_model().objects.create_user(
|
||||
username='testuser',
|
||||
email='testuser@email.com',
|
||||
password='password',
|
||||
first_name='First Name',
|
||||
last_name='Last Name'
|
||||
)
|
||||
self.test_group = Group.objects.create(name='Test Group')
|
||||
self.test_user.groups.add(self.test_group)
|
||||
self.login()
|
||||
|
||||
def get(self, params={}, group_id=None):
|
||||
return self.client.get(reverse('wagtailusers_groups:users', args=(group_id or self.test_group.pk, )), params)
|
||||
|
||||
def test_simple(self):
|
||||
response = self.get()
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertTemplateUsed(response, 'wagtailusers/users/index.html')
|
||||
self.assertContains(response, 'testuser')
|
||||
|
||||
def test_inexisting_group(self):
|
||||
response = self.get(group_id=9999)
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
||||
def test_search(self):
|
||||
response = self.get({'q': "Hello"})
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.context['query_string'], "Hello")
|
||||
|
||||
def test_search_query_one_field(self):
|
||||
response = self.get({'q': "first name"})
|
||||
self.assertEqual(response.status_code, 200)
|
||||
results = response.context['users'].object_list
|
||||
self.assertIn(self.test_user, results)
|
||||
|
||||
def test_search_query_multiple_fields(self):
|
||||
response = self.get({'q': "first name last name"})
|
||||
self.assertEqual(response.status_code, 200)
|
||||
results = response.context['users'].object_list
|
||||
self.assertIn(self.test_user, results)
|
||||
|
||||
def test_pagination(self):
|
||||
pages = ['0', '1', '-1', '9999', 'Not a page']
|
||||
for page in pages:
|
||||
response = self.get({'p': page})
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
|
||||
class TestUserIndexView(TestCase, WagtailTestUtils):
|
||||
def setUp(self):
|
||||
# create a user that should be visible in the listing
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from django.conf.urls import url
|
||||
from django.contrib.auth.models import Group
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
|
@ -5,7 +6,7 @@ from wagtail.admin.views import generic, mixins
|
|||
from wagtail.admin.viewsets.model import ModelViewSet
|
||||
from wagtail.core import hooks
|
||||
from wagtail.users.forms import GroupForm, GroupPagePermissionFormSet
|
||||
|
||||
from wagtail.users.views.users import index
|
||||
_permission_panel_classes = None
|
||||
|
||||
|
||||
|
@ -155,5 +156,15 @@ class GroupViewSet(ModelViewSet):
|
|||
edit_view_class = EditView
|
||||
delete_view_class = DeleteView
|
||||
|
||||
|
||||
@property
|
||||
def users_view(self):
|
||||
return index
|
||||
|
||||
def get_form_class(self, for_update=False):
|
||||
return GroupForm
|
||||
|
||||
def get_urlpatterns(self):
|
||||
return super().get_urlpatterns() + [
|
||||
url(r'^(\d+)/users/$', self.users_view, name='users'),
|
||||
]
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
from django.conf import settings
|
||||
from django.contrib.auth import get_user_model, update_session_auth_hash
|
||||
from django.contrib.auth.models import Group
|
||||
from django.core.paginator import Paginator
|
||||
from django.db.models import Q
|
||||
from django.shortcuts import get_object_or_404, redirect
|
||||
|
@ -45,10 +46,16 @@ def get_user_edit_form():
|
|||
|
||||
@any_permission_required(add_user_perm, change_user_perm, delete_user_perm)
|
||||
@vary_on_headers('X-Requested-With')
|
||||
def index(request):
|
||||
def index(request, *args):
|
||||
q = None
|
||||
is_searching = False
|
||||
|
||||
group = None
|
||||
group_filter = Q()
|
||||
if args:
|
||||
group = get_object_or_404(Group, id=args[0])
|
||||
group_filter = Q(groups=group) if args else Q()
|
||||
|
||||
model_fields = [f.name for f in User._meta.get_fields()]
|
||||
|
||||
if 'q' in request.GET:
|
||||
|
@ -71,12 +78,12 @@ def index(request):
|
|||
if 'email' in model_fields:
|
||||
conditions |= Q(email__icontains=term)
|
||||
|
||||
users = User.objects.filter(conditions)
|
||||
users = User.objects.filter(group_filter & conditions)
|
||||
else:
|
||||
form = SearchForm(placeholder=_("Search users"))
|
||||
|
||||
if not is_searching:
|
||||
users = User.objects.all()
|
||||
users = User.objects.filter(group_filter)
|
||||
|
||||
if 'last_name' in model_fields and 'first_name' in model_fields:
|
||||
users = users.order_by('last_name', 'first_name')
|
||||
|
@ -101,6 +108,7 @@ def index(request):
|
|||
})
|
||||
else:
|
||||
return TemplateResponse(request, "wagtailusers/users/index.html", {
|
||||
'group': group,
|
||||
'search_form': form,
|
||||
'users': users,
|
||||
'is_searching': is_searching,
|
||||
|
|
Ładowanie…
Reference in New Issue