From 03e2286cccf54687cecb4f4b633a53d2a5b863dc Mon Sep 17 00:00:00 2001 From: Hangzhi Yu <hangzhi@protonmail.com> Date: Thu, 20 Jun 2024 01:37:12 +0200 Subject: [PATCH] Make subject field editable --- .../components/coursebook/coursebook.graphql | 7 +++ .../documentation/Documentation.vue | 6 +- .../documentation/LessonInformation.vue | 61 ++++++++++++++----- .../documentation/LessonSummary.vue | 29 ++------- .../documentationCacheUpdateMixin.js | 29 +++++++++ .../apps/alsijil/frontend/messages/en.json | 5 ++ 6 files changed, 99 insertions(+), 38 deletions(-) create mode 100644 aleksis/apps/alsijil/frontend/components/coursebook/documentation/documentationCacheUpdateMixin.js diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/coursebook.graphql b/aleksis/apps/alsijil/frontend/components/coursebook/coursebook.graphql index f78545d8d..47518c0cb 100644 --- a/aleksis/apps/alsijil/frontend/components/coursebook/coursebook.graphql +++ b/aleksis/apps/alsijil/frontend/components/coursebook/coursebook.graphql @@ -146,6 +146,13 @@ mutation createOrUpdateDocumentations($input: [DocumentationInputType]!) { tardiness isOptimistic } + subject { + id + name + shortName + colourFg + colourBg + } } } } diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/documentation/Documentation.vue b/aleksis/apps/alsijil/frontend/components/coursebook/documentation/Documentation.vue index 5bbc21c0d..2bcc1b4ff 100644 --- a/aleksis/apps/alsijil/frontend/components/coursebook/documentation/Documentation.vue +++ b/aleksis/apps/alsijil/frontend/components/coursebook/documentation/Documentation.vue @@ -1,7 +1,11 @@ <template> <v-card :class="{ 'my-1 full-width': true, 'd-flex flex-column': !compact }"> <v-card-title v-if="!compact"> - <lesson-information v-bind="documentationPartProps" /> + <lesson-information + v-bind="{ ...$attrs, ...documentationPartProps }" + :is-create="false" + :gql-patch-mutation="documentationsMutation" + /> </v-card-title> <v-card-text diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/documentation/LessonInformation.vue b/aleksis/apps/alsijil/frontend/components/coursebook/documentation/LessonInformation.vue index 890e557e1..c008ca893 100644 --- a/aleksis/apps/alsijil/frontend/components/coursebook/documentation/LessonInformation.vue +++ b/aleksis/apps/alsijil/frontend/components/coursebook/documentation/LessonInformation.vue @@ -1,6 +1,8 @@ <script setup> import DocumentationStatus from "./DocumentationStatus.vue"; import PersonChip from "aleksis.core/components/person/PersonChip.vue"; +import SubjectChip from "aleksis.apps.cursus/components/SubjectChip.vue"; +import SubjectField from "aleksis.apps.cursus/components/SubjectField.vue"; </script> <template> @@ -37,16 +39,29 @@ import PersonChip from "aleksis.core/components/person/PersonChip.vue"; 'justify-start': !largeGrid, }" > - <subject-chip - v-if="documentation.subject" - :subject="documentation.subject" - v-bind="compact ? dialogActivator.attrs : {}" - v-on="compact ? dialogActivator.on : {}" - :class="{ - 'text-decoration-line-through': documentation.amends?.cancelled, - }" - :disabled="documentation.amends?.cancelled" - /> + <v-slide-x-transition> + <subject-chip + v-if="documentation.subject && !subjectField" + :subject="documentation.subject" + :append-icon="compact ? '' : '$edit'" + :disabled="loading" + v-bind="compact ? dialogActivator.attrs : {}" + v-on=" + compact + ? dialogActivator.on + : { click: () => (subjectField = true) } + " + /> + <subject-field + v-else-if="documentation.canEdit" + :value="documentation.subject" + :enable-create="false" + dense + filled + hide-details + @input="editSubject" + /> + </v-slide-x-transition> <subject-chip v-if=" documentation?.amends?.amends?.subject && @@ -88,20 +103,38 @@ import PersonChip from "aleksis.core/components/person/PersonChip.vue"; </template> <script> -import SubjectChip from "aleksis.apps.cursus/components/SubjectChip.vue"; import { DateTime } from "luxon"; + +import createOrPatchMixin from "aleksis.core/mixins/createOrPatchMixin.js"; + import documentationPartMixin from "./documentationPartMixin"; +import documentationCacheUpdateMixin from "./documentationCacheUpdateMixin"; export default { name: "LessonInformation", - mixins: [documentationPartMixin], - components: { - SubjectChip, + mixins: [ + createOrPatchMixin, + documentationCacheUpdateMixin, + documentationPartMixin, + ], + data() { + return { + subjectField: false, + }; }, methods: { toDateTime(dateString) { return DateTime.fromISO(dateString); }, + editSubject(subject) { + this.subjectField = false; + this.createOrPatch([ + { + id: this.documentation.id, + subject: subject.id, + }, + ]); + }, }, computed: { largeGrid() { diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/documentation/LessonSummary.vue b/aleksis/apps/alsijil/frontend/components/coursebook/documentation/LessonSummary.vue index f4ef410e2..3710a45f8 100644 --- a/aleksis/apps/alsijil/frontend/components/coursebook/documentation/LessonSummary.vue +++ b/aleksis/apps/alsijil/frontend/components/coursebook/documentation/LessonSummary.vue @@ -146,10 +146,15 @@ import DocumentationFullDetails from "./DocumentationFullDetails.vue"; <script> import createOrPatchMixin from "aleksis.core/mixins/createOrPatchMixin.js"; import documentationPartMixin from "./documentationPartMixin"; +import documentationCacheUpdateMixin from "./documentationCacheUpdateMixin"; export default { name: "LessonSummary", - mixins: [createOrPatchMixin, documentationPartMixin], + mixins: [ + createOrPatchMixin, + documentationCacheUpdateMixin, + documentationPartMixin, + ], emits: ["open"], data() { return { @@ -161,28 +166,6 @@ export default { }; }, methods: { - handleUpdateAfterCreateOrPatch(itemId) { - return (cached, incoming) => { - for (const object of incoming) { - console.log("summary: handleUpdateAfterCreateOrPatch", object); - // Replace the current documentation - const index = cached.findIndex( - (o) => o[itemId] === this.documentation.id, - ); - // merged with the incoming partial documentation - // if creation of proper documentation from dummy one, set ID of documentation currently being edited as oldID so that key in coursebook doesn't change - cached[index] = { - ...this.documentation, - ...object, - oldId: - this.documentation.id !== object.id - ? this.documentation.id - : this.documentation.oldId, - }; - } - return cached; - }; - }, handleAppendIconSuccess() { this.topicError = null; this.appendIcon = "$success"; diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/documentation/documentationCacheUpdateMixin.js b/aleksis/apps/alsijil/frontend/components/coursebook/documentation/documentationCacheUpdateMixin.js new file mode 100644 index 000000000..0e00a61a6 --- /dev/null +++ b/aleksis/apps/alsijil/frontend/components/coursebook/documentation/documentationCacheUpdateMixin.js @@ -0,0 +1,29 @@ +/** + * Mixin to provide the cache update functionality used after creating or patching documentations + */ +export default { + methods: { + handleUpdateAfterCreateOrPatch(itemId) { + return (cached, incoming) => { + for (const object of incoming) { + console.log("summary: handleUpdateAfterCreateOrPatch", object); + // Replace the current documentation + const index = cached.findIndex( + (o) => o[itemId] === this.documentation.id, + ); + // merged with the incoming partial documentation + // if creation of proper documentation from dummy one, set ID of documentation currently being edited as oldID so that key in coursebook doesn't change + cached[index] = { + ...this.documentation, + ...object, + oldId: + this.documentation.id !== object.id + ? this.documentation.id + : this.documentation.oldId, + }; + } + return cached; + }; + }, + }, +}; diff --git a/aleksis/apps/alsijil/frontend/messages/en.json b/aleksis/apps/alsijil/frontend/messages/en.json index 17769c47d..dfaf79485 100644 --- a/aleksis/apps/alsijil/frontend/messages/en.json +++ b/aleksis/apps/alsijil/frontend/messages/en.json @@ -90,6 +90,11 @@ }, "absences_exist": "Only show lessons with absent participants" }, + "information": { + "subject": { + "field": "Edit subject" + } + }, "present_number": "{present}/{total} present", "no_data": "No lessons for the selected groups and courses in this period", "no_results": "No search results for {search}", -- GitLab