diff --git a/aleksis/apps/chronos/frontend/components/AmendLesson.vue b/aleksis/apps/chronos/frontend/components/AmendLesson.vue new file mode 100644 index 0000000000000000000000000000000000000000..aae3630e00d9c0a1baca177e401f7315d68fcca5 --- /dev/null +++ b/aleksis/apps/chronos/frontend/components/AmendLesson.vue @@ -0,0 +1,189 @@ +<template> + <v-card-actions v-if="checkPermission('chronos.edit_substitution_rule')"> + <edit-button + i18n-key="chronos.event.amend.edit_button" + @click="amendEvent.open = true" + /> + <delete-button + v-if="selectedEvent.meta.amended" + i18n-key="chronos.event.amend.delete_button" + @click="amendEvent.delete = true" + /> + <dialog-object-form + v-model="amendEvent.open" + :fields="amendEvent.fields" + :is-create="!selectedEvent.meta.amended" + createItemI18nKey="chronos.event.amend.title" + :gql-create-mutation="amendEvent.gqlCreateMutation" + :get-create-data="transformCreateData" + :default-item="amendEvent.default" + editItemI18nKey="chronos.event.amend.title" + :gql-patch-mutation="amendEvent.gqlPatchMutation" + :get-patch-data="transformPatchData" + :edit-item="initPatchData" + @cancel="amendEvent.open = false" + @save="updateOnSave()" + > + <template #subject.field="{ attrs, on, item }"> + <v-autocomplete + :disabled="item.cancelled" + :items="amendableSubjects" + item-text="name" + item-value="id" + v-bind="attrs" + v-on="on" + /> + </template> + <template #teachers.field="{ attrs, on, item }"> + <v-autocomplete + :disabled="item.cancelled" + multiple + :items="amendableTeachers" + item-text="fullName" + item-value="id" + v-bind="attrs" + v-on="on" + chips + deletable-chips + /> + </template> + <template #rooms.field="{ attrs, on, item }"> + <v-autocomplete + :disabled="item.cancelled" + multiple + :items="amendableRooms" + item-text="name" + item-value="id" + v-bind="attrs" + v-on="on" + chips + deletable-chips + /> + </template> + <template #cancelled.field="{ attrs, on }"> + <v-checkbox v-bind="attrs" v-on="on" /> + </template> + <template #comment.field="{ attrs, on }"> + <v-textarea v-bind="attrs" v-on="on" /> + </template> + </dialog-object-form> + <delete-dialog + deleteSuccessMessageI18nKey="chronos.event.amend.delete_success" + :gql-mutation="amendEvent.gqlDeleteMutation" + v-model="amendEvent.delete" + :item="selectedEvent.meta" + @success="updateOnSave()" + > + <template #title> + {{ $t("chronos.event.amend.delete_dialog") }} + </template> + </delete-dialog> + </v-card-actions> +</template> + +<script> +import permissionsMixin from "aleksis.core/mixins/permissions.js"; +import EditButton from "aleksis.core/components/generic/buttons/EditButton.vue"; +import DialogObjectForm from "aleksis.core/components/generic/dialogs/DialogObjectForm.vue"; +import DeleteButton from "aleksis.core/components/generic/buttons/DeleteButton.vue"; +import DeleteDialog from "aleksis.core/components/generic/dialogs/DeleteDialog.vue"; +import { + gqlSubjects, + gqlPersons, + gqlRooms, + createAmendLesson, + patchAmendLesson, + deleteAmendLesson, +} from "./amendLesson.graphql"; + +export default { + name: "AmendLesson", + components: { + EditButton, + DialogObjectForm, + DeleteButton, + DeleteDialog, + }, + mixins: [permissionsMixin], + data() { + return { + amendEvent: { + open: false, + fields: [ + { + text: this.$t("chronos.event.amend.subject"), + value: "subject", + }, + { + text: this.$t("chronos.event.amend.teachers"), + value: "teachers", + }, + { + text: this.$t("chronos.event.amend.rooms"), + value: "rooms", + }, + { + text: this.$t("chronos.event.amend.cancelled"), + value: "cancelled", + }, + { + text: this.$t("chronos.event.amend.comment"), + value: "comment", + }, + ], + default: { + cancelled: this.selectedEvent.meta.cancelled, + comment: this.selectedEvent.meta.comment, + }, + gqlCreateMutation: createAmendLesson, + gqlPatchMutation: patchAmendLesson, + delete: false, + gqlDeleteMutation: deleteAmendLesson, + }, + }; + }, + methods: { + transformCreateData(item) { + return { + ...item, + amends: this.selectedEvent.meta.id, + datetimeStart: this.selectedEvent.startDateTime.toUTC().toISO(), + datetimeEnd: this.selectedEvent.endDateTime.toUTC().toISO(), + }; + }, + transformPatchData(item) { + let { id, __typename, cancelled, ...patchItem } = item; + return { + ...patchItem, + // Normalize cancelled, v-checkbox returns null & does not + // honor false-value. + cancelled: cancelled ? true : false, + }; + }, + updateOnSave() { + this.$emit('refreshCalendar'); + this.model = false; + }, + }, + computed: { + initPatchData() { + return { + id: this.selectedEvent.meta.id, + subject: this.selectedEvent.meta.subject?.id.toString(), + teachers: this.selectedEvent.meta.teachers.map((teacher) => teacher.id.toString()), + rooms: this.selectedEvent.meta.rooms.map((room) => room.id.toString()), + cancelled: this.selectedEvent.meta.cancelled, + comment: this.selectedEvent.meta.comment, + }; + }, + }, + apollo: { + amendableSubjects: gqlSubjects, + amendableTeachers: gqlPersons, + amendableRooms: gqlRooms, + }, + mounted() { + this.addPermissions(["chronos.edit_substitution_rule"]); + }, +}; +</script> diff --git a/aleksis/apps/chronos/frontend/components/calendar_feeds/details/LessonDetails.vue b/aleksis/apps/chronos/frontend/components/calendar_feeds/details/LessonDetails.vue index 110a40cd87f1c4bf3580417f71829d91b15da7af..c8df491e7f6c182785f91103f9c08c6382788a7e 100644 --- a/aleksis/apps/chronos/frontend/components/calendar_feeds/details/LessonDetails.vue +++ b/aleksis/apps/chronos/frontend/components/calendar_feeds/details/LessonDetails.vue @@ -96,113 +96,23 @@ </v-list-item-title> </v-list-item-content> </v-list-item> - <v-card-actions v-if="checkPermission('chronos.edit_substitution_rule')"> - <edit-button - i18n-key="chronos.event.amend.edit_button" - @click="amendEvent.open = true" - /> - <delete-button - v-if="selectedEvent.meta.amended" - i18n-key="chronos.event.amend.delete_button" - @click="amendEvent.delete = true" - /> - <dialog-object-form - v-model="amendEvent.open" - :fields="amendEvent.fields" - :is-create="!selectedEvent.meta.amended" - createItemI18nKey="chronos.event.amend.title" - :gql-create-mutation="amendEvent.gqlCreateMutation" - :get-create-data="transformCreateData" - :default-item="amendEvent.default" - editItemI18nKey="chronos.event.amend.title" - :gql-patch-mutation="amendEvent.gqlPatchMutation" - :get-patch-data="transformPatchData" - :edit-item="initPatchData" - @cancel="amendEvent.open = false" - @save="updateOnSave()" - > - <template #subject.field="{ attrs, on, item }"> - <v-autocomplete - :disabled="item.cancelled" - :items="amendableSubjects" - item-text="name" - item-value="id" - v-bind="attrs" - v-on="on" - /> - </template> - <template #teachers.field="{ attrs, on, item }"> - <v-autocomplete - :disabled="item.cancelled" - multiple - :items="amendableTeachers" - item-text="fullName" - item-value="id" - v-bind="attrs" - v-on="on" - chips - deletable-chips - /> - </template> - <template #rooms.field="{ attrs, on, item }"> - <v-autocomplete - :disabled="item.cancelled" - multiple - :items="amendableRooms" - item-text="name" - item-value="id" - v-bind="attrs" - v-on="on" - chips - deletable-chips - /> - </template> - <template #cancelled.field="{ attrs, on }"> - <v-checkbox v-bind="attrs" v-on="on" /> - </template> - <template #comment.field="{ attrs, on }"> - <v-textarea v-bind="attrs" v-on="on" /> - </template> - </dialog-object-form> - <delete-dialog - deleteSuccessMessageI18nKey="chronos.event.amend.delete_success" - :gql-mutation="amendEvent.gqlDeleteMutation" - v-model="amendEvent.delete" - :item="selectedEvent.meta" - @success="updateOnSave()" - > - <template #title> - {{ $t("chronos.event.amend.delete_dialog") }} - </template> - </delete-dialog> - </v-card-actions> + <amend-lesson /> </template> </base-calendar-feed-details> </template> <script> -import permissionsMixin from "aleksis.core/mixins/permissions.js"; import calendarFeedDetailsMixin from "aleksis.core/mixins/calendarFeedDetails.js"; import BaseCalendarFeedDetails from "aleksis.core/components/calendar/BaseCalendarFeedDetails.vue"; import CalendarStatusChip from "aleksis.core/components/calendar/CalendarStatusChip.vue"; import CancelledCalendarStatusChip from "aleksis.core/components/calendar/CancelledCalendarStatusChip.vue"; -import EditButton from "aleksis.core/components/generic/buttons/EditButton.vue"; -import DialogObjectForm from "aleksis.core/components/generic/dialogs/DialogObjectForm.vue"; -import DeleteButton from "aleksis.core/components/generic/buttons/DeleteButton.vue"; -import DeleteDialog from "aleksis.core/components/generic/dialogs/DeleteDialog.vue"; import LessonRelatedObjectChip from "../../LessonRelatedObjectChip.vue"; import lessonEvent from "../mixins/lessonEvent"; import LessonEventSubject from "../../LessonEventSubject.vue"; -import { - gqlSubjects, - gqlPersons, - gqlRooms, - createAmendLesson, - patchAmendLesson, - deleteAmendLesson, -} from "../../amendLesson.graphql"; + +import AmendLesson from "../../AmendLesson.vue"; export default { name: "LessonDetails", @@ -212,91 +122,8 @@ export default { BaseCalendarFeedDetails, CalendarStatusChip, CancelledCalendarStatusChip, - EditButton, - DialogObjectForm, - DeleteButton, - DeleteDialog, - }, - mixins: [permissionsMixin, calendarFeedDetailsMixin, lessonEvent], - data() { - return { - amendEvent: { - open: false, - fields: [ - { - text: this.$t("chronos.event.amend.subject"), - value: "subject", - }, - { - text: this.$t("chronos.event.amend.teachers"), - value: "teachers", - }, - { - text: this.$t("chronos.event.amend.rooms"), - value: "rooms", - }, - { - text: this.$t("chronos.event.amend.cancelled"), - value: "cancelled", - }, - { - text: this.$t("chronos.event.amend.comment"), - value: "comment", - }, - ], - default: { - cancelled: this.selectedEvent.meta.cancelled, - comment: this.selectedEvent.meta.comment, - }, - gqlCreateMutation: createAmendLesson, - gqlPatchMutation: patchAmendLesson, - delete: false, - gqlDeleteMutation: deleteAmendLesson, - }, - }; - }, - methods: { - transformCreateData(item) { - return { - ...item, - amends: this.selectedEvent.meta.id, - datetimeStart: this.selectedEvent.startDateTime.toUTC().toISO(), - datetimeEnd: this.selectedEvent.endDateTime.toUTC().toISO(), - }; - }, - transformPatchData(item) { - let { id, __typename, cancelled, ...patchItem } = item; - return { - ...patchItem, - // Normalize cancelled, v-checkbox returns null & does not - // honor false-value. - cancelled: cancelled ? true : false, - }; - }, - updateOnSave() { - this.$emit('refreshCalendar'); - this.model = false; - }, - }, - computed: { - initPatchData() { - return { - id: this.selectedEvent.meta.id, - subject: this.selectedEvent.meta.subject?.id.toString(), - teachers: this.selectedEvent.meta.teachers.map((teacher) => teacher.id.toString()), - rooms: this.selectedEvent.meta.rooms.map((room) => room.id.toString()), - cancelled: this.selectedEvent.meta.cancelled, - comment: this.selectedEvent.meta.comment, - }; - }, - }, - apollo: { - amendableSubjects: gqlSubjects, - amendableTeachers: gqlPersons, - amendableRooms: gqlRooms, - }, - mounted() { - this.addPermissions(["chronos.edit_substitution_rule"]); + AmendLesson, }, + mixins: [calendarFeedDetailsMixin, lessonEvent], }; </script>