Add notification on ticket messages

This commit is contained in:
cuom1999 2020-10-19 22:54:13 -05:00
parent aa43b26683
commit 7065d9ce6b
8 changed files with 90 additions and 10 deletions

View file

@ -0,0 +1,24 @@
# Generated by Django 2.2.12 on 2020-10-17 04:51
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('judge', '0108_submission_judged_date'),
]
operations = [
migrations.AddField(
model_name='notification',
name='html_link',
field=models.TextField(default='', max_length=1000, verbose_name='html link to comments, used for non-comments'),
),
migrations.AlterField(
model_name='notification',
name='comment',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='judge.Comment', verbose_name='comment'),
),
]

View file

@ -0,0 +1,19 @@
# Generated by Django 2.2.12 on 2020-10-17 05:10
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('judge', '0109_auto_20201017_1151'),
]
operations = [
migrations.AddField(
model_name='notification',
name='author',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='judge.Profile', verbose_name='who trigger, used for non-comment'),
),
]

View file

@ -189,6 +189,8 @@ class CommentLock(models.Model):
class Notification(models.Model):
owner = models.ForeignKey(Profile, verbose_name=_('owner'), related_name="notifications", on_delete=CASCADE)
time = models.DateTimeField(verbose_name=_('posted time'), auto_now_add=True)
comment = models.ForeignKey(Comment, verbose_name=_('comment'), on_delete=CASCADE)
comment = models.ForeignKey(Comment, null=True, verbose_name=_('comment'), on_delete=CASCADE)
read = models.BooleanField(verbose_name=_('read'), default=False)
category = models.CharField(verbose_name=_('category'), max_length=10)
category = models.CharField(verbose_name=_('category'), max_length=10)
html_link = models.TextField(default='', verbose_name=_('html link to comments, used for non-comments'), max_length=1000)
author = models.ForeignKey(Profile, null=True, verbose_name=_('who trigger, used for non-comment'), on_delete=CASCADE)

View file

@ -129,7 +129,6 @@ class Profile(models.Model):
def count_unseen_notifications(self):
query = {
'read': False,
'comment__hidden': False,
}
return self.notifications.filter(**query).count()

View file

@ -19,8 +19,8 @@ class NotificationList(ListView):
query = {
'owner': self.request.profile,
'comment__hidden': False,
}
self.queryset = Notification.objects.filter(**query)\
.order_by('-time')[:100] \
.annotate(seen=Value(True, output_field=BooleanField()))

View file

@ -1,5 +1,7 @@
import json
from itertools import chain
from django import forms
from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.exceptions import ImproperlyConfigured, PermissionDenied, ValidationError
@ -17,7 +19,7 @@ from django.views.generic import ListView
from django.views.generic.detail import SingleObjectMixin
from judge import event_poster as event
from judge.models import Problem, Profile, Ticket, TicketMessage
from judge.models import Problem, Profile, Ticket, TicketMessage, Notification
from judge.utils.diggpaginator import DiggPaginator
from judge.utils.tickets import filter_visible_tickets, own_ticket_filter
from judge.utils.views import SingleObjectFormView, TitleMixin, paginate_query_context
@ -29,6 +31,16 @@ ticket_widget = (forms.Textarea() if HeavyPreviewPageDownWidget is None else
preview_timeout=1000, hide_preview_button=True))
def add_ticket_notifications(users, author, link, ticket):
html = f"<a href=\"{link}\">{ticket.linked_item}</a>"
for user in users:
notification = Notification(owner=user,
html_link=html,
category='Ticket',
author=author)
notification.save()
class TicketForm(forms.Form):
title = forms.CharField(max_length=100, label=gettext_lazy('Ticket title'))
body = forms.CharField(widget=ticket_widget)
@ -66,13 +78,18 @@ class NewTicketView(LoginRequiredMixin, SingleObjectFormView):
message = TicketMessage(ticket=ticket, user=ticket.user, body=form.cleaned_data['body'])
message.save()
ticket.assignees.set(self.get_assignees())
link = reverse('ticket', args=[ticket.id])
add_ticket_notifications(ticket.assignees.all(), ticket.user, link, ticket)
if event.real:
event.post('tickets', {
'type': 'new-ticket', 'id': ticket.id,
'message': message.id, 'user': ticket.user_id,
'assignees': list(ticket.assignees.values_list('id', flat=True)),
})
return HttpResponseRedirect(reverse('ticket', args=[ticket.id]))
return HttpResponseRedirect(link)
class NewProblemTicketView(ProblemMixin, TitleMixin, NewTicketView):
@ -127,6 +144,13 @@ class TicketView(TitleMixin, LoginRequiredMixin, TicketMixin, SingleObjectFormVi
body=form.cleaned_data['body'],
ticket=self.object)
message.save()
link = '%s#message-%d' % (reverse('ticket', args=[self.object.id]), message.id)
notify_list = list(chain(self.object.assignees.all(), [self.object.user]))
notify_list.remove(message.user)
add_ticket_notifications(notify_list, message.user, link, self.object)
if event.real:
event.post('tickets', {
'type': 'ticket-message', 'id': self.object.id,
@ -136,7 +160,7 @@ class TicketView(TitleMixin, LoginRequiredMixin, TicketMixin, SingleObjectFormVi
event.post('ticket-%d' % self.object.id, {
'type': 'ticket-message', 'message': message.id,
})
return HttpResponseRedirect('%s#message-%d' % (reverse('ticket', args=[self.object.id]), message.id))
return HttpResponseRedirect(link)
def get_title(self):
return _('%(title)s - Ticket %(id)d') % {'title': self.object.title, 'id': self.object.id}

View file

@ -214,6 +214,7 @@
<a href="{{ ticket.linked_item.get_absolute_url() }}">
{{ ticket.linked_item|item_title }}</a>
</div>
<div>{{ link_user(ticket.user) }}</div>
</li>
{% endfor %}
</ul>

View file

@ -11,19 +11,30 @@
<tr>
<th>{{ _('User') }}</th>
<th>{{ _('Activity') }}</th>
<th>{{ _('Comment') }}</th>
<th>{{ _('Link') }}</th>
<th>{{ _('Time') }}</th>
</tr>
{% for notification in notifications %}
<tr class="{{ 'highlight' if not notification.seen }}">
<td>
{{ link_user(notification.comment.author) }}
{% if notification.comment %}
{{ link_user(notification.comment.author) }}
{% else %}
{{ link_user(notification.author) }}
{% endif %}
</td>
<td>
{{ notification.category }}
</td>
<td>
<a href="{{ notification.comment.link }}#comment-{{ notification.comment.id }}">{{ page_titles[notification.comment.page] }}</a>
{% if notification.comment %}
<a href="{{ notification.comment.link }}#comment-{{ notification.comment.id }}">{{ page_titles[notification.comment.page] }}</a>
{% else %}
{% autoescape off %}
{{notification.html_link}}
{% endautoescape %}
{% endif %}
</td>
<td>
{{ relative_time(notification.time) }}