From 32467ea743cccb9ce4021ffcaf6138c2a7c9f741 Mon Sep 17 00:00:00 2001 From: Jonathan Weth <git@jonathanweth.de> Date: Wed, 3 Apr 2024 23:32:09 +0200 Subject: [PATCH] Show readonly information with own components, add matching notices for future/empty documentations --- .../components/coursebook/coursebook.graphql | 1 + .../DocumentationCompactDetails.vue | 30 +++++++++ .../DocumentationFullDetails.vue | 34 +++++++++++ .../documentation/LessonInformation.vue | 8 ++- .../documentation/LessonSummary.vue | 61 ++++++++++++++++--- .../apps/alsijil/frontend/messages/en.json | 4 ++ aleksis/apps/alsijil/schema/documentation.py | 10 +++ 7 files changed, 140 insertions(+), 8 deletions(-) create mode 100644 aleksis/apps/alsijil/frontend/components/coursebook/documentation/DocumentationCompactDetails.vue create mode 100644 aleksis/apps/alsijil/frontend/components/coursebook/documentation/DocumentationFullDetails.vue diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/coursebook.graphql b/aleksis/apps/alsijil/frontend/components/coursebook/coursebook.graphql index 0701a39f3..db39747e9 100644 --- a/aleksis/apps/alsijil/frontend/components/coursebook/coursebook.graphql +++ b/aleksis/apps/alsijil/frontend/components/coursebook/coursebook.graphql @@ -60,6 +60,7 @@ query documentationsForCoursebook( dateEnd oldId canEdit + futureNotice canDelete } } diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/documentation/DocumentationCompactDetails.vue b/aleksis/apps/alsijil/frontend/components/coursebook/documentation/DocumentationCompactDetails.vue new file mode 100644 index 000000000..9160bd795 --- /dev/null +++ b/aleksis/apps/alsijil/frontend/components/coursebook/documentation/DocumentationCompactDetails.vue @@ -0,0 +1,30 @@ +<template> + <v-card outlined dense rounded="lg" v-bind="$attrs" v-on="$listeners"> + <div class="font-weight-medium mr-2"> + {{ $t("alsijil.coursebook.summary.topic") }}: + </div> + <div class="text-truncate">{{ documentation.topic || "–" }}</div> + + <div class="font-weight-medium mr-2"> + {{ $t("alsijil.coursebook.summary.homework.label") }}: + </div> + <div class="text-truncate">{{ documentation.homework || "–" }}</div> + + <div class="font-weight-medium mr-2"> + {{ $t("alsijil.coursebook.summary.group_note.label") }}: + </div> + <div class="text-truncate">{{ documentation.groupNote || "–" }}</div> + </v-card> +</template> + +<script> +export default { + name: "DocumentationCompactDetails", + props: { + documentation: { + type: Object, + required: true, + }, + }, +}; +</script> diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/documentation/DocumentationFullDetails.vue b/aleksis/apps/alsijil/frontend/components/coursebook/documentation/DocumentationFullDetails.vue new file mode 100644 index 000000000..ddb7ae276 --- /dev/null +++ b/aleksis/apps/alsijil/frontend/components/coursebook/documentation/DocumentationFullDetails.vue @@ -0,0 +1,34 @@ +<template> + <div v-bind="$attrs" v-on="$listeners"> + <v-card outlined dense rounded="lg" class="mb-2"> + <v-card-title class="text-subtitle-2 pb-1 font-weight-medium"> + {{ $t("alsijil.coursebook.summary.topic") }} + </v-card-title> + <v-card-text>{{ documentation.topic || "–" }}</v-card-text> + </v-card> + <v-card outlined dense rounded="lg" class="mb-2"> + <v-card-title class="text-subtitle-2 pb-1 font-weight-medium"> + {{ $t("alsijil.coursebook.summary.homework.label") }} + </v-card-title> + <v-card-text>{{ documentation.homework || "–" }}</v-card-text> + </v-card> + <v-card outlined dense rounded="lg"> + <v-card-title class="text-subtitle-2 pb-1 font-weight-medium"> + {{ $t("alsijil.coursebook.summary.group_note.label") }} + </v-card-title> + <v-card-text>{{ documentation.groupNote || "–" }}</v-card-text> + </v-card> + </div> +</template> + +<script> +export default { + name: "DocumentationFullDetails", + props: { + documentation: { + type: Object, + required: true, + }, + }, +}; +</script> diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/documentation/LessonInformation.vue b/aleksis/apps/alsijil/frontend/components/coursebook/documentation/LessonInformation.vue index 2632703da..04663954a 100644 --- a/aleksis/apps/alsijil/frontend/components/coursebook/documentation/LessonInformation.vue +++ b/aleksis/apps/alsijil/frontend/components/coursebook/documentation/LessonInformation.vue @@ -17,7 +17,13 @@ import PersonChip from "aleksis.core/components/person/PersonChip.vue"; </time> </div> </div> - <span :class="{ 'text-right': !largeGrid }"> + <span + :class="{ + 'text-right': !largeGrid, + 'text-subtitle-1': largeGrid, + 'font-weight-medium': largeGrid, + }" + > {{ documentation.course?.name }} </span> <div diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/documentation/LessonSummary.vue b/aleksis/apps/alsijil/frontend/components/coursebook/documentation/LessonSummary.vue index 52e921f33..f9c7aeb4b 100644 --- a/aleksis/apps/alsijil/frontend/components/coursebook/documentation/LessonSummary.vue +++ b/aleksis/apps/alsijil/frontend/components/coursebook/documentation/LessonSummary.vue @@ -5,7 +5,41 @@ class="d-flex flex-column flex-md-row align-stretch align-md-center gap justify-start fill-height" v-if="compact" > + <documentation-compact-details + v-bind="dialogActivator.attrs" + v-on="dialogActivator.on" + v-if=" + !documentation.canEdit && + (documentation.topic || + documentation.homework || + documentation.groupNote) + " + :documentation="documentation" + @click="$emit('open')" + :class="{ + 'flex-grow-1 min-width pa-1 read-only-grid': true, + 'full-width': $vuetify.breakpoint.mobile, + }" + /> + <v-alert + v-else-if="documentation.futureNotice" + type="warning" + outlined + class="min-width flex-grow-1 mb-0" + > + {{ $t("alsijil.coursebook.notices.future") }} + </v-alert> + <v-alert + v-else-if="!documentation.canEdit" + type="info" + outlined + class="min-width flex-grow-1 mb-0" + > + {{ $t("alsijil.coursebook.notices.no_entry") }} + </v-alert> + <v-text-field + v-if="documentation.canEdit" :class="{ 'flex-grow-1 min-width': true, 'full-width': $vuetify.breakpoint.mobile, @@ -18,7 +52,6 @@ @focusout="save" @keydown.enter="saveAndBlur" :loading="loading" - :readonly="!documentation.canEdit" > <template #append> <v-scroll-x-transition> @@ -33,6 +66,7 @@ 'flex-grow-1 max-width': true, 'full-width': $vuetify.breakpoint.mobile, }" + v-if="documentation.canEdit" > <v-card v-bind="dialogActivator.attrs" @@ -62,37 +96,44 @@ <!-- Are focusout & enter enough trigger? --> <v-text-field filled - v-if="!compact" + v-if="!compact && documentation.canEdit" :label="$t('alsijil.coursebook.summary.topic')" :value="documentation.topic" @input="topic = $event" - :readonly="!documentation.canEdit" /> <v-textarea filled auto-grow rows="3" clearable - v-if="!compact" + v-if="!compact && documentation.canEdit" :label="$t('alsijil.coursebook.summary.homework.label')" :value="documentation.homework" @input="homework = $event" - :readonly="!documentation.canEdit" /> <v-textarea filled auto-grow rows="3" clearable - v-if="!compact" + v-if="!compact && documentation.canEdit" :label="$t('alsijil.coursebook.summary.group_note.label')" :value="documentation.groupNote" @input="groupNote = $event" - :readonly="!documentation.canEdit" + /> + + <documentation-full-details + v-if="!compact && !documentation.canEdit" + :documentation="documentation" /> </div> </template> +<script setup> +import DocumentationCompactDetails from "./DocumentationCompactDetails.vue"; +import DocumentationFullDetails from "./DocumentationFullDetails.vue"; +</script> + <script> import createOrPatchMixin from "aleksis.core/mixins/createOrPatchMixin.js"; import documentationPartMixin from "./documentationPartMixin"; @@ -225,4 +266,10 @@ export default { display: grid; grid-template-columns: auto min-content; } + +.read-only-grid { + display: grid; + grid-template-columns: min-content auto; + grid-template-rows: auto; +} </style> diff --git a/aleksis/apps/alsijil/frontend/messages/en.json b/aleksis/apps/alsijil/frontend/messages/en.json index b09cde69c..f5b263f76 100644 --- a/aleksis/apps/alsijil/frontend/messages/en.json +++ b/aleksis/apps/alsijil/frontend/messages/en.json @@ -57,6 +57,10 @@ "empty": "No group note" } }, + "notices": { + "future": "Editing this lesson isn't allowed as this lesson is in the future.", + "no_entry": "There is no entry for this lesson yet." + }, "filter": { "own": "Only show own lessons", "groups": "Groups", diff --git a/aleksis/apps/alsijil/schema/documentation.py b/aleksis/apps/alsijil/schema/documentation.py index d115b03eb..6d623a39d 100644 --- a/aleksis/apps/alsijil/schema/documentation.py +++ b/aleksis/apps/alsijil/schema/documentation.py @@ -11,6 +11,7 @@ from graphene_django_cud.mutations import ( ) from guardian.shortcuts import get_objects_for_user +from aleksis.apps.alsijil.util.predicates import can_edit_documentation, is_in_allowed_time_range from aleksis.apps.chronos.models import LessonEvent from aleksis.apps.cursus.models import Subject from aleksis.apps.cursus.schema import CourseType, SubjectType @@ -50,6 +51,8 @@ class DocumentationType(PermissionsTypeMixin, DjangoFilterMixin, DjangoObjectTyp course = graphene.Field(CourseType, required=False) subject = graphene.Field(SubjectType, required=False) + future_notice = graphene.Boolean(required=False) + old_id = graphene.ID(required=False) @staticmethod @@ -58,6 +61,13 @@ class DocumentationType(PermissionsTypeMixin, DjangoFilterMixin, DjangoObjectTyp return root.teachers return root.lesson_event.teachers + @staticmethod + def resolve_future_notice(root: Documentation, info, **kwargs): + """Show whether the user can't edit the documentation because it's in the future.""" + return not is_in_allowed_time_range(info.context.user, root) and can_edit_documentation( + info.context.user, root + ) + @classmethod def get_queryset(cls, queryset, info): return get_objects_for_user(info.context.user, "alsijil.view_documentation", queryset) -- GitLab