diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/Coursebook.vue b/aleksis/apps/alsijil/frontend/components/coursebook/Coursebook.vue index 571a1e21ddbf8ae1f0a23f98071ad375457fadc3..97bd708a74af10d976e99e2b02ea223b95eb1c27 100644 --- a/aleksis/apps/alsijil/frontend/components/coursebook/Coursebook.vue +++ b/aleksis/apps/alsijil/frontend/components/coursebook/Coursebook.vue @@ -24,6 +24,7 @@ <absence-reason-buttons allow-empty empty-value="present" + @input="handleMultipleAction" /> </v-card-actions> </v-card> @@ -69,6 +70,8 @@ import CoursebookEmptyMessage from "./CoursebookEmptyMessage.vue"; import DocumentationModal from "./documentation/DocumentationModal.vue"; import DocumentationAbsencesModal from "./absences/DocumentationAbsencesModal.vue"; +import updateParticipationMixin from "./absences/updateParticipationMixin.js"; + export default { name: "Coursebook", components: { @@ -80,6 +83,7 @@ export default { DocumentationAbsencesModal, InfiniteScrollingDateSortedCRUDIterator, }, + mixins: [updateParticipationMixin], props: { filterType: { type: String, @@ -207,7 +211,16 @@ export default { if (index>=0) { this.selectedParticipations.splice(index, 1); } - } + }, + handleMultipleAction(absenceReasonId) { + this.loadSelectedParticiptions = true; + this.sendToServer(this.selectedParticipations, "absenceReason", absenceReasonId); + this.$once("save", this.resetMultipleAction); + }, + resetMultipleAction() { + this.loadSelectedParticiptions = false; + this.$set(this.selectedParticipations, []); + }, }, }; </script> diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/absences/ManageStudentsDialog.vue b/aleksis/apps/alsijil/frontend/components/coursebook/absences/ManageStudentsDialog.vue index a9f4fb0c7411407a5e98cdfe4a386f3b2c7cf678..373fd6fcd9a63938b549b4ecfb17f006f7ebc295 100644 --- a/aleksis/apps/alsijil/frontend/components/coursebook/absences/ManageStudentsDialog.vue +++ b/aleksis/apps/alsijil/frontend/components/coursebook/absences/ManageStudentsDialog.vue @@ -4,10 +4,8 @@ import AbsenceReasonChip from "aleksis.apps.kolego/components/AbsenceReasonChip. import AbsenceReasonGroupSelect from "aleksis.apps.kolego/components/AbsenceReasonGroupSelect.vue"; import CancelButton from "aleksis.core/components/generic/buttons/CancelButton.vue"; import MobileFullscreenDialog from "aleksis.core/components/generic/dialogs/MobileFullscreenDialog.vue"; -import mutateMixin from "aleksis.core/mixins/mutateMixin.js"; -import documentationPartMixin from "../documentation/documentationPartMixin"; +import updateParticipationMixin from "./updateParticipationMixin.js"; import LessonInformation from "../documentation/LessonInformation.vue"; -import { updateParticipationStatuses } from "./participationStatus.graphql"; import SlideIterator from "aleksis.core/components/generic/SlideIterator.vue"; export default { @@ -22,7 +20,7 @@ export default { MobileFullscreenDialog, SlideIterator, }, - mixins: [documentationPartMixin, mutateMixin], + mixins: [updateParticipationMixin], data() { return { dialog: false, @@ -45,58 +43,6 @@ export default { }, }, methods: { - sendToServer(participations, field, value) { - if (field !== "absenceReason") return; - - this.mutate( - updateParticipationStatuses, - { - input: participations.map((participation) => ({ - id: participation.id, - absenceReason: value === "present" ? null : value, - })), - }, - (storedDocumentations, incomingStatuses) => { - const documentation = storedDocumentations.find( - (doc) => doc.id === this.documentation.id, - ); - - incomingStatuses.forEach((newStatus) => { - const participationStatus = documentation.participations.find( - (part) => part.id === newStatus.id, - ); - participationStatus.absenceReason = newStatus.absenceReason; - participationStatus.isOptimistic = newStatus.isOptimistic; - }); - - return storedDocumentations; - }, - // { - // optimisticResponse: { - // updateParticipationStatuses: { - // items: [ - // { - // id: participation.id, - // isOptimistic: true, - // relatedDocumentation: { - // id: this.documentation.id, - // __typename: "DocumentationType", - // }, - // absenceReason: value === "present" ? null : { - // id: value, - // name: "", - // shortName: "", - // __typename: "AbsenceReasonType", - // }, - // __typename: "ParticipationStatusType", - // }, - // ], - // __typename: "ParticipationStatusBatchPatchMutation", - // }, - // }, - // }, - ); - }, handleMultipleAction(absenceReasonId) { this.loadSelected = true; this.sendToServer(this.selected, "absenceReason", absenceReasonId); diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/absences/updateParticipationMixin.js b/aleksis/apps/alsijil/frontend/components/coursebook/absences/updateParticipationMixin.js new file mode 100644 index 0000000000000000000000000000000000000000..6aab0c9bf83d097916fc4c866b8cf836d9d9c87e --- /dev/null +++ b/aleksis/apps/alsijil/frontend/components/coursebook/absences/updateParticipationMixin.js @@ -0,0 +1,64 @@ +/** + * Mixin to provide shared functionality needed to update participations +*/ +import { updateParticipationStatuses } from "./participationStatus.graphql"; +import mutateMixin from "aleksis.core/mixins/mutateMixin.js"; +import documentationPartMixin from "../documentation/documentationPartMixin"; + +export default { + mixins: [documentationPartMixin, mutateMixin], + methods: { + sendToServer(participations, field, value) { + if (field !== "absenceReason") return; + + this.mutate( + updateParticipationStatuses, + { + input: participations.map((participation) => ({ + id: Object.hasOwn(participation, "id") ? participation.id : participation, + absenceReason: value === "present" ? null : value, + })), + }, + (storedDocumentations, incomingStatuses) => { + const documentation = storedDocumentations.find( + (doc) => doc.id === this.documentation.id, + ); + + incomingStatuses.forEach((newStatus) => { + const participationStatus = documentation.participations.find( + (part) => part.id === newStatus.id, + ); + participationStatus.absenceReason = newStatus.absenceReason; + participationStatus.isOptimistic = newStatus.isOptimistic; + }); + + return storedDocumentations; + }, + // { + // optimisticResponse: { + // updateParticipationStatuses: { + // items: [ + // { + // id: participation.id, + // isOptimistic: true, + // relatedDocumentation: { + // id: this.documentation.id, + // __typename: "DocumentationType", + // }, + // absenceReason: value === "present" ? null : { + // id: value, + // name: "", + // shortName: "", + // __typename: "AbsenceReasonType", + // }, + // __typename: "ParticipationStatusType", + // }, + // ], + // __typename: "ParticipationStatusBatchPatchMutation", + // }, + // }, + // }, + ); + }, + }, +};