From 6a91631f9bc9f9d72da167e156f655f3db93a348 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laura=20Kl=C3=BCnder?= Date: Wed, 25 Dec 2019 10:16:40 +0100 Subject: [PATCH] quick comment feature for reports and stuff --- .../migrations/0081_auto_20191225_1015.py | 39 +++++++++++++++++++ src/c3nav/mapdata/models/report.py | 15 +++++-- src/c3nav/site/forms.py | 30 +++++++++++++- src/c3nav/site/templates/site/account.html | 2 +- .../site/templates/site/report_detail.html | 31 +++++++++++++++ src/c3nav/site/views.py | 21 +++++++++- 6 files changed, 131 insertions(+), 7 deletions(-) create mode 100644 src/c3nav/mapdata/migrations/0081_auto_20191225_1015.py diff --git a/src/c3nav/mapdata/migrations/0081_auto_20191225_1015.py b/src/c3nav/mapdata/migrations/0081_auto_20191225_1015.py new file mode 100644 index 00000000..ace2d53b --- /dev/null +++ b/src/c3nav/mapdata/migrations/0081_auto_20191225_1015.py @@ -0,0 +1,39 @@ +# Generated by Django 2.2.8 on 2019-12-25 09:15 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('mapdata', '0080_auto_20191224_2203'), + ] + + operations = [ + migrations.AlterModelOptions( + name='reportupdate', + options={'default_related_name': 'reportupdates', 'ordering': ('datetime',), 'verbose_name': 'Report update', 'verbose_name_plural': 'Report updates'}, + ), + migrations.AlterField( + model_name='reportupdate', + name='author', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, related_name='reportupdates', to=settings.AUTH_USER_MODEL, verbose_name='author'), + ), + migrations.AlterField( + model_name='reportupdate', + name='comment', + field=models.TextField(blank=True, verbose_name='comment'), + ), + migrations.AlterField( + model_name='reportupdate', + name='public', + field=models.BooleanField(verbose_name='comment is public'), + ), + migrations.AlterField( + model_name='reportupdate', + name='report', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='updates', to='mapdata.Report'), + ), + ] diff --git a/src/c3nav/mapdata/models/report.py b/src/c3nav/mapdata/models/report.py index 8370ab92..f3b94dea 100644 --- a/src/c3nav/mapdata/models/report.py +++ b/src/c3nav/mapdata/models/report.py @@ -130,6 +130,12 @@ class Report(models.Model): Q(permissions__review_group_reports__in=self.get_affected_group_ids()) ) + def request_can_review(self, request): + return ( + request.user_permissions.review_all_reports or + set(request.user_permissions.review_group_ids) & set(self.get_affected_group_ids()) + ) + def notify_reviewers(self): reviewers = tuple(self.get_reviewers_qs().values_list('pk', flat=True)) send_report_notification.delay(pk=self.pk, @@ -158,16 +164,17 @@ class Report(models.Model): class ReportUpdate(models.Model): - report = models.ForeignKey(Report, on_delete=models.CASCADE) + report = models.ForeignKey(Report, on_delete=models.CASCADE, related_name='updates') datetime = models.DateTimeField(auto_now_add=True, verbose_name=_('datetime')) author = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.PROTECT, verbose_name=_('author')) open = models.NullBooleanField(verbose_name=_('open')) - comment = models.TextField(verbose_name=_('comment')) + comment = models.TextField(verbose_name=_('comment'), blank=True) assigned_to = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.PROTECT, related_name='report_update_assigns', verbose_name=_('assigned to')) - public = models.BooleanField(verbose_name=_('public')) + public = models.BooleanField(verbose_name=_('comment is public')) class Meta: verbose_name = _('Report update') verbose_name_plural = _('Report updates') - default_related_name = 'reportupdate' + default_related_name = 'reportupdates' + ordering = ('datetime', ) diff --git a/src/c3nav/site/forms.py b/src/c3nav/site/forms.py index c63cd9e8..9481c9fc 100644 --- a/src/c3nav/site/forms.py +++ b/src/c3nav/site/forms.py @@ -1,7 +1,9 @@ +from django.db import transaction from django.forms import ModelForm +from django.utils.translation import ugettext_lazy as _ from c3nav.mapdata.forms import I18nModelFormMixin -from c3nav.mapdata.models.report import Report +from c3nav.mapdata.models.report import Report, ReportUpdate class ReportIssueForm(I18nModelFormMixin, ModelForm): @@ -18,3 +20,29 @@ class ReportMissingLocationForm(I18nModelFormMixin, ModelForm): class Meta: model = Report fields = ['title', 'description', 'created_title', 'created_groups'] + + +class ReportUpdateForm(ModelForm): + def __init__(self, request, *args, **kwargs): + super().__init__(*args, **kwargs) + self.request = request + self.fields['open'].label = _('change status') + self.fields['open'].widget.choices = ( + ('unknown', _('don\'t change')), + ('true', _('open')), + ('false', _('closed')), + ) + + def save(self): + with transaction.atomic(): + super().save() + report = self.instance.report + if self.instance.open is not None: + report.open = self.instance.open + if self.instance.assigned_to: + report.assigned_to = self.instance.assigned_to + report.save() + + class Meta: + model = ReportUpdate + fields = ['open', 'comment', 'public'] diff --git a/src/c3nav/site/templates/site/account.html b/src/c3nav/site/templates/site/account.html index 0b28b00b..574ced43 100644 --- a/src/c3nav/site/templates/site/account.html +++ b/src/c3nav/site/templates/site/account.html @@ -29,7 +29,7 @@ {% trans 'You can review reports' %}

- {% trans 'Show reports' %} + {% trans 'Show reports' %}

{% elif user_has_reports %}
diff --git a/src/c3nav/site/templates/site/report_detail.html b/src/c3nav/site/templates/site/report_detail.html index 073d0114..2d0c9dea 100644 --- a/src/c3nav/site/templates/site/report_detail.html +++ b/src/c3nav/site/templates/site/report_detail.html @@ -44,5 +44,36 @@

{% endif %} {% endfor %} + + {% for update in report.updates.all %} + {% if update_form or update.public or update.open != None %} +
+

{{ update.datetime }} – {{ update.author.username }}

+ {% if update.open == True %} +

{% trans 'Issue was opened.' %}

+ {% elif update.open == False %} +

{% trans 'Issue was closed.' %}

+ {% endif %} + {% if update.comment %} + {% if update.public or update_form %} +
{{ update.comment|linebreaksbr }}
+ {% endif %} + {% if update.public and update_form %} + {% trans '(public)' %} + {% endif %} + {% endif %} + {% endif %} + + {% endfor %} + + {% if update_form %} +
+
+ {% csrf_token %} +

{% trans 'Update issue' %}

+ {{ update_form }} +

+
+ {% endif %} {% endblock %} diff --git a/src/c3nav/site/views.py b/src/c3nav/site/views.py index 7c7edcfa..8f20e94a 100644 --- a/src/c3nav/site/views.py +++ b/src/c3nav/site/views.py @@ -29,12 +29,13 @@ from c3nav.mapdata.grid import grid from c3nav.mapdata.models import Location, Source from c3nav.mapdata.models.access import AccessPermissionToken from c3nav.mapdata.models.locations import LocationRedirect, SpecificLocation -from c3nav.mapdata.models.report import Report +from c3nav.mapdata.models.report import Report, ReportUpdate from c3nav.mapdata.utils.locations import (get_location_by_id_for_request, get_location_by_slug_for_request, levels_by_short_label_for_request) from c3nav.mapdata.utils.user import can_access_editor, get_user_data from c3nav.mapdata.views import set_tile_access_cookie from c3nav.routing.models import RouteOptions +from c3nav.site.forms import ReportUpdateForm from c3nav.site.models import Announcement, SiteUpdate @@ -455,7 +456,25 @@ def report_detail(request, pk, secret=None): form = report.form_cls(instance=report) + can_review = report.request_can_review(request) + if can_review: + new_update = ReportUpdate( + report=report, + author=request.user, + ) + if request.method == 'POST': + update_form = ReportUpdateForm(request, instance=new_update, data=request.POST) + if update_form.is_valid(): + update_form.save() + messages.success(request, _('Report updated.')) + return redirect(request.path_info) + else: + update_form = ReportUpdateForm(request, instance=new_update) + else: + update_form = None + return render(request, 'site/report_detail.html', { 'report': report, 'form': form, + 'update_form': update_form, })