allow editing playlist name and comment
This commit is contained in:
parent
383334cfe5
commit
8e9a6ca26d
@ -3,11 +3,17 @@
|
|||||||
<div class="d-flex justify-content-between">
|
<div class="d-flex justify-content-between">
|
||||||
<h1>{{ playlist.name }}</h1>
|
<h1>{{ playlist.name }}</h1>
|
||||||
<OverflowMenu>
|
<OverflowMenu>
|
||||||
|
<b-dropdown-item-btn @click="showEditModal = true">
|
||||||
|
Edit playlist
|
||||||
|
</b-dropdown-item-btn>
|
||||||
<b-dropdown-item-btn variant="danger" @click="deletePlaylist()">
|
<b-dropdown-item-btn variant="danger" @click="deletePlaylist()">
|
||||||
Delete playlist
|
Delete playlist
|
||||||
</b-dropdown-item-btn>
|
</b-dropdown-item-btn>
|
||||||
</OverflowMenu>
|
</OverflowMenu>
|
||||||
</div>
|
</div>
|
||||||
|
<p v-if="playlist.comment" class="text-muted">
|
||||||
|
{{ playlist.comment }}
|
||||||
|
</p>
|
||||||
<TrackList :tracks="playlist.tracks" @remove="remove(index)">
|
<TrackList :tracks="playlist.tracks" @remove="remove(index)">
|
||||||
<template #context-menu="{index}">
|
<template #context-menu="{index}">
|
||||||
<b-dropdown-item-button @click="remove(index)">
|
<b-dropdown-item-button @click="remove(index)">
|
||||||
@ -15,15 +21,30 @@
|
|||||||
</b-dropdown-item-button>
|
</b-dropdown-item-button>
|
||||||
</template>
|
</template>
|
||||||
</TrackList>
|
</TrackList>
|
||||||
|
<EditModal :visible.sync="showEditModal" :item="playlist" @confirm="updatePlaylist">
|
||||||
|
<template #title>
|
||||||
|
Edit playlist
|
||||||
|
</template>
|
||||||
|
<template #default="{ item }">
|
||||||
|
<b-form-group label="Name">
|
||||||
|
<b-form-input v-model="item.name" type="text" />
|
||||||
|
</b-form-group>
|
||||||
|
<b-form-group label="Comment">
|
||||||
|
<b-form-textarea v-model="item.comment" />
|
||||||
|
</b-form-group>
|
||||||
|
</template>
|
||||||
|
</EditModal>
|
||||||
</ContentLoader>
|
</ContentLoader>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import TrackList from '@/library/TrackList.vue'
|
import TrackList from '@/library/TrackList.vue'
|
||||||
|
import EditModal from '@/shared/components/EditModal.vue'
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
components: {
|
components: {
|
||||||
TrackList,
|
TrackList,
|
||||||
|
EditModal,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
id: { type: String, required: true }
|
id: { type: String, required: true }
|
||||||
@ -31,6 +52,7 @@
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
playlist: null as any,
|
playlist: null as any,
|
||||||
|
showEditModal: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
@ -49,6 +71,10 @@
|
|||||||
this.playlist.tracks.splice(index, 1)
|
this.playlist.tracks.splice(index, 1)
|
||||||
return this.$api.removeFromPlaylist(this.id, index.toString())
|
return this.$api.removeFromPlaylist(this.id, index.toString())
|
||||||
},
|
},
|
||||||
|
updatePlaylist(value: any) {
|
||||||
|
this.playlist = value
|
||||||
|
return this.$store.dispatch('updatePlaylist', this.playlist)
|
||||||
|
},
|
||||||
deletePlaylist() {
|
deletePlaylist() {
|
||||||
return this.$store.dispatch('deletePlaylist', this.id).then(() => {
|
return this.$store.dispatch('deletePlaylist', this.id).then(() => {
|
||||||
this.$router.replace({ name: 'playlists' })
|
this.$router.replace({ name: 'playlists' })
|
||||||
|
@ -203,6 +203,15 @@ export class API {
|
|||||||
return this.getPlaylists()
|
return this.getPlaylists()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async editPlaylist(playlistId: string, name: string, comment: string) {
|
||||||
|
const params = {
|
||||||
|
playlistId,
|
||||||
|
name,
|
||||||
|
comment,
|
||||||
|
}
|
||||||
|
await this.get('rest/updatePlaylist', params)
|
||||||
|
}
|
||||||
|
|
||||||
async deletePlaylist(id: string) {
|
async deletePlaylist(id: string) {
|
||||||
await this.get('rest/deletePlaylist', { id })
|
await this.get('rest/deletePlaylist', { id })
|
||||||
}
|
}
|
||||||
|
44
src/shared/components/EditModal.vue
Normal file
44
src/shared/components/EditModal.vue
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<template>
|
||||||
|
<b-modal ok-title="Save" :visible="visible" @ok="confirm" @change="change">
|
||||||
|
<template #modal-title>
|
||||||
|
<slot name="title" :item="copy">
|
||||||
|
{{ title }}
|
||||||
|
</slot>
|
||||||
|
</template>
|
||||||
|
<template v-if="visible">
|
||||||
|
<slot :item="copy" />
|
||||||
|
</template>
|
||||||
|
</b-modal>
|
||||||
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
|
import Vue from 'vue'
|
||||||
|
|
||||||
|
export default Vue.extend({
|
||||||
|
props: {
|
||||||
|
item: { type: Object, default: null },
|
||||||
|
visible: { type: Boolean, required: true },
|
||||||
|
title: { type: String, default: '' },
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
copy: null,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
item: {
|
||||||
|
immediate: true,
|
||||||
|
handler(value: any) {
|
||||||
|
this.copy = { ...value }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
confirm() {
|
||||||
|
this.$emit('confirm', this.copy)
|
||||||
|
},
|
||||||
|
change() {
|
||||||
|
this.$emit('update:visible', false)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
@ -13,6 +13,7 @@ import {
|
|||||||
BFormCheckbox,
|
BFormCheckbox,
|
||||||
BFormGroup,
|
BFormGroup,
|
||||||
BFormInput,
|
BFormInput,
|
||||||
|
BFormTextarea,
|
||||||
BModal,
|
BModal,
|
||||||
BOverlay,
|
BOverlay,
|
||||||
BProgress,
|
BProgress,
|
||||||
@ -27,6 +28,7 @@ Vue.component('BSidebar', BSidebar)
|
|||||||
Vue.component('BFormGroup', BFormGroup)
|
Vue.component('BFormGroup', BFormGroup)
|
||||||
Vue.component('BFormInput', BFormInput)
|
Vue.component('BFormInput', BFormInput)
|
||||||
Vue.component('BFormCheckbox', BFormCheckbox)
|
Vue.component('BFormCheckbox', BFormCheckbox)
|
||||||
|
Vue.component('BFormTextarea', BFormTextarea)
|
||||||
Vue.component('BButton', BButton)
|
Vue.component('BButton', BButton)
|
||||||
Vue.component('BProgress', BProgress)
|
Vue.component('BProgress', BProgress)
|
||||||
Vue.component('BOverlay', BOverlay)
|
Vue.component('BOverlay', BOverlay)
|
||||||
|
@ -41,6 +41,10 @@ const setupRootModule = (authService: AuthService, api: API): Module<State, any>
|
|||||||
state.playlists = playlists
|
state.playlists = playlists
|
||||||
.sort((a: any, b: any) => b.changed.localeCompare(a.changed))
|
.sort((a: any, b: any) => b.changed.localeCompare(a.changed))
|
||||||
},
|
},
|
||||||
|
setPlaylist(state, playlist: any) {
|
||||||
|
const idx = state.playlists.findIndex(x => x.id === playlist.id)
|
||||||
|
state.playlists.splice(idx, 1, playlist)
|
||||||
|
},
|
||||||
removePlaylist(state, id: string) {
|
removePlaylist(state, id: string) {
|
||||||
state.playlists = state.playlists.filter(p => p.id !== id)
|
state.playlists = state.playlists.filter(p => p.id !== id)
|
||||||
},
|
},
|
||||||
@ -62,6 +66,16 @@ const setupRootModule = (authService: AuthService, api: API): Module<State, any>
|
|||||||
commit('setPlaylists', result)
|
commit('setPlaylists', result)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
updatePlaylist({ commit, state }, { id, name, comment }) {
|
||||||
|
api.editPlaylist(id, name, comment).then(() => {
|
||||||
|
const playlist = {
|
||||||
|
...state.playlists.find(x => x.id === id),
|
||||||
|
name,
|
||||||
|
comment,
|
||||||
|
}
|
||||||
|
commit('setPlaylist', playlist)
|
||||||
|
})
|
||||||
|
},
|
||||||
addTrackToPlaylist({ }, { playlistId, trackId }) {
|
addTrackToPlaylist({ }, { playlistId, trackId }) {
|
||||||
api.addToPlaylist(playlistId, trackId)
|
api.addToPlaylist(playlistId, trackId)
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user