diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 6e62cd43e7ab02e65aa4842396c554d629fc0aae..483c7fb62c21be3feb9f333a0b559d4d4fffbc65 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,9 +6,22 @@ All notable changes to this project will be documented in this file. The format is based on `Keep a Changelog`_, and this project adheres to `Semantic Versioning`_. +Breaking changes +---------------- + +Removed +~~~~~~~ + +* Remove legacy menu entries. + Unreleased ---------- +Added +~~~~~ + +* Add SPA support. + Changed ~~~~~~~ diff --git a/aleksis/apps/alsijil/frontend/index.js b/aleksis/apps/alsijil/frontend/index.js new file mode 100644 index 0000000000000000000000000000000000000000..14bb71e6f8c2e7078c509ee8bf8d03a45ae75802 --- /dev/null +++ b/aleksis/apps/alsijil/frontend/index.js @@ -0,0 +1,393 @@ +import { notLoggedInValidator, hasPersonValidator } from "aleksis.core/routeValidators"; + +export default + { + meta: { + inMenu: true, + titleKey: "alsijil.menu_title", + icon: "mdi-account-group-outline", + validators: [ + hasPersonValidator + ] + }, + props: { + byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, + }, + children: [ + { + path: "lesson", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.lessonPeriod", + meta: { + inMenu: true, + titleKey: "alsijil.lesson.menu_title", + icon: "mdi-alarm", + permission: "alsijil.view_lesson_menu_rule", + }, + props: { + byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, + }, + }, + { + path: "lesson/:year(\\d+)/:week(\\d+)/:id_(\\d+)", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.lessonPeriodByCWAndID", + props: { + byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, + }, + }, + { + path: "extra_lesson/:id_(\\d+)/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.extraLessonByID", + props: { + byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, + }, + }, + { + path: "event/:id_(\\d+)/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.eventByID", + props: { + byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, + }, + }, + { + path: "week/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.weekView", + meta: { + inMenu: true, + titleKey: "alsijil.week.menu_title", + icon: "mdi-view-week-outline", + permission: "alsijil.view_week_menu_rule", + }, + props: { + byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, + }, + }, + { + path: "week/:year(\\d+)/:week(\\d+)/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.weekViewByWeek", + props: { + byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, + }, + }, + { + path: "week/year/cw/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.weekViewPlaceholders", + props: { + byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, + }, + }, + { + path: "week/:type_/:id_(\\d+)/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.weekViewByTypeAndID", + props: { + byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, + }, + }, + { + path: "week/year/cw/:type_/:id_(\\d+)/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.weekViewPlaceholdersByTypeAndID", + props: { + byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, + }, + }, + { + path: "week/:year(\\d+)/:week(\\d+)/:type_/:id_(\\d+)/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.weekViewByWeekTypeAndID", + props: { + byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, + }, + }, + { + path: "print/group/:id_(\\d+)", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.fullRegisterGroup", + props: { + byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, + }, + }, + { + path: "groups/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.myGroups", + meta: { + inMenu: true, + titleKey: "alsijil.groups.menu_title", + icon: "mdi-account-multiple-outline", + permission: "alsijil.view_my_groups_rule", + }, + props: { + byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, + }, + }, + { + path: "groups/:pk(\\d+)/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.studentsList", + props: { + byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, + }, + }, + { + path: "persons/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.myStudents", + meta: { + inMenu: true, + titleKey: "alsijil.persons.menu_title", + icon: "mdi-account-school-outline", + permission: "alsijil.view_my_students_rule", + }, + props: { + byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, + }, + }, + { + path: "persons/:id_(\\d+)/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.overviewPerson", + props: { + byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, + }, + }, + { + path: "me/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.overviewMe", + meta: { + inMenu: true, + titleKey: "alsijil.my_overview.menu_title", + icon: "mdi-chart-box-outline", + permission: "alsijil.view_person_overview_menu_rule", + }, + props: { + byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, + }, + }, + { + path: "notes/:pk(\\d+)/delete/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.deletePersonalNote", + props: { + byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, + }, + }, + { + path: "absence/new/:id_(\\d+)/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.registerAbsenceWithID", + props: { + byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, + }, + }, + { + path: "absence/new/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.registerAbsence", + meta: { + inMenu: true, + titleKey: "alsijil.absence.menu_title", + icon: "mdi-message-alert-outline", + permission: "alsijil.view_register_absence_rule", + }, + props: { + byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, + }, + }, + { + path: "extra_marks/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.extraMarks", + meta: { + inMenu: true, + titleKey: "alsijil.extra_marks.menu_title", + icon: "mdi-label-variant-outline", + permission: "alsijil.view_extramarks_rule", + }, + props: { + byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, + }, + }, + { + path: "extra_marks/create/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.createExtraMark", + props: { + byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, + }, + }, + { + path: "extra_marks/:pk(\\d+)/edit/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.editExtraMark", + props: { + byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, + }, + }, + { + path: "extra_marks/:pk(\\d+)/delete/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.deleteExtraMark", + props: { + byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, + }, + }, + { + path: "excuse_types/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.excuseTypes", + meta: { + inMenu: true, + titleKey: "alsijil.excuse_types.menu_title", + icon: "mdi-label-outline", + permission: "alsijil.view_excusetypes_rule", + }, + props: { + byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, + }, + }, + { + path: "excuse_types/create/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.createExcuseType", + props: { + byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, + }, + }, + { + path: "excuse_types/:pk(\\d+)/edit/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.editExcuseType", + props: { + byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, + }, + }, + { + path: "excuse_types/:pk(\\d+)/delete/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.deleteExcuseType", + props: { + byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, + }, + }, + { + path: "group_roles/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.groupRoles", + meta: { + inMenu: true, + titleKey: "alsijil.group_roles.menu_title_manage", + icon: "mdi-clipboard-plus-outline", + permission: "alsijil.view_grouproles_rule", + }, + props: { + byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, + }, + }, + { + path: "group_roles/create/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.createGroupRole", + props: { + byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, + }, + }, + { + path: "group_roles/:pk(\\d+)/edit/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.editGroupRole", + props: { + byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, + }, + }, + { + path: "group_roles/:pk(\\d+)/delete/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.deleteGroupRole", + props: { + byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, + }, + }, + { + path: "groups/:pk(\\d+)/group_roles/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.assignedGroupRoles", + props: { + byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, + }, + }, + { + path: "groups/:pk(\\d+)/group_roles/assign/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.assignGroupRole", + props: { + byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, + }, + }, + { + path: "groups/:pk(\\d+)/group_roles/:role_pk(\\d+)/assign/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.assignGroupRoleByRolePK", + props: { + byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, + }, + }, + { + path: "group_roles/assignments/:pk(\\d+)/edit/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.editGroupRoleAssignment", + props: { + byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, + }, + }, + { + path: "group_roles/assignments/:pk(\\d+)/stop/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.stopGroupRoleAssignment", + props: { + byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, + }, + }, + { + path: "group_roles/assignments/:pk(\\d+)/delete/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.deleteGroupRoleAssignment", + props: { + byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, + }, + }, + { + path: "group_roles/assignments/assign/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.assignGroupRoleMultiple", + meta: { + inMenu: true, + titleKey: "alsijil.group_roles.menu_title_assign", + icon: "mdi-clipboard-account-outline", + permission: "alsijil.assign_grouprole_for_multiple_rule", + }, + props: { + byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, + }, + }, + { + path: "all/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.allRegisterObjects", + meta: { + inMenu: true, + titleKey: "alsijil.all_lessons.menu_title", + icon: "mdi-format-list-text", + permission: "alsijil.view_register_objects_list_rule", + }, + }, + ], + } diff --git a/aleksis/apps/alsijil/frontend/messages/de.json b/aleksis/apps/alsijil/frontend/messages/de.json new file mode 100644 index 0000000000000000000000000000000000000000..527bebf46ef9ec7b38ba08b65cb0fa00a822c76d --- /dev/null +++ b/aleksis/apps/alsijil/frontend/messages/de.json @@ -0,0 +1,5 @@ +{ + "alsijil": { + "menu_title": "Klassenbuch" + } +} diff --git a/aleksis/apps/alsijil/frontend/messages/en.json b/aleksis/apps/alsijil/frontend/messages/en.json new file mode 100644 index 0000000000000000000000000000000000000000..cd9798229b0d867611da8dc6b89dfe02eae91f85 --- /dev/null +++ b/aleksis/apps/alsijil/frontend/messages/en.json @@ -0,0 +1,36 @@ +{ + "alsijil": { + "lesson": { + "menu_title": "Current lesson" + }, + "week": { + "menu_title": "Current week" + }, + "groups": { + "menu_title": "My groups" + }, + "persons": { + "menu_title": "My students" + }, + "absence": { + "menu_title": "Register absence" + }, + "my_overview": { + "menu_title": "My overview" + }, + "extra_marks": { + "menu_title": "Extra marks" + }, + "excuse_types": { + "menu_title": "Excuse types" + }, + "group_roles": { + "menu_title_manage": "Manage group roles", + "menu_title_assign": "Assign group roles" + }, + "all_lessons": { + "menu_title": "All lessons" + }, + "menu_title": "Class register" + } +} diff --git a/aleksis/apps/alsijil/menus.py b/aleksis/apps/alsijil/menus.py deleted file mode 100644 index fcf14e7cc8f8ea51eabee00abb5a75c61de42af8..0000000000000000000000000000000000000000 --- a/aleksis/apps/alsijil/menus.py +++ /dev/null @@ -1,139 +0,0 @@ -from django.utils.translation import gettext_lazy as _ - -MENUS = { - "NAV_MENU_CORE": [ - { - "name": _("Class register"), - "url": "#", - "svg_icon": "mdi:book-open-outline", - "root": True, - "validators": [ - "menu_generator.validators.is_authenticated", - "aleksis.core.util.core_helpers.has_person", - ], - "submenu": [ - { - "name": _("Current lesson"), - "url": "lesson_period", - "svg_icon": "mdi:alarm", - "validators": [ - ( - "aleksis.core.util.predicates.permission_validator", - "alsijil.view_lesson_menu_rule", - ), - ], - }, - { - "name": _("Current week"), - "url": "week_view", - "svg_icon": "mdi:view-week-outline", - "validators": [ - ( - "aleksis.core.util.predicates.permission_validator", - "alsijil.view_week_menu_rule", - ), - ], - }, - { - "name": _("My groups"), - "url": "my_groups", - "svg_icon": "mdi:account-multiple-outline", - "validators": [ - ( - "aleksis.core.util.predicates.permission_validator", - "alsijil.view_my_groups_rule", - ), - ], - }, - { - "name": _("My overview"), - "url": "overview_me", - "svg_icon": "mdi:chart-box-outline", - "validators": [ - ( - "aleksis.core.util.predicates.permission_validator", - "alsijil.view_person_overview_menu_rule", - ), - ], - }, - { - "name": _("My students"), - "url": "my_students", - "svg_icon": "mdi:account-school-outline", - "validators": [ - ( - "aleksis.core.util.predicates.permission_validator", - "alsijil.view_my_students_rule", - ), - ], - }, - { - "name": _("Assign group role"), - "url": "assign_group_role_multiple", - "svg_icon": "mdi:clipboard-account-outline", - "validators": [ - ( - "aleksis.core.util.predicates.permission_validator", - "alsijil.assign_grouprole_for_multiple_rule", - ), - ], - }, - { - "name": _("All lessons"), - "url": "all_register_objects", - "svg_icon": "mdi:format-list-text", - "validators": [ - ( - "aleksis.core.util.predicates.permission_validator", - "alsijil.view_register_objects_list_rule", - ), - ], - }, - { - "name": _("Register absence"), - "url": "register_absence", - "icon": "rate_review", - "validators": [ - ( - "aleksis.core.util.predicates.permission_validator", - "alsijil.view_register_absence_rule", - ), - ], - }, - { - "name": _("Excuse types"), - "url": "excuse_types", - "svg_icon": "mdi:label-outline", - "validators": [ - ( - "aleksis.core.util.predicates.permission_validator", - "alsijil.view_excusetypes_rule", - ), - ], - }, - { - "name": _("Extra marks"), - "url": "extra_marks", - "svg_icon": "mdi:label-variant-outline", - "validators": [ - ( - "aleksis.core.util.predicates.permission_validator", - "alsijil.view_extramarks_rule", - ), - ], - }, - { - "name": _("Manage group roles"), - "url": "group_roles", - "svg_icon": "mdi:clipboard-plus-outline", - "validators": [ - ( - "aleksis.core.util.predicates.permission_validator", - "alsijil.view_grouproles_rule", - ), - ], - }, - ], - } - ] -} diff --git a/aleksis/apps/alsijil/static/css/alsijil/lesson.css b/aleksis/apps/alsijil/static/css/alsijil/lesson.css index cb2d9399c9d865c7116c2f8137274edc1ec501d0..fbfa4d8d683d42b8fe003edc54bf10411fbbc7eb 100644 --- a/aleksis/apps/alsijil/static/css/alsijil/lesson.css +++ b/aleksis/apps/alsijil/static/css/alsijil/lesson.css @@ -130,4 +130,8 @@ width: calc(100% + 40px); padding: 10px 20px; margin: -10px -20px 0; -} \ No newline at end of file +} + +.tabs-icons .tab svg.iconify { + display: block; +} diff --git a/aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html b/aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html index fd376568067136e72107ec5f9363b4dc68ab4040..056bea93ca036f54869ad037f84b7575f3a2123d 100644 --- a/aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html +++ b/aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html @@ -3,7 +3,6 @@ {% load week_helpers material_form_internal material_form i18n static rules time_helpers %} {% block browser_title %}{% blocktrans %}Lesson{% endblocktrans %}{% endblock %} -{% block no_page_title %}{% endblock %} {% block extra_head %} {{ block.super }} <link rel="stylesheet" href="{% static 'css/alsijil/lesson.css' %}"/> @@ -13,48 +12,8 @@ {% endif %} {% endblock %} -{% block nav_content %} - <ul class="tabs tabs-transparent tabs-icons tabs-fixed-width"> - <li class="tab"> - <a href="#lesson-documentation"> - <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 iconify" data-icon="mdi:account-multiple-outline"></i> - {% trans "Persons" %} - </a> - </li> - {% endif %} - {% if with_seating_plan %} - <li class="tab"> - <a href="#seating-plan"> - <i class="material-icons iconify" data-icon="mdi:seat-outline"></i> - {% trans "Seating plan" %} - </a> - </li> - {% endif %} - {% if prev_lesson %} - {% has_perm "alsijil.view_lessondocumentation_rule" user prev_lesson as can_view_prev_lesson_documentation %} - {% if prev_lesson.get_lesson_documentation and can_view_prev_lesson_documentation %} - <li class="tab"> - <a href="#previous-lesson"> - <i class="material-icons iconify" data-icon="mdi:history"></i> - {% trans "Previous" %} - </a> - </li> - {% endif %} - {% endif %} - <li class="tab"> - <a href="#more"> - <i class="material-icons iconify" data-icon="mdi:dots-horizontal"></i> - {% trans "More" %} - </a> - </li> - </ul> +{% block page_title %} + {% include "alsijil/partials/lesson/heading.html" %} {% endblock %} {% block content %} @@ -62,54 +21,50 @@ {% has_perm "alsijil.edit_lessondocumentation_rule" user register_object as can_edit_lesson_documentation %} {% has_perm "alsijil.edit_register_object_personalnote_rule" user register_object as can_edit_register_object_personalnote %} - {% if next_lesson_person or prev_lesson_person or back_to_week_url %} - <div class="row margin-bottom z-depth-1 alsijil-nav-header"> - <div class="col s12 no-padding"> - {# Back to week view #} - {% 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 iconify left" data-icon="mdi:chevron-left"></i> {% trans "Week view" %} + <!-- Tab Buttons --> + <div class="col s12 margin-bottom"> + <ul class="tabs tabs-icons tabs-fixed-width"> + <li class="tab col"> + <a href="#lesson-documentation"> + <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 col"> + <a href="#personal-notes"> + <i class="material-icons iconify" data-icon="mdi:account-multiple-outline"></i> + {% trans "Persons" %} </a> - {% endif %} - - {% if prev_lesson_person or next_lesson_person %} - <div class="col s12 no-padding center alsijil-nav"> - {% 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 iconify left" data-icon="mdi:chevron-left"></i> {% trans "Week view" %} - </a> - {% endif %} - - {# Previous lesson #} - <a class="btn-flat waves-effect waves-light left primary-color-text {% if not prev_lesson_person %}disabled{% endif %}" - title="{% trans "My previous lesson" %}" - {% if prev_lesson_person %} - href="{% url "lesson_period" prev_lesson_person.week.year prev_lesson_person.week.week prev_lesson_person.id %}" - {% endif %} - > - <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> - {# Next lesson #} - <a class="btn-flat waves-effect waves-light right primary-color-text {% if not next_lesson_person %}disabled{% endif %}" - title="{% trans "My next lesson" %}" - {% if next_lesson_person %} - href="{% url "lesson_period" next_lesson_person.week.year next_lesson_person.week.week next_lesson_person.id %}" - {% endif %} - > - <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> + </li> + {% endif %} + {% if with_seating_plan %} + <li class="tab col"> + <a href="#seating-plan"> + <i class="material-icons iconify" data-icon="mdi:seat-outline"></i> + {% trans "Seating plan" %} + </a> + </li> + {% endif %} + {% if prev_lesson %} + {% has_perm "alsijil.view_lessondocumentation_rule" user prev_lesson as can_view_prev_lesson_documentation %} + {% if prev_lesson.get_lesson_documentation and can_view_prev_lesson_documentation %} + <li class="tab col"> + <a href="#previous-lesson"> + <i class="material-icons iconify" data-icon="mdi:history"></i> + {% trans "Previous" %} </a> - <span class="truncate">{{ request.user.person }}</span> - </div> + </li> {% endif %} - </div> - </div> - {% endif %} + {% endif %} + <li class="tab col"> + <a href="#more"> + <i class="material-icons iconify" data-icon="mdi:dots-horizontal"></i> + {% trans "More" %} + </a> + </li> + </ul> + </div> <form method="post" class="row"> {% csrf_token %} @@ -148,8 +103,6 @@ </div> </div> {% else %} - {% include "alsijil/partials/lesson/heading.html" %} - <div class="row no-margin"> <div class="container"> <div class="card"> diff --git a/aleksis/apps/alsijil/templates/alsijil/partials/lesson/heading.html b/aleksis/apps/alsijil/templates/alsijil/partials/lesson/heading.html index 4b768265a510df03c6fab59b40cb4e356f90290a..132e97f05acd0216d59f89a12cab08b96e123cc5 100644 --- a/aleksis/apps/alsijil/templates/alsijil/partials/lesson/heading.html +++ b/aleksis/apps/alsijil/templates/alsijil/partials/lesson/heading.html @@ -1,5 +1,54 @@ {% load i18n %} +{% if next_lesson_person or prev_lesson_person or back_to_week_url %} + <div class="row margin-bottom alsijil-nav-header"> + <div class="col s12 no-padding"> + {# Back to week view #} + {% 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 iconify left" data-icon="mdi:chevron-left"></i> {% trans "Week view" %} + </a> + {% endif %} + + {% if prev_lesson_person or next_lesson_person %} + <div class="col s12 no-padding center alsijil-nav"> + {% 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 iconify left" data-icon="mdi:chevron-left"></i> {% trans "Week view" %} + </a> + {% endif %} + + {# Previous lesson #} + <a class="btn-flat waves-effect waves-light left primary-color-text {% if not prev_lesson_person %}disabled{% endif %}" + title="{% trans "My previous lesson" %}" + {% if prev_lesson_person %} + href="{% url "lesson_period" prev_lesson_person.week.year prev_lesson_person.week.week prev_lesson_person.id %}" + {% endif %} + > + <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> + {# Next lesson #} + <a class="btn-flat waves-effect waves-light right primary-color-text {% if not next_lesson_person %}disabled{% endif %}" + title="{% trans "My next lesson" %}" + {% if next_lesson_person %} + href="{% url "lesson_period" next_lesson_person.week.year next_lesson_person.week.week next_lesson_person.id %}" + {% endif %} + > + <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> + <span class="truncate">{{ request.user.person }}</span> + </div> + {% endif %} + </div> + </div> +{% endif %} + <h1> <span class="right hide-on-small-only"> {% include "alsijil/partials/lesson_status.html" with register_object=register_object css_class="medium" %} diff --git a/aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/documentation.html b/aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/documentation.html index ef0f42048bf1df524924ec1f380f8d88dd7fab3e..22b396f457a13d4d04824836745fd49fdf7eac72 100644 --- a/aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/documentation.html +++ b/aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/documentation.html @@ -1,6 +1,5 @@ {% load i18n material_form_internal material_form %} -{% include "alsijil/partials/lesson/heading.html" %} {% include "alsijil/partials/lesson/prev_next.html" with with_save=0 %} <div class="hide-on-med-and-up margin-bottom"> diff --git a/aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/more.html b/aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/more.html index b7e010125077dd003e529bb85432dfc64adad7ab..ffc7706488757871e43de4e71da9e73802273a3f 100644 --- a/aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/more.html +++ b/aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/more.html @@ -1,7 +1,5 @@ {% load i18n %} -{% include "alsijil/partials/lesson/heading.html" %} - {% if group_roles %} {% include "alsijil/group_role/partials/assigned_roles.html" with roles=group_roles group=register_object.get_groups.first back_url=back_url %} {% endif %} 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 e94fb66d7632272eacbdbc0b09ba868127fc9f84..1b013252a8f316979cdf5bdcc87ef1c7463b6e36 100644 --- a/aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html +++ b/aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html @@ -1,6 +1,5 @@ {% load i18n material_form_internal material_form time_helpers %} -{% include "alsijil/partials/lesson/heading.html" %} {% include "alsijil/partials/lesson/prev_next.html" with with_save=1 %} {% if not blocked_because_holidays %} diff --git a/aleksis/apps/alsijil/views.py b/aleksis/apps/alsijil/views.py index 99809b7643f972c79ed0469adee90aa2ee7aac67..7cee4ac8d7b389cd4e838d992ef68750e31386d5 100644 --- a/aleksis/apps/alsijil/views.py +++ b/aleksis/apps/alsijil/views.py @@ -31,6 +31,7 @@ from aleksis.apps.chronos.managers import TimetableType from aleksis.apps.chronos.models import Event, ExtraLesson, Holiday, LessonPeriod, TimePeriod from aleksis.apps.chronos.util.build import build_weekdays from aleksis.apps.chronos.util.date import get_weeks_for_year, week_weekday_to_date +from aleksis.core.decorators import pwa_cache from aleksis.core.mixins import ( AdvancedCreateView, AdvancedDeleteView, @@ -77,6 +78,7 @@ from .util.alsijil_helpers import ( ) +@pwa_cache @permission_required("alsijil.view_register_object_rule", fn=get_register_object_by_pk) # FIXME def register_object( request: HttpRequest, @@ -326,6 +328,7 @@ def register_object( return render(request, "alsijil/class_register/lesson.html", context) +@pwa_cache @permission_required("alsijil.view_week_rule", fn=get_timetable_instance_by_pk) def week_view( request: HttpRequest, @@ -631,6 +634,7 @@ def week_view( return render(request, "alsijil/class_register/week_view.html", context) +@pwa_cache @permission_required( "alsijil.view_full_register_rule", fn=objectgetter_optional(Group, None, False) ) @@ -667,6 +671,7 @@ def full_register_group(request: HttpRequest, id_: int) -> HttpResponse: ) +@pwa_cache @permission_required("alsijil.view_my_students_rule") def my_students(request: HttpRequest) -> HttpResponse: context = {} @@ -707,6 +712,7 @@ def my_students(request: HttpRequest) -> HttpResponse: return render(request, "alsijil/class_register/persons.html", context) +@pwa_cache @permission_required( "alsijil.view_my_groups_rule", ) @@ -718,6 +724,7 @@ def my_groups(request: HttpRequest) -> HttpResponse: return render(request, "alsijil/class_register/groups.html", context) +@method_decorator(pwa_cache, "dispatch") class StudentsList(PermissionRequiredMixin, DetailView): model = Group template_name = "alsijil/class_register/students_list.html" @@ -737,6 +744,7 @@ class StudentsList(PermissionRequiredMixin, DetailView): return context +@pwa_cache @permission_required( "alsijil.view_person_overview_rule", fn=objectgetter_optional( @@ -1048,6 +1056,7 @@ class DeletePersonalNoteView(PermissionRequiredMixin, DetailView): return redirect("overview_person", note.person.pk) +@method_decorator(pwa_cache, "dispatch") class ExtraMarkListView(PermissionRequiredMixin, SingleTableView): """Table of all extra marks.""" @@ -1092,6 +1101,7 @@ class ExtraMarkDeleteView(PermissionRequiredMixin, RevisionMixin, AdvancedDelete success_message = _("The extra mark has been deleted.") +@method_decorator(pwa_cache, "dispatch") class ExcuseTypeListView(PermissionRequiredMixin, SingleTableView): """Table of all excuse types.""" @@ -1136,6 +1146,7 @@ class ExcuseTypeDeleteView(PermissionRequiredMixin, RevisionMixin, AdvancedDelet success_message = _("The excuse type has been deleted.") +@method_decorator(pwa_cache, "dispatch") class GroupRoleListView(PermissionRequiredMixin, SingleTableView): """Table of all group roles.""" @@ -1180,6 +1191,7 @@ class GroupRoleDeleteView(PermissionRequiredMixin, RevisionMixin, AdvancedDelete success_message = _("The group role has been deleted.") +@method_decorator(pwa_cache, "dispatch") class AssignedGroupRolesView(PermissionRequiredMixin, DetailView): permission_required = "alsijil.view_assigned_grouproles_rule" model = Group @@ -1302,6 +1314,7 @@ class GroupRoleAssignmentDeleteView( return reverse("assigned_group_roles", args=[pk]) +@method_decorator(pwa_cache, "dispatch") class AllRegisterObjectsView(PermissionRequiredMixin, View): """Provide overview of all register objects for coordinators.""" diff --git a/pyproject.toml b/pyproject.toml index a3a4aea8d9b8f3cfd286cab366900bcce9ee5b9c..c857f98eef3eace85829b5de01f3cb7d0867f161 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "AlekSIS-App-Alsijil" -version = "2.2.dev0" +version = "3.0.dev0" packages = [ { include = "aleksis" } ] @@ -48,8 +48,8 @@ secondary = true [tool.poetry.dependencies] python = "^3.9" -aleksis-core = "^2.12" -aleksis-app-chronos = "^2.2" +aleksis-core = "^3.0.dev3" +aleksis-app-chronos = "^3.0.dev1" aleksis-app-stoelindeling = { version = "^1.0", optional = true } [tool.poetry.dev-dependencies]