<template> <c-r-u-d-iterator i18n-key="alsijil.coursebook" :gql-query="gqlQuery" :gql-additional-query-args="gqlQueryArgs" :enable-create="false" :enable-edit="false" @lastQuery="lastQuery = $event" ref="iterator" > <template #additionalActions="{ attrs, on }"> <v-autocomplete :items="selectable" item-text="name" clearable return-object filled dense hide-details :placeholder="$t('alsijil.coursebook.filter.filter_for_obj')" :loading="selectLoading" :value="currentObj" @input="changeSelection" @click:clear="changeSelection" /> <v-switch :loading="selectLoading" :label="$t('alsijil.coursebook.filter.own')" :input-value="filterType === 'my'" @change=" changeSelection({ filterType: $event ? 'my' : 'all', type: objType, id: objId, }) " /> </template> <template #default="{ items }"> <v-list-item v-for="day in groupDocsByDay(items)" two-line> <v-list-item-content> <v-list-item-title>{{ $d(day[0], "short") }}</v-list-item-title> <v-list max-width="100%"> <v-list-item v-for="doc in day.slice(1)"> <documentation-modal :documentation="doc" :affected-query="lastQuery" /> </v-list-item> </v-list> </v-list-item-content> </v-list-item> </template> <template #loading> <CoursebookLoader /> </template> <template #no-data> <CoursebookEmptyMessage icon="mdi-book-off-outline"> {{ $t("alsijil.coursebook.no_data") }} </CoursebookEmptyMessage> </template> <template #no-results> <CoursebookEmptyMessage icon="mdi-book-alert-outline"> {{ $t("alsijil.coursebook.no_results", { search: $refs.iterator.search }) }} </CoursebookEmptyMessage> </template> </c-r-u-d-iterator> </template> <script> import CRUDIterator from "aleksis.core/components/generic/CRUDIterator.vue"; import DocumentationModal from "./documentation/DocumentationModal.vue"; import {DateTime} from "luxon"; import {coursesOfTeacher, documentationsForCoursebook, groupsByOwner,} from "./coursebook.graphql"; import CoursebookLoader from "./CoursebookLoader.vue"; import CoursebookEmptyMessage from "./CoursebookEmptyMessage.vue"; export default { name: "Coursebook", components: { CoursebookEmptyMessage, CoursebookLoader, CRUDIterator, DocumentationModal, }, props: { // Either as props OR route params // TODO: Remove default? filterType: { type: String, required: true, }, objId: { type: [Number, String], required: false, default: null, }, objType: { type: String, required: false, default: null, }, // Next two in ISODate dateStart: { type: String, required: false, default: "", }, dateEnd: { type: String, required: false, default: "", }, }, data() { return { gqlQuery: documentationsForCoursebook, lastQuery: null, // Placeholder values while query isn't completed yet groups: [], courses: [], }; }, apollo: { groups: { query: groupsByOwner, }, courses: { query: coursesOfTeacher, }, }, computed: { gqlQueryArgs() { return { // Assure courseId is a number own: this.filterType === "all" ? false : true, objId: this.objId ? Number(this.objId) : null, objType: this.objType?.toUpperCase(), dateStart: this.dateStart, dateEnd: this.dateEnd, }; }, selectable() { return [ { header: this.$t("alsijil.coursebook.filter.groups") }, ...this.groups.map((group) => ({ type: "group", ...group })), { header: this.$t("alsijil.coursebook.filter.courses") }, ...this.courses.map((course) => ({ type: "course", ...course })), ]; }, currentObj() { return this.selectable.find( (o) => o.type === this.objType && o.id === this.objId, ); }, selectLoading() { return ( this.$apollo.queries.groups.loading || this.$apollo.queries.courses.loading ); }, }, methods: { changeSelection(selection) { this.$router.push({ name: "alsijil.coursebook_by_type_and_date", params: { filterType: selection.filterType ? selection.filterType : this.filterType, objType: selection.type, objId: selection.id, dateStart: this.dateStart, dateEnd: this.dateEnd, }, }); }, // => [[dt doc ...] ...] groupDocsByDay(docs) { const byDay = docs.reduce((byDay, doc) => { // This works with dummy. Does actual doc have dateStart instead? const day = DateTime.fromISO(doc.datetimeStart).startOf("day"); byDay[day] ??= [day]; byDay[day].push(doc); return byDay; }, {}); return Object.keys(byDay) .sort() .map((key) => byDay[key]); }, }, }; </script>