Fix #1131: More consistent search UX on /albums, /artists, /radios and /playlists

This commit is contained in:
Agate 2020-07-06 13:21:07 +02:00
parent f6a81a9ecf
commit da2229c441
5 changed files with 55 additions and 106 deletions

View File

@ -0,0 +1 @@
More consistent search UX on /albums, /artists, /radios and /playlists (#1131)

View File

@ -4,13 +4,18 @@
<h2 class="ui header"> <h2 class="ui header">
<translate translate-context="Content/Album/Title">Browsing albums</translate> <translate translate-context="Content/Album/Title">Browsing albums</translate>
</h2> </h2>
<div :class="['ui', {'loading': isLoading}, 'form']"> <form :class="['ui', {'loading': isLoading}, 'form']" @submit.prevent="updateQueryString();fetchData()">
<div class="fields"> <div class="fields">
<div class="field"> <div class="field">
<label> <label>
<translate translate-context="Content/Search/Input.Label/Noun">Search</translate> <translate translate-context="Content/Search/Input.Label/Noun">Search</translate>
</label> </label>
<input type="text" name="search" v-model="query" :placeholder="labels.searchPlaceholder"/> <div class="ui action input">
<input type="text" name="search" v-model="query" :placeholder="labels.searchPlaceholder"/>
<button class="ui icon button" type="submit" :aria-label="$pgettext('Content/Search/Input.Label/Noun', 'Search')">
<i class="search icon"></i>
</button>
</div>
</div> </div>
<div class="field"> <div class="field">
<label><translate translate-context="*/*/*/Noun">Tags</translate></label> <label><translate translate-context="*/*/*/Noun">Tags</translate></label>
@ -40,7 +45,7 @@
</select> </select>
</div> </div>
</div> </div>
</div> </form>
<div class="ui hidden divider"></div> <div class="ui hidden divider"></div>
<div <div
v-if="result" v-if="result"
@ -144,7 +149,7 @@ export default {
} }
}, },
methods: { methods: {
updateQueryString: _.debounce(function() { updateQueryString: function() {
history.pushState( history.pushState(
{}, {},
null, null,
@ -157,8 +162,8 @@ export default {
ordering: this.getOrderingAsString() ordering: this.getOrderingAsString()
}).toString() }).toString()
) )
}, 500), },
fetchData: _.debounce(function() { fetchData: function() {
var self = this var self = this
this.isLoading = true this.isLoading = true
let url = FETCH_URL let url = FETCH_URL
@ -187,7 +192,7 @@ export default {
self.result = null self.result = null
self.isLoading = false self.isLoading = false
}) })
}, 500), },
selectPage: function(page) { selectPage: function(page) {
this.page = page this.page = page
} }
@ -197,26 +202,6 @@ export default {
this.updateQueryString() this.updateQueryString()
this.fetchData() this.fetchData()
}, },
paginateBy() {
this.updateQueryString()
this.fetchData()
},
ordering() {
this.updateQueryString()
this.fetchData()
},
orderingDirection() {
this.updateQueryString()
this.fetchData()
},
query() {
this.updateQueryString()
this.fetchData()
},
tags() {
this.updateQueryString()
this.fetchData()
},
"$store.state.moderation.lastUpdate": function () { "$store.state.moderation.lastUpdate": function () {
this.fetchData() this.fetchData()
} }

View File

@ -4,13 +4,18 @@
<h2 class="ui header"> <h2 class="ui header">
<translate translate-context="Content/Artist/Title">Browsing artists</translate> <translate translate-context="Content/Artist/Title">Browsing artists</translate>
</h2> </h2>
<div :class="['ui', {'loading': isLoading}, 'form']"> <form :class="['ui', {'loading': isLoading}, 'form']" @submit.prevent="updateQueryString();fetchData()">
<div class="fields"> <div class="fields">
<div class="field"> <div class="field">
<label> <label>
<translate translate-context="Content/Search/Input.Label/Noun">Search</translate> <translate translate-context="Content/Search/Input.Label/Noun">Search</translate>
</label> </label>
<input type="text" name="search" v-model="query" :placeholder="labels.searchPlaceholder"/> <div class="ui action input">
<input type="text" name="search" v-model="query" :placeholder="labels.searchPlaceholder"/>
<button class="ui icon button" type="submit" :aria-label="$pgettext('Content/Search/Input.Label/Noun', 'Search')">
<i class="search icon"></i>
</button>
</div>
</div> </div>
<div class="field"> <div class="field">
<label><translate translate-context="*/*/*/Noun">Tags</translate></label> <label><translate translate-context="*/*/*/Noun">Tags</translate></label>
@ -40,7 +45,7 @@
</select> </select>
</div> </div>
</div> </div>
</div> </form>
<div class="ui hidden divider"></div> <div class="ui hidden divider"></div>
<div v-if="result && result.results.length > 0" class="ui five app-cards cards"> <div v-if="result && result.results.length > 0" class="ui five app-cards cards">
<div v-if="isLoading" class="ui inverted active dimmer"> <div v-if="isLoading" class="ui inverted active dimmer">
@ -134,7 +139,7 @@ export default {
} }
}, },
methods: { methods: {
updateQueryString: _.debounce(function() { updateQueryString: function() {
history.pushState( history.pushState(
{}, {},
null, null,
@ -147,8 +152,8 @@ export default {
ordering: this.getOrderingAsString() ordering: this.getOrderingAsString()
}).toString() }).toString()
) )
}, 500), },
fetchData: _.debounce(function() { fetchData: function() {
var self = this var self = this
this.isLoading = true this.isLoading = true
let url = FETCH_URL let url = FETCH_URL
@ -178,7 +183,7 @@ export default {
self.result = null self.result = null
self.isLoading = false self.isLoading = false
}) })
}, 500), },
selectPage: function(page) { selectPage: function(page) {
this.page = page this.page = page
} }
@ -188,26 +193,6 @@ export default {
this.updateQueryString() this.updateQueryString()
this.fetchData() this.fetchData()
}, },
paginateBy() {
this.updateQueryString()
this.fetchData()
},
ordering() {
this.updateQueryString()
this.fetchData()
},
orderingDirection() {
this.updateQueryString()
this.fetchData()
},
query() {
this.updateQueryString()
this.fetchData()
},
tags() {
this.updateQueryString()
this.fetchData()
},
"$store.state.moderation.lastUpdate": function () { "$store.state.moderation.lastUpdate": function () {
this.fetchData() this.fetchData()
} }

View File

@ -25,11 +25,16 @@
<translate translate-context="Content/Radio/Button.Label/Verb">Create your own radio</translate> <translate translate-context="Content/Radio/Button.Label/Verb">Create your own radio</translate>
</router-link> </router-link>
<div class="ui hidden divider"></div> <div class="ui hidden divider"></div>
<div :class="['ui', {'loading': isLoading}, 'form']"> <form :class="['ui', {'loading': isLoading}, 'form']" @submit.prevent="updateQueryString();fetchData()">
<div class="fields"> <div class="fields">
<div class="field"> <div class="field">
<label><translate translate-context="Content/Search/Input.Label/Noun">Search</translate></label> <label><translate translate-context="Content/Search/Input.Label/Noun">Search</translate></label>
<input name="search" type="text" v-model="query" :placeholder="labels.searchPlaceholder"/> <div class="ui action input">
<input type="text" name="search" v-model="query" :placeholder="labels.searchPlaceholder"/>
<button class="ui icon button" type="submit" :aria-label="$pgettext('Content/Search/Input.Label/Noun', 'Search')">
<i class="search icon"></i>
</button>
</div>
</div> </div>
<div class="field"> <div class="field">
<label><translate translate-context="Content/Search/Dropdown.Label/Noun">Ordering</translate></label> <label><translate translate-context="Content/Search/Dropdown.Label/Noun">Ordering</translate></label>
@ -59,7 +64,7 @@
</select> </select>
</div> </div>
</div> </div>
</div> </form>
<div class="ui hidden divider"></div> <div class="ui hidden divider"></div>
<div v-if="result && !result.results.length > 0" class="ui placeholder segment"> <div v-if="result && !result.results.length > 0" class="ui placeholder segment">
<div class="ui icon header"> <div class="ui icon header">
@ -157,7 +162,7 @@ export default {
}, },
}, },
methods: { methods: {
updateQueryString: _.debounce(function() { updateQueryString: function() {
history.pushState( history.pushState(
{}, {},
null, null,
@ -169,8 +174,8 @@ export default {
ordering: this.getOrderingAsString() ordering: this.getOrderingAsString()
}).toString() }).toString()
) )
}, 500), },
fetchData: _.debounce(function() { fetchData: function() {
var self = this var self = this
this.isLoading = true this.isLoading = true
let url = FETCH_URL let url = FETCH_URL
@ -186,7 +191,7 @@ export default {
self.result = response.data self.result = response.data
self.isLoading = false self.isLoading = false
}) })
}, 500), },
selectPage: function(page) { selectPage: function(page) {
this.page = page this.page = page
} }
@ -196,22 +201,6 @@ export default {
this.updateQueryString() this.updateQueryString()
this.fetchData() this.fetchData()
}, },
paginateBy() {
this.updateQueryString()
this.fetchData()
},
ordering() {
this.updateQueryString()
this.fetchData()
},
orderingDirection() {
this.updateQueryString()
this.fetchData()
},
query() {
this.updateQueryString()
this.fetchData()
}
} }
} }
</script> </script>

View File

@ -2,17 +2,22 @@
<main v-title="labels.playlists"> <main v-title="labels.playlists">
<section class="ui vertical stripe segment"> <section class="ui vertical stripe segment">
<h2 class="ui header"><translate translate-context="Content/Playlist/Title">Browsing playlists</translate></h2> <h2 class="ui header"><translate translate-context="Content/Playlist/Title">Browsing playlists</translate></h2>
<div :class="['ui', {'loading': isLoading}, 'form']"> <template v-if="$store.state.auth.authenticated">
<template v-if="$store.state.auth.authenticated"> <button
<button @click="$store.commit('playlists/chooseTrack', null)"
@click="$store.commit('playlists/chooseTrack', null)" class="ui basic success button"><translate translate-context="Content/Playlist/Button.Label/Verb">Manage your playlists</translate></button>
class="ui basic success button"><translate translate-context="Content/Playlist/Button.Label/Verb">Manage your playlists</translate></button> <div class="ui hidden divider"></div>
<div class="ui hidden divider"></div> </template>
</template> <form :class="['ui', {'loading': isLoading}, 'form']" @submit.prevent="updateQueryString();fetchData()">
<div class="fields"> <div class="fields">
<div class="field"> <div class="field">
<label><translate translate-context="Content/Search/Input.Label/Noun">Search</translate></label> <label><translate translate-context="Content/Search/Input.Label/Noun">Search</translate></label>
<input type="text" name="search" v-model="query" :placeholder="labels.searchPlaceholder"/> <div class="ui action input">
<input type="text" name="search" v-model="query" :placeholder="labels.searchPlaceholder"/>
<button class="ui icon button" type="submit" :aria-label="$pgettext('Content/Search/Input.Label/Noun', 'Search')">
<i class="search icon"></i>
</button>
</div>
</div> </div>
<div class="field"> <div class="field">
<label><translate translate-context="Content/Search/Dropdown.Label/Noun">Ordering</translate></label> <label><translate translate-context="Content/Search/Dropdown.Label/Noun">Ordering</translate></label>
@ -38,7 +43,7 @@
</select> </select>
</div> </div>
</div> </div>
</div> </form>
<div class="ui hidden divider"></div> <div class="ui hidden divider"></div>
<playlist-card-list v-if="result && result.results.length > 0" :playlists="result.results"></playlist-card-list> <playlist-card-list v-if="result && result.results.length > 0" :playlists="result.results"></playlist-card-list>
<div v-else-if="result && !result.results.length > 0" class="ui placeholder segment sixteen wide column" style="text-align: center; display: flex; align-items: center"> <div v-else-if="result && !result.results.length > 0" class="ui placeholder segment sixteen wide column" style="text-align: center; display: flex; align-items: center">
@ -124,7 +129,7 @@ export default {
} }
}, },
methods: { methods: {
updateQueryString: _.debounce(function() { updateQueryString: function() {
history.pushState( history.pushState(
{}, {},
null, null,
@ -136,8 +141,8 @@ export default {
ordering: this.getOrderingAsString() ordering: this.getOrderingAsString()
}).toString() }).toString()
) )
}, 250), },
fetchData: _.debounce(function() { fetchData: function() {
var self = this var self = this
this.isLoading = true this.isLoading = true
let url = FETCH_URL let url = FETCH_URL
@ -153,7 +158,7 @@ export default {
self.result = response.data self.result = response.data
self.isLoading = false self.isLoading = false
}) })
}, 500), },
selectPage: function(page) { selectPage: function(page) {
this.page = page this.page = page
} }
@ -163,22 +168,6 @@ export default {
this.updateQueryString() this.updateQueryString()
this.fetchData() this.fetchData()
}, },
paginateBy() {
this.updateQueryString()
this.fetchData()
},
ordering() {
this.updateQueryString()
this.fetchData()
},
orderingDirection() {
this.updateQueryString()
this.fetchData()
},
query() {
this.updateQueryString()
this.fetchData()
}
} }
} }
</script> </script>