Newer
Older
import SubstitutionDay from "./substitutions/SubstitutionDay.vue";
import CRUDIterator from "aleksis.core/components/generic/CRUDIterator.vue";
import DateField from "aleksis.core/components/generic/forms/DateField.vue";
import SubjectChip from "aleksis.apps.cursus/components/SubjectChip.vue";
import { DateTime } from "luxon";
import {
amendedLessonsFromAbsences,
groupsByOwner,
} from "./amendLesson.graphql";
</script>
<template>
<c-r-u-d-iterator
:gql-query="gqlQuery"
:gql-additional-query-args="gqlQueryArgs"
:gql-patch-mutation="gqlPatchMutation"
:get-patch-data="gqlGetPatchData"
i18n-key="chronos.substitutions.overview"
:enable-create="false"
:show-create="false"
:enable-delete="false"
:enable-edit="true"
:force-model-item-update="true"
@lastQuery="lastQuery = $event"
>
<template #additionalActions="{ attrs, on }">
<v-autocomplete
:items="groups"
item-text="name"
clearable
return-object
filled
dense
hide-details
:placeholder="$t('chronos.substitutions.overview.filter.groups')"
:loading="$apollo.queries.groups.loading"
:value="currentObj"
@input="changeSelection"
@click:clear="changeSelection"
/>
</template>
<substitution-day
v-for="{ date, substitutions, first, last } in groupSubstitutionsByDay(items)"
v-intersect="{
handler: intersectHandler(date, first, last),
options: {
rootMargin: '-' + topMargin + 'px 0px 0px 0px',
threshold: [0, 1],
},
}"
:date="date"
:substitutions="substitutions"
:lastQuery="lastQuery"
:focus-on-mount="initDate && (initDate.toMillis() === date.toMillis())"
@init="transition"
:key="'day-' + date"
ref="days"
/>
</template>
</c-r-u-d-iterator>
</template>
<script>
name: "SubstitutionOverview",
props: {
objId: {
type: [Number, String],
required: false,
default: null,
// Next two in ISODate
dateStart: {
type: String,
required: false,
default: "",
},
dateEnd: {
type: String,
required: false,
default: "",
/**
* Margin from substitution list to top of viewport in pixels
*/
topMargin: {
type: Number,
required: false,
default: 165,
},
},
data() {
return {
gqlQuery: amendedLessonsFromAbsences,
gqlPatchMutation: patchAmendLessonsWithAmends,
lastQuery: null,
groups: [],
initDate: false,
ready: false,
groupSubstitutionsByDay(substitutions) {
// => {dt: {date: dt, substitutions: doc ...} ...}
const substitutionsByDay = substitutions.reduce((byDay, substitution) => {
const day = DateTime.fromISO(substitution.datetimeStart).startOf("day");
byDay[day] ??= {date: day, substitutions: []};
byDay[day].substitutions.push(substitution);
// => [{date: dt, substitutions: doc ..., idx: idx, lastIdx: last-idx} ...]
// sorting is necessary since backend can send substitutions unordered
return Object.keys(substitutionsByDay)
.map((key, idx, {length}) => {
const day = substitutionsByDay[key];
day.first = idx === 0;
const lastIdx = length - 1;
day.last = idx === lastIdx;
return day;
});
},
intersectHandler(date, first, last) {
console.log("intersect", date, first, last);
},
transition() {
this.initDate = false
this.ready = true
gqlGetPatchData(item) {
return { id: item.id, teachers: item.teachers };
},
changeSelection(selection) {
this.$router.push({
name: "chronos.substitutionOvervievByTypeAndDate",
params: {
objId: selection.id,
dateStart: this.dateStart,
dateEnd: this.dateEnd,
},
});
},
},
computed: {
gqlQueryArgs() {
return {
objId: this.objId ? Number(this.objId) : null,
dateStart: this.dateStart,
dateEnd: this.dateEnd,
};
},
currentObj() {
return this.groups.find((o) => o.id === this.objId);
},
},
apollo: {
groups: groupsByOwner,
},
};