<template> <div> <b-modal ref="modalNote" title="Editing a note" size="lg" @ok="saveNote" > <b-container fluid> <p v-if="typeof note.start !== 'undefined'"> This is the note for the timeslot on {{ prettyDateTime(note.start) }}. </p> <p v-else> You are creating a new note. </p> <b-row> <b-col cols="2"> Title: </b-col> <b-col cols="10"> <b-form-input v-model="title" type="text" placeholder="Enter a title" /> </b-col> <b-col cols="2" /> <b-col cols="10"> <small class="slug">Slug: {{ slug }}</small> </b-col> </b-row> <br> <b-row> <b-col cols="2"> Summary: </b-col> <b-col cols="10"> <b-form-textarea v-model="summary" :rows="4" placeholder="Enter a summary" /> </b-col> </b-row> <br> <b-row> <b-col cols="2"> Content: </b-col> <b-col cols="10"> <b-form-textarea v-model="content" :rows="8" placeholder="Enter a text describing this timeslot" /> </b-col> </b-row> <br> <b-row> <b-col cols="2"> Host: </b-col> <b-col cols="10"> <b-form-select v-model="host_selected" :options="hosts" class="mb-3" /> </b-col> </b-row> </b-container> </b-modal> </div> </template> <script> import { mapGetters } from 'vuex' import prettyDate from '../../mixins/prettyDate' import slugify from '../../mixins/slugify' import axios from 'axios' export default { mixins: [ prettyDate, slugify ], data () { return { note: {}, scheduleID: 0, timeslotID: 0, title: '', summary: '', content: '', backuptitle: '', backupsummary: '', backupcontent: '', backuphost: null, host_selected: null } }, computed: { slug () { return this.slugify(this.title) }, hosts () { // for the vue bootstrap select component we need an array of objects // with a value, a text and optionally a disabled element let hosts = [] for (let id of this.selectedShow.hosts) { let host = this.allHosts.find(h => h.id === id) hosts.push({ value: host.id, text: host.name, disabled: !host.is_active }) } return hosts }, ...mapGetters({ selectedShow: 'shows/selectedShow', allHosts: 'shows/hosts', }) }, methods: { update (event) { // only try to save if anything has changed if (this.title !== this.note.title || this.summary !== this.note.summary || this.content !== this.note.content || this.host_selected !== this.note.host) { // prevent the modal from closing automatically on click event.preventDefault() // backup the note contents this.backuptitle = this.note.title this.backupsummary = this.note.summary this.backupcontent = this.note.content this.backuphost = this.note.host // now set the new contents this.note.title = this.title this.note.summary = this.summary this.note.content = this.content this.note.host = this.host_selected // generate the uri for the API call: // /api/v1/shows/1/schedules/1/timeslots/1/note/1/ var uri = process.env.VUE_APP_API_STEERING_SHOWS + this.selectedShow.id + '/schedules/' + this.scheduleID + '/timeslots/' + this.timeslotID + '/note/' + this.note.id + '/' // now send the PUT request with our updated note axios.put(uri, this.note, { withCredentials: true, headers: { 'Authorization': 'Bearer ' + this.$parent.$parent.user.access_token } }).then(() => { // everything was fine, we can close the modal now this.$refs.modalNote.hide() }).catch(error => { this.$log.error(error.response.status + ' ' + error.response.statusText) this.$log.error(error.response) alert('Error: could not update the note. See console for details.') // as there was an error saving the show, we have to make sure // to restore the initial values of the note object this.note.title = this.backuptitle this.note.summary = this.backupsummary this.note.content = this.backupcontent this.note.host = this.backuphost // and we leave the modal open, so no call to its .hide function here }) // if nothing was changed, just close the modal } else { this.$refs.modalNote.hide() } }, new (event) { // title and content are necessary if (this.title.trim() === '' || this.content.trim() === '') { event.preventDefault() // TODO: make this nicer UI-wise (red text annotations next to input fields instead of simple alert) alert('Please provide at least a title and some content.') } else { // prevent the modal from closing automatically on click event.preventDefault() // prepare the new note this.note = { show: this.selectedShow.id, timeslot: this.timeslotID, host: this.host_selected, title: this.title, slug: this.slug, summary: this.summary, content: this.content, ppoi: '(0.5,0.5)', // TODO: implement height: null, // TODO: implement width: null, // TODO: implement image: null, // TODO: implement status: 1, // TODO: implement start: '', // TODO: implement cba_id: null, // TODO: implement audio_url: '' // TODO: implement } let modal = this.$refs.modalNote this.$store.dispatch('shows/submitNote', { id: this.selectedShow.id, scheduleID: this.scheduleID, timeslotID: this.timeslotID, note: this.note, callback: () => { modal.hide() }, callbackCancel: () => { // as there was an error saving the show, we have to make sure // to restore the initial values of the note object this.note.title = this.backuptitle this.note.summary = this.backupsummary this.note.content = this.backupcontent // and we have to set this back to undefined so next time we edit it // it will still be treated as a new note and not an existing one to update this.note.start = undefined // and we leave the modal open, so no call to its .hide function here } }) } }, saveNote (event) { if (typeof this.note.start === 'undefined') { this.new(event) } else { this.update(event) } }, openModal (note, timeslotID, scheduleID) { if (note === null) { this.note = {} this.title = '' this.summary = '' this.content = '' // TODO: integrate this into the user's app settings: // should the field be empty by default or filled with the first host of the show? this.host_selected = null } else { this.note = note this.title = this.note.title this.summary = this.note.summary this.content = this.note.content this.host_selected = this.note.host } this.timeslotID = timeslotID this.scheduleID = scheduleID this.$refs.modalNote.show() } } } </script> <style scoped> .slug { color: gray; } </style>