From 6a9a34d244ddc4c4298e5c5364bb214f420691cf Mon Sep 17 00:00:00 2001 From: Eliot Berriot <contact@eliotberriot.com> Date: Wed, 21 Mar 2018 12:19:07 +0100 Subject: [PATCH] Can now clear playlist --- api/funkwhale_api/playlists/views.py | 8 ++++++ api/tests/playlists/test_views.py | 12 ++++++++ .../src/components/common/DangerousButton.vue | 10 +++++-- front/src/components/playlists/Editor.vue | 28 +++++++++++++++++-- 4 files changed, 52 insertions(+), 6 deletions(-) diff --git a/api/funkwhale_api/playlists/views.py b/api/funkwhale_api/playlists/views.py index 4880b1886d..7b2e7651d3 100644 --- a/api/funkwhale_api/playlists/views.py +++ b/api/funkwhale_api/playlists/views.py @@ -75,6 +75,14 @@ class PlaylistViewSet( } return Response(data, status=201) + @detail_route(methods=['delete']) + @transaction.atomic + def clear(self, request, *args, **kwargs): + playlist = self.get_object() + playlist.playlist_tracks.all().delete() + playlist.save(update_fields=['modification_date']) + return Response(status=204) + def get_queryset(self): return self.queryset.filter( fields.privacy_level_query(self.request.user)) diff --git a/api/tests/playlists/test_views.py b/api/tests/playlists/test_views.py index ae3fd00740..e70fef6f0d 100644 --- a/api/tests/playlists/test_views.py +++ b/api/tests/playlists/test_views.py @@ -170,3 +170,15 @@ def test_can_add_multiple_tracks_at_once_via_api( for plt in playlist.playlist_tracks.order_by('index'): assert response.data['results'][plt.index]['id'] == plt.id assert plt.track == tracks[plt.index] + + +def test_can_clear_playlist_from_api( + factories, mocker, logged_in_api_client): + playlist = factories['playlists.Playlist'](user=logged_in_api_client.user) + plts = factories['playlists.PlaylistTrack'].create_batch( + size=5, playlist=playlist) + url = reverse('api:v1:playlists-clear', kwargs={'pk': playlist.pk}) + response = logged_in_api_client.delete(url) + + assert response.status_code == 204 + assert playlist.playlist_tracks.count() == 0 diff --git a/front/src/components/common/DangerousButton.vue b/front/src/components/common/DangerousButton.vue index 03a579d296..525b4c48ff 100644 --- a/front/src/components/common/DangerousButton.vue +++ b/front/src/components/common/DangerousButton.vue @@ -1,5 +1,5 @@ <template> - <div @click="showModal = true" class="ui red button"> + <div @click="showModal = true" :class="['ui', color, {disabled: disabled}, 'button']" :disabled="disabled"> <slot></slot> <modal class="small" :show.sync="showModal"> @@ -13,7 +13,7 @@ </div> <div class="actions"> <div class="ui cancel button">Cancel</div> - <div class="ui confirm red button" @click="confirm"> + <div :class="['ui', 'confirm', color, 'button']" @click="confirm"> <slot name="modal-confirm">Confirm</slot> </div> </div> @@ -25,7 +25,11 @@ import Modal from '@/components/semantic/Modal' export default { - props: ['action'], + props: { + action: {type: Function, required: true}, + disabled: {type: Boolean, default: false}, + color: {type: String, default: 'red'} + }, components: { Modal }, diff --git a/front/src/components/playlists/Editor.vue b/front/src/components/playlists/Editor.vue index 6f9ddfcd4b..b4354be6aa 100644 --- a/front/src/components/playlists/Editor.vue +++ b/front/src/components/playlists/Editor.vue @@ -2,12 +2,20 @@ <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 class="ui buttons"> + <div> <div @click="insertMany(queueTracks)" :disabled="queueTracks.length === 0" - :class="['ui', {disabled: queueTracks.length === 0}, 'button']" - title="Copy tracks from current queue to playlist">Insert from queue ({{ queueTracks.length }} tracks)</div> + :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> @@ -95,6 +103,19 @@ export default { let url = 'playlist-tracks/' + plt.id + '/' axios.delete(url).then((response) => { self.success() + self.$store.dispatch('playlists/fetchOwn') + }, error => { + self.errored(error.backendErrors) + }) + }, + clearPlaylist () { + this.plts = [] + let self = this + self.isLoading = true + let url = 'playlists/' + this.playlist.id + '/clear' + axios.delete(url).then((response) => { + self.success() + self.$store.dispatch('playlists/fetchOwn') }, error => { self.errored(error.backendErrors) }) @@ -111,6 +132,7 @@ export default { self.plts.push(r) }) self.success() + self.$store.dispatch('playlists/fetchOwn') }, error => { self.errored(error.backendErrors) }) -- GitLab