<template> <b-container> <b-row v-if="loaded.shows"> <b-col> <h3>{{ shows[currentShow].name }}</h3> </b-col> <b-col align="right"> <b-dropdown id="ddshows" text="Sendereihe auswählen" variant="outline-info" > <b-dropdown-item v-for="(show, index) in shows" :key="show.id" @click="switchShow(index)" > {{ show.name }} </b-dropdown-item> </b-dropdown> </b-col> </b-row> <b-row v-else> <b-col cols="12"> <div align="center"> ... loading show data ... </div> </b-col> </b-row> <hr> <full-calendar ref="calendar" editable="false" default-view="agendaWeek" :events="calendarSlots" :config="calendarConfig" @view-render="renderView" /> </b-container> </template> <script> import axios from 'axios' import { FullCalendar } from 'vue-full-calendar' import 'fullcalendar/dist/fullcalendar.css' export default { components: { FullCalendar, }, data () { return { currentShow: 0, shows: [], timeslots: [], calendarSlots: [], // this is the whole configuration for our schedule calendar, including // simple event handlers that do not need the whole components scope calendarConfig: { height: 600, firstDay: 1, header: { left: 'title', center: '', right: 'today prev,next' }, views: { agendaWeek: { columnHeaderFormat: 'ddd D.M.', timeFormat: 'k:mm', slotLabelFormat: 'k:mm', allDaySlot: false, }, }, // here we add a simple tooltip to every event, so that the full title // of a show can be viewed eventRender: function(event, element) { element.attr('title', event.title); }, }, loaded: { shows: false, timeslots: false, calendarSlots: false, }, } }, created () { if (this.$route.query.show) { this.currentShow = this.$route.query.show } else { this.currentShow = 0 } this.loadShows() }, methods: { switchShow (index) { this.currentShow = index this.loadCalendarSlots() }, getShowTitleById (id) { let i = this.shows.findIndex(show => show.id === id) if (i >= 0) { return this.shows[i].name } else { return 'Error: no show found for this timeslot' } }, // this is called when the user changes the calendar view, so we just // refetch the timeslots with the updated visible date range renderView (view) { if (this.loaded.shows) { this.$log.debug('refetching') this.loadTimeslots(view.start.format(), view.end.format()) } }, loadCalendarSlots () { this.loaded.calendarSlots = false this.calendarSlots = [] for (let i in this.timeslots) { let highlighting = 'otherShow' if (this.timeslots[i].show === this.shows[this.currentShow].id) { highlighting = 'currentShow' } this.calendarSlots.push({ start: this.timeslots[i].start, end: this.timeslots[i].end, title: this.getShowTitleById(this.timeslots[i].show), className: highlighting }) } this.loaded.calendarSlots = true }, loadTimeslots (start, end) { this.$log.debug('loadTimeslots: currentShow = '+this.currentShow) this.loaded.timeslots = false let uri = process.env.VUE_APP_API_STEERING + 'timeslots?start=' + start + '&end=' + end axios.get(uri, { withCredentials: true, headers: { 'Authorization': 'Bearer ' + this.$parent.user.access_token } }).then(response => { this.timeslots = response.data this.loaded.timeslots = true this.loadCalendarSlots() }).catch(error => { this.$log.error(error.response.status + ' ' + error.response.statusText) this.$log.error(error.response) alert('Error: could not load timeslots. See console for details.') }) }, loadShows () { this.loaded.shows = false let uri = process.env.VUE_APP_API_STEERING + 'shows' axios.get(uri, { withCredentials: true, headers: { 'Authorization': 'Bearer ' + this.$parent.user.access_token } }).then(response => { this.shows = response.data this.loaded.shows = true let start = this.$refs.calendar.fireMethod('getView').start.format() let end = this.$refs.calendar.fireMethod('getView').end.format() this.loadTimeslots(start, end) }).catch(error => { this.$log.error(error.response.status + ' ' + error.response.statusText) this.$log.error(error.response) alert('Error: could not load shows. See console for details.') }) }, updateSchedules () { this.$log.debug(this.$refs.calendar.fireMethod('getView').start.format()) } }, } </script> <style> .otherShow { background-color: #eee; } a.currentShow { background-color: #17a2b8; } </style>