From ccca292405d1536778bd0caa466430d4e6694324 Mon Sep 17 00:00:00 2001 From: Eliot Berriot <contact@eliotberriot.com> Date: Tue, 16 Jul 2019 14:50:39 +0200 Subject: [PATCH] See #432: added tag filter on artist/album browse page --- front/package.json | 1 + front/src/components/library/Albums.vue | 31 ++++++++++++++++--- front/src/components/library/Artists.vue | 31 ++++++++++++++++--- front/src/components/library/TagsSelector.vue | 2 +- front/src/router/index.js | 2 ++ front/yarn.lock | 2 +- 6 files changed, 59 insertions(+), 10 deletions(-) diff --git a/front/package.json b/front/package.json index 54cf3c8e..2c8f041f 100644 --- a/front/package.json +++ b/front/package.json @@ -22,6 +22,7 @@ "masonry-layout": "^4.2.2", "moment": "^2.22.2", "fomantic-ui-css": "^2.7", + "qs": "^6.7.0", "showdown": "^1.8.6", "vue": "^2.5.17", "vue-gettext": "^2.1.0", diff --git a/front/src/components/library/Albums.vue b/front/src/components/library/Albums.vue index 9817af83..ed97f7a4 100644 --- a/front/src/components/library/Albums.vue +++ b/front/src/components/library/Albums.vue @@ -20,6 +20,10 @@ </option> </select> </div> + <div class="field"> + <label><translate translate-context="*/*/*/Noun">Tags</translate></label> + <tags-selector v-model="tags"></tags-selector> + </div> <div class="field"> <label><translate translate-context="Content/Search/Dropdown.Label/Noun">Ordering direction</translate></label> <select class="ui dropdown" v-model="orderingDirection"> @@ -70,6 +74,7 @@ </template> <script> +import qs from 'qs' import axios from "axios" import _ from "@/lodash" import $ from "jquery" @@ -81,17 +86,20 @@ import PaginationMixin from "@/components/mixins/Pagination" import TranslationsMixin from "@/components/mixins/Translations" import AlbumCard from "@/components/audio/album/Card" import Pagination from "@/components/Pagination" +import TagsSelector from '@/components/library/TagsSelector' const FETCH_URL = "albums/" export default { mixins: [OrderingMixin, PaginationMixin, TranslationsMixin], props: { - defaultQuery: { type: String, required: false, default: "" } + defaultQuery: { type: String, required: false, default: "" }, + defaultTags: { type: Array, required: false, default: () => { return [] } }, }, components: { AlbumCard, - Pagination + Pagination, + TagsSelector, }, data() { let defaultOrdering = this.getOrderingFromString( @@ -102,6 +110,7 @@ export default { result: null, page: parseInt(this.defaultPage), query: this.defaultQuery, + tags: this.defaultTags.filter((t) => { return t.length > 0 }) || [], paginateBy: parseInt(this.defaultPaginateBy || 25), orderingDirection: defaultOrdering.direction || "+", ordering: defaultOrdering.field, @@ -130,6 +139,7 @@ export default { query: { query: this.query, page: this.page, + tag: this.tags, paginateBy: this.paginateBy, ordering: this.getOrderingAsString() } @@ -144,10 +154,19 @@ export default { page_size: this.paginateBy, q: this.query, ordering: this.getOrderingAsString(), - playable: "true" + playable: "true", + tag: this.tags, } logger.default.debug("Fetching albums") - axios.get(url, { params: params }).then(response => { + axios.get( + url, + { + params: params, + paramsSerializer: function(params) { + return qs.stringify(params, { indices: false }) + } + } + ).then(response => { self.result = response.data self.isLoading = false }) @@ -177,6 +196,10 @@ export default { this.updateQueryString() this.fetchData() }, + tags() { + this.updateQueryString() + this.fetchData() + }, "$store.state.moderation.lastUpdate": function () { this.fetchData() } diff --git a/front/src/components/library/Artists.vue b/front/src/components/library/Artists.vue index 5f4102ab..f16a6740 100644 --- a/front/src/components/library/Artists.vue +++ b/front/src/components/library/Artists.vue @@ -12,6 +12,10 @@ </label> <input type="text" name="search" v-model="query" :placeholder="labels.searchPlaceholder"/> </div> + <div class="field"> + <label><translate translate-context="*/*/*/Noun">Tags</translate></label> + <tags-selector v-model="tags"></tags-selector> + </div> <div class="field"> <label><translate translate-context="Content/Search/Dropdown.Label/Noun">Ordering</translate></label> <select class="ui dropdown" v-model="ordering"> @@ -67,6 +71,7 @@ </template> <script> +import qs from 'qs' import axios from "axios" import _ from "@/lodash" import $ from "jquery" @@ -78,17 +83,20 @@ import PaginationMixin from "@/components/mixins/Pagination" import TranslationsMixin from "@/components/mixins/Translations" import ArtistCard from "@/components/audio/artist/Card" import Pagination from "@/components/Pagination" +import TagsSelector from '@/components/library/TagsSelector' const FETCH_URL = "artists/" export default { mixins: [OrderingMixin, PaginationMixin, TranslationsMixin], props: { - defaultQuery: { type: String, required: false, default: "" } + defaultQuery: { type: String, required: false, default: "" }, + defaultTags: { type: Array, required: false, default: () => { return [] } }, }, components: { ArtistCard, - Pagination + Pagination, + TagsSelector, }, data() { let defaultOrdering = this.getOrderingFromString( @@ -99,6 +107,7 @@ export default { result: null, page: parseInt(this.defaultPage), query: this.defaultQuery, + tags: this.defaultTags.filter((t) => { return t.length > 0 }) || [], paginateBy: parseInt(this.defaultPaginateBy || 12), orderingDirection: defaultOrdering.direction || "+", ordering: defaultOrdering.field, @@ -127,6 +136,7 @@ export default { query: { query: this.query, page: this.page, + tag: this.tags, paginateBy: this.paginateBy, ordering: this.getOrderingAsString() } @@ -141,10 +151,19 @@ export default { page_size: this.paginateBy, name__icontains: this.query, ordering: this.getOrderingAsString(), - playable: "true" + playable: "true", + tag: this.tags, } logger.default.debug("Fetching artists") - axios.get(url, { params: params }).then(response => { + axios.get( + url, + { + params: params, + paramsSerializer: function(params) { + return qs.stringify(params, { indices: false }) + } + } + ).then(response => { self.result = response.data self.isLoading = false }) @@ -174,6 +193,10 @@ export default { this.updateQueryString() this.fetchData() }, + tags() { + this.updateQueryString() + this.fetchData() + }, "$store.state.moderation.lastUpdate": function () { this.fetchData() } diff --git a/front/src/components/library/TagsSelector.vue b/front/src/components/library/TagsSelector.vue index 5494fe9f..47cb83fa 100644 --- a/front/src/components/library/TagsSelector.vue +++ b/front/src/components/library/TagsSelector.vue @@ -4,7 +4,7 @@ <i class="dropdown icon"></i> <input type="text" class="search"> <div class="default text"> - <translate translate-context="*/Dropdown/Placeholder/Verb">Search for existing tags…</translate> + <translate translate-context="*/Dropdown/Placeholder/Verb">Search for tags…</translate> </div> </div> </template> diff --git a/front/src/router/index.js b/front/src/router/index.js index 6a9ba611..630d4890 100644 --- a/front/src/router/index.js +++ b/front/src/router/index.js @@ -401,6 +401,7 @@ export default new Router({ props: (route) => ({ defaultOrdering: route.query.ordering, defaultQuery: route.query.query, + defaultTags: Array.isArray(route.query.tag || []) ? route.query.tag : [route.query.tag], defaultPaginateBy: route.query.paginateBy, defaultPage: route.query.page }) @@ -413,6 +414,7 @@ export default new Router({ props: (route) => ({ defaultOrdering: route.query.ordering, defaultQuery: route.query.query, + defaultTags: Array.isArray(route.query.tag || []) ? route.query.tag : [route.query.tag], defaultPaginateBy: route.query.paginateBy, defaultPage: route.query.page }) diff --git a/front/yarn.lock b/front/yarn.lock index 1959e9e1..68e12838 100644 --- a/front/yarn.lock +++ b/front/yarn.lock @@ -7324,7 +7324,7 @@ q@^1.1.2: resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= -qs@6.7.0: +qs@6.7.0, qs@^6.7.0: version "6.7.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== -- GitLab