diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/coursebook.graphql b/aleksis/apps/alsijil/frontend/components/coursebook/coursebook.graphql index f78545d8db703b193e313cb36f7293d419bbcd92..47518c0cb5ae893d338f9f24f5f1152308a6a1f3 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 5bbc21c0de53b613986c30360e853ee6720526b5..2bcc1b4ff52870897bd86aa81ea6cb127f0b505c 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 890e557e162c64868de3a0362b248cea4c2604d8..c008ca893df909f3bd68028fb80af154fbf61a0e 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 f4ef410e2f12f17d7e284178e7a2b6acc8022e66..3710a45f83c7d267ba281f95d2cbbaaae95f46f3 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 0000000000000000000000000000000000000000..0e00a61a6cbcd5fbadbe5638a9138730acbf1369 --- /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 17769c47dbb20ca106eab4f05b046c51c158498a..dfaf794851353f2a2d490cf77b7d17bea76dfc5e 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}",