diff --git a/front/src/components/playlists/Editor.vue b/front/src/components/playlists/Editor.vue index b4354be6aac142a85d84d42d89bfdee89f4099b7..c668857ea1f88557b22d77ecb81acdfd5fe52162 100644 --- a/front/src/components/playlists/Editor.vue +++ b/front/src/components/playlists/Editor.vue @@ -1,30 +1,16 @@ <template> <div class="ui text container"> - <h2 class="ui header">Playlist editor</h2> - <p>Drag and drop rows to reorder tracks in the playlist</p> - <div> - <div - @click="insertMany(queueTracks)" - :disabled="queueTracks.length === 0" - :class="['ui', {disabled: queueTracks.length === 0}, 'labeled', 'icon', 'button']" - title="Copy tracks from current queue to playlist"> - <i class="plus icon"></i> Insert from queue ({{ queueTracks.length }} tracks)</div> - - <dangerous-button :disabled="plts.length === 0" class="labeled right floated icon" color='yellow' :action="clearPlaylist"> - <i class="eraser icon"></i> Clear playlist - <p slot="modal-header">Do you want to clear the playlist "{{ playlist.name }}"?</p> - <p slot="modal-content">This will remove all tracks from this playlist and cannot be undone.</p> - <p slot="modal-confirm">Clear playlist</p> - </dangerous-button> - </div> - <h5 class="ui header">Status</h5> - <div> + <playlist-form @updated="$emit('playlist-updated', $event)" :title="false" :playlist="playlist"></playlist-form> + <h3 class="ui top attached header"> + Playlist editor + </h3> + <div class="ui attached segment"> <template v-if="status === 'loading'"> <div class="ui active tiny inline loader"></div> Syncing changes to server... </template> <template v-else-if="status === 'errored'"> - <i class="red x icon"></i> + <i class="red close icon"></i> An error occured while saving your changes <div v-if="errors.length > 0" class="ui negative message"> <ul class="list"> @@ -36,36 +22,57 @@ <i class="green check icon"></i> Changes synced with server </template> </div> - <table class="ui compact very basic fixed single line unstackable table"> - <draggable v-model="plts" element="tbody" @update="reorder"> - <tr v-for="(plt, index) in plts" :key="plt.id"> - <td class="left aligned">{{ plt.index + 1}}</td> - <td class="center aligned"> - <img class="ui mini image" v-if="plt.track.album.cover" :src="plt.track.album.cover"> - <img class="ui mini image" v-else src="../../assets/audio/default-cover.png"> - </td> - <td colspan="4"> - <strong>{{ plt.track.title }}</strong><br /> - {{ plt.track.artist.name }} - </td> - <td class="right aligned"> - <i @click.stop="removePlt(index)" class="circular red trash icon"></i> - </td> - </tr> - </draggable> - </table> + <div class="ui bottom attached segment"> + <div + @click="insertMany(queueTracks)" + :disabled="queueTracks.length === 0" + :class="['ui', {disabled: queueTracks.length === 0}, 'labeled', 'icon', 'button']" + title="Copy tracks from current queue to playlist"> + <i class="plus icon"></i> Insert from queue ({{ queueTracks.length }} tracks)</div> + + <dangerous-button :disabled="plts.length === 0" class="labeled right floated icon" color='yellow' :action="clearPlaylist"> + <i class="eraser icon"></i> Clear playlist + <p slot="modal-header">Do you want to clear the playlist "{{ playlist.name }}"?</p> + <p slot="modal-content">This will remove all tracks from this playlist and cannot be undone.</p> + <p slot="modal-confirm">Clear playlist</p> + </dangerous-button> + <div class="ui hidden divider"></div> + <template v-if="plts.length > 0"> + <p>Drag and drop rows to reorder tracks in the playlist</p> + <table class="ui compact very basic fixed single line unstackable table"> + <draggable v-model="plts" element="tbody" @update="reorder"> + <tr v-for="(plt, index) in plts" :key="plt.id"> + <td class="left aligned">{{ plt.index + 1}}</td> + <td class="center aligned"> + <img class="ui mini image" v-if="plt.track.album.cover" :src="plt.track.album.cover"> + <img class="ui mini image" v-else src="../../assets/audio/default-cover.png"> + </td> + <td colspan="4"> + <strong>{{ plt.track.title }}</strong><br /> + {{ plt.track.artist.name }} + </td> + <td class="right aligned"> + <i @click.stop="removePlt(index)" class="circular red trash icon"></i> + </td> + </tr> + </draggable> + </table> + </template> + </div> </div> </template> <script> import {mapState} from 'vuex' import axios from 'axios' +import PlaylistForm from '@/components/playlists/Form' import draggable from 'vuedraggable' export default { components: { - draggable + draggable, + PlaylistForm }, props: ['playlist', 'playlistTracks'], data () { diff --git a/front/src/components/playlists/Form.vue b/front/src/components/playlists/Form.vue index 21ddfeaec799972914392710e7aefc29c670c8a0..634e310bcdc2bb57484a8e048f65cfd8834da0d0 100644 --- a/front/src/components/playlists/Form.vue +++ b/front/src/components/playlists/Form.vue @@ -1,8 +1,15 @@ <template> <form class="ui form" @submit.prevent="submit()"> - <h4 class="ui header">Create a new playlist</h4> + <h4 v-if="title" class="ui header">Create a new playlist</h4> <div v-if="success" class="ui positive message"> - <div class="header">Playlist created</div> + <div class="header"> + <template v-if="playlist"> + Playlist updated + </template> + <template v-else> + Playlist created + </template> + </div> </div> <div v-if="errors.length > 0" class="ui negative message"> <div class="header">We cannot create the playlist</div> @@ -10,7 +17,7 @@ <li v-for="error in errors">{{ error }}</li> </ul> </div> - <div class="fields"> + <div class="three fields"> <div class="field"> <label>Playlist name</label> <input v-model="name" required type="text" placeholder="My awesome playlist" /> @@ -23,7 +30,10 @@ </div> <div class="field"> <label> </label> - <button :class="['ui', {'loading': isLoading}, 'button']" type="submit">Create playlist</button> + <button :class="['ui', 'fluid', {'loading': isLoading}, 'button']" type="submit"> + <template v-if="playlist">Update playlist</template> + <template v-else>Create playlist</template> + </button> </div> </div> </form> @@ -36,13 +46,15 @@ import axios from 'axios' import logger from '@/logging' export default { + props: { + title: {type: Boolean, default: true}, + playlist: {type: Object, default: null} + }, mounted () { $(this.$el).find('.dropdown').dropdown() }, data () { - return { - privacyLevel: this.$store.state.auth.profile.privacy_level, - name: '', + let d = { errors: [], success: false, isLoading: false, @@ -61,6 +73,14 @@ export default { } ] } + if (this.playlist) { + d.name = this.playlist.name + d.privacyLevel = this.playlist.privacy_level + } else { + d.privacyLevel = this.$store.state.auth.profile.privacy_level + d.name = '' + } + return d }, methods: { submit () { @@ -72,12 +92,23 @@ export default { name: this.name, privacy_level: this.privacyLevel } - let url = `playlists/` - return axios.post(url, payload).then(response => { - logger.default.info('Successfully created playlist') + + let promise + let url + if (this.playlist) { + url = `playlists/${this.playlist.id}/` + promise = axios.patch(url, payload) + } else { + url = 'playlists/' + promise = axios.post(url, payload) + } + return promise.then(response => { self.success = true self.isLoading = false - self.name = '' + if (!self.playlist) { + self.name = '' + } + self.$emit('updated', response.data) self.$store.dispatch('playlists/fetchOwn') }, error => { logger.default.error('Error while creating playlist') diff --git a/front/src/views/playlists/Detail.vue b/front/src/views/playlists/Detail.vue index 52c38b61814ded5a768c3c0d524cd859597dd767..6c3a988fd195ae3df5d4e597a69f4bb3dee9c40b 100644 --- a/front/src/views/playlists/Detail.vue +++ b/front/src/views/playlists/Detail.vue @@ -36,7 +36,10 @@ </div> <div class="ui vertical stripe segment"> <template v-if="edit"> - <playlist-editor @tracks-updated="updatePlts" :playlist="playlist" :playlist-tracks="playlistTracks"></playlist-editor> + <playlist-editor + @playlist-updated="playlist = $event" + @tracks-updated="updatePlts" + :playlist="playlist" :playlist-tracks="playlistTracks"></playlist-editor> </template> <template v-else> <h2>Tracks</h2>