Skip to content

Commit 4fd95a0

Browse files
[ENG-11769] Redo recipients page (#11821)
* Add recipients list and preview views for notification campaigns
1 parent 8c770b2 commit 4fd95a0

5 files changed

Lines changed: 153 additions & 6 deletions

File tree

admin/notifications/urls.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,6 @@
1515
re_path(r'notification_campaigns_detail/(?P<pk>\d+)/$', views.NotificationCampaignDetail.as_view(), name='notification_campaigns_detail'),
1616
re_path(r'notification_campaigns_create/$', views.NotificationCampaignCreateView.as_view(), name='notification_campaigns_create'),
1717
re_path(r'notification_campaigns_recipients_preview/$', views.NotificationCampaignsRecipientsPreview.as_view(), name='notification_campaigns_recipients_preview'),
18+
re_path(r'notification_campaigns_recipients_list/$', views.NotificationCampaignsRecipientsView.as_view(), name='notification_campaigns_recipients_list'),
1819
re_path(r'notification_campaigns_start/(?P<pk>\d+)/$', views.StartNotificationCampaign.as_view(), name='notification_campaigns_start'),
1920
]

admin/notifications/views.py

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22
import json
33
from collections import defaultdict
44
from django.urls import reverse_lazy
5-
from django.db.models import Q
5+
from django.db.models import Q, F
66
from django.db import models
77
from django.shortcuts import get_object_or_404, redirect
88
from django.views.generic import ListView, DetailView, UpdateView, CreateView, View
99
from django.contrib import messages
1010
from django.contrib.auth.mixins import PermissionRequiredMixin
11-
from osf.models import NotificationSubscription, NotificationType, Notification, EmailTask, NotificationCampaign, OSFUser
11+
from osf.models import NotificationSubscription, NotificationType, Notification, EmailTask, NotificationCampaign, OSFUser, NotificationCampaignRecipient
1212
from osf.models.notification_campaign import NotificationCampaignStatus
1313
from django.forms.models import model_to_dict
1414
from .forms import NotificationTypeForm, NotificationCampaignCreateForm
@@ -549,7 +549,7 @@ def get_context_data(self, **kwargs):
549549

550550

551551
class NotificationCampaignsRecipientsPreview(PermissionRequiredMixin, ListView):
552-
template_name = 'users/list.html'
552+
template_name = 'notifications/notification_campaing_recipients_preview.html'
553553
permission_required = 'osf.view_osfuser'
554554
raise_exception = True
555555
paginate_by = 25
@@ -568,7 +568,10 @@ def get_queryset(self):
568568
else:
569569
filters[f'{item["field"]}__{item["lookup"]}'] = [value.strip() for value in item['value'].split(',')]
570570

571-
return filter_users(filters)
571+
qs = filter_users(filters)
572+
return qs.annotate(
573+
guid=F('guids___id')
574+
)
572575

573576
def get_context_data(self, **kwargs):
574577
users = self.get_queryset()
@@ -588,6 +591,45 @@ def get_context_data(self, **kwargs):
588591
is_paginated=is_paginated,
589592
)
590593

594+
class NotificationCampaignsRecipientsView(PermissionRequiredMixin, ListView):
595+
template_name = 'notifications/notification_campaing_recipients_list.html'
596+
permission_required = 'osf.view_osfuser'
597+
raise_exception = True
598+
paginate_by = 25
599+
600+
def get_queryset(self):
601+
status = self.request.GET.get('notification_status', None)
602+
campaign_id = self.request.GET.get('campaign_id', None)
603+
if not campaign_id:
604+
return NotificationCampaignRecipient.objects.none()
605+
query = {'campaign_id': campaign_id}
606+
if status:
607+
query['status'] = status
608+
609+
qs = NotificationCampaignRecipient.objects.filter(**query)
610+
611+
return qs.annotate(
612+
guid=F('user__guids___id')
613+
)
614+
615+
def get_context_data(self, **kwargs):
616+
users = self.get_queryset()
617+
618+
page_size = self.get_paginate_by(users)
619+
paginator, page, query_set, is_paginated = self.paginate_queryset(
620+
users,
621+
page_size,
622+
)
623+
# append search param to pagination links
624+
kwargs.update({'extra_query_params': f'&notification_status={self.request.GET.get("notification_status")}&campaign_id={self.request.GET.get('campaign_id')}'})
625+
return super().get_context_data(
626+
**kwargs,
627+
page=page,
628+
query_set=query_set,
629+
paginator=paginator,
630+
is_paginated=is_paginated,
631+
)
632+
591633
class StartNotificationCampaign(PermissionRequiredMixin, View):
592634
permission_required = 'osf.change_notificationtype'
593635

admin/templates/notifications/notification_campaigns_detail.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ <h4>General</h4>
5757
{% if field == 'Sent' and value != 0 %}
5858
<td>
5959
<a
60-
href="{% url 'notifications:notification_campaigns_recipients_preview' %}?filters={{ sent_filters_json|urlencode }}"
60+
href="{% url 'notifications:notification_campaigns_recipients_list' %}?notification_status=sent&campaign_id={{ notification_campaign.id }}"
6161
class="btn btn-default"
6262
target="_blank">
6363
Preview Recipients
@@ -67,7 +67,7 @@ <h4>General</h4>
6767
{% elif field == 'Failed' and value != 0 %}
6868
<td>
6969
<a
70-
href="{% url 'notifications:notification_campaigns_recipients_preview' %}?filters={{ failed_filters_json|urlencode }}"
70+
href="{% url 'notifications:notification_campaigns_recipients_list' %}?notification_status=failed&campaign_id={{ notification_campaign.id }}"
7171
class="btn btn-default"
7272
target="_blank">
7373
Preview Recipients
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
{% extends 'base.html' %}
2+
{% load static %}
3+
{% block title %}
4+
<title>User Search Results</title>
5+
{% endblock title %}
6+
{% block content %}
7+
{% load node_extras %}
8+
{% include "util/pagination.html" with items=page status=status %}
9+
{% if perms.osf.mark_spam %}
10+
<form action="{% url 'users:flagged-spam' %}" method="post">
11+
{% csrf_token %}
12+
{% endif %}
13+
<table class="table table-striped table-hover table-responsive">
14+
<thead>
15+
<tr>
16+
<th>GUID</th>
17+
<th>Username</th>
18+
<th>Status</th>
19+
<th>Error</th>
20+
<th>Updated at</th>
21+
</tr>
22+
</thead>
23+
<tbody>
24+
{% for record in query_set %}
25+
<tr>
26+
<td>
27+
<a href="{{ record.user | reverse_user }}" class="btn btn-primary">
28+
{{ record.guid }}
29+
</a>
30+
</td>
31+
<td>
32+
{{record.user.username}}
33+
</td>
34+
<td>
35+
{{ record.status }}
36+
</td>
37+
<td>
38+
{{ record.error_message }}
39+
</td>
40+
<td>
41+
{{ record.updated_at }}
42+
</td>
43+
</tr>
44+
{% endfor %}
45+
</tbody>
46+
</table>
47+
</form>
48+
49+
{% if not query_set|length %}
50+
<h3>No results found</h3>
51+
{% endif %}
52+
{% endblock content %}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
{% extends 'base.html' %}
2+
{% load static %}
3+
{% block title %}
4+
<title>User Search Results</title>
5+
{% endblock title %}
6+
{% block content %}
7+
{% load node_extras %}
8+
{% include "util/pagination.html" with items=page status=status %}
9+
{% if perms.osf.mark_spam %}
10+
<form action="{% url 'users:flagged-spam' %}" method="post">
11+
{% csrf_token %}
12+
{% endif %}
13+
<table class="table table-striped table-hover table-responsive">
14+
<thead>
15+
<tr>
16+
<th>GUID</th>
17+
<th>Username</th>
18+
<th>Fullname</th>
19+
<th>Date confirmed</th>
20+
<th>Date disabled</th>
21+
</tr>
22+
</thead>
23+
<tbody>
24+
{% for user in users %}
25+
<tr>
26+
<td>
27+
<a href="{{ user | reverse_user }}" class="btn btn-primary">
28+
{{ user.guid }}
29+
</a>
30+
</td>
31+
<td>
32+
{{user.username}}
33+
</td>
34+
<td>
35+
{{ user.fullname }}
36+
</td>
37+
<td>
38+
{{ user.is_confirmed }}
39+
</td>
40+
<td>
41+
{{ user.is_disabled }}
42+
</td>
43+
</tr>
44+
{% endfor %}
45+
</tbody>
46+
</table>
47+
</form>
48+
49+
{% if not users|length %}
50+
<h3>No results found</h3>
51+
{% endif %}
52+
{% endblock content %}

0 commit comments

Comments
 (0)