Merge branch 'add-filter-in-add-to-playlist' into 'develop'

Add field to filter existing playlists in “add to playlist…” dialog

Closes #974

See merge request funkwhale/funkwhale!966
environments/review-front-serv-f1ybnc/deployments/3672
Eliot Berriot 2019-12-07 17:06:24 +01:00
commit 4fc54fcc1e
2 zmienionych plików z 50 dodań i 20 usunięć

Wyświetl plik

@ -0,0 +1 @@
Support filtering playlist by name and several additional UX improvements in playlists modal (#974)

Wyświetl plik

@ -1,29 +1,30 @@
<template>
<modal @update:show="update" :show="$store.state.playlists.showModal">
<div class="header">
<translate translate-context="Popup/Playlist/Title/Verb">Manage playlists</translate>
</div>
<div class="scrolling content">
<div class="description">
<template v-if="track">
<h4 class="ui header"><translate translate-context="Popup/Playlist/Title">Current track</translate></h4>
<span
<template v-if="track">
<h2 class="ui header">
<translate translate-context="Popup/Playlist/Title/Verb">Add to playlist</translate>
<div
class="ui sub header"
translate-context="Popup/Playlist/Paragraph"
v-translate="{artist: track.artist.name, title: track.title}"
:translate-params="{artist: track.artist.name, title: track.title}">
"%{ title }", by %{ artist }
</span>
<div class="ui divider"></div>
</template>
<playlist-form :key="formKey"></playlist-form>
<div class="ui divider"></div>
</div>
</h2>
</template>
<translate v-else translate-context="Popup/Playlist/Title/Verb">Manage playlists</translate>
</div>
<div class="scrolling content">
<playlist-form :key="formKey"></playlist-form>
<div class="ui divider"></div>
<div v-if="playlists.length > 0">
<div v-if="showDuplicateTrackAddConfirmation" class="ui warning message">
<p translate-context="Popup/Playlist/Paragraph"
v-translate="{track: track.title, playlist: duplicateTrackAddInfo.playlist_name}"
:translate-params="{track: track.title, playlist: duplicateTrackAddInfo.playlist_name}"><strong>%{ track }</strong> is already in <strong>%{ playlist }</strong>.</p>
<button
@click="update(false)"
@click="duplicateTrackAddConfirm(false)"
class="ui small cancel button"><translate translate-context="*/*/Button.Label/Verb">Cancel</translate>
</button>
<button
@ -37,10 +38,16 @@
<li v-for="error in errors">{{ error }}</li>
</ul>
</div>
</div>
<div v-if="playlists.length > 0">
<h4 class="ui header"><translate translate-context="Popup/Playlist/Title">Available playlists</translate></h4>
<table class="ui unstackable very basic table">
<div class="ui form">
<div class="fields">
<div class="field">
<label for="playlist-name-filter"><translate translate-context="Popup/Playlist/Label">Filter</translate></label>
<input name="playlist-name-filter" v-model="playlistNameFilter" type="text" class="inline" :placeholder="labels.filterPlaylistField" />
</div>
</div>
</div>
<table v-if="sortedPlaylists.length > 0" class="ui unstackable very basic table">
<thead>
<tr>
<th></th>
@ -73,6 +80,13 @@
</tr>
</tbody>
</table>
<template v-else>
<div class="ui small placeholder segment">
<div class="ui header">
<translate translate-context="Popup/Playlist/EmptyState">No results matching your filter</translate>
</div>
</div>
</template>
</div>
<template v-else>
<div class="ui placeholder segment">
@ -93,7 +107,10 @@
</template>
<script>
import _ from '@/lodash'
import filter from "lodash/fp/filter";
import sortBy from "lodash/fp/sortBy";
import flow from "lodash/fp/flow";
import axios from 'axios'
import {mapState} from 'vuex'
@ -110,6 +127,7 @@ export default {
return {
formKey: String(new Date()),
errors: [],
playlistNameFilter: '',
duplicateTrackAddInfo: {},
showDuplicateTrackAddConfirmation: false,
lastSelectedPlaylist: -1,
@ -142,6 +160,9 @@ export default {
self.showDuplicateTrackAddConfirmation = false
}
})
},
duplicateTrackAddConfirm (v) {
this.showDuplicateTrackAddConfirmation = v
}
},
computed: {
@ -151,11 +172,16 @@ export default {
}),
labels () {
return {
addToPlaylist: this.$pgettext('Popup/Playlist/Table.Button.Tooltip/Verb', 'Add to this playlist')
addToPlaylist: this.$pgettext('Popup/Playlist/Table.Button.Tooltip/Verb', 'Add to this playlist'),
filterPlaylistField: this.$pgettext('Popup/Playlist/Form/Placeholder', 'Enter playlist name')
}
},
sortedPlaylists () {
let p = _.sortBy(this.playlists, [(e) => { return e.modification_date }])
let regexp = new RegExp(this.playlistNameFilter, 'i');
let p = flow(
filter((e) => e.name.match(regexp) !== null),
sortBy((e) => { return e.modification_date }),
)(this.playlists)
p.reverse()
return p
}
@ -175,4 +201,7 @@ export default {
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.ui.small.placeholder.segment {
min-height: auto;
}
</style>