diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 643ff17db9651a866c10dedddd59f1feb9d6f84f..5389b8747a7f76495756ad47fda11d9e410319cf 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -9,6 +9,12 @@ and this project adheres to `Semantic Versioning`_. Unreleased ---------- +Added +~~~~~ + +* New timetable interface based on calendar system. +* [Dev] LessonEvent and SupervisionEvent basing on calendar system. + `3.0.2`_ - 2023-09-10 --------------------- diff --git a/aleksis/apps/chronos/frontend/components/AmendLesson.vue b/aleksis/apps/chronos/frontend/components/AmendLesson.vue index 5219ca94448c3bef3995827a6e957bd849b71083..1d6ac1fadd0570fdf85aeb429bebc0ed3a210e6c 100644 --- a/aleksis/apps/chronos/frontend/components/AmendLesson.vue +++ b/aleksis/apps/chronos/frontend/components/AmendLesson.vue @@ -13,17 +13,18 @@ v-model="edit" :fields="fields" :is-create="!selectedEvent.meta.amended" - createItemI18nKey="chronos.event.amend.title" + create-item-i18n-key="chronos.event.amend.title" :gql-create-mutation="gqlCreateMutation" :get-create-data="transformCreateData" :default-item="defaultItem" - editItemI18nKey="chronos.event.amend.title" + edit-item-i18n-key="chronos.event.amend.title" :gql-patch-mutation="gqlPatchMutation" :get-patch-data="transformPatchData" :edit-item="initPatchData" @cancel="open = false" @save="updateOnSave()" > + <!-- eslint-disable-next-line vue/valid-v-slot --> <template #subject.field="{ attrs, on, item }"> <v-autocomplete :disabled="item.cancelled" @@ -34,6 +35,7 @@ v-on="on" /> </template> + <!-- eslint-disable-next-line vue/valid-v-slot --> <template #teachers.field="{ attrs, on, item }"> <v-autocomplete :disabled="item.cancelled" @@ -47,6 +49,7 @@ deletable-chips /> </template> + <!-- eslint-disable-next-line vue/valid-v-slot --> <template #rooms.field="{ attrs, on, item }"> <v-autocomplete :disabled="item.cancelled" @@ -60,20 +63,22 @@ deletable-chips /> </template> + <!-- eslint-disable-next-line vue/valid-v-slot --> <template #cancelled.field="{ attrs, on }"> <v-checkbox v-bind="attrs" v-on="on" /> </template> + <!-- eslint-disable-next-line vue/valid-v-slot --> <template #comment.field="{ attrs, on }"> <v-textarea v-bind="attrs" v-on="on" /> </template> </dialog-object-form> <delete-dialog - deleteSuccessMessageI18nKey="chronos.event.amend.delete_success" + delete-success-message-i18n-key="chronos.event.amend.delete_success" :gql-delete-mutation="gqlDeleteMutation" v-model="deleteEvent" :items="[selectedEvent.meta]" @save="updateOnSave()" - > + > <template #title> {{ $t("chronos.event.amend.delete_dialog") }} </template> diff --git a/aleksis/apps/chronos/managers.py b/aleksis/apps/chronos/managers.py index adc91d148d9b72723ccd37d52e411e7859858055..72b9a30645eebbeba469f33fa886143b3370bde0 100644 --- a/aleksis/apps/chronos/managers.py +++ b/aleksis/apps/chronos/managers.py @@ -927,13 +927,27 @@ class LessonEventQuerySet(PolymorphicQuerySet): ) def related_to_person(self, person: Union[int, Person]) -> "LessonEventQuerySet": - """Get all lesson events related to a certain person (as teacher/participant/group owner/parent group owner, including amends).""" + """Get all lesson events a certain person is allowed to see. + + This includes all lesson events the person is assigned to as + teacher/participant/group owner/parent group owner, + including those amended. + """ amended = self.filter( Q(amended_by__isnull=False) - & (Q(teachers=person) | Q(groups__members=person) | Q(groups__owners=person) | Q(groups__parent_groups__owners=person)) + & ( + Q(teachers=person) + | Q(groups__members=person) + | Q(groups__owners=person) + | Q(groups__parent_groups__owners=person) + ) ).values_list("amended_by__pk", flat=True) return self.filter( - Q(teachers=person) | Q(groups__members=person) | Q(groups__owners=person) | Q(groups__parent_groups__owners=person) | Q(pk__in=amended) + Q(teachers=person) + | Q(groups__members=person) + | Q(groups__owners=person) + | Q(groups__parent_groups__owners=person) + | Q(pk__in=amended) ).distinct() def not_amended(self) -> "LessonEventQuerySet": diff --git a/aleksis/apps/chronos/models.py b/aleksis/apps/chronos/models.py index 1711856a1998ceaba3c6831b9bd094dc20521a1a..862e719cc2f7583cd173407f270c0b7141f41651 100644 --- a/aleksis/apps/chronos/models.py +++ b/aleksis/apps/chronos/models.py @@ -1437,7 +1437,7 @@ class LessonEvent(CalendarEvent): def subject_name_with_amends(self: LessonEvent) -> str: """Get formatted subject name (including amends).""" my_subject = self.subject.name if self.subject else "" - amended_subject = self.amends.subject.name if self.amends else "" + amended_subject = self.amends.subject.name if self.amends and self.amends.subject else "" if my_subject and amended_subject: return _("{} (instead of {})").format(my_subject, amended_subject) @@ -1452,15 +1452,19 @@ class LessonEvent(CalendarEvent): """Get the title of the lesson event.""" if reference_object.title: return reference_object.title - elif reference_object.subject: - title = reference_object.subject.name + elif reference_object.subject or ( + reference_object.amends and reference_object.amends.subject + ): + title = reference_object.subject_name_with_amends if request and request.user.person in reference_object.teachers.all(): title += " · " + reference_object.group_names elif request: - title += " · " + reference_object.teacher_names + title += " · " + reference_object.teacher_names_with_amends else: - title += f" · {reference_object.group_names} · {reference_object.teacher_names}" - + title += ( + f" · {reference_object.group_names} · " + + f"{reference_object.teacher_names_with_amends}" + ) if reference_object.rooms.all().exists(): title += " · " + reference_object.room_names_with_amends return title diff --git a/aleksis/apps/chronos/schema/__init__.py b/aleksis/apps/chronos/schema/__init__.py index 2aebe36ef9ec9ac6e1d1e3c5b3963270e6b7a3a2..9c9861ad173dbcd597d2356596b32ae763690750 100644 --- a/aleksis/apps/chronos/schema/__init__.py +++ b/aleksis/apps/chronos/schema/__init__.py @@ -7,7 +7,11 @@ from django.db.models import F, ManyToManyField, OuterRef, Subquery, Q, Prefetch import graphene from graphene_django import DjangoObjectType -from graphene_django_cud.mutations import DjangoBatchCreateMutation, DjangoBatchDeleteMutation, DjangoBatchPatchMutation +from graphene_django_cud.mutations import ( + DjangoBatchCreateMutation, + DjangoBatchDeleteMutation, + DjangoBatchPatchMutation, +) from aleksis.core.models import CalendarEvent, Group, Person, Room from aleksis.core.schema.base import DeleteMutation, FilterOrderList @@ -106,7 +110,7 @@ class AmendLessonBatchCreateMutation(DatetimeTimezoneMixin, DjangoBatchCreateMut ) @classmethod - def before_save(cls, root, info, input, created_objects): + def before_save(cls, root, info, input, created_objects): # noqa: A002 for obj in created_objects: obj.timezone = obj.amends.timezone return created_objects @@ -119,7 +123,7 @@ class AmendLessonBatchPatchMutation(DatetimeTimezoneMixin, DjangoBatchPatchMutat only_fields = ("id", "subject", "teachers", "groups", "rooms", "cancelled", "comment") @classmethod - def before_save(cls, root, info, input, updated_objects): + def before_save(cls, root, info, input, updated_objects): # noqa: A002 for obj in updated_objects: obj.timezone = obj.amends.timezone return updated_objects