Newer
Older
:title="$t('noteEditor.editNote')"
:cancel-title="$t('cancel')"
size="lg"
@ok="saveNote"
>
<b-container fluid>
<p v-if="typeof note.start !== 'undefined'">
{{ $t('noteEditor.intro.existing', { date: prettyDateTime(note.start) })}}
<b-col cols="3">
{{ $t('noteEditor.title') }}:
<b-form-input
v-model="title"
type="text"
:placeholder="$t('noteEditor.titlePlaceholder')"
<b-col cols="3" />
<b-col cols="9">
<small class="slug">{{ $t('slug') }}: {{ slug }}</small>
<b-col cols="3">
{{ $t('noteEditor.summary') }}:
<b-form-textarea
v-model="summary"
:rows="4"
:placeholder="$t('noteEditor.summaryPlaceholder')"
<b-col cols="3">
{{ $t('noteEditor.content') }}:
<b-form-textarea
v-model="content"
:rows="8"
:placeholder="$t('noteEditor.contentPlaceholder')"
<b-col cols="3">
{{ $t('noteEditor.host') }}:
<b-form-select
v-model="host_selected"
:options="hosts"
class="mb-3"
/>
</b-col>
</b-row>
<b-row>
<b-col cols="3">
{{ $t('noteEditor.image') }}:
accept="image/*"
type="file"
class="mb-3"
@change="setNoteImage"
:browse-text="$t('browse')"
:placeholder="$t('noteEditor.chooseImage')"
/>
<img
v-if="noteImage"
class="tw-w-full tw-block"
:src="noteImage"
>
</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'
const SUBMIT_NEW = false
const SUBMIT_UPDATE = true
export default {
mixins: [prettyDate, slugify],
data() {
return {
note: {},
scheduleID: 0,
timeslotID: 0,
title: '',
summary: '',
content: '',
image: null,
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 = []
if (!this.$store.state.shows.loaded.hosts) {
return 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
},
noteImage() {
if (!this.note.image) {
return '';
}
return this.note.image.includes('http')
? this.note.image
: process.env.VUE_APP_BASEURI_STEERING + this.note.image
},
...mapGetters({
selectedShow: 'shows/selectedShow',
allHosts: 'shows/hosts',
})
},
methods: {
submit(event, updatemode) {
// prevent the modal from closing automatically on click
event.preventDefault()
// backup the note contents
const backupImage = this.note.image
const backupWidth = this.note.width
const backupHeight = this.note.height
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
if (this.image) {
this.note.image = this.image
}
// for new notes we need to set some extras that are not in the UI yet
if (updatemode === SUBMIT_NEW) {
this.note.show = this.selectedShow.id
this.note.timeslot = this.timeslotID
this.note.slug = this.slug
this.note.ppoi = '(0.5,0.5)' // TODO: implement
this.note.status = 1 // TODO: implement
this.note.start = '' // TODO: implement
this.note.cba_id = 0 // TODO: implement
this.note.audio_url = '' // TODO: implement
}
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
let modal = this.$refs.modalNote
this.$store.dispatch('shows/submitNote', {
update: updatemode,
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
this.note.host = this.backuphost
this.note.image = backupImage;
this.note.width = backupWidth;
this.note.height = backupHeight;
if (updatemode === SUBMIT_NEW) {
this.note.start = undefined
}
// and we leave the modal open, so no call to its .hide function here
}
})
},
setNoteImage(event) {
this.image = event.target.files.item(0);
},
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 || this.image) {
this.submit(event, SUBMIT_UPDATE)
}
// 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() === '' || this.host_selected === null) {
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 and choose a host!')
} else {
this.submit(event, SUBMIT_NEW)
}
},
saveNote(event) {
if (this.note.start === undefined) {
this.new(event)
return
}
// If the note image is a string we haven't updated the field
// and thus delete it, so the API doesn't try to update it by mistake.
if (typeof this.note.image === 'string') {
delete this.note.image
}
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
}
</script>
<style scoped>