<template> <div> <b-modal ref="modalNote" :title="$t('noteEditor.editNote')" :cancel-title="$t('cancel')" size="lg" @ok="saveNote" > <b-container fluid> <p> <template v-if="timeslot"> {{ $t('noteEditor.intro.existing', { date: prettyDateTime(timeslot.start) }) }} </template> <template v-else> {{ $t('noteEditor.intro.new') }} </template> </p> <b-row> <b-col cols="3"> {{ $t('noteEditor.title') }}: </b-col> <b-col cols="9"> <b-form-input v-model="title" type="text" :placeholder="$t('noteEditor.titlePlaceholder')" /> </b-col> <b-col cols="3" /> <b-col cols="9"> <small class="slug">{{ $t('slug') }}: {{ slug }}</small> </b-col> </b-row> <br /> <b-row> <b-col cols="3"> {{ $t('noteEditor.summary') }}: </b-col> <b-col cols="9"> <b-form-textarea v-model="summary" :rows="4" :placeholder="$t('noteEditor.summaryPlaceholder')" /> </b-col> </b-row> <br /> <b-row> <b-col cols="3"> {{ $t('noteEditor.content') }}: </b-col> <b-col cols="9"> <b-form-textarea v-model="content" :rows="8" :placeholder="$t('noteEditor.contentPlaceholder')" /> </b-col> </b-row> <br /> <b-row> <b-col cols="3"> {{ $t('noteEditor.image') }}: </b-col> <b-col cols="9"> <b-form-file accept="image/*" type="file" class="mb-3" :browse-text="$t('browse')" :placeholder="$t('noteEditor.chooseImage')" @change="setNoteImage" /> <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, timeslot: null, title: '', summary: '', content: '', image: null, backuptitle: '', backupsummary: '', backupcontent: '', } }, computed: { slug() { return this.slugify(this.title) }, noteImage() { if (!this.note.image) { return '' } return this.note.image.includes('http') ? this.note.image : import.meta.env.VUE_APP_BASEURI_STEERING + this.note.image }, ...mapGetters({ selectedShow: 'shows/selectedShow', getTimeslotById: 'shows/getTimeslotById', }), }, methods: { submit(event, updatemode) { // prevent the modal from closing automatically on click event.preventDefault() // backup the note contents const backupImage = this.note.image this.backuptitle = this.note.title this.backupsummary = this.note.summary this.backupcontent = this.note.content // now set the new contents this.note.title = this.title this.note.summary = this.summary this.note.content = this.content 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.cba_id = 0 // TODO: implement this.note.audio_url = '' // TODO: implement } const 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.image = backupImage // 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.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() === '') { 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 { this.submit(event, SUBMIT_NEW) } }, saveNote(event) { if (!this.note.id) { 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 } this.update(event) }, openModal(note, timeslotID, scheduleID) { if (note === null) { this.note = {} this.title = '' this.summary = '' this.content = '' } else { this.note = { ...note } this.title = this.note.title this.summary = this.note.summary this.content = this.note.content } this.timeslot = this.getTimeslotById(timeslotID) this.timeslotID = timeslotID this.scheduleID = scheduleID this.$refs.modalNote.show() }, }, } </script> <style scoped> .slug { color: gray; } </style>