diff --git a/aleksis/apps/chronos/forms.py b/aleksis/apps/chronos/forms.py index d519ba6c303717976801a3326ffca55a9ca670fe..685f67f7923f64f992822dd2004627adc8ba8760 100644 --- a/aleksis/apps/chronos/forms.py +++ b/aleksis/apps/chronos/forms.py @@ -1,7 +1,10 @@ from django import forms from django_select2.forms import ModelSelect2MultipleWidget +from django.utils.translation import gettext_lazy as _ +from material import Fieldset from .models import LessonSubstitution +from aleksis.core.forms import AnnouncementForm class LessonSubstitutionForm(forms.ModelForm): @@ -17,3 +20,6 @@ class LessonSubstitutionForm(forms.ModelForm): ] ) } + + +AnnouncementForm.add_node_to_layout(Fieldset(_("Options for timetables"), "show_in_timetables")) diff --git a/aleksis/apps/chronos/model_extensions.py b/aleksis/apps/chronos/model_extensions.py index 672600908bbb9d847ce8fae762ca5b1dd5da4b9b..31bdbab5eb0400b70ebb94fab1f7f86801b21866 100644 --- a/aleksis/apps/chronos/model_extensions.py +++ b/aleksis/apps/chronos/model_extensions.py @@ -1,6 +1,9 @@ from typing import Optional, Union -from aleksis.core.models import Person, Group +from django.utils.translation import gettext_lazy as _ +from jsonstore import BooleanField + +from aleksis.core.models import Person, Group, Announcement from .models import Lesson, LessonPeriod @@ -81,3 +84,11 @@ def lesson_periods_as_teacher(self): """ return LessonPeriod.objects.filter(lesson__teachers=self) + + +def for_timetables(cls): + return cls.objects.filter(show_in_timetables=True) + + +Announcement.class_method(for_timetables) +Announcement.field(show_in_timetables=BooleanField(verbose_name=_("Show announcement in timetable views?"))) diff --git a/aleksis/apps/chronos/models.py b/aleksis/apps/chronos/models.py index 311b0f7e8003b3d53f46fac1aa8ed8259e939ec1..b746f8f0fa6754e5d148c7a04133acf79b35cc03 100644 --- a/aleksis/apps/chronos/models.py +++ b/aleksis/apps/chronos/models.py @@ -8,6 +8,7 @@ from django.core import validators from django.core.exceptions import ValidationError from django.db import models from django.db.models import F, Max, Min, Q +from django.db.models.aggregates import Count from django.db.models.functions import Coalesce from django.forms import Media from django.http.request import QueryDict diff --git a/aleksis/apps/chronos/templates/chronos/my_timetable.html b/aleksis/apps/chronos/templates/chronos/my_timetable.html index d508fd43b0b02009c7124e5bb03c4bde2b77e8e5..cc9b03c973e664b89001ed8932f278da16493f58 100644 --- a/aleksis/apps/chronos/templates/chronos/my_timetable.html +++ b/aleksis/apps/chronos/templates/chronos/my_timetable.html @@ -26,7 +26,7 @@ <div class="row nomargin"> <div class="col m12 s12 l6 xl4"> - {# {% include "timetable/hintsinplan.html" %}#} + {% include "core/announcements.html" with announcements=announcements %} </div> </div> diff --git a/aleksis/apps/chronos/templates/chronos/partials/hints/substitutions.html b/aleksis/apps/chronos/templates/chronos/partials/hints/substitutions.html deleted file mode 100644 index 037925c82f935e76b34e3f70c81ce057b3e0e1fd..0000000000000000000000000000000000000000 --- a/aleksis/apps/chronos/templates/chronos/partials/hints/substitutions.html +++ /dev/null @@ -1,27 +0,0 @@ -{% load martortags %} -{% if hints %} - <ul class="collapsible"> - <li> - <div class="collapsible-header " style="font-size: 16px;"> - <div class="col s12"> - <i class="material-icons left">announcement</i>Es gibt {{ hints|length }} - Hinweis{{ hints|pluralize:"e" }} für diesen Tag. - <i class="material-icons right collapsible-trigger"></i> - </div> - </div> - <div class="collapsible-body"> - {% for hint in hints %} - <div> - <strong> - {{ hint.classes_formatted }}{% if hint.teachers and hint.classes.all %},{% endif %} - </strong> - {% if hint.teachers %} - <span class="badge new green no-float no-margin">Lehrkräfte</span> - {% endif %}: - {{ hint.text|safe_markdown }} - </div> - {% endfor %} - </div> - </li> - </ul> -{% endif %} diff --git a/aleksis/apps/chronos/templates/chronos/partials/hints/substitutions_print.html b/aleksis/apps/chronos/templates/chronos/partials/hints/substitutions_print.html deleted file mode 100644 index d39760fac1dd3843c4f286c252c8088193443c91..0000000000000000000000000000000000000000 --- a/aleksis/apps/chronos/templates/chronos/partials/hints/substitutions_print.html +++ /dev/null @@ -1,16 +0,0 @@ -{% load martortags %} -{% if c.hints %} - {% for hint in c.hints %} - <div class="alert primary"> - <div> - <strong> - {{ hint.classes_formatted }}{% if hint.teachers and hint.classes.all %}, Lehrkräfte{% endif %}: - </strong> - - <i class="material-icons left">announcement</i> - - {{ hint.text|safe_markdown }} - </div> - </div> - {% endfor %} -{% endif %} diff --git a/aleksis/apps/chronos/templates/chronos/partials/hints/timetable.html b/aleksis/apps/chronos/templates/chronos/partials/hints/timetable.html deleted file mode 100644 index a8f09d1c10341be931157bd449e6c9c792488832..0000000000000000000000000000000000000000 --- a/aleksis/apps/chronos/templates/chronos/partials/hints/timetable.html +++ /dev/null @@ -1,63 +0,0 @@ -{% load martortags %} -{% if hints %} - {% for hint in hints %} - <div class="alert primary"> - <div> - <em class="right hide-on-small-and-down">Hinweis für {{ hint.from_date|date:"D, d.m." }}, - {% if hint.from_date != hint.to_date %} - bis {{ hint.to_date|date:"D, d.m." }} - {% endif %} </em> - - <i class="material-icons left">announcement</i> - - {{ hint.text|safe_markdown }} - - <em class="hide-on-med-and-up">Hinweis für {{ hint.from_date|date:"D, d.m." }}, - {% if hint.from_date != hint.to_date %} - bis {{ hint.to_date|date:"D, d.m." }} - {% endif %} </em> - </div> - </div> - {% endfor %} -{% endif %} - -{% if hints_b %} - <ul class="collapsible"> - <li> - <div class="collapsible-header " style="font-size: 16px;"> - <div class="col s12"> - <i class="material-icons left">add</i> - Es gibt - {% if hints_b_mode == "week" %} - diese Woche - {% else %} - heute - {% endif %} - {% if hints %} - noch - {% endif %} - {{ hints_b|length }} - {% if hints %} - weitere{{ hints_b|pluralize:"n," }} - {% endif %} - Hinweis{{ hints_b|pluralize:"e" }}. - <i class="material-icons right collapsible-trigger"></i> - </div> - </div> - <div class="collapsible-body"> - {% for hint in hints_b %} - {% if not hint.teachers %} - <div> - <strong> - {{ hint.classes_formatted }}, - </strong> - {{ hint.from_date|date:"D, d.m." }}{% if hint.from_date != hint.to_date %}, bis - {{ hint.to_date|date:"D, d.m." }}{% endif %}: - {{ hint.text|safe_markdown }} - </div> - {% endif %} - {% endfor %} - </div> - </li> - </ul> -{% endif %} diff --git a/aleksis/apps/chronos/templates/chronos/substitutions.html b/aleksis/apps/chronos/templates/chronos/substitutions.html index 0dc5e242852375b05ff6f48e2b35430d61510727..febc6aeb9313a6ac73e75bd2a720093f530ef2a4 100644 --- a/aleksis/apps/chronos/templates/chronos/substitutions.html +++ b/aleksis/apps/chronos/templates/chronos/substitutions.html @@ -28,7 +28,7 @@ <div class="col s12 m6 l8"> {% include "chronos/partials/headerbox.html" %} - {# {% include "chronos/hintsinsub.html" %}#} + {% include "core/announcements.html" with announcements=announcements show_recipients=1 %} </div> <div class="col s12 m6 l4 no-padding"> {% include "chronos/partials/datepicker.html" %} diff --git a/aleksis/apps/chronos/templates/chronos/substitutions_print.html b/aleksis/apps/chronos/templates/chronos/substitutions_print.html index bc041f24c2c366b6ae2764afde621a2e8802a291..400124f2391306d6353af0c2a5819d97ad89a228 100644 --- a/aleksis/apps/chronos/templates/chronos/substitutions_print.html +++ b/aleksis/apps/chronos/templates/chronos/substitutions_print.html @@ -16,7 +16,7 @@ {% for day, c in days.items %} <h4>{% trans "Substitutions" %} {{ c.day|date:"l" }} {{ c.day }}</h4> - {# {% include "timetable/hintsinsubprint.html" %}#} + {% include "core/announcements.html" with announcements=announcements show_recipients=1 %} {% include "chronos/partials/headerbox.html" with affected_teachers=c.affected_teachers affected_groups=c.affected_groups print=1 %} diff --git a/aleksis/apps/chronos/templates/chronos/timetable.html b/aleksis/apps/chronos/templates/chronos/timetable.html index 4fa91ac68f3ef7c34678ae9c94958f324ca43380..4605d70b690b1168903910b21fd6bda4e6b4bd79 100644 --- a/aleksis/apps/chronos/templates/chronos/timetable.html +++ b/aleksis/apps/chronos/templates/chronos/timetable.html @@ -113,7 +113,7 @@ {% endif %} </div> - {# {% include "chronos/hintsinplan.html" %}#} + {% include "core/announcements.html" with announcements=announcements show_interval=1 %} {# show full timetable on tablets, laptops and pcs #} <div class="timetable-plan hide-on-small-and-down"> diff --git a/aleksis/apps/chronos/views.py b/aleksis/apps/chronos/views.py index daad66d7c699cfd95d711ad9faa2760274fe8049..f1c06bb4a533ef95e75112c98f3e514cfac2a7b3 100644 --- a/aleksis/apps/chronos/views.py +++ b/aleksis/apps/chronos/views.py @@ -13,7 +13,7 @@ from django.utils.translation import ugettext as _ from django_tables2 import RequestConfig from aleksis.core.decorators import admin_required -from aleksis.core.models import Person, Group +from aleksis.core.models import Person, Group, Announcement from aleksis.core.util import messages from .forms import LessonSubstitutionForm from .models import LessonPeriod, LessonSubstitution, TimePeriod, Room @@ -77,6 +77,7 @@ def my_timetable( context["day"] = wanted_day context["periods"] = TimePeriod.get_times_dict() context["smart"] = True + context["announcements"] = Announcement.for_timetables().on_date(wanted_day).for_person(person) context["url_prev"], context["url_next"] = TimePeriod.get_prev_next_by_day( wanted_day, "my_timetable_by_date" @@ -167,6 +168,11 @@ def timetable( "dest": reverse("timetable", args=[type_, pk]) } + if is_smart: + start = wanted_week[TimePeriod.weekday_min] + stop = wanted_week[TimePeriod.weekday_max] + context["announcements"] = Announcement.for_timetables().relevant_for(el).within_days(start, stop) + week_prev = wanted_week - 1 week_next = wanted_week + 1 @@ -306,6 +312,8 @@ def substitutions( subs = LessonSubstitution.objects.on_day(day).order_by("lesson_period__lesson__groups", "lesson_period__period") day_contexts[day]["substitutions"] = subs + day_contexts[day]["announcements"] = Announcement.for_timetables().on_date(day).filter(show_in_timetables=True) + if config.CHRONOS_SUBSTITUTIONS_SHOW_HEADER_BOX: day_contexts[day]["affected_teachers"] = subs.affected_teachers() day_contexts[day]["affected_groups"] = subs.affected_groups() diff --git a/poetry.lock b/poetry.lock index bb493dd0c914cea4050b3ce0ec22fd12e2eab2ac..2501592e0e17a920c18de1b072718beadfca5378 100644 --- a/poetry.lock +++ b/poetry.lock @@ -12,7 +12,6 @@ Pillow = "^7.0" calendarweek = "^0.4.3" colour = "^0.1.5" django-any-js = "^1.0" -django-bootstrap4 = "^1.0" django-ckeditor = "^5.8.0" django-debug-toolbar = "^2.0" django-easy-audit = "^1.2rc1" @@ -212,17 +211,6 @@ version = "1.0.3" django = "*" six = "*" -[[package]] -category = "main" -description = "Bootstrap support for Django projects" -name = "django-bootstrap4" -optional = false -python-versions = "*" -version = "1.1.1" - -[package.dependencies] -beautifulsoup4 = "*" - [[package]] category = "main" description = "Bulk update using one query over Django ORM." @@ -1000,10 +988,6 @@ django-appconf = [ {file = "django-appconf-1.0.3.tar.gz", hash = "sha256:35f13ca4d567f132b960e2cd4c832c2d03cb6543452d34e29b7ba10371ba80e3"}, {file = "django_appconf-1.0.3-py2.py3-none-any.whl", hash = "sha256:c98a7af40062e996b921f5962a1c4f3f0c979fa7885f7be4710cceb90ebe13a6"}, ] -django-bootstrap4 = [ - {file = "django-bootstrap4-1.1.1.tar.gz", hash = "sha256:39f97cbce85eb66f6d76be2029bae171bd3863d0c6932b1c2dae7f299c569b90"}, - {file = "django_bootstrap4-1.1.1-py3-none-any.whl", hash = "sha256:0fcd84f8414a58b43df0b331c00c8b2f1786ae28f75f419b4d33b06fca43e0d1"}, -] django-bulk-update = [ {file = "django-bulk-update-2.2.0.tar.gz", hash = "sha256:5ab7ce8a65eac26d19143cc189c0f041d5c03b9d1b290ca240dc4f3d6aaeb337"}, {file = "django_bulk_update-2.2.0-py2.py3-none-any.whl", hash = "sha256:49a403392ae05ea872494d74fb3dfa3515f8df5c07cc277c3dc94724c0ee6985"},