diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/coursebook.graphql b/aleksis/apps/alsijil/frontend/components/coursebook/coursebook.graphql index 08064df0901ce59c0de868b522c3fa141aa9ed2a..59071abceb0e37f858c2dc02452827aedb6a356f 100644 --- a/aleksis/apps/alsijil/frontend/components/coursebook/coursebook.graphql +++ b/aleksis/apps/alsijil/frontend/components/coursebook/coursebook.graphql @@ -38,6 +38,11 @@ query documentationsForCoursebook( lessonEvent { id } + teachers { + id + shortName + fullName + } subject { id name diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/documentation/LessonInformation.vue b/aleksis/apps/alsijil/frontend/components/coursebook/documentation/LessonInformation.vue index 52b8bf8ad927ff9b01703ec629255f98cfab33ba..172ab1549d37838e8831761029cc859a1d12c5c0 100644 --- a/aleksis/apps/alsijil/frontend/components/coursebook/documentation/LessonInformation.vue +++ b/aleksis/apps/alsijil/frontend/components/coursebook/documentation/LessonInformation.vue @@ -1,22 +1,38 @@ +<script setup> +import PersonChip from "aleksis.core/components/person/PersonChip.vue"; +</script> + <template> - <div :class="{ 'full-width grid mr-0': true, 'mr-md-4': compact }"> + <div :class="{ 'full-width grid mr-0 mb-2': true, 'mr-md-4 mb-0': compact, 'large-grid': largeGrid }"> <div> - <time :datetime="documentation.datetimeStart" :class="{ 'd-block': compact }"> - {{ $d(toDateTime(documentation.datetimeStart), "shortTime") }} - </time> - <span v-if="!compact">–</span> - <time :datetime="documentation.datetimeEnd" :class="{ 'd-block': compact }"> - {{ $d(toDateTime(documentation.datetimeEnd), "shortTime") }} - </time> + <div :class="{ 'text-right d-flex flex-column fit-content': largeGrid }"> + <time :datetime="documentation.datetimeStart" class="text-no-wrap"> + {{ $d(toDateTime(documentation.datetimeStart), "shortTime") }} + </time> + <span v-if="!largeGrid">–</span> + <time :datetime="documentation.datetimeEnd" class="text-no-wrap"> + {{ $d(toDateTime(documentation.datetimeEnd), "shortTime") }} + </time> + </div> </div> - <span class="text-center"> + <span :class="{ 'text-right': !largeGrid }"> {{ documentation.course?.name }} </span> + <div :class="{ 'd-flex align-center flex-wrap gap': true, 'justify-center': largeGrid }"> + <person-chip + v-for="teacher in documentation.teachers" + :person="teacher" + no-link + v-bind="compact ? dialogActivator.attrs : {}" + v-on="compact ? dialogActivator.on : {}" + /> + </div> <subject-chip v-if="documentation.subject" :subject="documentation.subject" class="subject" - :append-icon="documentation.canEdit ? '$edit' : undefined" + v-bind="compact ? dialogActivator.attrs : {}" + v-on="compact ? dialogActivator.on : {}" /> </div> </template> @@ -37,18 +53,44 @@ export default { return DateTime.fromISO(dateString); }, }, + computed: { + largeGrid() { + return this.compact && !this.$vuetify.breakpoint.mobile; + } + }, }; </script> <style scoped> .grid { display: grid; - grid-template-columns: 1fr max-content 1fr; + grid-template-columns: auto auto; align-items: center; gap: 1em; + align-content: start; +} + +.large-grid { + grid-template-columns: min-content 1fr 1fr 1fr; + align-content: unset; +} + +.grid:not(.large-grid):nth-child(odd) { + justify-self: start; +} +.grid:not(.large-grid):nth-child(even) { + justify-self: end; } .subject { justify-self: end; } + +.fit-content { + width: fit-content; +} + +.gap { + gap: 0.25em; +} </style> diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/documentation/LessonNotes.vue b/aleksis/apps/alsijil/frontend/components/coursebook/documentation/LessonNotes.vue index adb7b88c7d9567c1fdc1f4d38867a19d95b7f14b..7e91c4c32ebdf0e23ca538de167280f7ae6356ac 100644 --- a/aleksis/apps/alsijil/frontend/components/coursebook/documentation/LessonNotes.vue +++ b/aleksis/apps/alsijil/frontend/components/coursebook/documentation/LessonNotes.vue @@ -26,6 +26,9 @@ > Hausaufgaben vergessen </v-chip> + <v-chip dense color="primary" outlined> + <v-icon>$edit</v-icon> + </v-chip> </div> </template> diff --git a/aleksis/apps/alsijil/schema/documentation.py b/aleksis/apps/alsijil/schema/documentation.py index 71ad9c468770d0952fb7990c7f14c3ea5d23ee25..9389755f923f43dac882498e6f1ec72ad98a9039 100644 --- a/aleksis/apps/alsijil/schema/documentation.py +++ b/aleksis/apps/alsijil/schema/documentation.py @@ -12,7 +12,9 @@ from graphene_django_cud.mutations import ( from guardian.shortcuts import get_objects_for_user from aleksis.apps.chronos.models import LessonEvent +from aleksis.apps.cursus.models import Subject from aleksis.apps.cursus.schema import CourseType, SubjectType +from aleksis.core.models import Person from aleksis.core.schema.base import ( DeleteMutation, DjangoFilterMixin, @@ -38,6 +40,7 @@ class DocumentationType(PermissionsTypeMixin, DjangoFilterMixin, DjangoObjectTyp "datetime_end", "date_start", "date_end", + "teachers", ) filter_fields = { "id": ["exact", "lte", "gte"], @@ -47,6 +50,12 @@ class DocumentationType(PermissionsTypeMixin, DjangoFilterMixin, DjangoObjectTyp course = graphene.Field(CourseType, required=False) subject = graphene.Field(SubjectType, required=False) + @staticmethod + def resolve_teachers(root: Documentation, info, **kwargs): + if not str(root.pk).startswith("DUMMY") and hasattr(root, "teachers"): + return root.teachers + return root.lesson_event.teachers + @classmethod def get_queryset(cls, queryset, info): return get_objects_for_user(info.context.user, "alsijil.view_documentation", queryset) @@ -129,6 +138,7 @@ class DocumentationInputType(graphene.InputObjectType): id = graphene.ID(required=True) course = graphene.ID(required=False) subject = graphene.ID(required=False) + teachers = graphene.List(graphene.ID, required=False) topic = graphene.String(required=False) homework = graphene.String(required=False) @@ -158,7 +168,7 @@ class DocumentationBatchCreateOrUpdateMutation(graphene.Mutation): # Timezone removal is necessary due to ISO style offsets are no valid timezones. # Instead, we take the timezone from the lesson_event and save it in a dedicated field. - return Documentation.objects.create( + obj = Documentation.objects.create( datetime_start=datetime.fromisoformat(datetime_start).replace(tzinfo=timezone.utc), datetime_end=datetime.fromisoformat(datetime_end).replace(tzinfo=timezone.utc), timezone=lesson_event.timezone, @@ -169,6 +179,12 @@ class DocumentationBatchCreateOrUpdateMutation(graphene.Mutation): homework=doc.homework or "", group_note=doc.group_note or "", ) + if doc.teachers is not None: + obj.teachers.add(*doc.teachers) + else: + obj.teachers.set(lesson_event.teachers) + obj.save() + return obj else: obj = Documentation.objects.get(id=_id) @@ -182,6 +198,11 @@ class DocumentationBatchCreateOrUpdateMutation(graphene.Mutation): if doc.group_note is not None: obj.group_note = doc.group_note + if doc.subject is not None: + obj.subject = Subject.objects.get(pk=doc.subject) + if doc.teachers is not None: + obj.teachers.set(Person.objects.filter(pk__in=doc.teachers)) + obj.save() return obj