diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/absences/AbsenceCreationForm.vue b/aleksis/apps/alsijil/frontend/components/coursebook/absences/AbsenceCreationForm.vue index 902a33f2582cc30a76d8145e619da432d0092a4c..c8f446807e490128b2b901a0c2fc0d42d8ca1d59 100644 --- a/aleksis/apps/alsijil/frontend/components/coursebook/absences/AbsenceCreationForm.vue +++ b/aleksis/apps/alsijil/frontend/components/coursebook/absences/AbsenceCreationForm.vue @@ -24,32 +24,46 @@ </div> </v-row> <v-row> - <v-col cols="12" :sm="6" class="pl-0"> + <v-col cols="12" :sm="startPeriods ? 4 : 6" class="pl-0"> <div aria-required="true"> <date-time-field :label="$t('forms.labels.start')" - :max-date="maxStartDate" - :max-time="maxStartTime" - :limit-selectable-range="false" :rules="$rules().required.build()" - :value="startDate" + :value="start.toISO()" @input="handleStartDate" /> </div> </v-col> - <v-col cols="12" :sm="6" class="pr-0"> + <v-col cols="12" :sm="2" v-if="startPeriods" align-self="end"> + <v-select + :label="$t('lesrooster.slot.period')" + :items="startPeriods" + item-text="period" + :value="startSlot" + @input="handleStartSlot" + return-object + /> + </v-col> + <v-col cols="12" :sm="endPeriods ? 4 : 6" class="pr-0"> <div aria-required="true"> <date-time-field :label="$t('forms.labels.end')" - :min-date="minEndDate" - :min-time="minEndTime" - :limit-selectable-range="false" :rules="$rules().required.build()" - :value="endDate" + :value="end.toISO()" @input="handleEndDate" /> </div> </v-col> + <v-col cols="12" :sm="2" v-if="endPeriods" align-self="end"> + <v-select + :label="$t('lesrooster.slot.period')" + :items="endPeriods" + item-text="period" + :value="endSlot" + @input="handleEndSlot" + return-object + /> + </v-col> </v-row> <v-row> <v-text-field @@ -75,7 +89,10 @@ <script> import AbsenceReasonGroupSelect from "aleksis.apps.kolego/components/AbsenceReasonGroupSelect.vue"; import DateTimeField from "aleksis.core/components/generic/forms/DateTimeField.vue"; -import { persons } from "./absenceCreation.graphql"; +import { + periodsByDay, + persons, +} from "./absenceCreation.graphql"; import formRulesMixin from "aleksis.core/mixins/formRulesMixin.js"; import { DateTime } from "luxon"; @@ -96,6 +113,13 @@ export default { ], apollo: { allPersons: persons, + periodsByDay: { + query: periodsByDay, + result({ data: { periodsByDay } }) { + this.handleStartDate(this.start); + this.handleEndDate(this.end); + }, + }, }, props: { persons: { @@ -123,60 +147,91 @@ export default { required: true, }, }, + data() { + return { + startDT: DateTime.fromISO(this.startDate), + endDT: DateTime.fromISO(this.endDate), + startPeriods: false, + endPeriods: false, + startSlot: undefined, + endSlot: undefined, + }; + }, computed: { - maxStartTime() { - // Only if on the same day - const start = DateTime.fromISO(this.startDate); - const end = DateTime.fromISO(this.endDate); - - if (start.day !== end.day) return; - - return end.minus({ minutes: 5 }).toFormat("HH:mm"); + start: { + get() { + return this.startDT; + }, + set(dt) { + this.startDT = dt; + if (dt >= this.end) { + this.end = dt.plus({ minutes: 5 }); + } + this.$emit("start-date", dt.toISO()); + console.log("Set start", this.startDT.toISO()); + }, }, - minEndTime() { - // Only if on the same day - const start = DateTime.fromISO(this.startDate); - const end = DateTime.fromISO(this.endDate); - - if (start.day !== end.day) return; - - return start.plus({ minutes: 5 }).toFormat("HH:mm"); - }, - maxStartDate() { - const end = DateTime.fromISO(this.endDate); - return end.toISODate(); - }, - minEndDate() { - const start = DateTime.fromISO(this.startDate); - return start.toISODate(); + end: { + get() { + return this.endDT; + }, + set(dt) { + this.endDT = dt; + if (dt <= this.start) { + this.start = dt.minus({ minutes: 5 }); + } + this.$emit("end-date", dt.toISO()); + }, }, }, methods: { - handleStartDate(startDate) { - const parsedStart = DateTime.fromISO(startDate); - const parsedEnd = DateTime.fromISO(this.endDate); - if (parsedStart >= parsedEnd) { - this.$emit( - "end-date", - parsedStart.plus({ minutes: 5 }).toISO({ suppressSeconds: true }), - ); + getPeriodsForWeekday(weekday) { + // Adapt from python conventions + const pythonWeekday = weekday - 1; + return this.periodsByDay.find((period) => period.weekday === pythonWeekday).periods; + }, + handleStartDate(date) { + console.log("handleStartDate", date); + this.start = DateTime.fromISO(date); + + if (this.periodsByDay.length > 0) { + // Select periods for day + this.startPeriods = this.getPeriodsForWeekday(this.start.weekday); + // Sync PeriodSelect + const startTime = this.start.toFormat("HH:mm:ss") + console.log("syncing to ", startTime) + this.startSlot = this.startPeriods.find((period) => period.timeStart === startTime) + console.log("startSlot ", this.startSlot) } - this.$emit("start-date", startDate); - this.$refs.form.resetValidation(); - this.$refs.form.validate(); }, - handleEndDate(endDate) { - const parsedStart = DateTime.fromISO(this.startDate); - const parsedEnd = DateTime.fromISO(endDate); - if (parsedEnd <= parsedStart) { - this.$emit( - "start-date", - parsedEnd.minus({ minutes: 5 }).toISO({ suppressSeconds: true }), - ); + handleEndDate(date) { + this.end = DateTime.fromISO(date); + + if (this.periodsByDay.length > 0) { + // Select periods for day + this.endPeriods = this.getPeriodsForWeekday(this.end.weekday); + // Sync PeriodSelect + const endTime = this.end.toFormat("HH:mm:ss") + this.endSlot = this.endPeriods.find((period) => period.endTime === endTime) } - this.$emit("end-date", endDate); - this.$refs.form.resetValidation(); - this.$refs.form.validate(); + }, + handleStartSlot(slot) { + // Sync TimeSelect + const startTime = DateTime.fromISO(slot.timeStart) + this.start = this.start.set({ + hour: startTime.hour, + minute: startTime.minute, + second: startTime.second, + }); + }, + handleEndSlot(slot) { + // Sync TimeSelect + const endTime = DateTime.fromISO(slot.timeEnd) + this.end = this.end.set({ + hour: endTime.hour, + minute: endTime.minute, + second: endTime.second, + }); }, }, }; diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/absences/absenceCreation.graphql b/aleksis/apps/alsijil/frontend/components/coursebook/absences/absenceCreation.graphql index 5a520453f35062d49edd5eb82aca291384e2f739..e164d0868c4bd378416941becb0e1e45a88eaaa9 100644 --- a/aleksis/apps/alsijil/frontend/components/coursebook/absences/absenceCreation.graphql +++ b/aleksis/apps/alsijil/frontend/components/coursebook/absences/absenceCreation.graphql @@ -6,6 +6,17 @@ query persons { } } +query periodsByDay { + periodsByDay: periodsByDay { + weekday + periods { + period + timeStart + timeEnd + } + } +} + query lessonsForPersons($persons: [ID]!, $start: DateTime!, $end: DateTime!) { items: lessonsForPersons(persons: $persons, start: $start, end: $end) { id