From 53b88764763f623ba3bcdd618c4411d705438738 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20H=C3=A4ttasch?= <benjamin.haettasch@cs.tu-darmstadt.de> Date: Fri, 25 Oct 2019 17:18:18 +0200 Subject: [PATCH] Allow edit and delete of AK slot durations --- AKSubmission/forms.py | 12 ++- .../locale/de_DE/LC_MESSAGES/django.po | 87 ++++++++++++++++--- .../templates/AKSubmission/ak_detail.html | 11 +++ .../AKSubmission/akslot_add_update.html | 37 ++++++++ .../templates/AKSubmission/akslot_delete.html | 43 +++++++++ AKSubmission/urls.py | 3 + AKSubmission/views.py | 70 ++++++++++++++- 7 files changed, 245 insertions(+), 18 deletions(-) create mode 100644 AKSubmission/templates/AKSubmission/akslot_add_update.html create mode 100644 AKSubmission/templates/AKSubmission/akslot_delete.html diff --git a/AKSubmission/forms.py b/AKSubmission/forms.py index fdb8f194..dc8bd854 100644 --- a/AKSubmission/forms.py +++ b/AKSubmission/forms.py @@ -4,7 +4,7 @@ from django import forms from django.core.exceptions import ValidationError from django.utils.translation import ugettext_lazy as _ -from AKModel.models import AK, AKOwner, AKCategory, AKRequirement +from AKModel.models import AK, AKOwner, AKCategory, AKRequirement, AKSlot class AKForm(forms.ModelForm): @@ -135,3 +135,13 @@ class AKOwnerForm(forms.ModelForm): class Meta: model = AKOwner fields = ['name', 'institution', 'link'] + + +class AKDurationForm(forms.ModelForm): + class Meta: + model = AKSlot + fields = ['duration', 'ak', 'event'] + widgets = { + 'ak': forms.HiddenInput, + 'event': forms.HiddenInput + } diff --git a/AKSubmission/locale/de_DE/LC_MESSAGES/django.po b/AKSubmission/locale/de_DE/LC_MESSAGES/django.po index 86af55c0..d91e4032 100644 --- a/AKSubmission/locale/de_DE/LC_MESSAGES/django.po +++ b/AKSubmission/locale/de_DE/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-10-25 00:53+0000\n" +"POT-Creation-Date: 2019-10-25 15:15+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -17,20 +17,20 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: forms.py:40 +#: forms.py:43 msgid "Separate multiple tags with semicolon" msgstr "Mehrere Tags mit Semikolon trennen" -#: forms.py:61 +#: forms.py:67 #, python-format msgid "\"%(duration)s\" is not a valid duration" msgstr "\"%(duration)s\" ist keine gültige Dauer" -#: forms.py:95 +#: forms.py:110 msgid "Duration(s)" msgstr "Dauer(n)" -#: forms.py:96 +#: forms.py:112 msgid "" "Enter at least one planned duration (in hours). If your AK should have " "multiple slots, use multiple lines" @@ -42,6 +42,8 @@ msgstr "" #: templates/AKSubmission/ak_edit.html:8 templates/AKSubmission/ak_list.html:8 #: templates/AKSubmission/ak_list.html:14 #: templates/AKSubmission/akowner_create_update.html:7 +#: templates/AKSubmission/akslot_add_update.html:7 +#: templates/AKSubmission/akslot_delete.html:7 #: templates/AKSubmission/submission_overview.html:6 #: templates/AKSubmission/submission_overview.html:15 #: templates/AKSubmission/submit_new.html:8 @@ -50,6 +52,7 @@ msgid "AKs" msgstr "AKs" #: templates/AKSubmission/ak_detail.html:8 +#: templates/AKSubmission/akslot_delete.html:30 #, fuzzy #| msgid "AKs" msgid "AK" @@ -60,6 +63,8 @@ msgstr "AKs" #: templates/AKSubmission/ak_list.html:13 #: templates/AKSubmission/ak_list.html:18 #: templates/AKSubmission/akowner_create_update.html:13 +#: templates/AKSubmission/akslot_add_update.html:13 +#: templates/AKSubmission/akslot_delete.html:13 #: templates/AKSubmission/submission_overview.html:6 #: templates/AKSubmission/submission_overview.html:11 #: templates/AKSubmission/submit_new.html:19 @@ -96,18 +101,23 @@ msgstr "Tags" msgid "Reso?" msgstr "Reso?" -#: templates/AKSubmission/ak_detail.html:60 +#: templates/AKSubmission/ak_detail.html:62 msgid "When?" msgstr "Wann?" -#: templates/AKSubmission/ak_detail.html:61 +#: templates/AKSubmission/ak_detail.html:63 +#: templates/AKSubmission/akslot_delete.html:31 msgid "Duration" msgstr "Dauer" -#: templates/AKSubmission/ak_detail.html:62 +#: templates/AKSubmission/ak_detail.html:64 msgid "Room" msgstr "Raum" +#: templates/AKSubmission/ak_detail.html:86 +msgid "Add another slot" +msgstr "Einen neuen AK-Slot hinzufügen" + #: templates/AKSubmission/ak_edit.html:8 templates/AKSubmission/ak_edit.html:21 msgid "Edit AK" msgstr "AK bearbeiten" @@ -139,19 +149,42 @@ msgid "AK Owner" msgstr "AK-Leitung" #: templates/AKSubmission/akowner_create_update.html:25 +#: templates/AKSubmission/akslot_add_update.html:26 #: templates/AKSubmission/submit_new.html:34 msgid "Reset" msgstr "Zurücksetzen" #: templates/AKSubmission/akowner_create_update.html:29 +#: templates/AKSubmission/akslot_add_update.html:30 +#: templates/AKSubmission/akslot_delete.html:36 #: templates/AKSubmission/submit_new.html:38 msgid "Cancel" msgstr "Abbrechen" #: templates/AKSubmission/akowner_create_update.html:32 +#: templates/AKSubmission/akslot_add_update.html:33 msgid "Continue" msgstr "Weiter" +#: templates/AKSubmission/akslot_add_update.html:7 +#: templates/AKSubmission/akslot_add_update.html:15 +#: templates/AKSubmission/akslot_add_update.html:20 +#: templates/AKSubmission/akslot_delete.html:7 +#: templates/AKSubmission/akslot_delete.html:15 +#: templates/AKSubmission/akslot_delete.html:20 +#, fuzzy +#| msgid "Duration(s)" +msgid "AK Duration(s)" +msgstr "Dauer(n)" + +#: templates/AKSubmission/akslot_delete.html:25 +msgid "Do you really want to delete this AK Slot?" +msgstr "" + +#: templates/AKSubmission/akslot_delete.html:39 +msgid "Confirm" +msgstr "Bestätigen" + #: templates/AKSubmission/submission_overview.html:19 msgid "" "On this page you can see a list of current AKs, change them and add new ones." @@ -193,28 +226,54 @@ msgstr "Aktuelle AKs" msgid "Submit" msgstr "Eintragen" -#: views.py:44 +#: views.py:43 msgid "Wishes" msgstr "Wünsche" -#: views.py:44 +#: views.py:43 msgid "AKs one would like to have" msgstr "" "AKs die sich gewünscht wurden, aber bei denen noch nicht klar ist, wer sie " "macht. Falls du dir das vorstellen kannst, trag dich einfach ein" -#: views.py:105 +#: views.py:104 msgid "AK successfully created" msgstr "AK erfolgreich angelegt" -#: views.py:152 +#: views.py:157 msgid "AK successfully updated" msgstr "AK erfolgreich bearbeitet" -#: views.py:209 +#: views.py:215 msgid "Person Info successfully updated" msgstr "Personen-Info erfolgreich bearbeitet" -#: views.py:221 +#: views.py:228 msgid "No user selected" msgstr "Keine Person ausgewählt" + +#: views.py:254 +#, fuzzy +#| msgid "AK successfully created" +msgid "AK Slot successfully added" +msgstr "AK erfolgreich angelegt" + +#: views.py:266 +msgid "You cannot edit a slot that has already been scheduled" +msgstr "Bereits geplante AK-Slots können nicht mehr bearbeitet werden" + +#: views.py:276 +#, fuzzy +#| msgid "AK successfully updated" +msgid "AK Slot successfully updated" +msgstr "AK erfolgreich bearbeitet" + +#: views.py:287 +msgid "You cannot delete a slot that has already been scheduled" +msgstr "Bereits geplante AK-Slots können nicht mehr gelöscht werden" + +#: views.py:297 +#, fuzzy +#| msgid "AK successfully created" +msgid "AK Slot successfully deleted" +msgstr "AK erfolgreich angelegt" diff --git a/AKSubmission/templates/AKSubmission/ak_detail.html b/AKSubmission/templates/AKSubmission/ak_detail.html index 2e9bd6f4..0bf39673 100644 --- a/AKSubmission/templates/AKSubmission/ak_detail.html +++ b/AKSubmission/templates/AKSubmission/ak_detail.html @@ -60,6 +60,7 @@ <th>{% trans "When?" %}</th> <th>{% trans "Duration" %}</th> <th>{% trans "Room" %}</th> + <th></th> </tr> </thead> <tbody> @@ -68,9 +69,19 @@ <td>{{ slot.start_simplified }}</td> <td>{{ slot.duration }}</td> <td>{{ slot.room }}</td> + <td> + {% if not slot.start %} + <a href="{% url 'submit:akslot_edit' event_slug=ak.event.slug pk=slot.pk %}" class="btn btn-success">{% fontawesome_icon 'pencil-alt' %}</a> + <a href="{% url 'submit:akslot_delete' event_slug=ak.event.slug pk=slot.pk %}" class="btn btn-danger">{% fontawesome_icon 'times' %}</a> + {% endif %} + </td> </tr> {% endfor %} </tbody> </table> + <div class=""> + <a href="{% url 'submit:akslot_add' event_slug=ak.event.slug pk=ak.pk %}" class="btn btn-success">{% fontawesome_icon 'plus' %} {% trans "Add another slot" %}</a> + </div> + {% endblock %} diff --git a/AKSubmission/templates/AKSubmission/akslot_add_update.html b/AKSubmission/templates/AKSubmission/akslot_add_update.html new file mode 100644 index 00000000..8ef2d78d --- /dev/null +++ b/AKSubmission/templates/AKSubmission/akslot_add_update.html @@ -0,0 +1,37 @@ +{% extends 'base.html' %} + +{% load i18n %} +{% load bootstrap4 %} +{% load fontawesome %} + +{% block title %}{% trans "AKs" %}: {{ event.name }} - {% trans "AK Duration(s)" %}{% endblock %} + +{% block breadcrumbs %} + <li class="breadcrumb-item"><a href="#">AKPlanning</a></li> + <li class="breadcrumb-item"><a href="#">{{ event.slug }}</a></li> + <li class="breadcrumb-item"><a + href="{% url 'submit:submission_overview' event_slug=event.slug %}">{% trans "AK Submission" %}</a></li> + <li class="breadcrumb-item"><a href="{% url 'submit:ak_detail' event_slug=event.slug pk=ak.pk %}">{{ ak.short_name }}</a></li> + <li class="breadcrumb-item active">{% trans "AK Duration(s)" %}</li> +{% endblock %} + +{% block content %} + {% block headline %} + <h2>{% trans 'AK Duration(s)' %}</h2> + {% endblock %} + <form method="POST" class="post-form">{% csrf_token %} + {% bootstrap_form form %} + {% buttons %} + <button type="reset" class="btn btn-danger"> + {% fontawesome_icon "undo-alt" %} {% trans "Reset" %} + </button> + + <a href="{% url 'submit:ak_detail' event_slug=event.slug pk=ak.pk %}" class="btn btn-secondary"> + {% fontawesome_icon "times" %} {% trans "Cancel" %} + </a> + <button type="submit" class="save btn btn-primary float-right"> + {% fontawesome_icon "check" %} {% trans "Continue" %} + </button> + {% endbuttons %} + </form> +{% endblock %} diff --git a/AKSubmission/templates/AKSubmission/akslot_delete.html b/AKSubmission/templates/AKSubmission/akslot_delete.html new file mode 100644 index 00000000..9233ba7d --- /dev/null +++ b/AKSubmission/templates/AKSubmission/akslot_delete.html @@ -0,0 +1,43 @@ +{% extends 'base.html' %} + +{% load i18n %} +{% load bootstrap4 %} +{% load fontawesome %} + +{% block title %}{% trans "AKs" %}: {{ event.name }} - {% trans "AK Duration(s)" %}{% endblock %} + +{% block breadcrumbs %} + <li class="breadcrumb-item"><a href="#">AKPlanning</a></li> + <li class="breadcrumb-item"><a href="#">{{ event.slug }}</a></li> + <li class="breadcrumb-item"><a + href="{% url 'submit:submission_overview' event_slug=event.slug %}">{% trans "AK Submission" %}</a></li> + <li class="breadcrumb-item"><a href="{% url 'submit:ak_detail' event_slug=event.slug pk=ak.pk %}">{{ ak.short_name }}</a></li> + <li class="breadcrumb-item active">{% trans "AK Duration(s)" %}</li> +{% endblock %} + +{% block content %} + {% block headline %} + <h2>{% trans 'AK Duration(s)' %}</h2> + {% endblock %} + <form method="POST" class="post-form">{% csrf_token %} + + <div class="alert alert-danger" style="margin-top:20px;margin-bottom: 20px;"> + <h4>{% trans "Do you really want to delete this AK Slot?" %}</h4> + </div> + + <table class="table"> + <tbody> + <tr><td>{% trans "AK" %}</td><td>{{ akslot.ak }}</td></tr> + <tr><td>{% trans "Duration" %}</td><td>{{ akslot.duration }}</td></tr> + </tbody> + </table> + {% buttons %} + <a href="{% url 'submit:ak_detail' event_slug=event.slug pk=ak.pk %}" class="btn btn-secondary"> + {% fontawesome_icon "times" %} {% trans "Cancel" %} + </a> + <button type="submit" class="save btn btn-danger float-right" value="Confirm"> + {% fontawesome_icon "check" %} {% trans "Confirm" %} + </button> + {% endbuttons %} + </form> +{% endblock %} diff --git a/AKSubmission/urls.py b/AKSubmission/urls.py index 637ce835..c40cb596 100644 --- a/AKSubmission/urls.py +++ b/AKSubmission/urls.py @@ -11,6 +11,9 @@ urlpatterns = [ path('', views.SubmissionOverviewView.as_view(), name='submission_overview'), path('ak/<int:pk>', views.AKDetailView.as_view(), name='ak_detail'), path('ak/<int:pk>/edit/', views.AKEditView.as_view(), name='ak_edit'), + path('ak/<int:pk>/add_slot/', views.AKSlotAddView.as_view(), name='akslot_add'), + path('akslot/<int:pk>/edit/', views.AKSlotEditView.as_view(), name='akslot_edit'), + path('akslot/<int:pk>/delete/', views.AKSlotDeleteView.as_view(), name='akslot_delete'), path('aks/', views.AKListView.as_view(), name='ak_list'), path('aks/category/<int:category_pk>', views.AKListByCategoryView.as_view(), name='ak_list_by_category'), path('aks/tag/<int:tag_pk>', views.AKListByTagView.as_view(), name='ak_list_by_tag'), diff --git a/AKSubmission/views.py b/AKSubmission/views.py index 45b1a288..66ab16f5 100644 --- a/AKSubmission/views.py +++ b/AKSubmission/views.py @@ -1,17 +1,17 @@ from django.conf import settings from django.contrib import messages from django.http import Http404, HttpResponseRedirect -from django.shortcuts import get_object_or_404 +from django.shortcuts import get_object_or_404, redirect from django.urls import reverse_lazy from django.utils.translation import gettext_lazy as _ from django.views import View -from django.views.generic import ListView, DetailView, CreateView, UpdateView +from django.views.generic import ListView, DetailView, CreateView, UpdateView, DeleteView from AKModel.models import AK, AKCategory, AKTag, AKOwner, AKSlot from AKModel.models import Event from AKModel.views import EventSlugMixin from AKModel.views import FilterByEventSlugMixin -from AKSubmission.forms import AKWishForm, AKOwnerForm, AKEditForm, AKSubmissionForm +from AKSubmission.forms import AKWishForm, AKOwnerForm, AKEditForm, AKSubmissionForm, AKDurationForm class SubmissionOverviewView(FilterByEventSlugMixin, ListView): @@ -232,3 +232,67 @@ class AKOwnerEditDispatchView(EventSlugMixin, View): owner = get_object_or_404(AKOwner, pk=request.POST["owner_id"]) return HttpResponseRedirect( reverse_lazy('submit:akowner_edit', kwargs={'event_slug': kwargs['event_slug'], 'slug': owner.slug})) + + +class AKSlotAddView(EventSlugMixin, CreateView): + model = AKSlot + form_class = AKDurationForm + template_name = "AKSubmission/akslot_add_update.html" + + def get_initial(self): + initials = super(AKSlotAddView, self).get_initial() + initials['event'] = self.event + initials['ak'] = get_object_or_404(AK, pk=self.kwargs['pk']) + return initials + + def get_context_data(self, *, object_list=None, **kwargs): + context = super().get_context_data(object_list=object_list, **kwargs) + context['ak'] = get_object_or_404(AK, pk=self.kwargs['pk']) + return context + + def get_success_url(self): + messages.add_message(self.request, messages.SUCCESS, _("AK Slot successfully added")) + return reverse_lazy('submit:ak_detail', kwargs={'event_slug': self.kwargs['event_slug'], 'pk': self.object.ak.pk}) + + +class AKSlotEditView(EventSlugMixin, UpdateView): + model = AKSlot + form_class = AKDurationForm + template_name = "AKSubmission/akslot_add_update.html" + + def get(self, request, *args, **kwargs): + akslot = get_object_or_404(AKSlot, pk=kwargs["pk"]) + if akslot.start is not None: + messages.add_message(self.request, messages.WARNING, _("You cannot edit a slot that has already been scheduled")) + return redirect('submit:ak_detail', event_slug=self.kwargs['event_slug'], pk=akslot.ak.pk) + return super().get(request, *args, **kwargs) + + def get_context_data(self, *, object_list=None, **kwargs): + context = super().get_context_data(object_list=object_list, **kwargs) + context['ak'] = self.object.ak + return context + + def get_success_url(self): + messages.add_message(self.request, messages.SUCCESS, _("AK Slot successfully updated")) + return reverse_lazy('submit:ak_detail', kwargs={'event_slug': self.kwargs['event_slug'], 'pk': self.object.ak.pk}) + + +class AKSlotDeleteView(EventSlugMixin, DeleteView): + model = AKSlot + template_name = "AKSubmission/akslot_delete.html" + + def get(self, request, *args, **kwargs): + akslot = get_object_or_404(AKSlot, pk=kwargs["pk"]) + if akslot.start is not None: + messages.add_message(self.request, messages.WARNING, _("You cannot delete a slot that has already been scheduled")) + return redirect('submit:ak_detail', event_slug=self.kwargs['event_slug'], pk=akslot.ak.pk) + return super().get(request, *args, **kwargs) + + def get_context_data(self, *, object_list=None, **kwargs): + context = super().get_context_data(object_list=object_list, **kwargs) + context['ak'] = self.object.ak + return context + + def get_success_url(self): + messages.add_message(self.request, messages.SUCCESS, _("AK Slot successfully deleted")) + return reverse_lazy('submit:ak_detail', kwargs={'event_slug': self.kwargs['event_slug'], 'pk': self.object.ak.pk}) -- GitLab