diff --git a/api/funkwhale_api/federation/filters.py b/api/funkwhale_api/federation/filters.py index 3b5bfd739..ff7575ba5 100644 --- a/api/funkwhale_api/federation/filters.py +++ b/api/funkwhale_api/federation/filters.py @@ -1,6 +1,7 @@ import django_filters from funkwhale_api.common import fields +from funkwhale_api.common import search from . import models @@ -23,8 +24,21 @@ class LibraryFilter(django_filters.FilterSet): class LibraryTrackFilter(django_filters.FilterSet): library = django_filters.CharFilter("library__uuid") status = django_filters.CharFilter(method="filter_status") - q = fields.SearchFilter( - search_fields=["artist_name", "title", "album_title", "library__actor__domain"] + q = fields.SmartSearchFilter( + config=search.SearchConfig( + search_fields={ + "domain": {"to": "library__actor__domain"}, + "artist": {"to": "artist_name"}, + "album": {"to": "album_title"}, + "title": {"to": "title"}, + }, + filter_fields={ + "domain": {"to": "library__actor__domain"}, + "artist": {"to": "artist_name__iexact"}, + "album": {"to": "album_title__iexact"}, + "title": {"to": "title__iexact"}, + }, + ) ) def filter_status(self, queryset, field_name, value): diff --git a/changes/changelog.d/344.feature b/changes/changelog.d/344.feature new file mode 100644 index 000000000..6dc146673 --- /dev/null +++ b/changes/changelog.d/344.feature @@ -0,0 +1,22 @@ +Implemented a basic but functionnal Github-like search on federated tracks list (#344) + + +Improved search on federated tracks list +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Having a powerful but easy-to-use search is important but difficult to achieve, especially +if you do not want to have a real complex search interface. + +Github does a pretty good job with that, using a structured but simple query system +(See https://help.github.com/articles/searching-issues-and-pull-requests/#search-only-issues-or-pull-requests). + +This release implements a limited but working subset of this query system. You can use it only on the federated +tracks list (/manage/federation/tracks) at the moment, but depending on feedback it will be rolled-out on other pages as well. + +This is the type of query you can run: + +- ``hello world``: search for "hello" and "world" in all the available fields +- ``hello in:artist`` search for results where artist name is "hello" +- ``spring in:artist,album`` search for results where artist name or album title contain "spring" +- ``artist:hello`` search for results where artist name equals "hello" +- ``artist:"System of a Down" domain:instance.funkwhale`` search for results where artist name equals "System of a Down" and inside "instance.funkwhale" library diff --git a/front/src/App.vue b/front/src/App.vue index a6da038b2..8e1abae7f 100644 --- a/front/src/App.vue +++ b/front/src/App.vue @@ -236,6 +236,7 @@ html, body { .discrete.link { color: rgba(0, 0, 0, 0.87); + cursor: pointer; } .floated.buttons .button ~ .dropdown { diff --git a/front/src/components/federation/LibraryTrackTable.vue b/front/src/components/federation/LibraryTrackTable.vue index 645663964..082629197 100644 --- a/front/src/components/federation/LibraryTrackTable.vue +++ b/front/src/components/federation/LibraryTrackTable.vue @@ -2,7 +2,7 @@
-
+
@@ -56,16 +56,16 @@ {{ scope.obj.title|truncate(30) }} - {{ scope.obj.artist_name|truncate(30) }} + {{ scope.obj.artist_name|truncate(30) }} - {{ scope.obj.album_title|truncate(20) }} + {{ scope.obj.album_title|truncate(20) }} - {{ scope.obj.library.actor.domain }} + {{ scope.obj.library.actor.domain }} @@ -120,6 +120,12 @@ export default { this.fetchData() }, methods: { + updateSearch ({key, value}) { + if (value.indexOf(' ') > -1) { + value = `"${value}"` + } + this.search = `${key}:${value}` + }, fetchData () { let params = _.merge({ 'page': this.page,