diff --git a/CHANGELOG.rst b/CHANGELOG.rst index f674ada03aa2b05ac3c76f49565b0781ca8a9007..400cc01641890d1a9c7e2421e459390fca21b465 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -9,6 +9,11 @@ and this project adheres to `Semantic Versioning`_. Unreleased ---------- +Added +~~~~~ + +* Integrate seating plans in lesson overview + Fixed ~~~~~ diff --git a/aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html b/aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html index 08af12a757d7377747075f5952cc380e5f300595..6de367aee293d9a4c74708ebc2bdaabff775ed88 100644 --- a/aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html +++ b/aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html @@ -7,6 +7,10 @@ {% block extra_head %} {{ block.super }} <link rel="stylesheet" href="{% static 'css/alsijil/lesson.css' %}"/> + + {% if with_seating_plan %} + <link rel="stylesheet" href="{% static "css/stoelindeling/seating_plan.css" %}"> + {% endif %} {% endblock %} {% block nav_content %} @@ -25,6 +29,14 @@ </a> </li> {% endif %} + {% if with_seating_plan %} + <li class="tab"> + <a href="#seating-plan"> + <i class="material-icons">event_seat</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 %} @@ -125,6 +137,12 @@ </div> {% endif %} + {% if with_seating_plan %} + <div class="col s12 no-padding" id="seating-plan"> + {% include "alsijil/partials/lesson/tabs/seating_plan.html" %} + </div> + {% endif %} + <div class="col s12 no-padding" id="more"> {% include "alsijil/partials/lesson/tabs/more.html" %} </div> 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 new file mode 100644 index 0000000000000000000000000000000000000000..1dcfbed7d043b1f068e8e8f7f2f74e9028aa8de7 --- /dev/null +++ b/aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/seating_plan.html @@ -0,0 +1,89 @@ +{% load i18n material_form_internal material_form time_helpers rules %} + + +{% if seating_plan %} + <div class="card no-mobile-card"> + <div class="card-content"> + <div class="card-title margin-bottom"> + {% blocktrans with group=seating_plan.group room=seating_plan.room %}Seating plan for {{ group }} in + {{ room }}{% endblocktrans %} + </div> + {% if seating_plan_parent %} + <figure class="alert primary"> + <i class="material-icons left">info</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. + {% endblocktrans %} + </figure> + {% endif %} + + <div class="row margin-bottom no-padding"> + <div class="col s12 no-padding"> + {% has_perm "stoelindeling.edit_seatingplan_rule" user seating_plan as can_edit %} + {% has_perm "stoelindeling.copy_seatingplan_for_group_rule" user first_group as can_copy %} + + {% 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> + {% 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> + {% trans "Copy plan and edit" %} + </a> + {% endif %} + </div> + </div> + + <div class="row"> + <div class="col s12"> + {% include "stoelindeling/seating_plan/render.html" %} + </div> + </div> + </div> + </div> +{% else %} + <div class="container"> + <div class="card"> + <div class="card-content"> + <div class="card-title"> + <i class="material-icons left small orange-text">warning</i> + {% trans "There is no seating plan for this lesson." %} + </div> + {% has_perm "stoelindeling.add_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> + {% 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 %} + </a> + </div> + </div> + {% endif %} + {% for parent_group in first_group.parent_groups.all %} + {% has_perm "stoelindeling.add_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> + {% blocktrans with group=parent_group.name room=register_object.get_room.name %} + Create a new seating plan for {{ group }} in {{ room }} + {% endblocktrans %} + </a> + </div> + </div> + {% endif %} + {% endfor %} + </div> + </div> + </div> +{% endif %} diff --git a/aleksis/apps/alsijil/views.py b/aleksis/apps/alsijil/views.py index 2d8968207f7f94ec8eac1717a68435fbe555d996..c8b1c96a3717fd190bd4a2a622fdb7fcd3d645f9 100644 --- a/aleksis/apps/alsijil/views.py +++ b/aleksis/apps/alsijil/views.py @@ -3,6 +3,7 @@ from copy import deepcopy from datetime import date, datetime, timedelta from typing import Any, Dict, Optional +from django.apps import apps from django.core.exceptions import PermissionDenied from django.db.models import Count, Exists, FilteredRelation, OuterRef, Prefetch, Q, Sum from django.db.models.expressions import Case, When @@ -185,6 +186,11 @@ def register_object( ) if not blocked_because_holidays: + groups = register_object.get_groups().all() + if groups: + first_group = groups.first() + context["first_group"] = first_group + # Group roles show_group_roles = request.user.person.preferences[ "alsijil__group_roles_in_lesson_view" @@ -192,10 +198,22 @@ def register_object( "alsijil.view_assigned_grouproles_for_register_object_rule", register_object ) if show_group_roles: - groups = register_object.get_groups().all() group_roles = GroupRole.objects.with_assignments(date_of_lesson, groups) context["group_roles"] = group_roles + with_seating_plan = ( + apps.is_installed("aleksis.apps.stoelindeling") + and groups + and request.user.has_perm("stoelindeling.view_seatingplan_for_group_rule", first_group) + ) + context["with_seating_plan"] = with_seating_plan + + if with_seating_plan: + seating_plan = register_object.seating_plan + context["seating_plan"] = register_object.seating_plan + if seating_plan and seating_plan.group != first_group: + context["seating_plan_parent"] = True + # Create or get lesson documentation object; can be empty when first opening lesson lesson_documentation = register_object.get_or_create_lesson_documentation(wanted_week) context["has_documentation"] = bool(lesson_documentation.topic)