mirror of
https://github.com/Hopiu/wagtail.git
synced 2026-03-16 22:10:28 +00:00
Merge branch 'author-specific-locking' of https://github.com/jacobtoppm/wagtail into kaedroho-author-specific-locking
This commit is contained in:
commit
3f27014a86
9 changed files with 100 additions and 7 deletions
|
|
@ -224,6 +224,22 @@ Hooks for building new areas of the admin interface (alongside pages, images, do
|
|||
As ``construct_main_menu``, but modifies the 'Settings' sub-menu rather than the top-level menu.
|
||||
|
||||
|
||||
.. _register_reports_menu_item:
|
||||
|
||||
``register_reports_menu_item``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
As ``register_admin_menu_item``, but registers menu items into the 'Reports' sub-menu rather than the top-level menu.
|
||||
|
||||
|
||||
.. _construct_reports_menu:
|
||||
|
||||
``construct_reports_menu``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
As ``construct_main_menu``, but modifies the 'Reports' sub-menu rather than the top-level menu.
|
||||
|
||||
|
||||
.. _register_admin_search_area:
|
||||
|
||||
``register_admin_search_area``
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ Database fields
|
|||
|
||||
The user who has currently locked the page. Only this user can edit the page.
|
||||
|
||||
If this is ``None`` when ``locked`` is ``False``, nobody can edit the page.
|
||||
If this is ``None`` when ``locked`` is ``True``, nobody can edit the page.
|
||||
|
||||
.. attribute:: locked_at
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,9 @@
|
|||
<div class="panel nice-padding">{# TODO try moving these classes onto the section tag #}
|
||||
<section>
|
||||
<h2>{% trans "Your locked pages" %}</h2>
|
||||
<a href="{% url 'wagtailadmin_reports:locked_pages' %}" class="button button-small button-secondary">{% trans "See all locked pages" %}</a>
|
||||
{% if can_remove_locks %}
|
||||
<a href="{% url 'wagtailadmin_reports:locked_pages' %}" class="button button-small button-secondary">{% trans "See all locked pages" %}</a>
|
||||
{% endif %}
|
||||
<table class="listing listing-page">
|
||||
<col />
|
||||
<col width="15%"/>
|
||||
|
|
|
|||
|
|
@ -2,13 +2,32 @@
|
|||
|
||||
{% load i18n wagtailadmin_tags %}
|
||||
|
||||
|
||||
{% block page_navigation %}
|
||||
<td>
|
||||
{% page_permissions page as perms %}
|
||||
<p>
|
||||
Locked
|
||||
{% if page.locked_by %}by <b>{% if page.locked_by_id == request.user.pk %}you{% else %}{{ page.locked_by }}{% endif %}</b>{% endif %}
|
||||
{% if page.locked_at %}at <b>{{ page.locked_at|date:"d M Y H:i" }}</b>{% endif %}
|
||||
{% if page.locked_at %}
|
||||
{% with page.locked_at|date:"d M Y H:i" as locking_date %}
|
||||
{% if page.locked_by %}
|
||||
{% if page.locked_by_id == request.user.pk %}
|
||||
{% blocktrans %}
|
||||
Locked by <b>you</b> at <b>{{ locking_date }}</b>
|
||||
{% endblocktrans %}
|
||||
{% else %}
|
||||
{% blocktrans with locked_by=page.locked_by %}
|
||||
Locked by <b>{{ locked_by }}</b> at <b>{{ locking_date }}</b>
|
||||
{% endblocktrans %}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% blocktrans %}
|
||||
Locked at <b>{{ locking_date }}</b>
|
||||
{% endblocktrans %}
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
{% else %}
|
||||
{% trans 'Locked' %}
|
||||
{% endif %}
|
||||
</p>
|
||||
{% if perms.can_unlock %}
|
||||
<form action="{% url 'wagtailadmin_pages:unlock' page.id %}" method="post">
|
||||
|
|
|
|||
35
wagtail/admin/tests/test_reports_views.py
Normal file
35
wagtail/admin/tests/test_reports_views.py
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
from django.test import TestCase
|
||||
from django.urls import reverse
|
||||
from django.utils import timezone
|
||||
|
||||
from wagtail.core.models import Page
|
||||
from wagtail.tests.utils import WagtailTestUtils
|
||||
|
||||
|
||||
class TestLockedPagesView(TestCase, WagtailTestUtils):
|
||||
def setUp(self):
|
||||
self.user = self.login()
|
||||
|
||||
def get(self, params={}):
|
||||
return self.client.get(reverse('wagtailadmin_reports:locked_pages'), params)
|
||||
|
||||
def test_simple(self):
|
||||
response = self.get()
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertTemplateUsed(response, 'wagtailadmin/reports/locked_pages.html')
|
||||
|
||||
# Initially there should be no locked pages
|
||||
self.assertContains(response, "No locked pages found.")
|
||||
|
||||
self.page = Page.objects.first()
|
||||
self.page.locked = True
|
||||
self.page.locked_by = self.user
|
||||
self.page.locked_at = timezone.now()
|
||||
self.page.save()
|
||||
|
||||
# Now the listing should contain our locked page
|
||||
response = self.get()
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertTemplateUsed(response, 'wagtailadmin/reports/locked_pages.html')
|
||||
self.assertNotContains(response, "No locked pages found.")
|
||||
self.assertContains(response, self.page.title)
|
||||
|
|
@ -59,7 +59,8 @@ class LockedPagesPanel:
|
|||
'locked_pages': Page.objects.filter(
|
||||
locked=True,
|
||||
locked_by=self.request.user,
|
||||
)
|
||||
),
|
||||
'can_remove_locks': UserPagePermissionsProxy(self.request.user).can_remove_locks()
|
||||
}, request=self.request)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ from django.utils.translation import ugettext_lazy as _
|
|||
from django.views.generic.base import TemplateResponseMixin
|
||||
from django.views.generic.list import BaseListView
|
||||
|
||||
from wagtail.admin.auth import permission_denied
|
||||
from wagtail.core.models import UserPagePermissionsProxy
|
||||
|
||||
|
||||
|
|
@ -28,3 +29,8 @@ class LockedPagesView(ReportView):
|
|||
pages = UserPagePermissionsProxy(self.request.user).editable_pages().filter(locked=True)
|
||||
self.queryset = pages
|
||||
return super().get_queryset()
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
if not UserPagePermissionsProxy(request.user).can_remove_locks():
|
||||
return permission_denied(request)
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
|
|
|||
|
|
@ -619,9 +619,14 @@ class ReportsMenuItem(SubmenuMenuItem):
|
|||
template = 'wagtailadmin/shared/menu_submenu_item.html'
|
||||
|
||||
|
||||
class LockedPagesMenuItem(MenuItem):
|
||||
def is_shown(self, request):
|
||||
return UserPagePermissionsProxy(request.user).can_remove_locks()
|
||||
|
||||
|
||||
@hooks.register('register_reports_menu_item')
|
||||
def register_locked_pages_menu_item():
|
||||
return MenuItem(_('Locked Pages'), reverse('wagtailadmin_reports:locked_pages'), classnames='icon icon-locked', order=700)
|
||||
return LockedPagesMenuItem(_('Locked Pages'), reverse('wagtailadmin_reports:locked_pages'), classnames='icon icon-locked', order=700)
|
||||
|
||||
|
||||
@hooks.register('register_admin_menu_item')
|
||||
|
|
|
|||
|
|
@ -1838,6 +1838,15 @@ class UserPagePermissionsProxy:
|
|||
"""Return True if the user has permission to publish any pages"""
|
||||
return self.publishable_pages().exists()
|
||||
|
||||
def can_remove_locks(self):
|
||||
"""Returns True if the user has permission to unlock pages they have not locked"""
|
||||
if self.user.is_superuser:
|
||||
return True
|
||||
if not self.user.is_active:
|
||||
return False
|
||||
else:
|
||||
return self.permissions.filter(permission_type='unlock').exists()
|
||||
|
||||
|
||||
class PagePermissionTester:
|
||||
def __init__(self, user_perms, page):
|
||||
|
|
|
|||
Loading…
Reference in a new issue