diff --git a/src/components/ShowManager.vue b/src/components/ShowManager.vue index 6a3b75e6c6493729b4ee3516be6cc3e1695573f9..dbe00fdd3ee5e6efc2319caea80f37ef49721eb6 100644 --- a/src/components/ShowManager.vue +++ b/src/components/ShowManager.vue @@ -274,6 +274,7 @@ <hr> <h2>Allgemeine Einstellungen zur Sendereihe:</h2> + <b-row> <b-col lg="6"> <p> @@ -399,6 +400,56 @@ </b-col> </b-row> + <hr v-if="$parent.user.steeringUser.is_superuser"> + <b-row v-if="$parent.user.steeringUser.is_superuser"> + <b-col lg="2"> + <b-badge + variant="info" + style="width:80%;" + > + Owners: + </b-badge> <img + src="../assets/16x16/emblem-system.png" + alt="edit" + @click="$refs.appModalSuperuser.showModalOwners(shows[currentShow])" + > + </b-col> + <b-col lg="10"> + <div v-if="loaded.owners"> + <p v-if="shows[currentShow].owners.length === 0"> + <small><i>(none set)</i></small> + </p> + <p v-else> + <!-- TODO: make link on name; when user clicks, open modal to edit host --> + <ul> + <li + v-for="owner in current.owners" + :key="owner.id" + > + {{ owner.first_name }} {{ owner.last_name }} + <b-badge variant="light"> + username: + </b-badge> <small>{{ owner.username }}</small> + <span v-if="owner.email.length > 0"> + <b-badge variant="light"> + email: + </b-badge> <small>{{ owner.email }}</small> + </span> + </li> + </ul> + </p> + </div> + <div v-else> + <img + src="../assets/radio.gif" + height="24px" + alt="loading data" + ><br> + </div> + </b-col> + </b-row> + <hr v-if="$parent.user.steeringUser.is_superuser"> + <b-row> <b-col lg="2"> <b-badge style="width:80%;"> @@ -671,7 +722,8 @@ export default { topics: false, musicfocus: false, fundingcategory: false, - type: false + type: false, + owners: false, }, // the current object is used to hold all the necessary data to describe @@ -695,7 +747,8 @@ export default { note: {}, notes: [], image: '', - logo: '' + logo: '', + owners: [], }, // this is used to configure the table with all the filtered timeslots @@ -812,6 +865,7 @@ export default { this.loaded.languages = false this.loaded.musicfocus = false this.loaded.fundingcategory = false + this.loaded.owners = false // set the current show and its ID to whatever we want to switch to now this.currentShow = index this.currentShowID = this.shows[this.currentShow].id @@ -829,6 +883,9 @@ export default { this.getMusicfocus() this.getFundingCategory() this.getType() + if (this.$parent.user.steeringUser.is_superuser) { + this.getOwners() + } // now fetch the timeslots (including notes) for a given show from PV backend this.getTimeslots(this.dateStart, this.dateEnd, this.numSlots) }, @@ -1124,6 +1181,29 @@ export default { if (!loadingError) { this.loaded.type = true } }, + getOwners: function () { + this.current.owners = [] + let loadingError = false + if (this.shows[this.currentShow].owners.length === 0) { + this.loaded.owners = true + } else { + for (let i in this.shows[this.currentShow].owners) { + axios.get(process.env.VUE_APP_API_STEERING + 'users/' + this.shows[this.currentShow].owners[i] + '/', { + withCredentials: true, + headers: { 'Authorization': 'Bearer ' + this.$parent.user.access_token } + }).then(response => { + this.current.owners.push(response.data) + }).catch(error => { + loadingError = true + this.$log.error(error.response.status + ' ' + error.response.statusText) + this.$log.error(error.response) + alert('Error: could not load owner data. See console for details.') + }) + } + if (!loadingError) { this.loaded.owners = true } + } + }, + // Just a placeholder function we can use in the UI, to signal if something // is not yet implemented notYetImplemented: function () { diff --git a/src/components/ShowManagerModalSuperuser.vue b/src/components/ShowManagerModalSuperuser.vue index 27001a9536e69a37db16c22076d45e640702135c..85e7dcc42aad923f190aff6000912bebbbfbfb2d 100644 --- a/src/components/ShowManagerModalSuperuser.vue +++ b/src/components/ShowManagerModalSuperuser.vue @@ -99,6 +99,124 @@ Are you sure you want to continue? </div> </b-modal> + + <!-- Modal to edit show owners --> + <b-modal + ref="modalOwners" + title="Edit owners of the show" + size="lg" + @ok="updateOwners" + > + <div v-if="loaded.users"> + <p> + Users with access to <b>{{ show.name }}</b>: + </p> + <div v-if="owners.length === 0"> + <ul> + <li> + <small><i>(none set)</i></small> + </li> + </ul> + </div> + <div v-else> + <b-table + striped + hover + :items="owners" + :fields="ownersTableFields" + > + <template + slot="name" + slot-scope="data" + > + {{ data.item.first_name }} {{ data.item.last_name }} + </template> + <template + slot="username" + slot-scope="data" + > + <small>{{ data.value }}</small> + </template> + <template + slot="email" + slot-scope="data" + > + <small>{{ data.value }}</small> + </template> + <template + slot="options" + slot-scope="data" + > + <b-button + variant="danger" + size="sm" + @click="deleteOwner(data.item.id)" + > + Delete + </b-button> + </template> + </b-table> + </div> + + <hr> + + <!-- TODO: as the list of users might be quite large we need some sort + of pagination and/or a search box. also those users who already have + access should not be listed (or at least the add button should be disabled) + --> + <p> + You can + <b-badge variant="success"> + add new users + </b-badge> + from the table below: + </p> + <b-table + striped + hover + :items="users" + :fields="ownersTableFields" + > + <template + slot="name" + slot-scope="data" + > + {{ data.item.first_name }} {{ data.item.last_name }} + </template> + <template + slot="username" + slot-scope="data" + > + <small>{{ data.value }}</small> + </template> + <template + slot="email" + slot-scope="data" + > + <small>{{ data.value }}</small> + </template> + <template + slot="options" + slot-scope="data" + > + <b-button + variant="success" + size="sm" + @click="addOwner(data.item.id)" + > + Add + </b-button> + </template> + </b-table> + </div> + <div v-else> + <img + src="../assets/radio.gif" + height="32px" + alt="loading user data" + > + </div> + </b-modal> </div> </template> @@ -127,12 +245,17 @@ export default { id: null, name: '', }, + show: null, loaded: { types: false, fundingcategories: false, + users: false, }, types: [], fundingcategories: [], + users: [], + owners: [], + ownersTableFields: ['name', 'username', 'email', 'options'] } }, @@ -231,6 +354,50 @@ export default { }) }, + // remove an owner from the list of show owners + deleteOwner (id) { + // we only have to find the item in our array and splice it out + // saving is done when the updateOwners method is called + let i = this.owners.findIndex(o => o.id === id) + this.owners.splice(i, 1) + }, + + // add a user as an owner to the list of show owners + addOwner (id) { + // we only have to push the user object to our owners array, if it is + // not already there. saving is done by the updateOwners method. + if (this.owners.findIndex(o => o.id === id) >= 0) { + alert('This user already has access to the show.') + } else { + this.owners.push(this.users.find(u => u.id === id)) + } + }, + + // set new list of show owners by updating the show + updateOwners (event) { + // prevent the modal from closing automatically on click + event.preventDefault() + // now we have to fill the show's owner list anew with the selected owners + this.show.owners = [] + for (let i in this.owners) { + this.show.owners.push(this.owners[i].id) + } + // ready to update the show + let uri = process.env.VUE_APP_API_STEERING_SHOWS + this.show.id + '/' + axios.put(uri, this.show, { + withCredentials: true, + headers: { 'Authorization': 'Bearer ' + this.$parent.$parent.user.access_token } + }).then(() => { + this.$refs.modalOwners.hide() + this.$parent.loadAndSwitch(this.show.id) + }).catch(error => { + this.$log.error(error.response.status + ' ' + error.response.statusText) + this.$log.error(error.response) + alert('Error: could not update show owners. See console for details.') + // and we leave the modal open, so no call to its .hide function here + }) + }, + // clear and fetch modal data and open the modal to add new shows showModalAddShow () { this.newShow.name = '' @@ -248,6 +415,14 @@ export default { this.$refs.modalDeleteShow.show() }, + // open the modal to edit a show's owners + showModalOwners (show) { + this.show = show + this.owners = [] + this.loadUsers() + this.$refs.modalOwners.show() + }, + // fetch all available (that is: active) show type from steering loadTypes () { this.loaded.types = false @@ -279,6 +454,25 @@ export default { alert('Error: could not load available funding categories. See console for details.') }) }, + + // fetch all users from steering + loadUsers () { + this.loaded.users = false + axios.get(process.env.VUE_APP_API_STEERING + 'users', { + withCredentials: true, + headers: { 'Authorization': 'Bearer ' + this.$parent.$parent.user.access_token } + }).then(response => { + this.users = response.data + for (let i in this.show.owners) { + this.owners.push(this.users.find(user => user.id === this.show.owners[i])) + } + this.loaded.users = true + }).catch(error => { + this.$log.error(error.response.status + ' ' + error.response.statusText) + this.$log.error(error.response) + alert('Error: could not load users. See console for details.') + }) + }, } } </script>