Can now clear playlist
This commit is contained in:
parent
f66dff3504
commit
6a9a34d244
|
@ -75,6 +75,14 @@ class PlaylistViewSet(
|
||||||
}
|
}
|
||||||
return Response(data, status=201)
|
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):
|
def get_queryset(self):
|
||||||
return self.queryset.filter(
|
return self.queryset.filter(
|
||||||
fields.privacy_level_query(self.request.user))
|
fields.privacy_level_query(self.request.user))
|
||||||
|
|
|
@ -170,3 +170,15 @@ def test_can_add_multiple_tracks_at_once_via_api(
|
||||||
for plt in playlist.playlist_tracks.order_by('index'):
|
for plt in playlist.playlist_tracks.order_by('index'):
|
||||||
assert response.data['results'][plt.index]['id'] == plt.id
|
assert response.data['results'][plt.index]['id'] == plt.id
|
||||||
assert plt.track == tracks[plt.index]
|
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
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div @click="showModal = true" class="ui red button">
|
<div @click="showModal = true" :class="['ui', color, {disabled: disabled}, 'button']" :disabled="disabled">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
|
|
||||||
<modal class="small" :show.sync="showModal">
|
<modal class="small" :show.sync="showModal">
|
||||||
|
@ -13,7 +13,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<div class="ui cancel button">Cancel</div>
|
<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>
|
<slot name="modal-confirm">Confirm</slot>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -25,7 +25,11 @@
|
||||||
import Modal from '@/components/semantic/Modal'
|
import Modal from '@/components/semantic/Modal'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: ['action'],
|
props: {
|
||||||
|
action: {type: Function, required: true},
|
||||||
|
disabled: {type: Boolean, default: false},
|
||||||
|
color: {type: String, default: 'red'}
|
||||||
|
},
|
||||||
components: {
|
components: {
|
||||||
Modal
|
Modal
|
||||||
},
|
},
|
||||||
|
|
|
@ -2,12 +2,20 @@
|
||||||
<div class="ui text container">
|
<div class="ui text container">
|
||||||
<h2 class="ui header">Playlist editor</h2>
|
<h2 class="ui header">Playlist editor</h2>
|
||||||
<p>Drag and drop rows to reorder tracks in the playlist</p>
|
<p>Drag and drop rows to reorder tracks in the playlist</p>
|
||||||
<div class="ui buttons">
|
<div>
|
||||||
<div
|
<div
|
||||||
@click="insertMany(queueTracks)"
|
@click="insertMany(queueTracks)"
|
||||||
:disabled="queueTracks.length === 0"
|
:disabled="queueTracks.length === 0"
|
||||||
:class="['ui', {disabled: queueTracks.length === 0}, 'button']"
|
:class="['ui', {disabled: queueTracks.length === 0}, 'labeled', 'icon', 'button']"
|
||||||
title="Copy tracks from current queue to playlist">Insert from queue ({{ queueTracks.length }} tracks)</div>
|
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>
|
</div>
|
||||||
<h5 class="ui header">Status</h5>
|
<h5 class="ui header">Status</h5>
|
||||||
<div>
|
<div>
|
||||||
|
@ -95,6 +103,19 @@ export default {
|
||||||
let url = 'playlist-tracks/' + plt.id + '/'
|
let url = 'playlist-tracks/' + plt.id + '/'
|
||||||
axios.delete(url).then((response) => {
|
axios.delete(url).then((response) => {
|
||||||
self.success()
|
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 => {
|
}, error => {
|
||||||
self.errored(error.backendErrors)
|
self.errored(error.backendErrors)
|
||||||
})
|
})
|
||||||
|
@ -111,6 +132,7 @@ export default {
|
||||||
self.plts.push(r)
|
self.plts.push(r)
|
||||||
})
|
})
|
||||||
self.success()
|
self.success()
|
||||||
|
self.$store.dispatch('playlists/fetchOwn')
|
||||||
}, error => {
|
}, error => {
|
||||||
self.errored(error.backendErrors)
|
self.errored(error.backendErrors)
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue