ShowManagerModalNotes.vue 8.73 KB
Newer Older
1
<template>
2
  <div>
3
4
5
6
7
8
    <b-modal
      ref="modalNote"
      title="Editing a note"
      size="lg"
      @ok="saveNote"
    >
9
      <b-container fluid>
10
11
12
13
14
15
        <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>
16
        <b-row>
17
18
19
20
21
22
23
24
25
26
27
28
29
30
          <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>
31
        </b-row>
32
        <br>
33
        <b-row>
34
35
36
37
38
39
40
41
42
43
          <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>
44
        </b-row>
45
        <br>
46
        <b-row>
47
48
49
50
51
52
53
54
55
56
          <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>
57
        </b-row>
58
        <br>
59
        <b-row>
60
61
62
63
64
65
66
67
68
69
          <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>
70
        </b-row>
71
72
73
      </b-container>
    </b-modal>
  </div>
74
75
76
77
</template>

<script>
import prettyDate from '../mixins/prettyDate'
78
import slugify from '../mixins/slugify'
79
80
import axios from 'axios'

81
export default {
82
  mixins: [ prettyDate, slugify ],
83
  props: {
84
85
    show: { type: Object, required: true },
    showAggregate: { type: Object, required: true }
86
87
88
  },
  data () {
    return {
89
90
91
92
93
94
95
96
      note: {},
      scheduleID: 0,
      timeslotID: 0,
      title: '',
      summary: '',
      content: '',
      backuptitle: '',
      backupsummary: '',
97
98
99
100
101
102
103
      backupcontent: '',
      backuphost: null,
      host_selected: null
    }
  },
  computed: {
    slug: function () {
104
      return this.slugify(this.title)
105
106
107
108
109
110
111
112
113
114
115
116
117
    },
    hosts: function () {
      // for the vue bootstrap select component we need an array of objects
      // with a value, a text and optionally a disabled element
      var hosts = []
      for (var i in this.showAggregate.hosts) {
        hosts.push({
          value: this.showAggregate.hosts[i].id,
          text: this.showAggregate.hosts[i].name,
          disabled: !this.showAggregate.hosts[i].is_active
        })
      }
      return hosts
118
119
120
    }
  },
  methods: {
121
122
    update (event) {
      // only try to save if anything has changed
123
      if (this.title !== this.note.title || this.summary !== this.note.summary || this.content !== this.note.content || this.host_selected !== this.note.host) {
124
125
126
127
128
129
        // 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
130
        this.backuphost = this.note.host
131
132
133
134
        // now set the new contents
        this.note.title = this.title
        this.note.summary = this.summary
        this.note.content = this.content
135
        this.note.host = this.host_selected
136
        // generate the uri for the API call:
137
        //   /api/v1/shows/1/schedules/1/timeslots/1/note/1/
138
        var uri = process.env.VUE_APP_API_STEERING_SHOWS + this.show.id +
139
140
141
142
143
144
        '/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,
145
          headers: { 'Authorization': 'Bearer ' + this.$parent.$parent.user.access_token }
146
        }).then(() => {
147
148
149
          // everything was fine, we can close the modal now
          this.$refs.modalNote.hide()
        }).catch(error => {
150
151
152
          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.')
153
154
155
156
157
          // 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
158
          this.note.host = this.backuphost
159
160
161
162
163
164
165
          // 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()
      }
    },
166
167
168
169
170
171
172
    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 {
173
174
175
176
177
178
        // prevent the modal from closing automatically on click
        event.preventDefault()
        // prepare the new note
        this.note = {
          show: this.show.id,
          timeslot: this.timeslotID,
179
          host: this.host_selected,
180
          title: this.title,
181
          slug: this.slug,
182
183
184
185
186
187
188
189
190
191
192
193
194
          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
        }
        // generate the uri for the API call:
        //   /api/v1/shows/1/schedules/1/timeslots/1/note
195
        var uri = process.env.VUE_APP_API_STEERING_SHOWS + this.show.id +
196
197
198
199
200
201
        '/schedules/' + this.scheduleID +
        '/timeslots/' + this.timeslotID +
        '/note/'
        // now send the POST request with our updated note
        axios.post(uri, this.note, {
          withCredentials: true,
202
203
          responseType: 'json',  // we need this explicitly here, as it does not seem to work automagically as in GET and PUT requests
          headers: { 'Authorization': 'Bearer ' + this.$parent.$parent.user.access_token }
204
        }).then(response => {
205
206
207
208
209
210
211
          this.note = response.data
          for (var i in this.showAggregate.timeslots) {
            if (this.showAggregate.timeslots[i].id === this.timeslotID) {
              this.showAggregate.timeslots[i].note_id = this.note.id
              this.showAggregate.notes.push(this.note)
            }
          }
212
213
214
          // everything was fine, we can close the modal now
          this.$refs.modalNote.hide()
        }).catch(error => {
215
216
217
          this.$log.error(error.response.status + ' ' + error.response.statusText)
          this.$log.error(error.response)
          alert('Error: could not post the new note. See console for details.')
218
219
220
221
222
          // 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
223
224
225
          // 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
226
227
228
          // and we leave the modal open, so no call to its .hide function here
        })
      }
229
230
231
    },
    saveNote (event) {
      if (typeof this.note.start === 'undefined') {
232
        this.new(event)
233
234
235
236
237
238
239
240
241
242
      } else {
        this.update(event)
      }
    },
    showModal (note, timeslotID, scheduleID) {
      if (note === null) {
        this.note = {}
        this.title = ''
        this.summary = ''
        this.content = ''
243
244
245
        // 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 = this.showAggregate.hosts[0].id
246
247
248
249
250
      } else {
        this.note = note
        this.title = this.note.title
        this.summary = this.note.summary
        this.content = this.note.content
251
        this.host_selected = this.note.host
252
253
254
255
      }
      this.timeslotID = timeslotID
      this.scheduleID = scheduleID
      this.$refs.modalNote.show()
256
257
258
259
260
261
    }
  }
}
</script>

<style scoped>
262
263
264
.slug {
  color: gray;
}
265
</style>