Add PageSubscription model and hook up the comment notifications switch

pull/7050/head
Karl Hobley 2021-04-16 13:12:55 +01:00 zatwierdzone przez Matt Westcott
rodzic 25257de151
commit 9e98e680e9
9 zmienionych plików z 226 dodań i 10 usunięć

Wyświetl plik

@ -801,6 +801,12 @@ class PrivacyModalPanel(EditHandler):
class CommentPanel(EditHandler):
def required_fields(self):
# Adds the comment notifications field to the form.
# Note, this field is defined directly on WagtailAdminPageForm.
return ['comment_notifications']
def required_formsets(self):
# add the comments formset
# we need to pass in the current user for validation on the formset
@ -877,6 +883,7 @@ class CommentPanel(EditHandler):
panel = render_to_string(self.template, self.get_context())
return panel
# Now that we've defined EditHandlers, we can set up wagtailcore.Page to have some.

Wyświetl plik

@ -103,16 +103,32 @@ class PageViewRestrictionForm(BaseViewRestrictionForm):
class WagtailAdminPageForm(WagtailAdminModelForm):
comment_notifications = forms.BooleanField(widget=forms.CheckboxInput(), required=False)
class Meta:
# (dealing with Treebeard's tree-related fields that really should have
# been editable=False)
exclude = ['content_type', 'path', 'depth', 'numchild']
def __init__(self, data=None, files=None, parent_page=None, *args, **kwargs):
super().__init__(data, files, *args, **kwargs)
def __init__(self, data=None, files=None, parent_page=None, subscription=None, *args, **kwargs):
self.subscription = subscription
initial = kwargs.pop('initial', {})
if self.subscription:
initial['comment_notifications'] = subscription.comment_notifications
super().__init__(data, files, *args, initial=initial, **kwargs)
self.parent_page = parent_page
def save(self, commit=True):
# Save updates to PageSubscription
if self.subscription:
self.subscription.comment_notifications = self.cleaned_data['comment_notifications']
if commit:
self.subscription.save()
return super().save(commit=commit)
def clean(self):
cleaned_data = super().clean()
if 'slug' in self.cleaned_data:

Wyświetl plik

@ -18,7 +18,7 @@
<div class="comment-notifications-toggle">
<label class="switch switch--teal-background">
{% trans "Comment notifications" %}
<input type="checkbox" checked>
{{ self.form.comment_notifications }}
<span class="switch__toggle"></span>
</label>
</div>

Wyświetl plik

@ -1120,3 +1120,55 @@ class TestLocaleSelectorOnRootPage(TestCase, WagtailTestUtils):
add_translation_url = reverse('wagtailadmin_pages:add', args=['demosite', 'homepage', self.root_page.id]) + '?locale=fr'
self.assertNotContains(response, f'<a href="{add_translation_url}" aria-label="French" class="u-link is-live">')
class TestPageSubscriptionSettings(TestCase, WagtailTestUtils):
def setUp(self):
# Find root page
self.root_page = Page.objects.get(id=2)
# Login
self.user = self.login()
def test_commment_notifications_switched_on_by_default(self):
response = self.client.get(reverse('wagtailadmin_pages:add', args=['tests', 'simplepage', self.root_page.id]))
self.assertEqual(response.status_code, 200)
self.assertContains(response, '<input type="checkbox" name="comment_notifications" id="id_comment_notifications" checked>')
def test_post_with_comment_notifications_switched_on(self):
post_data = {
'title': "New page!",
'content': "Some content",
'slug': 'hello-world',
'comment_notifications': 'on'
}
response = self.client.post(reverse('wagtailadmin_pages:add', args=['tests', 'simplepage', self.root_page.id]), post_data)
page = Page.objects.get(path__startswith=self.root_page.path, slug='hello-world').specific
self.assertRedirects(response, reverse('wagtailadmin_pages:edit', args=[page.id]))
# Check the subscription
subscription = page.subscribers.get()
self.assertEqual(subscription.user, self.user)
self.assertTrue(subscription.comment_notifications)
def test_post_with_comment_notifications_switched_off(self):
post_data = {
'title': "New page!",
'content': "Some content",
'slug': 'hello-world',
}
response = self.client.post(reverse('wagtailadmin_pages:add', args=['tests', 'simplepage', self.root_page.id]), post_data)
page = Page.objects.get(path__startswith=self.root_page.path, slug='hello-world').specific
self.assertRedirects(response, reverse('wagtailadmin_pages:edit', args=[page.id]))
# Check the subscription
subscription = page.subscribers.get()
self.assertEqual(subscription.user, self.user)
self.assertFalse(subscription.comment_notifications)

Wyświetl plik

@ -14,7 +14,8 @@ from django.utils.translation import gettext_lazy as _
from wagtail.admin.tests.pages.timestamps import submittable_timestamp
from wagtail.core.exceptions import PageClassNotFoundError
from wagtail.core.models import GroupPagePermission, Locale, Page, PageRevision, Site
from wagtail.core.models import (
GroupPagePermission, Locale, Page, PageRevision, PageSubscription, Site)
from wagtail.core.signals import page_published
from wagtail.tests.testapp.models import (
EVENT_AUDIENCE_CHOICES, Advert, AdvertPlacement, EventCategory, EventPage,
@ -1952,3 +1953,77 @@ class TestLocaleSelector(TestCase, WagtailTestUtils):
edit_translation_url = reverse('wagtailadmin_pages:edit', args=[self.translated_christmas_page.id])
self.assertNotContains(response, f'<a href="{edit_translation_url}" aria-label="French" class="u-link is-live">')
class TestPageSubscriptionSettings(TestCase, WagtailTestUtils):
def setUp(self):
# Find root page
self.root_page = Page.objects.get(id=2)
# Add child page
child_page = SimplePage(
title="Hello world!",
slug="hello-world",
content="hello",
)
self.root_page.add_child(instance=child_page)
child_page.save_revision().publish()
self.child_page = SimplePage.objects.get(id=child_page.id)
# Login
self.user = self.login()
def test_commment_notifications_switched_off(self):
response = self.client.get(reverse('wagtailadmin_pages:edit', args=[self.child_page.id]))
self.assertEqual(response.status_code, 200)
self.assertContains(response, '<input type="checkbox" name="comment_notifications" id="id_comment_notifications">')
def test_commment_notifications_switched_on(self):
PageSubscription.objects.create(
page=self.child_page,
user=self.user,
comment_notifications=True
)
response = self.client.get(reverse('wagtailadmin_pages:edit', args=[self.child_page.id]))
self.assertEqual(response.status_code, 200)
self.assertContains(response, '<input type="checkbox" name="comment_notifications" id="id_comment_notifications" checked>')
def test_post_with_comment_notifications_switched_on(self):
post_data = {
'title': "I've been edited!",
'content': "Some content",
'slug': 'hello-world',
'comment_notifications': 'on'
}
response = self.client.post(reverse('wagtailadmin_pages:edit', args=[self.child_page.id]), post_data)
self.assertRedirects(response, reverse('wagtailadmin_pages:edit', args=[self.child_page.id]))
# Check the subscription
page = Page.objects.get(path__startswith=self.root_page.path, slug='hello-world').specific
subscription = page.subscribers.get()
self.assertEqual(subscription.user, self.user)
self.assertTrue(subscription.comment_notifications)
def test_post_with_comment_notifications_switched_off(self):
# Switch on comment notifications so we can test switching them off
subscription = PageSubscription.objects.create(
page=self.child_page,
user=self.user,
comment_notifications=True
)
post_data = {
'title': "I've been edited!",
'content': "Some content",
'slug': 'hello-world',
}
response = self.client.post(reverse('wagtailadmin_pages:edit', args=[self.child_page.id]), post_data)
self.assertRedirects(response, reverse('wagtailadmin_pages:edit', args=[self.child_page.id]))
# Check the subscription
subscription.refresh_from_db()
self.assertFalse(subscription.comment_notifications)

Wyświetl plik

@ -16,7 +16,7 @@ from wagtail.admin import messages, signals
from wagtail.admin.action_menu import PageActionMenu
from wagtail.admin.views.generic import HookResponseMixin
from wagtail.admin.views.pages.utils import get_valid_next_url_from_request
from wagtail.core.models import Locale, Page, UserPagePermissionsProxy
from wagtail.core.models import Locale, Page, PageSubscription, UserPagePermissionsProxy
def add_subpage(request, parent_page_id):
@ -91,13 +91,16 @@ class CreateView(TemplateResponseMixin, ContextMixin, HookResponseMixin, View):
self.edit_handler = self.edit_handler.bind_to(request=self.request, instance=self.page)
self.form_class = self.edit_handler.get_form_class()
# Note: Comment notifications should be enabled by default for pages that a user creates
self.subscription = PageSubscription(page=self.page, user=self.request.user, comment_notifications=True)
self.next_url = get_valid_next_url_from_request(self.request)
return super().dispatch(request)
def post(self, request):
self.form = self.form_class(
self.request.POST, self.request.FILES, instance=self.page, parent_page=self.parent_page
self.request.POST, self.request.FILES, instance=self.page, subscription=self.subscription, parent_page=self.parent_page
)
if self.form.is_valid():
@ -134,6 +137,10 @@ class CreateView(TemplateResponseMixin, ContextMixin, HookResponseMixin, View):
# Save revision
self.page.save_revision(user=self.request.user, log_action=False)
# Save subscription settings
self.subscription.page = self.page
self.subscription.save()
# Notification
messages.success(self.request, _("Page '{0}' created.").format(self.page.get_admin_display_title()))
@ -153,6 +160,10 @@ class CreateView(TemplateResponseMixin, ContextMixin, HookResponseMixin, View):
# Save revision
revision = self.page.save_revision(user=self.request.user, log_action=False)
# Save subscription settings
self.subscription.page = self.page
self.subscription.save()
# Publish
response = self.run_hook('before_publish_page', self.request, self.page)
if response:
@ -202,6 +213,10 @@ class CreateView(TemplateResponseMixin, ContextMixin, HookResponseMixin, View):
workflow = self.page.get_workflow()
workflow.start(self.page, self.request.user)
# Save subscription settings
self.subscription.page = self.page
self.subscription.save()
# Notification
buttons = []
if self.page.is_previewable():
@ -247,7 +262,7 @@ class CreateView(TemplateResponseMixin, ContextMixin, HookResponseMixin, View):
def get(self, request):
signals.init_new_page.send(sender=CreateView, page=self.page, parent=self.parent_page)
self.form = self.form_class(instance=self.page, parent_page=self.parent_page)
self.form = self.form_class(instance=self.page, subscription=self.subscription, parent_page=self.parent_page)
self.has_unsaved_changes = False
self.edit_handler = self.edit_handler.bind_to(form=self.form)

Wyświetl plik

@ -17,7 +17,7 @@ from wagtail.admin.action_menu import PageActionMenu
from wagtail.admin.views.generic import HookResponseMixin
from wagtail.admin.views.pages.utils import get_valid_next_url_from_request
from wagtail.core.exceptions import PageClassNotFoundError
from wagtail.core.models import Page, UserPagePermissionsProxy, WorkflowState
from wagtail.core.models import Page, PageSubscription, UserPagePermissionsProxy, WorkflowState
class EditView(TemplateResponseMixin, ContextMixin, HookResponseMixin, View):
@ -115,6 +115,11 @@ class EditView(TemplateResponseMixin, ContextMixin, HookResponseMixin, View):
if response:
return response
try:
self.subscription = PageSubscription.objects.get(page=self.page, user=self.request.user)
except PageSubscription.DoesNotExist:
self.subscription = PageSubscription(page=self.page, user=self.request.user)
self.edit_handler = self.page_class.get_edit_handler()
self.edit_handler = self.edit_handler.bind_to(instance=self.page, request=self.request)
self.form_class = self.edit_handler.get_form_class()
@ -182,7 +187,7 @@ class EditView(TemplateResponseMixin, ContextMixin, HookResponseMixin, View):
extra_tags="lock"
)
self.form = self.form_class(instance=self.page, parent_page=self.parent)
self.form = self.form_class(instance=self.page, subscription=self.subscription, parent_page=self.parent)
self.has_unsaved_changes = False
self.edit_handler = self.edit_handler.bind_to(form=self.form)
self.add_legacy_moderation_warning()
@ -209,7 +214,7 @@ class EditView(TemplateResponseMixin, ContextMixin, HookResponseMixin, View):
return HttpResponse(status=405)
self.form = self.form_class(
self.request.POST, self.request.FILES, instance=self.page, parent_page=self.parent
self.request.POST, self.request.FILES, instance=self.page, subscription=self.subscription, parent_page=self.parent
)
self.is_cancelling_workflow = bool(self.request.POST.get('action-cancel-workflow')) and self.workflow_state and self.workflow_state.user_can_cancel(self.request.user)
@ -249,6 +254,7 @@ class EditView(TemplateResponseMixin, ContextMixin, HookResponseMixin, View):
def save_action(self):
self.page = self.form.save(commit=False)
self.subscription.save()
# Save revision
self.page.save_revision(
@ -268,6 +274,7 @@ class EditView(TemplateResponseMixin, ContextMixin, HookResponseMixin, View):
def publish_action(self):
self.page = self.form.save(commit=False)
self.subscription.save()
# Save revision
revision = self.page.save_revision(
@ -357,6 +364,7 @@ class EditView(TemplateResponseMixin, ContextMixin, HookResponseMixin, View):
def submit_action(self):
self.page = self.form.save(commit=False)
self.subscription.save()
# Save revision
self.page.save_revision(
@ -393,6 +401,7 @@ class EditView(TemplateResponseMixin, ContextMixin, HookResponseMixin, View):
def restart_workflow_action(self):
self.page = self.form.save(commit=False)
self.subscription.save()
# save revision
self.page.save_revision(
@ -427,6 +436,7 @@ class EditView(TemplateResponseMixin, ContextMixin, HookResponseMixin, View):
def perform_workflow_action(self):
self.page = self.form.save(commit=False)
self.subscription.save()
if self.has_content_changes:
# Save revision
@ -452,6 +462,7 @@ class EditView(TemplateResponseMixin, ContextMixin, HookResponseMixin, View):
def cancel_workflow_action(self):
self.workflow_state.cancel(user=self.request.user)
self.page = self.form.save(commit=False)
self.subscription.save()
# Save revision
self.page.save_revision(

Wyświetl plik

@ -0,0 +1,28 @@
# Generated by Django 3.1.7 on 2021-04-16 11:08
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('wagtailcore', '0064_comment_resolved'),
]
operations = [
migrations.CreateModel(
name='PageSubscription',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('comment_notifications', models.BooleanField()),
('page', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='subscribers', to='wagtailcore.page')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='page_subscriptions', to=settings.AUTH_USER_MODEL)),
],
options={
'unique_together': {('page', 'user')},
},
),
]

Wyświetl plik

@ -4953,3 +4953,15 @@ class CommentReply(models.Model):
def __str__(self):
return "CommentReply left by '{0}': '{1}'".format(self.user, self.text)
class PageSubscription(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='page_subscriptions')
page = models.ForeignKey(Page, on_delete=models.CASCADE, related_name='subscribers')
comment_notifications = models.BooleanField()
class Meta:
unique_together = [
('page', 'user'),
]