Allow to filter search by multiple tags
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
parent
50666e5dd7
commit
2198b2cb87
|
@ -1,8 +1,8 @@
|
||||||
import gql from "graphql-tag";
|
import gql from "graphql-tag";
|
||||||
|
|
||||||
export const SEARCH_EVENTS = gql`
|
export const SEARCH_EVENTS = gql`
|
||||||
query SearchEvents($location: String, $radius: Float, $tag: String, $term: String) {
|
query SearchEvents($location: String, $radius: Float, $tags: String, $term: String) {
|
||||||
searchEvents(location: $location, radius: $radius, tag: $tag, term: $term) {
|
searchEvents(location: $location, radius: $radius, tags: $tags, term: $term) {
|
||||||
total
|
total
|
||||||
elements {
|
elements {
|
||||||
title
|
title
|
||||||
|
|
|
@ -83,7 +83,7 @@ const tabsName: { events: number; groups: number } = {
|
||||||
variables() {
|
variables() {
|
||||||
return {
|
return {
|
||||||
term: this.search,
|
term: this.search,
|
||||||
tag: this.actualTag,
|
tags: this.actualTag,
|
||||||
location: this.geohash,
|
location: this.geohash,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
|
@ -46,7 +46,7 @@ defmodule Mobilizon.GraphQL.Schema.SearchType do
|
||||||
@desc "Search events"
|
@desc "Search events"
|
||||||
field :search_events, :events do
|
field :search_events, :events do
|
||||||
arg(:term, :string, default_value: "")
|
arg(:term, :string, default_value: "")
|
||||||
arg(:tag, :string)
|
arg(:tags, :string, description: "A comma-separated string listing the tags")
|
||||||
arg(:location, :string, description: "A geohash for coordinates")
|
arg(:location, :string, description: "A geohash for coordinates")
|
||||||
arg(:radius, :float, default_value: 50)
|
arg(:radius, :float, default_value: 50)
|
||||||
arg(:page, :integer, default_value: 1)
|
arg(:page, :integer, default_value: 1)
|
||||||
|
|
|
@ -463,9 +463,11 @@ defmodule Mobilizon.Events do
|
||||||
term
|
term
|
||||||
|> normalize_search_string()
|
|> normalize_search_string()
|
||||||
|> events_for_search_query()
|
|> events_for_search_query()
|
||||||
|> events_for_tag(args)
|
|> events_for_tags(args)
|
||||||
|> events_for_location(args)
|
|> events_for_location(args)
|
||||||
|
|> filter_future_events(true)
|
||||||
|> filter_local_or_from_followed_instances_events()
|
|> filter_local_or_from_followed_instances_events()
|
||||||
|
|> order_by([q], asc: q.id)
|
||||||
|> Page.build_page(page, limit)
|
|> Page.build_page(page, limit)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1279,11 +1281,12 @@ defmodule Mobilizon.Events do
|
||||||
defp events_for_search_query(search_string) do
|
defp events_for_search_query(search_string) do
|
||||||
Event
|
Event
|
||||||
|> where([e], e.visibility == ^:public)
|
|> where([e], e.visibility == ^:public)
|
||||||
|
|> distinct([e], e.id)
|
||||||
|> do_event_for_search_query(search_string)
|
|> do_event_for_search_query(search_string)
|
||||||
end
|
end
|
||||||
|
|
||||||
@spec do_event_for_search_query(Ecto.Query.t(), String.t()) :: Ecto.Query.t()
|
@spec do_event_for_search_query(Ecto.Query.t(), String.t()) :: Ecto.Query.t()
|
||||||
# defp do_event_for_search_query(query, ""), do: query
|
defp do_event_for_search_query(query, ""), do: query
|
||||||
|
|
||||||
defp do_event_for_search_query(query, search_string) do
|
defp do_event_for_search_query(query, search_string) do
|
||||||
from(event in query,
|
from(event in query,
|
||||||
|
@ -1293,19 +1296,19 @@ defmodule Mobilizon.Events do
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
@spec events_for_tag(Ecto.Query.t(), map()) :: Ecto.Query.t()
|
@spec events_for_tags(Ecto.Query.t(), map()) :: Ecto.Query.t()
|
||||||
defp events_for_tag(query, %{tag: tag}) when not is_nil(tag) and tag != "" do
|
defp events_for_tags(query, %{tags: tags}) when is_valid_string?(tags) do
|
||||||
query
|
query
|
||||||
|> join(:inner, [q, _r], te in "events_tags", on: q.id == te.event_id)
|
|> join(:inner, [q], te in "events_tags", on: q.id == te.event_id)
|
||||||
|> join(:inner, [q, _r, te], t in Tag, on: te.tag_id == t.id)
|
|> join(:inner, [q, ..., te], t in Tag, on: te.tag_id == t.id)
|
||||||
|> where([q, _r, te, t], t.title == ^tag)
|
|> where([q, ..., t], t.title in ^String.split(tags, ",", trim: true))
|
||||||
end
|
end
|
||||||
|
|
||||||
defp events_for_tag(query, _args), do: query
|
defp events_for_tags(query, _args), do: query
|
||||||
|
|
||||||
@spec events_for_location(Ecto.Query.t(), map()) :: Ecto.Query.t()
|
@spec events_for_location(Ecto.Query.t(), map()) :: Ecto.Query.t()
|
||||||
defp events_for_location(query, %{location: location, radius: radius})
|
defp events_for_location(query, %{location: location, radius: radius})
|
||||||
when not is_nil_or_empty_string(location) and not is_nil(radius) do
|
when is_valid_string?(location) and not is_nil(radius) do
|
||||||
with {lon, lat} <- Geohax.decode(location),
|
with {lon, lat} <- Geohax.decode(location),
|
||||||
point <- Geo.WKT.decode!("SRID=4326;POINT(#{lon} #{lat})") do
|
point <- Geo.WKT.decode!("SRID=4326;POINT(#{lon} #{lat})") do
|
||||||
query
|
query
|
||||||
|
@ -1553,6 +1556,7 @@ defmodule Mobilizon.Events do
|
||||||
|
|
||||||
defp filter_future_events(query, false), do: query
|
defp filter_future_events(query, false), do: query
|
||||||
|
|
||||||
|
@spec filter_local_or_from_followed_instances_events(Ecto.Query.t()) :: Ecto.Query.t()
|
||||||
defp filter_local_or_from_followed_instances_events(query) do
|
defp filter_local_or_from_followed_instances_events(query) do
|
||||||
from(q in query,
|
from(q in query,
|
||||||
left_join: s in Share,
|
left_join: s in Share,
|
||||||
|
|
|
@ -3,5 +3,7 @@ defmodule Mobilizon.Service.Guards do
|
||||||
Various guards
|
Various guards
|
||||||
"""
|
"""
|
||||||
|
|
||||||
defguard is_nil_or_empty_string(value) when is_nil(value) or value == ""
|
defguard is_valid_string?(value) when is_binary(value) and value != ""
|
||||||
|
|
||||||
|
defguard is_valid_list?(value) when is_list(value) and length(value) > 0
|
||||||
end
|
end
|
||||||
|
|
|
@ -15,8 +15,8 @@ defmodule Mobilizon.GraphQL.Resolvers.SearchTest do
|
||||||
|
|
||||||
describe "search events/3" do
|
describe "search events/3" do
|
||||||
@search_events_query """
|
@search_events_query """
|
||||||
query SearchEvents($location: String, $radius: Float, $tag: String, $term: String) {
|
query SearchEvents($location: String, $radius: Float, $tags: String, $term: String) {
|
||||||
searchEvents(location: $location, radius: $radius, tag: $tag, term: $term) {
|
searchEvents(location: $location, radius: $radius, tags: $tags, term: $term) {
|
||||||
total,
|
total,
|
||||||
elements {
|
elements {
|
||||||
id
|
id
|
||||||
|
@ -108,12 +108,13 @@ defmodule Mobilizon.GraphQL.Resolvers.SearchTest do
|
||||||
tag = insert(:tag, title: "Café")
|
tag = insert(:tag, title: "Café")
|
||||||
tag2 = insert(:tag, title: "Thé")
|
tag2 = insert(:tag, title: "Thé")
|
||||||
event = insert(:event, title: "Tour du monde", tags: [tag, tag2])
|
event = insert(:event, title: "Tour du monde", tags: [tag, tag2])
|
||||||
|
insert(:event, title: "Autre événement")
|
||||||
Workers.BuildSearch.insert_search_event(event)
|
Workers.BuildSearch.insert_search_event(event)
|
||||||
|
|
||||||
res =
|
res =
|
||||||
AbsintheHelpers.graphql_query(conn,
|
AbsintheHelpers.graphql_query(conn,
|
||||||
query: @search_events_query,
|
query: @search_events_query,
|
||||||
variables: %{tag: "Café"}
|
variables: %{tags: "Café,Sirop"}
|
||||||
)
|
)
|
||||||
|
|
||||||
assert res["errors"] == nil
|
assert res["errors"] == nil
|
||||||
|
@ -160,7 +161,7 @@ defmodule Mobilizon.GraphQL.Resolvers.SearchTest do
|
||||||
res =
|
res =
|
||||||
AbsintheHelpers.graphql_query(conn,
|
AbsintheHelpers.graphql_query(conn,
|
||||||
query: @search_events_query,
|
query: @search_events_query,
|
||||||
variables: %{location: geohash, radius: 10, tag: "Thé", term: "Monde"}
|
variables: %{location: geohash, radius: 10, tags: "Thé", term: "Monde"}
|
||||||
)
|
)
|
||||||
|
|
||||||
assert res["errors"] == nil
|
assert res["errors"] == nil
|
||||||
|
|
Loading…
Reference in a new issue