Notification emails #80

Merged
Oleg-Komarov merged 31 commits from notifications into main 2024-04-18 16:11:20 +02:00
4 changed files with 97 additions and 0 deletions
Showing only changes of commit 4310e69a39 - Show all commits

View File

@ -39,6 +39,7 @@ urlpatterns = [
path('', include('users.urls')),
path('', include('teams.urls')),
path('', include('reviewers.urls')),
path('', include('notifications.urls')),
path('api/swagger/', RedirectView.as_view(url='/api/v1/swagger/')),
path('api/v1/', SpectacularAPIView.as_view(), name='schema_v1'),
path('api/v1/swagger/', SpectacularSwaggerView.as_view(url_name='schema_v1'), name='swagger'),

View File

@ -0,0 +1,22 @@
{% extends "common/base.html" %}
{% load i18n %}
{% block page_title %}{% blocktranslate %}Notifications{% endblocktranslate %}{% endblock page_title %}
{% block content %}
{% if notification_list %}
{% for notification in notification_list %}
<div class="row">
{{ notification.action }}
{% if notification.read_at %}
{% else %}
{% blocktranslate %}Mark as read{% endblocktranslate %}
{% endif %}
</div>
{% endfor %}
{% else %}
<p>
{% blocktranslate %}You have no notifications{% endblocktranslate %}
</p>
{% endif %}
{% endblock content %}

25
notifications/urls.py Normal file
View File

@ -0,0 +1,25 @@
from django.urls import path, include
import notifications.views as views
app_name = 'notifications'
urlpatterns = [
path(
'notifications/',
include(
[
path('', views.NotificationsView.as_view(), name='notifications'),
path(
'mark-read-all/',
views.MarkReadAllView.as_view(),
name='notifications-mark-read-all',
),
path(
'<int:pk>/mark-read/',
views.MarkReadView.as_view(),
name='notifications-mark-read',
),
],
),
),
]

49
notifications/views.py Normal file
View File

@ -0,0 +1,49 @@
"""Notifications pages."""
from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import HttpResponseForbidden
from django.http.response import JsonResponse
from django.utils import timezone
from django.views.generic import ListView
from django.views.generic.detail import SingleObjectMixin
from django.views.generic.edit import FormView
from django.views import View
from notifications.models import Notification
class NotificationsView(LoginRequiredMixin, ListView):
model = Notification
ordering = None # FIXME
paginate_by = 10
def get_queryset(self):
return Notification.objects.filter(recipient=self.request.user)
class MarkReadAllView(LoginRequiredMixin, FormView):
model = Notification
raise_exception = True
def post(self, request, *args, **kwargs):
"""Mark all previously unread notifications as read."""
unread = self.model.objects.filter(recipient=request.user, read_at__isnull=True)
now = timezone.now()
for notification in unread:
notification.read_at = now
Notification.objects.bulk_update(unread, ['read_at'])
return JsonResponse({})
class MarkReadView(LoginRequiredMixin, SingleObjectMixin, View):
model = Notification
raise_exception = True
def post(self, request, *args, **kwargs):
notification = self.get_object()
if notification.recipient != request.user:
return HttpResponseForbidden()
notification.read_at = timezone.now()
notification.save(update_fields=['read_at'])
return JsonResponse({})