<script> import { gqlAvailableTimetables } from "./timetables.graphql"; import NoTimetableCard from "./NoTimetableCard.vue"; export default { name: "Timetable", components: { NoTimetableCard }, apollo: { availableTimetables: { query: gqlAvailableTimetables, }, }, data() { return { availableTimetables: [], selected: null, selectedFull: null, search: "", selectedTypes: ["GROUP", "TEACHER", "ROOM"], types: { GROUP: { name: "Groups", id: "GROUP", icon: "mdi-account-group-outline", }, TEACHER: { name: "Teachers", id: "TEACHER", icon: "mdi-account-outline", }, ROOM: { name: "Rooms", id: "ROOM", icon: "mdi-door" }, }, }; }, watch: { selected(selected) { if (selected == null) { this.selectedFull = null; } }, selectedFull(selectedFull) { // Align navigation with currently selected timetable if (!selectedFull) { this.$router.push({ name: "chronos.timetable" }); } else if ( selectedFull.objId !== this.$route.params.id || selectedFull.type !== this.$route.params.type ) { this.$router.push({ name: "chronos.timetableWithId", params: { type: selectedFull.type.toLowerCase(), id: selectedFull.objId, }, }); } }, }, methods: { findNextTimetable(offset = 1) { const currentIndex = this.availableTimetablesIds.indexOf( this.selectedFull.id ); const newIndex = currentIndex + offset; if (newIndex < 0 || newIndex >= this.availableTimetablesIds.length) { return null; } return this.availableTimetables[newIndex]; }, selectTimetable(timetable) { this.selected = timetable.id; this.selectedFull = timetable; }, }, computed: { selectedTypesFull() { return this.selectedTypes.map((type) => { return this.types[type]; }); }, availableTimetablesFiltered() { // Filter timetables by selected types return this.availableTimetables.filter((timetable) => { return this.selectedTypes.indexOf(timetable.type) !== -1; }); }, availableTimetablesIds() { return this.availableTimetables.map((timetable) => timetable.id); }, prevTimetable() { return this.findNextTimetable(-1); }, nextTimetable() { return this.findNextTimetable(1); }, }, }; </script> <template> <div> <v-row> <v-col cols="2"> <v-card> <v-card-text class="mb-0"> <!-- Search field for timetables --> <v-text-field search filled rounded clearable autofocus v-model="search" :placeholder="$t('chronos.timetable.search')" prepend-inner-icon="mdi-magnify" hide-details="auto" class="mb-2" /> <!-- Filter by timetable types --> <v-btn-toggle v-model="selectedTypes" dense block multiple class="d-flex" > <v-btn v-for="type in types" :key="type.id" class="flex-grow-1" :value="type.id" > {{ type.name }} </v-btn> </v-btn-toggle> </v-card-text> <!-- Select of available timetables --> <v-data-iterator :items="availableTimetablesFiltered" item-key="id" :search="search" single-expand > <template #default="{ items, isExpanded, expand }"> <v-list> <v-list-item-group v-model="selected"> <v-list-item v-for="item in items" @click="selectedFull = item" :value="item.id" :key="item.id" > <v-list-item-icon color="primary"> <v-icon v-if="item.type in types" color="secondary"> {{ types[item.type].icon }} </v-icon> <v-icon v-else color="secondary">mdi-grid</v-icon> </v-list-item-icon> <v-list-item-content> <v-list-item-title>{{ item.name }}</v-list-item-title> </v-list-item-content> <v-list-item-action> <v-icon>mdi-chevron-right</v-icon> </v-list-item-action> </v-list-item> </v-list-item-group> </v-list> </template> </v-data-iterator> </v-card> </v-col> <v-col cols="10" class="full-height"> <!-- No timetable card--> <no-timetable-card v-if="selectedFull == null" /> <!-- Calendar card--> <v-card v-else> <div class="d-flex"> <v-card-title> {{ selectedFull.name }} </v-card-title> <v-spacer /> <div class="pa-2 mt-1"> <v-btn icon :disabled="!prevTimetable" @click="selectTimetable(prevTimetable)" :title="$t('chronos.timetable.prev')" > <v-icon>mdi-chevron-left</v-icon> </v-btn> <v-chip label color="secondary" outlined class="mx-1">{{ selectedFull.shortName }}</v-chip> <v-btn icon :disabled="!nextTimetable" @click="selectTimetable(nextTimetable)" :title="$t('chronos.timetable.next')" > <v-icon>mdi-chevron-right</v-icon> </v-btn> </div> </div> <calendar-with-controls :calendar-feeds="[{ name: 'lesson' }]" :params="{ type: selectedFull.type, id: selectedFull.objId }" /> </v-card> </v-col> </v-row> </div> </template>