Commit 18ce2b7c authored by jackie / Andrea Ida Malkah Klaura's avatar jackie / Andrea Ida Malkah Klaura
Browse files

refactor emission manager modals to vuex

parent b7bced95
<template>
<b-container>
<b-row v-if="loaded.shows">
<b-col>
<b-alert
:show="showChangedAlert.countdown"
@dismiss-count-down="showChangedAlertCountdown"
>
Selected new show: <b>{{ shows[currentShow].name }}</b>
<b-progress
variant="info"
animated
:max="showChangedAlert.seconds"
:value="showChangedAlert.countdown"
height="3px"
/>
</b-alert>
<b-alert
:show="!showChangedAlert.countdown"
variant="light"
>
Currently selected show: <b>{{ shows[currentShow].name }}</b>
</b-alert>
</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>
<show-selector
title="Emissions"
:callback="showHasSwitched"
/>
<hr>
<b-alert
......@@ -136,8 +94,10 @@
</template>
<script>
import { mapGetters } from 'vuex'
import { FullCalendar } from 'vue-full-calendar'
import 'fullcalendar/dist/fullcalendar.css'
import showSelector from './ShowSelector.vue'
import modalEmissionManagerCreate from './emissions/ModalCreate.vue'
import modalEmissionManagerResolve from './emissions/ModalResolve.vue'
import modalEmissionManagerEdit from './emissions/ModalEdit.vue'
......@@ -146,6 +106,7 @@ import rrules from '../mixins/rrules'
export default {
components: {
FullCalendar,
'show-selector': showSelector,
'app-modalEmissionManagerCreate': modalEmissionManagerCreate,
'app-modalEmissionManagerResolve': modalEmissionManagerResolve,
'app-modalEmissionManagerEdit': modalEmissionManagerEdit,
......@@ -155,14 +116,8 @@ export default {
data () {
return {
currentShow: 0,
calendarSlots: [],
showChangedAlert: {
countdown: 0,
seconds: 3
},
// flag for when submitting resolve data
submitting: false,
......@@ -203,34 +158,43 @@ export default {
},
computed: {
shows () { return this.$store.state.shows.shows },
timeslots () { return this.$store.state.shows.timeslots },
loaded () {
return {
shows: this.$store.state.shows.loaded['shows'],
timeslots: this.$store.state.shows.loaded['timeslots'],
}
},
...mapGetters({
shows: 'shows/shows',
selectedShow: 'shows/selectedShow',
timeslots: 'shows/timeslots',
getPlaylistById: 'playlists/getPlaylistById',
files: 'files/files',
getFileById: 'files/getFileById',
})
},
created () {
if (this.$route.query.show) {
this.currentShow = this.$route.query.show
} else {
this.currentShow = 0
}
this.loadShows()
this.$store.dispatch('shows/fetchShows', {
callback: () => {
this.showHasSwitched()
}
})
},
methods: {
switchShow (index) {
this.currentShow = index
switchShow () {
this.loadCalendarSlots()
this.showChangedAlert.countdown = this.showChangedAlert.seconds
},
showChangedAlertCountdown(countdown) {
this.showChangedAlert.countdown = countdown
// This is the callback function that is activated by the show-selector
// component, whenever the user switches to a different show
showHasSwitched () {
this.$log.debug('show has switched to', this.selectedShow.name)
let start = this.$refs.calendar.fireMethod('getView').start.format()
let end = this.$refs.calendar.fireMethod('getView').end.format()
this.loadTimeslots(start, end)
},
getShowTitleById (id) {
......@@ -271,10 +235,10 @@ export default {
// currently selected show.
else {
let timeslot = this.timeslots.find(slot => slot.id === event.id)
if (timeslot.show !== this.shows[this.currentShow].id) {
if (timeslot.show !== this.selectedShow.id) {
this.switchShow(this.getShowIndexById(timeslot.show))
} else {
this.$refs.appModalEmissionManagerEdit.open(timeslot, this.shows[this.currentShow])
this.$refs.appModalEmissionManagerEdit.open(timeslot)
}
}
},
......@@ -514,7 +478,7 @@ export default {
this.$log.debug('resolveSubmit: schedule:', resolvedSchedule)
this.submitting = true
this.$store.dispatch('shows/submitSchedule', {
showId: this.shows[this.currentShow].id,
showId: this.selectedShow.id,
schedule: resolvedSchedule,
callback: (response) => {
this.submitting = false
......@@ -535,7 +499,7 @@ export default {
this.calendarSlots = []
for (let i in this.timeslots) {
let highlighting = 'otherShow'
if (this.timeslots[i].show === this.shows[this.currentShow].id) {
if (this.timeslots[i].show === this.selectedShow.id) {
highlighting = 'currentShow'
}
this.calendarSlots.push({
......@@ -553,22 +517,11 @@ export default {
start: start,
end: end,
callback: () => {
this.$log.debug('loadTimeslots callback executed')
this.loadCalendarSlots()
}
})
},
loadShows () {
this.$store.dispatch('shows/fetchShows', {
callback: () => {
let start = this.$refs.calendar.fireMethod('getView').start.format()
let end = this.$refs.calendar.fireMethod('getView').end.format()
this.loadTimeslots(start, end)
}
})
},
notYetImplemented: function () {
alert('By the mighty witchcraftry of the mother of time!\n\nThis feature is not implemented yet.')
},
......
......@@ -11,8 +11,8 @@
Creating schedule for:
</b-col>
<b-col cols="9">
<b v-if="$parent.loaded.shows">
{{ $parent.shows[$parent.currentShow].name }}
<b v-if="loaded.shows">
{{ selectedShow.name }}
</b>!
</b-col>
</b-row>
......@@ -25,7 +25,7 @@
Try again or change the start date to something in the future.
</b-alert>
<div v-if="loaded && !submitting">
<div v-if="loaded.modal && !submitting">
<b-row>
<b-col cols="2">
Start:
......@@ -89,7 +89,7 @@
</template>
<script>
import axios from 'axios'
import { mapGetters } from 'vuex'
import prettyDate from '../../mixins/prettyDate'
import rrules from '../../mixins/rrules'
......@@ -99,7 +99,7 @@ export default {
data () {
return {
newSchedule: null,
loaded: false,
loadedModal: false,
submitting: false,
pastEventWarning: false,
valuePick: {
......@@ -112,6 +112,19 @@ export default {
}
},
computed: {
loaded () {
return {
shows: this.$store.state.shows.loaded['shows'],
modal: this.loadedModal,
}
},
...mapGetters({
selectedShow: 'shows/selectedShow',
})
},
methods: {
create (event) {
// prevent the modal from closing automatically on click
......@@ -135,65 +148,56 @@ export default {
this.newSchedule.schedule.until = this.valuePick.until
this.newSchedule.schedule.rrule = this.valuePick.rrule
this.newSchedule.schedule.byweekday = this.getWeekdayFromApiDate(this.valuePick.dstart)
// now generate the URL and POST our new schedule
let uri = process.env.VUE_APP_API_STEERING_SHOWS + this.$parent.shows[this.$parent.currentShow].id + '/schedules/'
// ok then, let's submit and see if any conflicts arise
this.submitting = true
axios.post(uri, this.newSchedule, {
withCredentials: true,
headers: { 'Authorization': 'Bearer ' + this.$parent.$parent.user.access_token }
}).then(response => {
// we have to check if there are any conflicts with existing timeslots
let conflicts = false
for (let i in response.data.projected) {
if (response.data.projected[i].collisions.length > 0) {
conflicts = true
break
this.$store.dispatch('shows/submitSchedule', {
showId: this.selectedShow.id,
schedule: this.newSchedule,
callback: (response) => {
// we have to check if there are any conflicts with existing timeslots
let conflicts = false
for (let i in response.data.projected) {
if (response.data.projected[i].collisions.length > 0) {
conflicts = true
break
}
}
}
// if there are no conflicts we can set an empty solutions object
// in our newSchedule and submit it.
if (!conflicts) {
this.newSchedule.solutions = {}
this.submit()
// otherwise we have to resolve the conflict first.
} else {
this.submitting = false
this.$parent.resolve(response.data)
this.$refs.modalEmissionManagerCreate.hide()
}
}).catch(error => {
this.submitting = false
this.$log.error(error.response.status + ' ' + error.response.statusText)
this.$log.error(error.response)
alert('Error: could not create schedule. See console for details.')
// and we leave the modal open, so no call to its .hide function here
// if there are no conflicts we can set an empty solutions object
// in our newSchedule and submit it.
if (!conflicts) {
this.newSchedule.solutions = {}
this.submit()
// otherwise we have to resolve the conflict first.
} else {
this.submitting = false
this.$parent.resolve(response.data)
this.$refs.modalEmissionManagerCreate.hide()
}
},
callbackCancel: () => { this.submitting = false }
})
},
submit () {
let uri = process.env.VUE_APP_API_STEERING_SHOWS + this.$parent.shows[this.$parent.currentShow].id + '/schedules/'
axios.post(uri, this.newSchedule, {
withCredentials: true,
headers: { 'Authorization': 'Bearer ' + this.$parent.$parent.user.access_token }
}).then(response => {
this.submitting = false
// if for some reason a new conflict arose, e.g. because in the meantime
// someone else inserted a conflicting schedule, we have to resolve.
// TODO: based on single event schedule
// TODO: check for complex schedules with resolved conflicts
if (response.data.projected === undefined) {
this.$parent.renderView(null)
} else {
this.$log.debug('Timeslot conflict. Switching to resolve mode.')
this.$parent.resolve(response.data)
}
this.$refs.modalEmissionManagerCreate.hide()
}).catch(error => {
this.submitting = false
this.$log.error(error.response.status + ' ' + error.response.statusText)
this.$log.error(error.response)
alert('Error: could not submit final schedule. See console for details.')
// and we leave the modal open, so no call to its .hide function here
this.$store.dispatch('shows/submitSchedule', {
showId: this.selectedShow.id,
schedule: this.newSchedule,
callback: (response) => {
this.submitting = false
// if for some reason a new conflict arose, e.g. because in the meantime
// someone else inserted a conflicting schedule, we have to resolve.
// TODO: based on single event schedule
// TODO: check for complex schedules with resolved conflicts
if (response.data.projected === undefined) {
this.$parent.renderView(null)
} else {
this.$log.debug('Timeslot conflict. Switching to resolve mode.')
this.$parent.resolve(response.data)
}
this.$refs.modalEmissionManagerCreate.hide()
},
callbackCancel: () => { this.submitting = false }
})
},
......@@ -230,7 +234,7 @@ export default {
automation_id: 0,
}
}
this.loaded = true
this.loadedModal = true
this.submitting = false
this.$refs.modalEmissionManagerCreate.show()
},
......
......@@ -5,14 +5,11 @@
title="Edit a schedule"
size="lg"
>
<p>
Editing a timeslot/schedule for show:
<b v-if="loaded.modal">
<b>{{ show.name }}</b>
</b>
<p v-if="loaded.shows">
Editing a timeslot/schedule for show: <b>{{ selectedShow.name }}</b>
</p>
<p v-if="loaded.modal">
<div v-if="timeslot && loaded.schedule">
This timeslot starts at
<b-badge variant="info">
{{ prettyDateTime(timeslot.start) }}
......@@ -21,9 +18,7 @@
<b-badge variant="info">
{{ prettyDateTime(timeslot.end) }}
</b-badge>
</p>
<div v-if="loaded.schedule">
<div v-if="schedule.rrule === 1">
<p>
This is a single emission.
......@@ -147,7 +142,7 @@
</template>
<script>
import axios from 'axios'
import { mapGetters } from 'vuex'
import prettyDate from '../../mixins/prettyDate'
import rrules from '../../mixins/rrules'
......@@ -157,14 +152,6 @@ export default {
data () {
return {
timeslot: null,
schedule: null,
scheduleTimeslots: null,
show: null,
loaded: {
modal: false,
schedule: false,
scheduleTimeslots: false,
},
deletion: {
amount: 0,
count: 0,
......@@ -172,35 +159,43 @@ export default {
}
},
computed: {
loaded () {
return {
shows: this.$store.state.shows.loaded.shows,
schedule: this.$store.state.shows.loaded.schedule,
scheduleTimeslots: this.$store.state.shows.loaded.scheduleTimeslots,
}
},
...mapGetters({
selectedShow: 'shows/selectedShow',
schedule: 'shows/schedule',
scheduleTimeslots: 'shows/scheduleTimeslots',
})
},
methods: {
deleteFullSchedule (id) {
let uri = process.env.VUE_APP_API_STEERING + 'shows/' + this.show.id + '/schedules/' + id + '/'
axios.delete(uri, {
withCredentials: true,
headers: { 'Authorization': 'Bearer ' + this.$parent.$parent.user.access_token }
}).then(() => {
this.$refs.modalEmissionManagerEdit.hide()
this.$parent.renderView(null)
}).catch(error => {
this.$log.error(error.response.status + ' ' + error.response.statusText)
this.$log.error(error.response)
alert('Error: could not delete full schedule. See console for details.')
this.$store.dispatch('shows/deleteSchedule', {
show: this.selectedShow.id,
schedule: id,
callback: () => {
this.$refs.modalEmissionManagerEdit.hide()
this.$parent.renderView(null)
}
})
},
deleteSingleTimeslot (scheduleId, timeslotId) {
let uri = process.env.VUE_APP_API_STEERING + 'shows/' + this.show.id +
'/schedules/' + scheduleId + '/timeslots/' + timeslotId + '/'
axios.delete(uri, {
withCredentials: true,
headers: { 'Authorization': 'Bearer ' + this.$parent.$parent.user.access_token }
}).then(() => {
this.$refs.modalEmissionManagerEdit.hide()
this.$parent.renderView(null)
}).catch(error => {
this.$log.error(error.response.status + ' ' + error.response.statusText)
this.$log.error(error.response)
alert('Error: could not delete full schedule. See console for details.')
this.$store.dispatch('shows/deleteTimeslot', {
show: this.selectedShow.id,
schedule: scheduleId,
timeslot: timeslotId,
callback: () => {
this.$refs.modalEmissionManagerEdit.hide()
this.$parent.renderView(null)
}
})
},
......@@ -223,76 +218,52 @@ export default {
this.deletion.count = 0
this.$refs.modalEmissionManagerDeleteTimeslots.show()
let uri = process.env.VUE_APP_API_STEERING + 'shows/' + this.show.id + '/schedules/' + scheduleId + '/'
for (let i in toDelete) {
this.$log.debug('Deleting timeslot', toDelete[i])
axios.delete(uri + 'timeslots/' + toDelete[i] + '/', {
withCredentials: true,
headers: { 'Authorization': 'Bearer ' + this.$parent.$parent.user.access_token }
}).then(() => {
this.deletion.count++
this.$log.debug('deleted ' + this.deletion.count + ' timeslots')
if (this.deletion.count === this.deletion.amount) {
this.$parent.renderView(null)
this.$refs.modalEmissionManagerDeleteTimeslots.hide()
this.$refs.modalEmissionManagerEdit.hide()
this.$store.dispatch('shows/deleteTimeslot', {
show: this.selectedShow.id,
schedule: scheduleId,
timeslot: toDelete[i],
callback: () => {
this.deletion.count++
this.$log.debug('deleted ' + this.deletion.count + ' timeslots')
if (this.deletion.count === this.deletion.amount) {
this.$parent.renderView(null)
this.$refs.modalEmissionManagerDeleteTimeslots.hide()
this.$refs.modalEmissionManagerEdit.hide()
}
}
}).catch(error => {
this.$log.error(error.response.status + ' ' + error.response.statusText)
this.$log.error(error.response)
alert('Error: could not delete full timeslot. See console for details.')
})
}
}
},
loadSchedule (id) {
this.loaded.schedule = false
let uri = process.env.VUE_APP_API_STEERING + 'shows/' + this.show.id + '/schedules/' + id + '/'
axios.get(uri, {
withCredentials: true,
headers: { 'Authorization': 'Bearer ' + this.$parent.$parent.user.access_token }
}).then(response => {
this.schedule = response.data
this.loaded.schedule = true
this.loadScheduleTimeslots(this.schedule.id)
}).catch(error => {
this.$log.error(error.response.status + ' ' + error.response.statusText)
this.$log.error(error.response)
alert('Error: could not load schedule. See console for details.')
loadSchedule (scheduleId) {
this.$store.dispatch('shows/fetchSchedule', {
show: this.selectedShow.id,
schedule: scheduleId,
callback: () => {
this.loadScheduleTimeslots(scheduleId)
}
})
},
loadScheduleTimeslots (id) {
this.loaded.scheduleTimeslots = false
let uri = process.env.VUE_APP_API_STEERING + 'shows/' + this.show.id + '/schedules/' + id + '/timeslots/'
uri += '?start=' + this.schedule.dstart + '&end=' + this.schedule.until
axios.get(uri, {
withCredentials: true,
headers: { 'Authorization': 'Bearer ' + this.$parent.$parent.user.access_token }
}).then(response => {
this.scheduleTimeslots = response.data
this.loaded.scheduleTimeslots = true
}).catch(error => {
this.$log.error(error.response.status + ' ' + error.response.statusText)
this.$log.error(error.response)
alert('Error: could not load timeslots of this schedule. See console for details.')
loadScheduleTimeslots (scheduleId) {
this.$store.dispatch('shows/fetchTimeslots', {
id: this.selectedShow.id,
schedule: scheduleId,
start: this.schedule.dstart,
end: this.schedule.until,
})
},
// initialise a new schedule and open the modal
open (timeslot, show) {
open (timeslot) {
this.timeslot = timeslot
this.show = show
this.loaded.modal = true
this.$refs.modalEmissionManagerEdit.show()
this.loadSchedule(timeslot.schedule)
},
notYetImplemented: function () {
alert('By the mighty witchcraftry of the mother of time!\n\nThis feature is not implemented yet.')
},
}
}
</script>
......
......@@ -8,11 +8,11 @@
>
<p>
Resolving a conflict for a new schedule of the show:
<b v-if="$parent.loaded.shows">
<b>{{ $parent.shows[$parent.currentShow].name }}</b>
<b v-if="loaded.shows">
<b>{{ selectedShow.name }}</b>