diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index ccc75937408fdbeb5e724bb618e223bb390182a4..0000000000000000000000000000000000000000 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,11 +0,0 @@ -<!-- AlekSIS is developed on EduGit. GitHub only serves as - backup mirror and to help people find the project. If - possible, please submit your merge request on EduGit! - - EduGit accepts logins with GitHub accounts. ---> - -[ ] I have read the above and have no way to contribute on EduGit -[ ] I understand that GitHub's terms of service exclude young and - learning contributors, but still cannot contribute on EduGit - instead. diff --git a/CHANGELOG.rst b/CHANGELOG.rst index e0428a7443980df6b69b32ffd17343a33fb2978f..7680489d9c9af051329fee2a02f1576d037bd787 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -13,12 +13,27 @@ Changed ~~~~~~~ * [Dev] Rename the "late" field in the PersonalNote model to "tardiness". +* Use new icon set inside of models and templates +* Run full register printout generation in background + +Fixed +~~~~~ + +* Extra marks and excused absences were counted multiple times in some class register views. +* Substitution teachers couldn't see any persons in the person list of a substituted lesson. + +`2.1.1`_ - 2022-09-01 +--------------------- Fixed ~~~~~ * Register absence form wasn't accessible without direct access to class register. * Printing the full group register failed when a person had no personal notes. +* Data checks reported all Lesson Documentations as being during Holidays if there was no Holiday object. +* Students were displayed multiple times in class register views. +* Absences were counted multiple times in some class register views. +* Group owners couldn't create new seating plans. `2.1`_ - 2022-06-25 ------------------- @@ -272,3 +287,4 @@ Fixed .. _2.0: https://edugit.org/AlekSIS/Official/AlekSIS-App-Alsijil/-/tags/2.0 .. _2.0.1: https://edugit.org/AlekSIS/Official/AlekSIS-App-Alsijil/-/tags/2.0.1 .. _2.1: https://edugit.org/AlekSIS/Official/AlekSIS-App-Alsijil/-/tags/2.1 +.. _2.1.1: https://edugit.org/AlekSIS/Official/AlekSIS-App-Alsijil/-/tags/2.1.1 diff --git a/aleksis/apps/alsijil/data_checks.py b/aleksis/apps/alsijil/data_checks.py index 864f019646411443605b0495075ba6acfb47219b..cb056e8cb3728a01c98e110f15e12da629df7ff9 100644 --- a/aleksis/apps/alsijil/data_checks.py +++ b/aleksis/apps/alsijil/data_checks.py @@ -113,7 +113,7 @@ class LessonDocumentationOnHolidaysDataCheck(DataCheck): documentations = LessonDocumentation.objects.not_empty().annotate_date_range() - q = Q() + q = Q(pk__in=[]) for holiday in holidays: q = q | Q(day_end__gte=holiday.date_start, day_start__lte=holiday.date_end) documentations = documentations.filter(q) @@ -147,7 +147,7 @@ class PersonalNoteOnHolidaysDataCheck(DataCheck): personal_notes = PersonalNote.objects.not_empty().annotate_date_range() - q = Q() + q = Q(pk__in=[]) for holiday in holidays: q = q | Q(day_end__gte=holiday.date_start, day_start__lte=holiday.date_end) personal_notes = personal_notes.filter(q) diff --git a/aleksis/apps/alsijil/menus.py b/aleksis/apps/alsijil/menus.py index 71ce1d9f119ffbe23dbea6f42dbd40a83811e82a..fcf14e7cc8f8ea51eabee00abb5a75c61de42af8 100644 --- a/aleksis/apps/alsijil/menus.py +++ b/aleksis/apps/alsijil/menus.py @@ -5,7 +5,7 @@ MENUS = { { "name": _("Class register"), "url": "#", - "icon": "chrome_reader_mode", + "svg_icon": "mdi:book-open-outline", "root": True, "validators": [ "menu_generator.validators.is_authenticated", @@ -15,7 +15,7 @@ MENUS = { { "name": _("Current lesson"), "url": "lesson_period", - "icon": "alarm", + "svg_icon": "mdi:alarm", "validators": [ ( "aleksis.core.util.predicates.permission_validator", @@ -26,7 +26,7 @@ MENUS = { { "name": _("Current week"), "url": "week_view", - "icon": "view_week", + "svg_icon": "mdi:view-week-outline", "validators": [ ( "aleksis.core.util.predicates.permission_validator", @@ -37,7 +37,7 @@ MENUS = { { "name": _("My groups"), "url": "my_groups", - "icon": "people", + "svg_icon": "mdi:account-multiple-outline", "validators": [ ( "aleksis.core.util.predicates.permission_validator", @@ -48,7 +48,7 @@ MENUS = { { "name": _("My overview"), "url": "overview_me", - "icon": "insert_chart", + "svg_icon": "mdi:chart-box-outline", "validators": [ ( "aleksis.core.util.predicates.permission_validator", @@ -59,7 +59,7 @@ MENUS = { { "name": _("My students"), "url": "my_students", - "icon": "people", + "svg_icon": "mdi:account-school-outline", "validators": [ ( "aleksis.core.util.predicates.permission_validator", @@ -70,7 +70,7 @@ MENUS = { { "name": _("Assign group role"), "url": "assign_group_role_multiple", - "icon": "assignment_ind", + "svg_icon": "mdi:clipboard-account-outline", "validators": [ ( "aleksis.core.util.predicates.permission_validator", @@ -81,7 +81,7 @@ MENUS = { { "name": _("All lessons"), "url": "all_register_objects", - "icon": "list", + "svg_icon": "mdi:format-list-text", "validators": [ ( "aleksis.core.util.predicates.permission_validator", @@ -96,14 +96,14 @@ MENUS = { "validators": [ ( "aleksis.core.util.predicates.permission_validator", - "alsijil.register_absence_rule", + "alsijil.view_register_absence_rule", ), ], }, { "name": _("Excuse types"), "url": "excuse_types", - "icon": "label", + "svg_icon": "mdi:label-outline", "validators": [ ( "aleksis.core.util.predicates.permission_validator", @@ -114,7 +114,7 @@ MENUS = { { "name": _("Extra marks"), "url": "extra_marks", - "icon": "label", + "svg_icon": "mdi:label-variant-outline", "validators": [ ( "aleksis.core.util.predicates.permission_validator", @@ -125,7 +125,7 @@ MENUS = { { "name": _("Manage group roles"), "url": "group_roles", - "icon": "assignment_ind", + "svg_icon": "mdi:clipboard-plus-outline", "validators": [ ( "aleksis.core.util.predicates.permission_validator", diff --git a/aleksis/apps/alsijil/model_extensions.py b/aleksis/apps/alsijil/model_extensions.py index 5fd9b1b248e73fc91294efca5cdfc091944a9261..2c94f1fd980f54de9a18f2d7eb8f8424c241699a 100644 --- a/aleksis/apps/alsijil/model_extensions.py +++ b/aleksis/apps/alsijil/model_extensions.py @@ -434,6 +434,7 @@ def generate_person_list_with_class_register_statistics( "filtered_personal_notes", filter=Q(filtered_personal_notes__absent=True) & ~Q(filtered_personal_notes__excuse_type__count_as_absent=False), + distinct=True, ), excused=Count( "filtered_personal_notes", @@ -442,6 +443,7 @@ def generate_person_list_with_class_register_statistics( filtered_personal_notes__excused=True, ) & ~Q(filtered_personal_notes__excuse_type__count_as_absent=False), + distinct=True, ), excused_without_excuse_type=Count( "filtered_personal_notes", @@ -450,15 +452,16 @@ def generate_person_list_with_class_register_statistics( filtered_personal_notes__excused=True, filtered_personal_notes__excuse_type__isnull=True, ), + distinct=True, ), unexcused=Count( "filtered_personal_notes", filter=Q(filtered_personal_notes__absent=True, filtered_personal_notes__excused=False), + distinct=True, ), tardiness=Sum("filtered_personal_notes__tardiness"), tardiness_count=Count( - "filtered_personal_notes", - filter=Q(filtered_personal_notes__tardiness__gt=0), + "filtered_personal_notes", filter=Q(filtered_personal_notes__late__gt=0), distinct=True ), ) @@ -468,6 +471,7 @@ def generate_person_list_with_class_register_statistics( extra_mark.count_label: Count( "filtered_personal_notes", filter=Q(filtered_personal_notes__extra_marks=extra_mark), + distinct=True, ) } ) @@ -481,6 +485,7 @@ def generate_person_list_with_class_register_statistics( filtered_personal_notes__absent=True, filtered_personal_notes__excuse_type=excuse_type, ), + distinct=True, ) } ) diff --git a/aleksis/apps/alsijil/models.py b/aleksis/apps/alsijil/models.py index 917a6d5b1b94fa7882302eecd3ad7f9088a86710..b504a294164a6388099148fda5149091767577a7 100644 --- a/aleksis/apps/alsijil/models.py +++ b/aleksis/apps/alsijil/models.py @@ -5,6 +5,7 @@ from urllib.parse import urlparse from django.db import models from django.db.models.constraints import CheckConstraint from django.db.models.query_utils import Q +from django.urls import reverse from django.utils.formats import date_format from django.utils.translation import gettext_lazy as _ @@ -31,6 +32,7 @@ from aleksis.apps.alsijil.managers import ( from aleksis.apps.chronos.managers import GroupPropertiesMixin from aleksis.apps.chronos.mixins import WeekRelatedMixin from aleksis.apps.chronos.models import Event, ExtraLesson, LessonPeriod, TimePeriod +from aleksis.core.data_checks import field_validation_data_check_factory from aleksis.core.mixins import ExtensibleModel, GlobalPermissionModel from aleksis.core.models import SchoolTerm from aleksis.core.util.core_helpers import get_site_preferences @@ -450,6 +452,8 @@ class ExtraMark(ExtensibleModel): class GroupRole(ExtensibleModel): + data_checks = [field_validation_data_check_factory("alsijil", "GroupRole", "icon")] + objects = GroupRoleManager.from_queryset(GroupRoleQuerySet)() name = models.CharField(max_length=255, verbose_name=_("Name")) @@ -467,6 +471,9 @@ class GroupRole(ExtensibleModel): ] permissions = (("assign_group_role", _("Can assign group role")),) + def get_absolute_url(self) -> str: + return reverse("edit_group_role", args=[self.id]) + class GroupRoleAssignment(GroupPropertiesMixin, ExtensibleModel): objects = GroupRoleAssignmentManager.from_queryset(GroupRoleAssignmentQuerySet)() diff --git a/aleksis/apps/alsijil/rules.py b/aleksis/apps/alsijil/rules.py index b2640b8cfbf2eb8a1874926ee5a5bce2809ef1dd..e9011c6c2b33ed58a21b6412f6c7e366b1b5e49e 100644 --- a/aleksis/apps/alsijil/rules.py +++ b/aleksis/apps/alsijil/rules.py @@ -156,15 +156,20 @@ view_week_personal_notes_predicate = has_person & ( add_perm("alsijil.view_week_personalnote_rule", view_week_personal_notes_predicate) # Register absence -register_absence_predicate = has_person & ( +view_register_absence_predicate = has_person & ( ( is_person_group_owner & is_site_preference_set("alsijil", "register_absence_as_primary_group_owner") ) | has_global_perm("alsijil.register_absence") +) + +register_absence_predicate = has_person & ( + view_register_absence_predicate | has_object_perm("core.register_absence_person") | has_person_group_object_perm("core.register_absence_group") ) +add_perm("alsijil.view_register_absence_rule", view_register_absence_predicate) add_perm("alsijil.register_absence_rule", register_absence_predicate) # View full register for group diff --git a/aleksis/apps/alsijil/tasks.py b/aleksis/apps/alsijil/tasks.py new file mode 100644 index 0000000000000000000000000000000000000000..aa8de7b5a075b9a1ae37b129b1870482966577a5 --- /dev/null +++ b/aleksis/apps/alsijil/tasks.py @@ -0,0 +1,182 @@ +from copy import deepcopy +from datetime import date, timedelta + +from django.db.models import Q +from django.utils.translation import gettext as _ + +from calendarweek import CalendarWeek +from celery.result import allow_join_result +from celery.states import SUCCESS + +from aleksis.apps.chronos.models import Event, ExtraLesson, LessonPeriod +from aleksis.core.models import Group, PDFFile +from aleksis.core.util.celery_progress import ProgressRecorder, recorded_task +from aleksis.core.util.pdf import generate_pdf_from_template + +from .models import ExcuseType, ExtraMark, LessonDocumentation, PersonalNote + + +@recorded_task +def generate_full_register_printout(group: int, file_object: int, recorder: ProgressRecorder): + """Generate a full register printout as PDF for a group.""" + context = {} + + _number_of_steps = 8 + + recorder.set_progress(1, _number_of_steps, _("Load data ...")) + + group = Group.objects.get(pk=group) + file_object = PDFFile.objects.get(pk=file_object) + + groups_q = ( + Q(lesson_period__lesson__groups=group) + | Q(lesson_period__lesson__groups__parent_groups=group) + | Q(extra_lesson__groups=group) + | Q(extra_lesson__groups__parent_groups=group) + | Q(event__groups=group) + | Q(event__groups__parent_groups=group) + ) + personal_notes = ( + PersonalNote.objects.prefetch_related( + "lesson_period__substitutions", "lesson_period__lesson__teachers" + ) + .not_empty() + .filter(groups_q) + .filter(groups_of_person=group) + ) + documentations = LessonDocumentation.objects.not_empty().filter(groups_q) + + recorder.set_progress(2, _number_of_steps, _("Sort data ...")) + + sorted_documentations = {"extra_lesson": {}, "event": {}, "lesson_period": {}} + sorted_personal_notes = {"extra_lesson": {}, "event": {}, "lesson_period": {}, "person": {}} + for documentation in documentations: + key = documentation.register_object.label_ + sorted_documentations[key][documentation.register_object_key] = documentation + + for note in personal_notes: + key = note.register_object.label_ + sorted_personal_notes[key].setdefault(note.register_object_key, []) + sorted_personal_notes[key][note.register_object_key].append(note) + sorted_personal_notes["person"].setdefault(note.person.pk, []) + sorted_personal_notes["person"][note.person.pk].append(note) + + recorder.set_progress(3, _number_of_steps, _("Load lesson data ...")) + + # Get all lesson periods for the selected group + lesson_periods = LessonPeriod.objects.filter_group(group).distinct() + events = Event.objects.filter_group(group).distinct() + extra_lessons = ExtraLesson.objects.filter_group(group).distinct() + weeks = CalendarWeek.weeks_within(group.school_term.date_start, group.school_term.date_end) + + register_objects_by_day = {} + for extra_lesson in extra_lessons: + day = extra_lesson.date + register_objects_by_day.setdefault(day, []).append( + ( + extra_lesson, + sorted_documentations["extra_lesson"].get(extra_lesson.pk), + sorted_personal_notes["extra_lesson"].get(extra_lesson.pk, []), + None, + ) + ) + + for event in events: + day_number = (event.date_end - event.date_start).days + 1 + for i in range(day_number): + day = event.date_start + timedelta(days=i) + event_copy = deepcopy(event) + event_copy.annotate_day(day) + register_objects_by_day.setdefault(day, []).append( + ( + event_copy, + sorted_documentations["event"].get(event.pk), + sorted_personal_notes["event"].get(event.pk, []), + None, + ) + ) + + recorder.set_progress(4, _number_of_steps, _("Sort lesson data ...")) + + weeks = CalendarWeek.weeks_within( + group.school_term.date_start, + group.school_term.date_end, + ) + + for lesson_period in lesson_periods: + for week in weeks: + day = week[lesson_period.period.weekday] + + if ( + lesson_period.lesson.validity.date_start + <= day + <= lesson_period.lesson.validity.date_end + ): + filtered_documentation = sorted_documentations["lesson_period"].get( + f"{lesson_period.pk}_{week.week}_{week.year}" + ) + filtered_personal_notes = sorted_personal_notes["lesson_period"].get( + f"{lesson_period.pk}_{week.week}_{week.year}", [] + ) + + substitution = lesson_period.get_substitution(week) + + register_objects_by_day.setdefault(day, []).append( + (lesson_period, filtered_documentation, filtered_personal_notes, substitution) + ) + + recorder.set_progress(5, _number_of_steps, _("Load statistics ...")) + + persons = group.members.prefetch_related(None).select_related(None) + persons = group.generate_person_list_with_class_register_statistics(persons) + + prefetched_persons = [] + for person in persons: + person.filtered_notes = sorted_personal_notes["person"].get(person.pk, []) + prefetched_persons.append(person) + + context["school_term"] = group.school_term + context["persons"] = prefetched_persons + context["excuse_types"] = ExcuseType.objects.filter(count_as_absent=True) + context["excuse_types_not_absent"] = ExcuseType.objects.filter(count_as_absent=False) + context["extra_marks"] = ExtraMark.objects.all() + context["group"] = group + context["weeks"] = weeks + context["register_objects_by_day"] = register_objects_by_day + context["register_objects"] = list(lesson_periods) + list(events) + list(extra_lessons) + context["today"] = date.today() + context["lessons"] = ( + group.lessons.all() + .select_related(None) + .prefetch_related(None) + .select_related("validity", "subject") + .prefetch_related("teachers", "lesson_periods") + ) + context["child_groups"] = ( + group.child_groups.all() + .select_related(None) + .prefetch_related(None) + .prefetch_related( + "lessons", + "lessons__validity", + "lessons__subject", + "lessons__teachers", + "lessons__lesson_periods", + ) + ) + + recorder.set_progress(6, _number_of_steps, _("Generate template ...")) + + file_object, result = generate_pdf_from_template( + "alsijil/print/full_register.html", context, file_object=file_object + ) + + recorder.set_progress(7, _number_of_steps, _("Generate PDF ...")) + + with allow_join_result(): + result.wait() + file_object.refresh_from_db() + if not result.status == SUCCESS and file_object.file: + raise Exception(_("PDF generation failed")) + + recorder.set_progress(8, _number_of_steps) diff --git a/aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html b/aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html index dc069357060d16e16983d7e913c9881e9e394537..2c427ef2fa701a4e1beb36b40fc5c1de09ca8e44 100644 --- a/aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html +++ b/aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html @@ -18,11 +18,11 @@ </div> <div class="collection"> <div class="collection-item"> - <i class="material-icons left">date_range</i> + <i class="material-icons iconify left" data-icon="mdi:calendar-range"></i> {{ form_data.date_start }}, {{ form_data.from_period }}. – {{ form_data.date_end }}, {{ form_data.to_period }}. {% if form_data.date_start != form_data.date_end %} <figure class="alert warning"> - <i class="material-icons left">warning</i> + <i class="material-icons iconify left" data-icon="mdi:alert-outline"></i> {% blocktrans %} As the length of this absence is longer than one day, please double check the correctness of your entry. @@ -31,12 +31,12 @@ {% endif %} </div> <div class="collection-item"> - <i class="material-icons left">list</i> + <i class="material-icons iconify left" data-icon="mdi:format-list-bulleted"></i> {% blocktrans with count=affected_lessons %} {{ count }} affected lessons {% endblocktrans %} {% if affected_lessons == 0 %} <div class="alert error"> <div> - <i class="material-icons left">error</i> + <i class="material-icons iconify left" data-icon="mdi:alert-octagon-outline"></i> {% blocktrans %} There are no affected lessons. Registering this absence won't have any effect. {% endblocktrans %} @@ -45,7 +45,7 @@ {% endif %} </div> <div class="collection-item"> - <i class="material-icons left">label</i> + <i class="material-icons iconify left" data-icon="mdi:label-outline"></i> {% if form_data.absent %} <span class="chip red white-text">{% trans "Absent" %}</span> {% if form_data.excused and form_data.excuse_type %} @@ -59,7 +59,7 @@ </div> {% if form_data.remarks %} <div class="collection-item"> - <i class="material-icons left">edit</i> + <i class="material-icons iconify left" data-icon="mdi:pencil-outline"></i> {{ form_data.remarks }} </div> {% endif %} @@ -75,7 +75,7 @@ <input type="hidden" name="confirmed" value="1"> {% include "core/partials/save_button.html" %} <a class="btn red waves-effect waves-light" href="{% url "register_absence" person.pk %}"> - <i class="material-icons left">cancel</i> + <i class="material-icons iconify left" data-icon="mdi:close"></i> {% trans "Cancel" %} </a> </form> diff --git a/aleksis/apps/alsijil/templates/alsijil/class_register/groups.html b/aleksis/apps/alsijil/templates/alsijil/class_register/groups.html index 8c6254cdbd54ea045ec16df9684b6e65171a9d33..43a6eeeb9349969b58c61111e6017b7d24e74f60 100644 --- a/aleksis/apps/alsijil/templates/alsijil/class_register/groups.html +++ b/aleksis/apps/alsijil/templates/alsijil/class_register/groups.html @@ -31,23 +31,23 @@ <td> <div class="right"> <a class="btn primary-color waves-effect waves-light" href="{% url "students_list" group.pk %}"> - <i class="material-icons left">people</i> + <i class="material-icons iconify left" data-icon="mdi:account-multiple-outline"></i> {% trans "Students list" %} </a> <a class="btn secondary-color waves-effect waves-light" href="{% url "week_view" "group" group.pk %}"> - <i class="material-icons left">view_week</i> + <i class="material-icons iconify left" data-icon="mdi:view-week-outline"></i> {% trans "Week view" %} </a> {% has_perm "alsijil.view_assigned_grouproles_rule" user group as can_view_assigned_group_roles %} {% if can_view_assigned_group_roles %} <a class="btn primary waves-effect waves-light" href="{% url 'assigned_group_roles' group.pk %}"> - <i class="material-icons left">assignment_ind</i> + <i class="material-icons iconify left" data-icon="mdi:clipboard-account-outline"></i> {% trans "Roles" %} </a> {% endif %} <a class="btn primary waves-effect waves-light" href="{% url "full_register_group" group.pk %}" target="_blank"> - <i class="material-icons left">print</i> + <i class="material-icons iconify left" data-icon="mdi:printer-outline"></i> {% trans "Generate printout" %} </a> </div> @@ -72,13 +72,13 @@ </p> <p> <a class="btn primary-color waves-effect waves-light" href="{% url "week_view" "group" group.pk %}"> - <i class="material-icons left">people</i> + <i class="material-icons iconify left" data-icon="mdi:account-multiple-outline"></i> {% trans "Students list" %} </a> </p> <p> <a class="btn secondary-color waves-effect waves-light" href="{% url "week_view" "group" group.pk %}"> - <i class="material-icons left">view_week</i> + <i class="material-icons iconify left" data-icon="mdi:view-week-outline"></i> {% trans "Week view" %} </a> </p> @@ -86,7 +86,7 @@ {% if can_view_assigned_group_roles %} <p> <a class="btn primary waves-effect waves-light" href="{% url 'assigned_group_roles' group.pk %}"> - <i class="material-icons left">assignment_ind</i> + <i class="material-icons iconify left" data-icon="mdi:clipboard-account-outline"></i> {% trans "Roles" %} </a> </p> @@ -94,7 +94,7 @@ <p> <a class="btn primary waves-effect waves-light" href="{% url "full_register_group" group.pk %}" target="_blank"> - <i class="material-icons left">print</i> + <i class="material-icons iconify left" data-icon="mdi:printer-outline"></i> {% trans "Generate printout" %} </a> </p> diff --git a/aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html b/aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html index 6de367aee293d9a4c74708ebc2bdaabff775ed88..fd376568067136e72107ec5f9363b4dc68ab4040 100644 --- a/aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html +++ b/aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html @@ -17,14 +17,14 @@ <ul class="tabs tabs-transparent tabs-icons tabs-fixed-width"> <li class="tab"> <a href="#lesson-documentation"> - <i class="material-icons">speaker_notes</i> + <i class="material-icons iconify" data-icon="mdi:message-bulleted"></i> {% trans "Period" %} </a> </li> {% if register_object.label_ != "lesson_period" or not register_object.get_substitution.cancelled or not request.site.preferences.alsijil__block_personal_notes_for_cancelled %} <li class="tab"> <a href="#personal-notes"> - <i class="material-icons">people</i> + <i class="material-icons iconify" data-icon="mdi:account-multiple-outline"></i> {% trans "Persons" %} </a> </li> @@ -32,7 +32,7 @@ {% if with_seating_plan %} <li class="tab"> <a href="#seating-plan"> - <i class="material-icons">event_seat</i> + <i class="material-icons iconify" data-icon="mdi:seat-outline"></i> {% trans "Seating plan" %} </a> </li> @@ -42,7 +42,7 @@ {% if prev_lesson.get_lesson_documentation and can_view_prev_lesson_documentation %} <li class="tab"> <a href="#previous-lesson"> - <i class="material-icons">history</i> + <i class="material-icons iconify" data-icon="mdi:history"></i> {% trans "Previous" %} </a> </li> @@ -50,7 +50,7 @@ {% endif %} <li class="tab"> <a href="#more"> - <i class="material-icons">more_horiz</i> + <i class="material-icons iconify" data-icon="mdi:dots-horizontal"></i> {% trans "More" %} </a> </li> @@ -69,7 +69,7 @@ {% if back_to_week_url %} <a href="{{ back_to_week_url }}" class="btn secondary-color waves-light waves-effect margin-bottom {% if prev_lesson_person or next_lesson_person %}hide-on-extra-large-only{% endif %}"> - <i class="material-icons left">chevron_left</i> {% trans "Week view" %} + <i class="material-icons iconify left" data-icon="mdi:chevron-left"></i> {% trans "Week view" %} </a> {% endif %} @@ -78,7 +78,7 @@ {% if back_to_week_url %} <a href="{{ back_to_week_url }}" class="btn-flat secondary-color-text waves-light waves-effect left hide-on-med-and-down hide-on-large-only show-on-extra-large"> - <i class="material-icons left">chevron_left</i> {% trans "Week view" %} + <i class="material-icons iconify left" data-icon="mdi:chevron-left"></i> {% trans "Week view" %} </a> {% endif %} @@ -89,7 +89,7 @@ href="{% url "lesson_period" prev_lesson_person.week.year prev_lesson_person.week.week prev_lesson_person.id %}" {% endif %} > - <i class="material-icons left">navigate_before</i> + <i class="material-icons iconify left" data-icon="mdi:chevron-left"></i> <span class="hide-on-small-only">{% trans "My previous lesson" %}</span> <span class="hide-on-med-and-up">{% trans "Previous" %}</span> </a> @@ -100,7 +100,7 @@ href="{% url "lesson_period" next_lesson_person.week.year next_lesson_person.week.week next_lesson_person.id %}" {% endif %} > - <i class="material-icons right">navigate_next</i> + <i class="material-icons iconify right" data-icon="mdi:chevron-right"></i> <span class="hide-on-small-only">{% trans "My next lesson" %}</span> <span class="hide-on-med-and-up">{% trans "Next" %}</span> </a> @@ -155,7 +155,7 @@ <div class="card"> <div class="card-content center-align"> <p> - <i class="material-icons medium orange-text">warning</i> + <i class="material-icons iconify medium orange-text" data-icon="mdi:alert-outline"></i> </p> <p class="card-title"> {% blocktrans %} diff --git a/aleksis/apps/alsijil/templates/alsijil/class_register/person.html b/aleksis/apps/alsijil/templates/alsijil/class_register/person.html index d11b192fbecb27004b1cb850e0e3070239975187..78792a793cce1b93577d7bf6ca55da771a43a7df 100644 --- a/aleksis/apps/alsijil/templates/alsijil/class_register/person.html +++ b/aleksis/apps/alsijil/templates/alsijil/class_register/person.html @@ -15,7 +15,7 @@ {% if has_students %} <a href="{% url "my_students" %}" class="btn-flat primary-color-text waves-light waves-effect"> - <i class="material-icons left">chevron_left</i> {% trans "Back" %} + <i class="material-icons iconify left" data-icon="mdi:chevron-left"></i> {% trans "Back" %} </a> {% endif %} <span id="heading"> @@ -26,7 +26,7 @@ {% has_perm "alsijil.register_absence_rule" user person as can_register_absence %} {% if can_register_absence %} <a class="btn primary-color waves-effect waves-light right" href="{% url "register_absence" person.pk %}"> - <i class="material-icons left">rate_review</i> + <i class="material-icons iconify left" data-icon="mdi:message-draw"></i> {% trans "Register absence" %} </a> {% endif %} @@ -70,13 +70,13 @@ </figure> <div class="modal-footer"> <button type="button" class="btn-flat secondary-color-text waves-effect waves-ripple" id="remove-filters"> - <i class="material-icons left">clear</i>{% trans "Clear all filters" %} + <i class="material-icons iconify left" data-icon="mdi:close"></i>{% trans "Clear all filters" %} </button> <button type="button" class="modal-close btn-flat red-text waves-effect waves-ripple waves-red"> - <i class="material-icons left">cancel</i>{% trans "Close" %} + <i class="material-icons iconify left" data-icon="mdi:close-circle-outline"></i>{% trans "Close" %} </button> <button type="submit" class="modal-close btn-flat primary-color-text waves-effect waves-ripple waves-light"> - <i class="material-icons left">filter_alt</i>{% trans "Filter" %} + <i class="material-icons iconify left" data-icon="mdi:filter-outline"></i>{% trans "Filter" %} </button> </div> </form> @@ -88,7 +88,8 @@ {% if can_mark_all_as_excused %} medium-high-right {% endif %}" data-target="filter-modal" type="button"> - {% trans "Filter results" %} ({{ num_filters }})<i class="material-icons right">filter_alt</i> + {% trans "Filter results" %} ({{ num_filters }}) + <i class="material-icons iconify right" data-icon="mdi:filter-outline"></i> </button> </div> <form action="" method="post" class=""> @@ -100,7 +101,7 @@ </div> <div class="col s12 m3"> <button type="submit" class="btn waves-effect waves-light medium-high full-width-s"> - Run <i class="material-icons right">send</i> + Run <i class="material-icons iconify right" data-icon="mdi:send-outline"></i> </button> </div> {% endif %} @@ -121,7 +122,7 @@ {% for school_term, stat in stats %} <li {% if forloop.first %}class="active"{% endif %}> <div class="collapsible-header"> - <i class="material-icons">date_range</i>{{ school_term }}</div> + <i class="material-icons iconify" data-icon="mdi:calendar-range"></i>{{ school_term }}</div> <div class="collapsible-body"> <table> <tr> diff --git a/aleksis/apps/alsijil/templates/alsijil/class_register/persons.html b/aleksis/apps/alsijil/templates/alsijil/class_register/persons.html index f2c8394912a6f9bd7ddd15d734870168e08b0ee1..6873ddc84a1cdbad62ff43b09d1d50ece163a01a 100644 --- a/aleksis/apps/alsijil/templates/alsijil/class_register/persons.html +++ b/aleksis/apps/alsijil/templates/alsijil/class_register/persons.html @@ -23,11 +23,11 @@ <div class="hundred-percent"> <span class="right show-on-active hide-on-small-and-down"> <a class="btn primary-color waves-effect waves-light" href="{% url "week_view" "group" group.pk %}"> - <i class="material-icons left">view_week</i> + <i class="material-icons iconify left" data-icon="mdi:view-week-outline"></i> {% trans "Week view" %} </a> <a class="btn waves-effect waves-light" href="{% url "full_register_group" group.pk %}" target="_blank"> - <i class="material-icons left">print</i> + <i class="material-icons iconify left" data-icon="mdi:printer-outline"></i> {% trans "Generate printout" %} </a> </span> @@ -39,14 +39,14 @@ <p class="show-on-active hide-on-med-and-up"> <a class="btn primary-color waves-effect waves-light hundred-percent" href="{% url "week_view" "group" group.pk %}"> - <i class="material-icons left">view_week</i> + <i class="material-icons iconify left" data-icon="mdi:view-week-outline"></i> {% trans "Week view" %} </a> </p> <p class="show-on-active hide-on-med-and-up"> <a class="btn waves-effect waves-light hundred-percent" href="{% url "full_register_group" group.pk %}" target="_blank"> - <i class="material-icons left">print</i> + <i class="material-icons iconify left" data-icon="mdi:printer-outline"></i> {% trans "Generate printout" %} </a> </p> diff --git a/aleksis/apps/alsijil/templates/alsijil/class_register/students_list.html b/aleksis/apps/alsijil/templates/alsijil/class_register/students_list.html index 245addc839dfb2991eb535b46017aa5866def7d2..72bb8071f1b05f7e911bf75776a1740a9a5d5ae9 100644 --- a/aleksis/apps/alsijil/templates/alsijil/class_register/students_list.html +++ b/aleksis/apps/alsijil/templates/alsijil/class_register/students_list.html @@ -7,16 +7,16 @@ {% block page_title %} <a href="{% url "my_groups" %}" class="btn-flat primary-color-text waves-light waves-effect"> - <i class="material-icons left">chevron_left</i> {% trans "Back" %} + <i class="material-icons iconify left" data-icon="mdi:chevron-left"></i> {% trans "Back" %} </a> {% blocktrans with group=group %}Students list: {{ group }}{% endblocktrans %} <span class="right show-on-active hide-on-small-and-down"> <a class="btn primary-color waves-effect waves-light" href="{% url "week_view" "group" group.pk %}"> - <i class="material-icons left">view_week</i> + <i class="material-icons iconify left" data-icon="mdi:view-week-outline"></i> {% trans "Week view" %} </a> <a class="btn waves-effect waves-light" href="{% url "full_register_group" group.pk %}" target="_blank"> - <i class="material-icons left">print</i> + <i class="material-icons iconify left" data-icon="mdi:printer-outline"></i> {% trans "Generate printout" %} </a> </span> @@ -31,14 +31,14 @@ <p class="show-on-active hide-on-med-and-up"> <a class="btn primary-color waves-effect waves-light hundred-percent" href="{% url "week_view" "group" group.pk %}"> - <i class="material-icons left">view_week</i> + <i class="material-icons iconify left" data-icon="mdi:view-week-outline"></i> {% trans "Week view" %} </a> </p> <p class="show-on-active hide-on-med-and-up"> <a class="btn waves-effect waves-light hundred-percent" href="{% url "full_register_group" group.pk %}" target="_blank"> - <i class="material-icons left">print</i> + <i class="material-icons iconify left" data-icon="mdi:printer-outline"></i> {% trans "Generate printout" %} </a> </p> diff --git a/aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html b/aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html index 4742b43208a86a35e4fcd51ea7e3ef07ddc4dee2..ce38ee671b6e51a9f4417cb8507dc530b2b81a48 100644 --- a/aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html +++ b/aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html @@ -17,20 +17,20 @@ <ul class="tabs tabs-transparent tabs-icons tabs-fixed-width"> <li class="tab col"> <a class="active" href="#week-overview"> - <i class="material-icons">speaker_notes</i> + <i class="material-icons iconify" data-icon="mdi:message-bulleted"></i> {% trans "Lesson documentations" %} </a> </li> <li class="tab col"> <a href="#personal-notes"> - <i class="material-icons">people</i> + <i class="material-icons iconify" data-icon="mdi:account-multiple-outline"></i> {% trans "Persons" %} </a> </li> {% if group_roles %} <li class="tab col"> <a href="#group-roles"> - <i class="material-icons">assignment_ind</i> + <i class="material-icons iconify" data-icon="mdi:clipboard-account-outline"></i> {% trans "Group roles" %} </a> </li> @@ -50,16 +50,14 @@ {% csrf_token %} {% form form=select_form %}{% endform %} <button type="submit" class="btn waves-effect waves-light primary-color"> - <i class="material-icons left">check</i> + <i class="material-icons iconify left" data-icon="mdi:check"></i> {% blocktrans %}Select{% endblocktrans %} </button> </form> </div> <div class="col s12 m4 l2 right"> <button type="button" class="btn waves-effect waves-light hundred-percent" id="toggle-button"> - <i class="material-icons left"> - filter_alt - </i> {% trans "Toggle filters" %} + <i class="material-icons iconify left" data-icon="mdi:filter-outline"></i> {% trans "Toggle filters" %} </button> </div> </div> @@ -74,11 +72,11 @@ {% if group %} <p class="hide-on-med-and-down"> <a class="btn primary-color waves-effect waves-light" href="{% url "students_list" group.pk %}"> - <i class="material-icons left">people</i> + <i class="material-icons iconify left" data-icon="mdi:account-multiple-outline"></i> {% trans "Students list" %} </a> <a class="btn waves-effect waves-light" href="{% url "full_register_group" group.pk %}" target="_blank"> - <i class="material-icons left">print</i> + <i class="material-icons iconify left" data-icon="mdi:printer-outline"></i> {% trans "Generate printout" %} </a> </p> @@ -86,14 +84,14 @@ <p class="hide-on-med-and-up"> <a class="btn primary-color waves-effect waves-light hundred-percent" href="{% url "students_list" group.pk %}"> - <i class="material-icons left">people</i> + <i class="material-icons iconify left" data-icon="mdi:account-multiple-outline"></i> {% trans "Students list" %} </a> </p> <p class="hide-on-med-and-up"> <a class="btn waves-effect waves-light hundred-percent" href="{% url "full_register_group" group.pk %}" target="_blank"> - <i class="material-icons left">print</i> + <i class="material-icons iconify left" data-icon="mdi:printer-outline"></i> {% trans "Generate printout" %} </a> </p> @@ -212,7 +210,7 @@ <li class=""> <div class="collapsible-header flow-text"> {{ advanced_weekday.name }}, {{ advanced_weekday.date }} <i - class="material-icons collapsible-icon-right">expand_more</i> + class="material-icons iconify collapsible-icon-right" data-icon="mdi:unfold-more-horizontal"></i> </div> <div class="collapsible-body"> <div class="collection"> @@ -290,9 +288,8 @@ <p class="subtitle"> <span>{{ advanced_weekday.date }}</span> <button class="btn-superflat right waves-effect unfold-trigger"> - {% trans "Unfold" %} <i class="material-icons"> - expand_less - </i> + {% trans "Unfold" %} + <i class="material-icons iconify" data-icon="mdi:unfold-less-horizontal"></i> </button> </p> <div class="horizontal-scroll-container"> @@ -381,7 +378,7 @@ {% if can_register_absence %} <a class="btn primary-color waves-effect waves-light right" href="{% url "register_absence" person.person.pk %}"> - <i class="material-icons left">rate_review</i> + <i class="material-icons iconify left" data-icon="mdi:message-draw"></i> {% trans "Register absence" %} </a> {% endif %} @@ -432,7 +429,7 @@ <div class="card"> <div class="card-content"> <span class="card-title"> - <i class="material-icons red-text left">warning</i> + <i class="material-icons iconify red-text left" data-icon="mdi:alert-outline"></i> {% blocktrans %}No lessons available{% endblocktrans %} </span> <p> diff --git a/aleksis/apps/alsijil/templates/alsijil/excuse_type/list.html b/aleksis/apps/alsijil/templates/alsijil/excuse_type/list.html index c394784f0a9bfbb681a33c5f6875206f8d94b42a..e6235a32f382aa9cf80ae3d8ad0ad1704e25e2e9 100644 --- a/aleksis/apps/alsijil/templates/alsijil/excuse_type/list.html +++ b/aleksis/apps/alsijil/templates/alsijil/excuse_type/list.html @@ -14,7 +14,7 @@ {% has_perm "alsijil.add_excusetype_rule" user as add_excusetype %} {% if add_excusetype %} <a class="btn green waves-effect waves-light" href="{% url 'create_excuse_type' %}"> - <i class="material-icons left">add</i> + <i class="material-icons iconify left"data-icon="mdi:plus"></i> {% trans "Create excuse type" %} </a> {% endif %} diff --git a/aleksis/apps/alsijil/templates/alsijil/excuse_type/warning.html b/aleksis/apps/alsijil/templates/alsijil/excuse_type/warning.html index 9ff8af6e9c6f3c2e81970e40067a82c772e5c54c..811b90b33381c578469552154092333b2b38624d 100644 --- a/aleksis/apps/alsijil/templates/alsijil/excuse_type/warning.html +++ b/aleksis/apps/alsijil/templates/alsijil/excuse_type/warning.html @@ -1,6 +1,6 @@ {% load i18n %} <figure class="alert warning"> - <i class="material-icons left">warning</i> + <i class="material-icons iconify left" data-icon="mdi:alert-outline"></i> {% blocktrans %} This function should only be used to define alternatives to the default excuse which also will be counted extra. Don't use this to create a default excuse or if you don't divide between different types of excuse. diff --git a/aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html b/aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html index a1a12b38096de60bae34d61425a1da9c688ab9d6..9eeb63b1a81162e6490072ca7184059be7a5193a 100644 --- a/aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html +++ b/aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html @@ -10,7 +10,7 @@ {% block content %} <a class="btn green waves-effect waves-light" href="{% url 'create_extra_mark' %}"> - <i class="material-icons left">add</i> + <i class="material-icons iconify left" data-icon="mdi:plus"></i> {% trans "Create extra mark" %} </a> diff --git a/aleksis/apps/alsijil/templates/alsijil/group_role/assign.html b/aleksis/apps/alsijil/templates/alsijil/group_role/assign.html index a4a5ac137179ea12278d16029c06428221c0ef25..194c45e8871716491635c2b1a9da670c38b8c729 100644 --- a/aleksis/apps/alsijil/templates/alsijil/group_role/assign.html +++ b/aleksis/apps/alsijil/templates/alsijil/group_role/assign.html @@ -30,7 +30,7 @@ {% form form=form %}{% endform %} <button type="submit" class="btn green waves-effect waves-light"> - <i class="material-icons left">assignment_ind</i> + <i class="material-icons iconify left" data-icon="mdi:clipboard-account-outline"></i> {% trans "Assign" %} </button> </form> diff --git a/aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html b/aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html index a5533b444615836ccddefed3b45f009ced5b987c..bed7ae1c9a4f061f71ca19dcd5e87e2625ae6f48 100644 --- a/aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html +++ b/aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html @@ -24,7 +24,7 @@ {% has_perm "alsijil.view_my_groups_rule" user as can_view_group_overview %} {% if can_view_group_overview %} <a class="btn waves-effect waves-light" href="{% url "my_groups" %}"> - <i class="material-icons left">arrow_back</i> + <i class="material-icons iconify left" data-icon="mdi:arrow-left"></i> {% trans "Back to my groups" %} </a> {% endif %} @@ -32,7 +32,7 @@ {% has_perm "alsijil.assign_grouprole_for_group_rule" user object as can_assign_group_role %} {% if can_assign_group_role %} <a class="btn green waves-effect waves-light" href="{% url "assign_group_role" object.pk %}"> - <i class="material-icons left">assignment_ind</i> + <i class="material-icons iconify left" data-icon="mdi:clipboard-account-outline"></i> {% trans "Assign a role to a person" %} </a> {% endif %} @@ -79,7 +79,7 @@ <td> <a class="btn waves-effect waves-light dropdown-trigger" href="#" data-target="dropdown-{{ assignment.pk }}-d2"> - <i class="material-icons left">list</i> + <i class="material-icons iconify left" data-icon="mdi:format-list-bulleted"></i> {% trans "Actions" %} </a> {% include "alsijil/group_role/partials/assignment_options.html" with assignment=assignment back_url=back_url suffix="-d2" %} diff --git a/aleksis/apps/alsijil/templates/alsijil/group_role/chip.html b/aleksis/apps/alsijil/templates/alsijil/group_role/chip.html index 530ffa05b531acd34bfa7726b374e56ee703298b..41e520302a9d3cac6b7f1d3e3b145c8c7692bde4 100644 --- a/aleksis/apps/alsijil/templates/alsijil/group_role/chip.html +++ b/aleksis/apps/alsijil/templates/alsijil/group_role/chip.html @@ -1,7 +1,7 @@ {# -*- engine:django -*- #} <div class="chip white-text" style="background-color: {{ role.colour|default:"black" }};"> - <i class="material-icons left">{{ role.icon|default:"assignment_ind" }}</i> + <i class="material-icons iconify left" data-icon="mdi:{{ role.icon|default:"clipboard-account-outline" }}"></i> {{ role.name }} {% if small %} <small>({{ small }})</small> diff --git a/aleksis/apps/alsijil/templates/alsijil/group_role/list.html b/aleksis/apps/alsijil/templates/alsijil/group_role/list.html index 73606d95b0f2cef8b24939dc7ab55a80d0a8721a..3b10aadb2fc1db3d3c1e37fc11a168be19e550eb 100644 --- a/aleksis/apps/alsijil/templates/alsijil/group_role/list.html +++ b/aleksis/apps/alsijil/templates/alsijil/group_role/list.html @@ -12,7 +12,7 @@ {% has_perm "alsijil.add_grouprole_rule" user as add_group_role %} {% if add_group_role %} <a class="btn green waves-effect waves-light" href="{% url 'create_group_role' %}"> - <i class="material-icons left">add</i> + <i class="material-icons iconify left" data-icon="mdi:plus"></i> {% trans "Create group role" %} </a> {% endif %} diff --git a/aleksis/apps/alsijil/templates/alsijil/group_role/partials/assigned_roles.html b/aleksis/apps/alsijil/templates/alsijil/group_role/partials/assigned_roles.html index fddec1113e80669262402327a7ba3ff23fa45373..f1955e749e67325ee1195fe7831bacf0157c9be3 100644 --- a/aleksis/apps/alsijil/templates/alsijil/group_role/partials/assigned_roles.html +++ b/aleksis/apps/alsijil/templates/alsijil/group_role/partials/assigned_roles.html @@ -8,7 +8,7 @@ {% if can_assign_group_role %} <a class="btn waves-effect waves-light right hide-on-med-and-up" href="{% url "assign_group_role" group.pk role.pk %}?next={{ back_url }}"> - <i class="material-icons center">add</i> + <i class="material-icons iconify center" data-icon="mdi:plus"></i> </a> {% endif %} @@ -21,7 +21,7 @@ {% if can_assign_group_role %} <a class="btn waves-effect waves-light right hide-on-small-only" href="{% url "assign_group_role" group.pk role.pk %}?next={{ back_url }}"> - <i class="material-icons center">add</i> + <i class="material-icons iconify center" data-icon="mdi:plus"></i> </a> {% endif %} @@ -37,7 +37,7 @@ </div> <figure class="alert primary"> - <i class="material-icons left">info</i> + <i class="material-icons iconify left" data-icon="information-outline"></i> {% blocktrans %} You can get some additional actions for each group role assignment if you click on the name of the corresponding person. diff --git a/aleksis/apps/alsijil/templates/alsijil/group_role/partials/assignment_options.html b/aleksis/apps/alsijil/templates/alsijil/group_role/partials/assignment_options.html index 6c6928934229e4b1f721fa98a7df49683d77d556..3fcd3f57b4aa4cb47702515eaaab5eae1b40190f 100644 --- a/aleksis/apps/alsijil/templates/alsijil/group_role/partials/assignment_options.html +++ b/aleksis/apps/alsijil/templates/alsijil/group_role/partials/assignment_options.html @@ -10,7 +10,7 @@ {% if can_edit %} <li> <a href="{% url "edit_group_role_assignment" assignment.pk %}?next={{ back_url }}"> - <i class="material-icons left">edit</i> {% trans "Edit" %} + <i class="material-icons iconify left" data-icon="mdi:pencil-outline"></i> {% trans "Edit" %} </a> </li> {% endif %} @@ -18,7 +18,7 @@ {% if not assignment.date_end and can_stop %} <li> <a href="#"> - <i class="material-icons left">stop</i> {% trans "Stop" %} + <i class="material-icons iconify left" data-icon="mdi:stop"></i> {% trans "Stop" %} </a> </li> {% endif %} @@ -26,7 +26,7 @@ {% if can_delete %} <li> <a href="{% url "delete_group_role_assignment" assignment.pk %}?next={{ back_url }}" class="red-text"> - <i class="material-icons left">delete</i> {% trans "Delete" %} + <i class="material-icons iconify left" data-icon="mdi:delete-outline"></i> {% trans "Delete" %} </a> </li> {% endif %} diff --git a/aleksis/apps/alsijil/templates/alsijil/group_role/warning.html b/aleksis/apps/alsijil/templates/alsijil/group_role/warning.html index 9ff8af6e9c6f3c2e81970e40067a82c772e5c54c..811b90b33381c578469552154092333b2b38624d 100644 --- a/aleksis/apps/alsijil/templates/alsijil/group_role/warning.html +++ b/aleksis/apps/alsijil/templates/alsijil/group_role/warning.html @@ -1,6 +1,6 @@ {% load i18n %} <figure class="alert warning"> - <i class="material-icons left">warning</i> + <i class="material-icons iconify left" data-icon="mdi:alert-outline"></i> {% blocktrans %} This function should only be used to define alternatives to the default excuse which also will be counted extra. Don't use this to create a default excuse or if you don't divide between different types of excuse. diff --git a/aleksis/apps/alsijil/templates/alsijil/partials/lesson/heading.html b/aleksis/apps/alsijil/templates/alsijil/partials/lesson/heading.html index 07c14a649a96892987b984aa315e955df856cbf7..4b768265a510df03c6fab59b40cb4e356f90290a 100644 --- a/aleksis/apps/alsijil/templates/alsijil/partials/lesson/heading.html +++ b/aleksis/apps/alsijil/templates/alsijil/partials/lesson/heading.html @@ -10,14 +10,14 @@ href="{% url "lesson_period" prev_lesson.week.year prev_lesson.week.week prev_lesson.id %}" {% endif %} > - <i class="material-icons center">navigate_before</i> + <i class="material-icons iconify center" data-icon="mdi:chevron-left"></i> </a> <a class="btn-flat waves-effect waves-light primary-color-text right alsijil-header-nav-button hide-on-med-and-up {% if not next_lesson %}disabled{% endif %}" {% if next_lesson %} href="{% url "lesson_period" next_lesson.week.year next_lesson.week.week next_lesson.id %}" {% endif %} > - <i class="material-icons center">navigate_next</i> + <i class="material-icons iconify center" data-icon="mdi:chevron-right"></i> </a> <span class="alsijil-time-head"> diff --git a/aleksis/apps/alsijil/templates/alsijil/partials/lesson/prev_next.html b/aleksis/apps/alsijil/templates/alsijil/partials/lesson/prev_next.html index dcddcfcc13a6437bf1982f9e3ce20930e9aaf774..a12cf71e843ada4d1caeec54a82c8ca1876cb7ec 100644 --- a/aleksis/apps/alsijil/templates/alsijil/partials/lesson/prev_next.html +++ b/aleksis/apps/alsijil/templates/alsijil/partials/lesson/prev_next.html @@ -5,7 +5,8 @@ {% if not blocked_because_holidays and with_save %} {% if can_edit_lesson_documentation or can_edit_register_object_personalnote %} <button type="submit" class="btn waves-effect waves-light green margin-bottom"> - <i class="material-icons left">save</i> {% trans "Save" %} + <i class="material-icons iconify left" data-icon="mdi:content-save-outline"></i> + {% trans "Save" %} </button> {% endif %} {% endif %} @@ -15,7 +16,7 @@ href="{% url "lesson_period" prev_lesson.week.year prev_lesson.week.week prev_lesson.id %}" {% endif %} > - <i class="material-icons left">arrow_back</i> + <i class="material-icons iconify left" data-icon="mdi:arrow-left"></i> {% blocktrans with subject=register_object.get_subject.short_name %} Previous {{ subject }} lesson {% endblocktrans %} @@ -26,7 +27,7 @@ href="{% url "lesson_period" next_lesson.week.year next_lesson.week.week next_lesson.id %}" {% endif %} > - <i class="material-icons right">arrow_forward</i> + <i class="material-icons iconify right" data-icon="mdi:arrow-right"></i> {% blocktrans with subject=register_object.get_subject.short_name %} Next {{ subject }} lesson {% endblocktrans %} diff --git a/aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html b/aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html index 3147e1fcf97b9c0665cf90f552eadd40e80247f2..e94fb66d7632272eacbdbc0b09ba868127fc9f84 100644 --- a/aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html +++ b/aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html @@ -7,7 +7,7 @@ {% if can_edit_lesson_documentation or can_edit_register_object_personalnote %} <button type="submit" class="btn waves-effect waves-light green margin-bottom hundred-percent hide-on-med-and-up"> - <i class="material-icons left">save</i> {% trans "Save" %} + <i class="material-icons iconify left" data-icon="mdi:content-save-outline"></i> {% trans "Save" %} </button> {% endif %} {% endif %} @@ -105,14 +105,18 @@ {% endfor %} </p> </td> - <td><i class="material-icons center">{{ form.absent.value|yesno:"check,clear" }}</i></td> <td> - <i class="material-icons center">{{ form.tardiness.value|yesno:"check,clear" }}</i> + <i class="material-icons iconify center" data-icon="mdi:{{ form.absent.value|yesno:"check,close" }}"></i> + </td> + <td> + <i class="material-icons iconify center" data-icon="mdi:{{ form.tardiness.value|yesno:"check,close" }}"></i> <span class="alsijil-tardiness-text"> {% if form.tardiness.value %}{{ form.tardiness.value|to_time|time:"i\m" }}{% endif %} </span> </td> - <td><i class="material-icons center">{{ form.excused.value|yesno:"check,clear" }}</i></td> + <td> + <i class="material-icons iconify center" data-icon="mdi:{{ form.excused.value|yesno:"check,close" }}"></i> + </td> <td>{% firstof form.instance.excuse_type "–" %}</td> <td> {% for extra_mark in form.instance.extra_marks.all %} @@ -133,7 +137,7 @@ {% if can_edit_lesson_documentation or can_edit_register_object_personalnote %} <button type="submit" class="btn waves-effect waves-light green margin-bottom hundred-percent hide-on-med-and-up"> - <i class="material-icons left">save</i> {% trans "Save" %} + <i class="material-icons iconify left" data-icon="mdi:content-save-outline"></i> {% trans "Save" %} </button> {% endif %} {% endif %} \ No newline at end of file diff --git a/aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/seating_plan.html b/aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/seating_plan.html index 1dcfbed7d043b1f068e8e8f7f2f74e9028aa8de7..de5e9f44f947ac49a951d30b6de58a02e844f044 100644 --- a/aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/seating_plan.html +++ b/aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/seating_plan.html @@ -10,7 +10,7 @@ </div> {% if seating_plan_parent %} <figure class="alert primary"> - <i class="material-icons left">info</i> + <i class="material-icons iconify left" data-icon="information-outline"></i> {% blocktrans with child_group=first_group %} This seating plan is taken from the parent group of {{ child_group }}. If you want, you can take it over for your group and then customize it. @@ -26,14 +26,14 @@ {% if can_edit %} <a class="btn orange waves-effect waves-light" href="{% url "edit_seating_plan" seating_plan.pk %}?next={{ back_url }}#seating-plan"> - <i class="material-icons left">edit</i> + <i class="material-icons iconify left" data-icon="mdi:pencil-outline"></i> {% trans "Edit seating plan" %} </a> {% endif %} {% if can_copy and seating_plan_parent %} <a class="btn orange waves-effect waves-light" href="{% url "copy_seating_plan" seating_plan.pk %}?next={{ back_url }}#seating-plan"> - <i class="material-icons left">content_copy</i> + <i class="material-icons iconify left" data-icon="mdi:content-copy"></i> {% trans "Copy plan and edit" %} </a> {% endif %} @@ -52,15 +52,15 @@ <div class="card"> <div class="card-content"> <div class="card-title"> - <i class="material-icons left small orange-text">warning</i> + <i class="material-icons iconify left small orange-text" data-icon="mdi:alert-outline"></i> {% trans "There is no seating plan for this lesson." %} </div> - {% has_perm "stoelindeling.add_seatingplan_rule" user first_group as can_add %} + {% has_perm "stoelindeling.create_seatingplan_rule" user first_group as can_add %} {% if can_add %} <div class="row margin-bottom"> <div class="col s12"> <a class="btn waves-effect waves-light" href="{% url "create_seating_plan" %}?group={{ first_group.pk }}&subject={{ register_object.get_subject.pk }}&room={{ register_object.get_room.pk }}&next={{ back_url }}#seating-plan"> - <i class="material-icons left">add</i> + <i class="material-icons iconify left" data-icon="mdi:plus"></i> {% blocktrans with group=first_group.name subject=register_object.get_subject.name room=register_object.get_room.name %} Create a new seating plan for {{ group }} ({{ subject }}) in {{ room }} {% endblocktrans %} @@ -69,12 +69,12 @@ </div> {% endif %} {% for parent_group in first_group.parent_groups.all %} - {% has_perm "stoelindeling.add_seatingplan_rule" user parent_group as can_add %} + {% has_perm "stoelindeling.create_seatingplan_rule" user parent_group as can_add %} {% if can_add %} <div class="row"> <div class="col s12"> <a class="btn waves-effect waves-light" href="{% url "create_seating_plan" %}?group={{ parent_group.pk }}&subject={{ register_object.get_subject.pk }}&room={{ register_object.get_room.pk }}&next={{ back_url }}#seating-plan"> - <i class="material-icons left">add</i> + <i class="material-icons iconify left" data-icon="mdi:plus"></i> {% blocktrans with group=parent_group.name room=register_object.get_room.name %} Create a new seating plan for {{ group }} in {{ room }} {% endblocktrans %} diff --git a/aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html b/aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html index 41c80fd25d208e34f38bbcd9e4137016a0734301..acd8d283d6ecc9fe7ed84234600444e1424a0e49 100644 --- a/aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html +++ b/aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html @@ -3,7 +3,7 @@ {% now_datetime as now_dt %} {% if has_documentation or register_object.has_documentation %} - {% include "alsijil/partials/lesson_status_icon.html" with text=_("Data complete") icon="check_circle" color="green" %} + {% include "alsijil/partials/lesson_status_icon.html" with text=_("Data complete") icon="mdi:check-circle-outline" color="green" %} {% elif not register_object.period %} {% if week %} {% period_to_time_start week register_object.raw_period_from_on_day as time_start %} @@ -14,23 +14,23 @@ {% endif %} {% if now_dt > time_end %} - {% include "alsijil/partials/lesson_status_icon.html" with text=_("Missing data") icon="warning" color="red" %} + {% include "alsijil/partials/lesson_status_icon.html" with text=_("Missing data") icon="mdi:alert-outline" color="red" %} {% elif now_dt > time_start and now_dt < time_end %} - {% include "alsijil/partials/lesson_status_icon.html" with text=_("Pending") icon="more_horiz" color="orange" %} + {% include "alsijil/partials/lesson_status_icon.html" with text=_("Pending") icon="mdi:dots-horizontal" color="orange" %} {% else %} - {% include "alsijil/partials/lesson_status_icon.html" with text=_("Event") icon="event" color="purple" %} + {% include "alsijil/partials/lesson_status_icon.html" with text=_("Event") icon="mdi:calendar" color="purple" %} {% endif %} {% else %} {% period_to_time_start week register_object.period as time_start %} {% period_to_time_end week register_object.period as time_end %} {% if substitution.cancelled or register_object.get_substitution.cancelled %} - {% include "alsijil/partials/lesson_status_icon.html" with text=_("Lesson cancelled") icon="cancel" color="red" %} + {% include "alsijil/partials/lesson_status_icon.html" with text=_("Lesson cancelled") icon="mdi:close" color="red" %} {% elif now_dt > time_end %} - {% include "alsijil/partials/lesson_status_icon.html" with text=_("Missing data") icon="warning" color="red" %} + {% include "alsijil/partials/lesson_status_icon.html" with text=_("Missing data") icon="mdi:alert-outline" color="red" %} {% elif now_dt > time_start and now_dt < time_end %} - {% include "alsijil/partials/lesson_status_icon.html" with text=_("Pending") icon="more_horiz" color="orange" %} + {% include "alsijil/partials/lesson_status_icon.html" with text=_("Pending") icon="mdi:dots-horizontal" color="orange" %} {% elif substitution or register_object.get_substitution %} - {% include "alsijil/partials/lesson_status_icon.html" with text=_("Substitution") icon="update" color="orange" %} + {% include "alsijil/partials/lesson_status_icon.html" with text=_("Substitution") icon="mdi:update" color="orange" %} {% endif %} {% endif %} diff --git a/aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html b/aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html index 046b3ffbdacbbb5f18232668363fae195457faa1..2c016c685bb89e8edca9e75408fd11109f655e0b 100644 --- a/aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html +++ b/aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html @@ -1,14 +1,12 @@ {% if chip %} <span class="{% if chip %}chip{% endif %} {{ color }} white-text {{ css_class }}"> - <i class="material-icons left"> - {{ icon }} - </i> + <i class="material-icons iconify left" data-icon="{{ icon }}"></i> {{ text }} </span> {% else %} - <i class="material-icons {{ color }}{% firstof color_suffix "-text" %} tooltipped {{ css_class }}" + <i class="material-icons iconify {{ color }}{% firstof color_suffix "-text" %} tooltipped {{ css_class }}" + data-icon="{{ icon }}" data-position="bottom" data-tooltip="{{ text }}" title="{{ text }}"> - {{ icon }} </i> {% endif %} diff --git a/aleksis/apps/alsijil/templates/alsijil/partials/objects_table.html b/aleksis/apps/alsijil/templates/alsijil/partials/objects_table.html index f13e6043935b6fe5b1e91915158cc12d39a8f2e0..e2053816e4a682b5de56596f0cf998e2b4e0a371 100644 --- a/aleksis/apps/alsijil/templates/alsijil/partials/objects_table.html +++ b/aleksis/apps/alsijil/templates/alsijil/partials/objects_table.html @@ -5,7 +5,7 @@ <form action="" method="get"> {% form form=filter_form %}{% endform %} <button type="submit" class="btn waves-effect waves-light"> - <i class="material-icons left">refresh</i> + <i class="material-icons iconify left" data-icon="mdi:refresh"></i> {% trans "Update filters" %} </button> </form> @@ -29,7 +29,7 @@ <div class="col s12 m4"> <button type="submit" class="btn waves-effect waves-primary"> {% trans "Execute" %} - <i class="material-icons right">send</i> + <i class="material-icons iconify right" data-icon="mdi:send-outline"></i> </button> </div> </div> diff --git a/aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html b/aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html index efa5bc3a89d72c75fbf5f3d1c9de5426c668270f..bb60dbbd0984d1dab0130ada052cb423288aee2e 100644 --- a/aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html +++ b/aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html @@ -2,7 +2,7 @@ {% if not persons %} <figure class="alert primary"> - <i class="material-icons left">warning</i> + <i class="material-icons iconify left" data-icon="mdi:alert-outline"></i> {% blocktrans %}No students available.{% endblocktrans %} </figure> {% else %} @@ -126,7 +126,7 @@ <td> <a class="btn primary waves-effect waves-light" href="{% url "overview_person" person.pk %}"> - <i class="material-icons left">insert_chart</i> + <i class="material-icons iconify left" data-icon="mdi:chart-box-outline"></i> <span class="hide-on-med-and-down"> {% trans "Show more details" %}</span> <span class="hide-on-large-only">{% trans "Details" %}</span> </a> @@ -134,7 +134,7 @@ {% has_perm "alsijil.register_absence_rule" user person as can_register_absence %} {% if can_register_absence %} <a class="btn primary-color waves-effect waves-light" href="{% url "register_absence" person.pk %}"> - <i class="material-icons left">rate_review</i> + <i class="material-icons iconify left" data-icon="mdi:message-draw"></i> {% trans "Register absence" %} </a> {% endif %} diff --git a/aleksis/apps/alsijil/templates/alsijil/print/full_register.html b/aleksis/apps/alsijil/templates/alsijil/print/full_register.html index 258ed824beb7222f6bd1c764e072dbafaedf75ee..c699287a00987ad99c1fd0c2d4617827670fae2f 100644 --- a/aleksis/apps/alsijil/templates/alsijil/print/full_register.html +++ b/aleksis/apps/alsijil/templates/alsijil/print/full_register.html @@ -17,8 +17,8 @@ <h5>{{ school_term }}</h5> <p>({{ school_term.date_start }}–{{ school_term.date_end }})</p> {% static "img/aleksis-banner.svg" as aleksis_banner %} - <img src="{% firstof request.site.preferences.theme__logo.url aleksis_banner %}" - alt="{{ request.site.preferences.general__title }} – Logo" class="max-size-600 center"> + <img src="{% firstof SITE_PREFERENCES.theme__logo.url aleksis_banner %}" + alt="{{ SITE_PREFERENCES.general__title }} – Logo" class="max-size-600 center"> <h4 id="group-desc"> {{ group.name }} </h4> @@ -256,29 +256,29 @@ <img src="{% static 'img/fallback.png' %}" alt="{{ person.first_name }} {{ person.last_name }}"/> {% endif %} </td> - <td><i class="material-icons">person</i></td> + <td><i class="material-icons iconify" data-icon="mdi:account-outline"></i></td> <td colspan="2">{{ person.first_name }} {{ person.additional_name }} {{ person.last_name }}</td> </tr> <tr> - <td><i class="material-icons">face</i></td> + <td><i class="material-icons iconify" data-icon="mdi:human-non-binary"></i></td> <td colspan="2">{{ person.get_sex_display }}</td> </tr> <tr> - <td><i class="material-icons">home</i></td> + <td><i class="material-icons iconify" data-icon="mdi:map-marker-outline"></i></td> <td>{{ person.street }} {{ person.housenumber }}</td> <td>{{ person.postal_code }} {{ person.place }}</td> </tr> <tr> - <td><i class="material-icons">phone</i></td> + <td><i class="material-icons iconify" data-icon="mdi:phone-outline"></i></td> <td>{{ person.phone_number }}</td> <td>{{ person.mobile_number }}</td> </tr> <tr> - <td><i class="material-icons">email</i></td> + <td><i class="material-icons iconify" data-icon="mdi:email-outline"></i></td> <td colspan="2">{{ person.email }}</td> </tr> <tr> - <td><i class="material-icons">cake</i></td> + <td><i class="material-icons iconify" data-icon="mdi:cake"></i></td> <td colspan="2">{{ person.date_of_birth|date }}</td> </tr> </table> diff --git a/aleksis/apps/alsijil/views.py b/aleksis/apps/alsijil/views.py index 2f6a2b14a5e33ef953382cb99e68d21cb501073d..eabce1ff687ec433c943d5954f03ece20bb01877 100644 --- a/aleksis/apps/alsijil/views.py +++ b/aleksis/apps/alsijil/views.py @@ -1,6 +1,6 @@ from contextlib import nullcontext from copy import deepcopy -from datetime import date, datetime, timedelta +from datetime import datetime, timedelta from typing import Any, Dict, Optional from django.apps import apps @@ -37,10 +37,10 @@ from aleksis.core.mixins import ( AdvancedEditView, SuccessNextMixin, ) -from aleksis.core.models import Group, Person, SchoolTerm +from aleksis.core.models import Group, PDFFile, Person, SchoolTerm from aleksis.core.util import messages +from aleksis.core.util.celery_progress import render_progress_page from aleksis.core.util.core_helpers import get_site_preferences, objectgetter_optional -from aleksis.core.util.pdf import render_pdf from aleksis.core.util.predicates import check_global_permission from .filters import PersonalNoteFilter @@ -58,14 +58,7 @@ from .forms import ( RegisterObjectActionForm, SelectForm, ) -from .models import ( - ExcuseType, - ExtraMark, - GroupRole, - GroupRoleAssignment, - LessonDocumentation, - PersonalNote, -) +from .models import ExcuseType, ExtraMark, GroupRole, GroupRoleAssignment, PersonalNote from .tables import ( ExcuseTypeTable, ExtraMarkTable, @@ -74,6 +67,7 @@ from .tables import ( RegisterObjectSelectTable, RegisterObjectTable, ) +from .tasks import generate_full_register_printout from .util.alsijil_helpers import ( annotate_documentations, generate_list_of_all_register_objects, @@ -236,13 +230,14 @@ def register_object( if not request.user.has_perm( "alsijil.view_register_object_personalnote_rule", register_object ): - persons = Person.objects.filter(pk=request.user.person.pk) + persons = Person.objects.filter( + Q(pk=request.user.person.pk) + | Q(person__member_of__in=request.user.person.owner_of.all()) + ).distinct() else: persons = Person.objects.all() - persons_qs = register_object.get_personal_notes(persons, wanted_week).filter( - person__member_of__in=request.user.person.owner_of.all() - ) + persons_qs = register_object.get_personal_notes(persons, wanted_week).distinct() # Annotate group roles if show_group_roles: @@ -476,12 +471,16 @@ def week_view( if not request.user.has_perm("alsijil.view_week_personalnote_rule", instance): persons_qs = persons_qs.filter(pk=request.user.person.pk) elif group: - persons_qs = persons_qs.filter(member_of=group).filter( - member_of__in=request.user.person.owner_of.all() + persons_qs = ( + persons_qs.filter(member_of=group) + .filter(member_of__in=request.user.person.owner_of.all()) + .distinct() ) else: - persons_qs = persons_qs.filter(member_of__in=groups).filter( - member_of__in=request.user.person.owner_of.all() + persons_qs = ( + persons_qs.filter(member_of__in=groups) + .filter(member_of__in=request.user.person.owner_of.all()) + .distinct() ) # Prefetch object permissions for persons and groups the persons are members of @@ -637,138 +636,36 @@ def week_view( "alsijil.view_full_register_rule", fn=objectgetter_optional(Group, None, False) ) def full_register_group(request: HttpRequest, id_: int) -> HttpResponse: - context = {} - group = get_object_or_404(Group, pk=id_) - groups_q = ( - Q(lesson_period__lesson__groups=group) - | Q(lesson_period__lesson__groups__parent_groups=group) - | Q(extra_lesson__groups=group) - | Q(extra_lesson__groups__parent_groups=group) - | Q(event__groups=group) - | Q(event__groups__parent_groups=group) - ) - personal_notes = ( - PersonalNote.objects.prefetch_related( - "lesson_period__substitutions", "lesson_period__lesson__teachers" - ) - .not_empty() - .filter(groups_q) - .filter(groups_of_person=group) - ) - documentations = LessonDocumentation.objects.not_empty().filter(groups_q) - sorted_documentations = {"extra_lesson": {}, "event": {}, "lesson_period": {}} - sorted_personal_notes = {"extra_lesson": {}, "event": {}, "lesson_period": {}, "person": {}} - for documentation in documentations: - key = documentation.register_object.label_ - sorted_documentations[key][documentation.register_object_key] = documentation + file_object = PDFFile.objects.create() - for note in personal_notes: - key = note.register_object.label_ - sorted_personal_notes[key].setdefault(note.register_object_key, []) - sorted_personal_notes[key][note.register_object_key].append(note) - sorted_personal_notes["person"].setdefault(note.person.pk, []) - sorted_personal_notes["person"][note.person.pk].append(note) - - # Get all lesson periods for the selected group - lesson_periods = LessonPeriod.objects.filter_group(group).distinct() - events = Event.objects.filter_group(group).distinct() - extra_lessons = ExtraLesson.objects.filter_group(group).distinct() - weeks = CalendarWeek.weeks_within(group.school_term.date_start, group.school_term.date_end) - - register_objects_by_day = {} - for extra_lesson in extra_lessons: - day = extra_lesson.date - register_objects_by_day.setdefault(day, []).append( - ( - extra_lesson, - sorted_documentations["extra_lesson"].get(extra_lesson.pk), - sorted_personal_notes["extra_lesson"].get(extra_lesson.pk, []), - None, - ) - ) + redirect_url = reverse("redirect_to_pdf_file", args=[file_object.pk]) - for event in events: - day_number = (event.date_end - event.date_start).days + 1 - for i in range(day_number): - day = event.date_start + timedelta(days=i) - event_copy = deepcopy(event) - event_copy.annotate_day(day) - register_objects_by_day.setdefault(day, []).append( - ( - event_copy, - sorted_documentations["event"].get(event.pk), - sorted_personal_notes["event"].get(event.pk, []), - None, - ) - ) + result = generate_full_register_printout.delay(group.pk, file_object.pk) - weeks = CalendarWeek.weeks_within( - group.school_term.date_start, - group.school_term.date_end, + back_url = request.GET.get("back", "") + back_url_is_safe = url_has_allowed_host_and_scheme( + url=back_url, + allowed_hosts={request.get_host()}, + require_https=request.is_secure(), ) - - for lesson_period in lesson_periods: - for week in weeks: - day = week[lesson_period.period.weekday] - - if ( - lesson_period.lesson.validity.date_start - <= day - <= lesson_period.lesson.validity.date_end - ): - filtered_documentation = sorted_documentations["lesson_period"].get( - f"{lesson_period.pk}_{week.week}_{week.year}" - ) - filtered_personal_notes = sorted_personal_notes["lesson_period"].get( - f"{lesson_period.pk}_{week.week}_{week.year}", [] - ) - - substitution = lesson_period.get_substitution(week) - - register_objects_by_day.setdefault(day, []).append( - (lesson_period, filtered_documentation, filtered_personal_notes, substitution) - ) - - persons = group.members.prefetch_related(None).select_related(None) - persons = group.generate_person_list_with_class_register_statistics(persons) - - prefetched_persons = [] - for person in persons: - person.filtered_notes = sorted_personal_notes["person"].get(person.pk, []) - prefetched_persons.append(person) - - context["school_term"] = group.school_term - context["persons"] = prefetched_persons - context["excuse_types"] = ExcuseType.objects.filter(count_as_absent=True) - context["excuse_types_not_absent"] = ExcuseType.objects.filter(count_as_absent=False) - context["extra_marks"] = ExtraMark.objects.all() - context["group"] = group - context["weeks"] = weeks - context["register_objects_by_day"] = register_objects_by_day - context["register_objects"] = list(lesson_periods) + list(events) + list(extra_lessons) - context["today"] = date.today() - context["lessons"] = ( - group.lessons.all() - .select_related(None) - .prefetch_related(None) - .select_related("validity", "subject") - .prefetch_related("teachers", "lesson_periods") + if not back_url_is_safe: + back_url = reverse("my_groups") + + return render_progress_page( + request, + result, + title=_("Generate full register printout for {}").format(group), + progress_title=_("Generate full register printout …"), + success_message=_("The printout has been generated successfully."), + error_message=_("There was a problem while generating the printout."), + redirect_on_success_url=redirect_url, + back_url=back_url, + button_title=_("Download PDF"), + button_url=redirect_url, + button_icon="picture_as_pdf", ) - context["child_groups"] = ( - group.child_groups.all() - .select_related(None) - .prefetch_related(None) - .prefetch_related( - "lessons", - "lessons__validity", - "lessons__subject", - "lessons__teachers", - "lessons__lesson_periods", - ) - ) - return render_pdf(request, "alsijil/print/full_register.html", context) @permission_required("alsijil.view_my_students_rule") @@ -797,7 +694,7 @@ def my_students(request: HttpRequest) -> HttpResponse: "primary_group__owners", Prefetch("member_of", queryset=relevant_groups, to_attr="member_of_prefetched"), ) - ).filter(member_of__in=request.user.person.owner_of.all()) + ).distinct() persons_for_group = [] for person in persons: person.set_object_permission_checker(checker) @@ -830,10 +727,10 @@ class StudentsList(PermissionRequiredMixin, DetailView): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context["group"] = self.object - context[ - "persons" - ] = self.object.generate_person_list_with_class_register_statistics().filter( - member_of__in=self.request.user.person.owner_of.all() + context["persons"] = ( + self.object.generate_person_list_with_class_register_statistics() + .filter(member_of__in=self.request.user.person.owner_of.all()) + .distinct() ) context["extra_marks"] = ExtraMark.objects.all() context["excuse_types"] = ExcuseType.objects.filter(count_as_absent=True) diff --git a/docs/conf.py b/docs/conf.py index 1bb1712a1d993fe8523eed1d34291b7865c37aa6..59ca213449c1f46b86ef5340aaac7c21447cb4e8 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -31,7 +31,7 @@ author = "The AlekSIS Team" # The short X.Y version version = "2.1" # The full version, including alpha/beta/rc tags -release = "2.1.1.dev0" +release = "2.2.dev0" # -- General configuration --------------------------------------------------- diff --git a/pyproject.toml b/pyproject.toml index 1381bc6d33e3ef546a6555d1e8695cae267f33d9..a3a4aea8d9b8f3cfd286cab366900bcce9ee5b9c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "AlekSIS-App-Alsijil" -version = "2.1.1.dev0" +version = "2.2.dev0" packages = [ { include = "aleksis" } ] @@ -48,7 +48,7 @@ secondary = true [tool.poetry.dependencies] python = "^3.9" -aleksis-core = "^2.7" +aleksis-core = "^2.12" aleksis-app-chronos = "^2.2" aleksis-app-stoelindeling = { version = "^1.0", optional = true } diff --git a/tox.ini b/tox.ini index 749e0606f4f02fcbd1649627219b15850cbc0a90..78e09567e193b72a299dfb3f776499420ecc04ec 100644 --- a/tox.ini +++ b/tox.ini @@ -10,7 +10,7 @@ skip_install = true envdir = {toxworkdir}/globalenv commands_pre = poetry install - poetry run aleksis-admin yarn install + poetry run aleksis-admin webpack_bundle poetry run aleksis-admin collectstatic --no-input commands = poetry run pytest --cov=. {posargs} aleksis/