Skip to content
Snippets Groups Projects
NotesModal.vue 6.43 KiB
Newer Older
  • Learn to ignore specific revisions
  • Konrad Mohrfeldt's avatar
    Konrad Mohrfeldt committed
      <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>
    
    Konrad Mohrfeldt's avatar
    Konrad Mohrfeldt committed
            </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"
                />
    
    Konrad Mohrfeldt's avatar
    Konrad Mohrfeldt committed
                <img v-if="noteImage" class="tw-w-full tw-block" :src="noteImage" />
              </b-col>
            </b-row>
          </b-container>
        </b-modal>
      </div>
    
    Konrad Mohrfeldt's avatar
    Konrad Mohrfeldt committed
    import { mapGetters } from 'vuex'
    import prettyDate from '../../mixins/prettyDate'
    import slugify from '../../mixins/slugify'
    
    Konrad Mohrfeldt's avatar
    Konrad Mohrfeldt committed
    const SUBMIT_NEW = false
    const SUBMIT_UPDATE = true
    
    Konrad Mohrfeldt's avatar
    Konrad Mohrfeldt committed
    export default {
      mixins: [prettyDate, slugify],
    
    Konrad Mohrfeldt's avatar
    Konrad Mohrfeldt committed
      data() {
        return {
          note: {},
          scheduleID: 0,
          timeslotID: 0,
    
    Konrad Mohrfeldt's avatar
    Konrad Mohrfeldt committed
          title: '',
          summary: '',
          content: '',
          image: null,
          backuptitle: '',
          backupsummary: '',
          backupcontent: '',
        }
      },
    
    Konrad Mohrfeldt's avatar
    Konrad Mohrfeldt committed
      computed: {
        slug() {
          return this.slugify(this.title)
        },
    
    Konrad Mohrfeldt's avatar
    Konrad Mohrfeldt committed
        noteImage() {
          if (!this.note.image) {
            return ''
          }
    
    Konrad Mohrfeldt's avatar
    Konrad Mohrfeldt committed
          return this.note.image.includes('http')
            ? this.note.image
            : import.meta.env.VUE_APP_BASEURI_STEERING + this.note.image
        },
    
    Konrad Mohrfeldt's avatar
    Konrad Mohrfeldt committed
        ...mapGetters({
          selectedShow: 'shows/selectedShow',
    
          getTimeslotById: 'shows/getTimeslotById',
    
    Konrad Mohrfeldt's avatar
    Konrad Mohrfeldt committed
      methods: {
        submit(event, updatemode) {
          // prevent the modal from closing automatically on click
          event.preventDefault()
          // backup the note contents
          const backupImage = this.note.image
    
    Konrad Mohrfeldt's avatar
    Konrad Mohrfeldt committed
          this.backuptitle = this.note.title
          this.backupsummary = this.note.summary
          this.backupcontent = this.note.content
    
    Konrad Mohrfeldt's avatar
    Konrad Mohrfeldt committed
          // now set the new contents
          this.note.title = this.title
          this.note.summary = this.summary
          this.note.content = this.content
    
    Konrad Mohrfeldt's avatar
    Konrad Mohrfeldt committed
          if (this.image) {
            this.note.image = this.image
          }
    
    Konrad Mohrfeldt's avatar
    Konrad Mohrfeldt committed
          // 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
    
    Konrad Mohrfeldt's avatar
    Konrad Mohrfeldt committed
          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
            },
          })
        },
    
    Konrad Mohrfeldt's avatar
    Konrad Mohrfeldt committed
        setNoteImage(event) {
          this.image = event.target.files.item(0)
        },
    
    Konrad Mohrfeldt's avatar
    Konrad Mohrfeldt committed
        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()
          }
        },
    
    Konrad Mohrfeldt's avatar
    Konrad Mohrfeldt committed
        new(event) {
          // title and content are necessary
    
          if (this.title.trim() === '' || this.content.trim() === '') {
    
    Konrad Mohrfeldt's avatar
    Konrad Mohrfeldt committed
            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!')
    
    Konrad Mohrfeldt's avatar
    Konrad Mohrfeldt committed
          } else {
            this.submit(event, SUBMIT_NEW)
          }
        },
    
    Konrad Mohrfeldt's avatar
    Konrad Mohrfeldt committed
        saveNote(event) {
    
    Konrad Mohrfeldt's avatar
    Konrad Mohrfeldt committed
            this.new(event)
            return
          }
    
    Konrad Mohrfeldt's avatar
    Konrad Mohrfeldt committed
          // 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
          }
    
    Konrad Mohrfeldt's avatar
    Konrad Mohrfeldt committed
          this.update(event)
        },
    
    Konrad Mohrfeldt's avatar
    Konrad Mohrfeldt committed
        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)
    
    Konrad Mohrfeldt's avatar
    Konrad Mohrfeldt committed
          this.timeslotID = timeslotID
          this.scheduleID = scheduleID
    
    Konrad Mohrfeldt's avatar
    Konrad Mohrfeldt committed
          this.$refs.modalNote.show()
        },
      },
    }
    
    Konrad Mohrfeldt's avatar
    Konrad Mohrfeldt committed
    .slug {
      color: gray;
    }