Skip to content
Snippets Groups Projects
Verified Commit f63c1fe5 authored by Jonathan Weth's avatar Jonathan Weth :keyboard:
Browse files

Include graphical announcement form

parent 327bf3ab
No related branches found
Tags 2.0rc7
1 merge request!173Frontend based announcement management
from datetime import time
from django import forms
from django.contrib.auth import get_user_model
from django.core.exceptions import ValidationError
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from django_select2.forms import ModelSelect2MultipleWidget, Select2Widget
from material import Layout, Fieldset, Row
from .models import Group, Person, School, SchoolTerm
from .models import Group, Person, School, SchoolTerm, Announcement
class PersonAccountForm(forms.ModelForm):
......@@ -132,3 +137,72 @@ class EditTermForm(forms.ModelForm):
class Meta:
model = SchoolTerm
fields = ["caption", "date_start", "date_end"]
class AnnouncementForm(forms.ModelForm):
valid_from = forms.DateTimeField(required=False)
valid_until = forms.DateTimeField(required=False)
valid_from_date = forms.DateField(label=_("Date"))
valid_from_time = forms.TimeField(label=_("Time"))
valid_until_date = forms.DateField(label=_("Date"))
valid_until_time = forms.TimeField(label=_("Time"))
layout = Layout(
Fieldset(
_("From when until when should the announcement be displayed?"),
Row("valid_from_date", "valid_from_time", "valid_until_date", "valid_until_time"),
),
Fieldset(_("Write your announcement:"), "title", "description"),
)
@classmethod
def get_initial(cls):
return {
"valid_from_date": timezone.datetime.now(),
"valid_from_time": time(0,0),
"valid_until_date": timezone.datetime.now(),
"valid_until_time": time(23, 59)
}
def clean(self):
data = super().clean()
from_date = data["valid_from_date"]
from_time = data["valid_from_time"]
until_date = data["valid_until_date"]
until_time = data["valid_until_time"]
valid_from = timezone.datetime.combine(from_date, from_time)
valid_until = timezone.datetime.combine(until_date, until_time)
if valid_until < timezone.datetime.now():
raise ValidationError(
_("You are not allowed to create announcements which are only valid in the past.")
)
elif valid_from > valid_until:
raise ValidationError(
_("The from date and time must be earlier then the until date and time.")
)
data["valid_from"] = valid_from
data["valid_until"] = valid_until
return data
def save(self, _ = False):
a = self.instance if self.instance is not None else Announcement()
a.valid_from = self.cleaned_data["valid_from"]
a.valid_until = self.cleaned_data["valid_until"]
a.title = self.cleaned_data["title"]
a.description = self.cleaned_data["description"]
a.save()
return a
class Meta:
model = Announcement
exclude = []
......@@ -57,6 +57,15 @@ MENUS = {
"menu_generator.validators.is_superuser",
],
"submenu": [
{
"name": _("Announcements"),
"url": "announcements",
"icon": "announcement",
"validators": [
"menu_generator.validators.is_authenticated",
"menu_generator.validators.is_superuser",
],
},
{
"name": _("Data management"),
"url": "data_management",
......
{# -*- engine:django -*- #}
{% extends "core/base.html" %}
{% load i18n material_form %}
{% block browser_title %}
{% if mode == "edit" %}
{% blocktrans %}Edit announcement{% endblocktrans %}
{% else %}
{% blocktrans %}Publish announcement{% endblocktrans %}
{% endif %}
{% endblock %}
{% block page_title %}
{% if mode == "edit" %}
{% blocktrans %}Edit announcement{% endblocktrans %}
{% else %}
{% blocktrans %}Publish new announcement{% endblocktrans %}
{% endif %}
{% endblock %}
{% block content %}
<form action="" method="post">
{% csrf_token %}
{% form form=form %}{% endform %}
<button type="submit" class="btn green waves-effect waves-light">
<i class="material-icons left">save</i>
{% trans "Save und publish announcement" %}
</button>
</form>
{% endblock %}
{# -*- engine:django -*- #}
{% extends "core/base.html" %}
{% load i18n %}
{% block browser_title %}{% blocktrans %}Announcements{% endblocktrans %}{% endblock %}
{% block page_title %}{% blocktrans %}Announcements{% endblocktrans %}{% endblock %}
{% block content %}
<a class="btn green waves-effect waves-light" href="{% url "add_announcement" %}">
<i class="material-icons left">add</i>
{% trans "Publish new announcement" %}
</a>
<table class="highlight">
<thead>
<tr>
<th>{% trans "Title" %}</th>
<th>{% trans "Valid from" %}</th>
<th>{% trans "Valid until" %}</th>
<th>{% trans "Recipients" %}</th>
<th>{% trans "Actions" %}</th>
</tr>
</thead>
<tbody>
{% for announcement in announcements %}
<tr>
<td>{{ announcement.title }}</td>
<td>{{ announcement.valid_from }}</td>
<td>{{ announcement.valid_until }}</td>
<td>{{ announcement.recipients.all|join:", " }}</td>
<td>
<a class="btn-flat waves-effect waves-orange orange-text" href="{% url "edit_announcement" announcement.id %}">
<i class="material-icons left">edit</i>
{% trans "Edit" %}
</a>
</td>
</tr>
{% empty %}
<tr>
<td colspan="4">
<p class="flow-text">{% trans "There are no announcements." %}</p>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
......@@ -35,6 +35,9 @@ urlpatterns = [
path("group/<int:id_>/edit", views.edit_group, name="edit_group_by_id"),
path("", views.index, name="index"),
path("notifications/mark-read/<int:id_>", views.notification_mark_read, name="notification_mark_read"),
path("announcements/", views.announcements, name="announcements"),
path("announcement/create/", views.announcement_form, name="add_announcement"),
path("announcement/edit/<int:pk>/", views.announcement_form, name="edit_announcement"),
path("maintenance-mode/", include("maintenance_mode.urls")),
path("impersonate/", include("impersonate.urls")),
path("__i18n__/", include("django.conf.urls.i18n")),
......
......@@ -15,6 +15,7 @@ from .forms import (
EditSchoolForm,
EditTermForm,
PersonsAccountsFormSet,
AnnouncementForm,
)
from .models import Activity, Group, Notification, Person, School, DashboardWidget, Announcement
from .tables import GroupsTable, PersonsTable
......@@ -271,3 +272,47 @@ def notification_mark_read(request: HttpRequest, id_: int) -> HttpResponse:
raise PermissionDenied(_("You are not allowed to mark notifications from other users as read!"))
return redirect("index")
@admin_required
def announcements(request: HttpRequest) -> HttpResponse:
context = {}
# Get all persons
announcements = Announcement.objects.all()
context["announcements"] = announcements
return render(request, "core/announcement/list.html", context)
@admin_required
def announcement_form(request: HttpRequest, pk: Optional[int] = None) -> HttpResponse:
context = {}
if pk:
announcement = get_object_or_404(Announcement, pk=pk)
form = AnnouncementForm(
request.POST or None,
instance=announcement,
initial={
"valid_from_date": announcement.valid_from.date(),
"valid_from_time": announcement.valid_from.time(),
"valid_until_date": announcement.valid_until.date(),
"valid_until_time": announcement.valid_until.time()
}
)
context["mode"] = "edit"
else:
form = AnnouncementForm(request.POST or None, initial=AnnouncementForm.get_initial())
context["mode"] = "add"
if request.method == "POST":
if form.is_valid():
form.save()
messages.success(request, _("The announcement has been saved."))
return redirect("announcements")
context["form"] = form
return render(request, "core/announcement/form.html", context)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment