mirror of
https://github.com/plausible/analytics.git
synced 2024-09-11 09:56:02 +03:00
Implement goal contains filter + search in Conversions > Details (#4404)
* Implement goal contains * add search into ConversionsModal --------- Co-authored-by: Robert Joonas <robertjoonas16@gmail.com>
This commit is contained in:
parent
05b70e37a8
commit
a1ee58426e
@ -5,6 +5,7 @@ import BreakdownModal from "./breakdown-modal";
|
||||
import * as metrics from "../reports/metrics";
|
||||
import * as url from '../../util/url';
|
||||
import { useSiteContext } from "../../site-context";
|
||||
import { addFilter } from "../../query";
|
||||
|
||||
/*global BUILD_EXTRA*/
|
||||
function ConversionsModal() {
|
||||
@ -25,6 +26,10 @@ function ConversionsModal() {
|
||||
}
|
||||
}, [reportInfo.dimension])
|
||||
|
||||
const addSearchFilter = useCallback((query, searchString) => {
|
||||
return addFilter(query, ['contains', reportInfo.dimension, [searchString]])
|
||||
}, [reportInfo.dimension])
|
||||
|
||||
function chooseMetrics() {
|
||||
return [
|
||||
metrics.createVisitors({ renderLabel: (_query) => "Uniques" }),
|
||||
@ -60,7 +65,7 @@ function ConversionsModal() {
|
||||
afterFetchData={BUILD_EXTRA ? afterFetchData : undefined}
|
||||
afterFetchNextPage={BUILD_EXTRA ? afterFetchNextPage : undefined}
|
||||
getFilterInfo={getFilterInfo}
|
||||
searchEnabled={false}
|
||||
addSearchFilter={addSearchFilter}
|
||||
/>
|
||||
</Modal>
|
||||
)
|
||||
|
@ -21,7 +21,7 @@ defmodule Plausible.Goals.Filters do
|
||||
`pathname`, and also skips the `e.name == "pageview"` check.
|
||||
"""
|
||||
def add_filter(query, [operation, "event:goal", clauses], opts \\ [])
|
||||
when operation in [:is] do
|
||||
when operation in [:is, :contains] do
|
||||
imported? = Keyword.get(opts, :imported?, false)
|
||||
|
||||
Enum.reduce(clauses, false, fn clause, dynamic_statement ->
|
||||
@ -39,6 +39,9 @@ defmodule Plausible.Goals.Filters do
|
||||
case operation do
|
||||
:is ->
|
||||
Plausible.Goal.display_name(goal) == clause
|
||||
|
||||
:contains ->
|
||||
String.contains?(Plausible.Goal.display_name(goal), clause)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
@ -330,7 +330,7 @@ defmodule Plausible.Stats.Filters.QueryParser do
|
||||
defp validate_goal_filters(query) do
|
||||
goal_filter_clauses =
|
||||
Enum.flat_map(query.filters, fn
|
||||
[_operation, "event:goal", clauses] -> clauses
|
||||
[:is, "event:goal", clauses] -> clauses
|
||||
_ -> []
|
||||
end)
|
||||
|
||||
|
@ -2278,6 +2278,40 @@ defmodule PlausibleWeb.Api.ExternalStatsController.QueryTest do
|
||||
]
|
||||
end
|
||||
|
||||
test "goal contains filter for goal breakdown", %{conn: conn, site: site} do
|
||||
populate_stats(site, [
|
||||
build(:event, name: "Onboarding conversion: Step 1"),
|
||||
build(:event, name: "Onboarding conversion: Step 1"),
|
||||
build(:event, name: "Onboarding conversion: Step 2"),
|
||||
build(:event, name: "Unrelated"),
|
||||
build(:pageview, pathname: "/conversion")
|
||||
])
|
||||
|
||||
insert(:goal, site: site, event_name: "Onboarding conversion: Step 1")
|
||||
insert(:goal, site: site, event_name: "Onboarding conversion: Step 2")
|
||||
insert(:goal, site: site, event_name: "Unrelated")
|
||||
insert(:goal, site: site, page_path: "/conversion")
|
||||
|
||||
conn =
|
||||
post(conn, "/api/v2/query", %{
|
||||
"site_id" => site.domain,
|
||||
"metrics" => ["visitors"],
|
||||
"date_range" => "all",
|
||||
"dimensions" => ["event:goal"],
|
||||
"filters" => [
|
||||
["contains", "event:goal", ["conversion"]]
|
||||
]
|
||||
})
|
||||
|
||||
%{"results" => results} = json_response(conn, 200)
|
||||
|
||||
assert results == [
|
||||
%{"dimensions" => ["Onboarding conversion: Step 1"], "metrics" => [2]},
|
||||
%{"dimensions" => ["Onboarding conversion: Step 2"], "metrics" => [1]},
|
||||
%{"dimensions" => ["Visit /conversion"], "metrics" => [1]}
|
||||
]
|
||||
end
|
||||
|
||||
test "mixed multi-goal filter for breakdown by visit:country", %{conn: conn, site: site} do
|
||||
populate_stats(site, [
|
||||
build(:pageview, country_code: "EE", pathname: "/en/register"),
|
||||
|
@ -1113,5 +1113,56 @@ defmodule PlausibleWeb.Api.StatsController.ConversionsTest do
|
||||
}
|
||||
]
|
||||
end
|
||||
|
||||
test "filtering with goal contains filter", %{
|
||||
conn: conn,
|
||||
site: site
|
||||
} do
|
||||
site_import =
|
||||
insert(:site_import,
|
||||
site: site,
|
||||
start_date: ~D[2005-01-01],
|
||||
end_date: Timex.today(),
|
||||
source: :universal_analytics
|
||||
)
|
||||
|
||||
insert(:goal, site: site, event_name: "Onboarding: Step 1")
|
||||
insert(:goal, site: site, event_name: "Onboarding: Step 2")
|
||||
insert(:goal, site: site, event_name: "Unrelated")
|
||||
|
||||
populate_stats(site, site_import.id, [
|
||||
build(:event, name: "Onboarding: Step 1"),
|
||||
build(:event, name: "Onboarding: Step 1"),
|
||||
build(:event, name: "Onboarding: Step 2"),
|
||||
build(:event, name: "Unrelated"),
|
||||
build(:imported_custom_events, name: "Onboarding: Step 1", visitors: 2, events: 2),
|
||||
build(:imported_custom_events, name: "Onboarding: Step 2"),
|
||||
build(:imported_custom_events, name: "Unrelated"),
|
||||
build(:imported_visitors, visitors: 4)
|
||||
])
|
||||
|
||||
filters = Jason.encode!(%{goal: "~Onboarding"})
|
||||
|
||||
conn =
|
||||
get(
|
||||
conn,
|
||||
"/api/stats/#{site.domain}/conversions?period=day&filters=#{filters}&with_imported=true"
|
||||
)
|
||||
|
||||
assert json_response(conn, 200)["results"] == [
|
||||
%{
|
||||
"name" => "Onboarding: Step 1",
|
||||
"visitors" => 4,
|
||||
"events" => 4,
|
||||
"conversion_rate" => 50
|
||||
},
|
||||
%{
|
||||
"name" => "Onboarding: Step 2",
|
||||
"visitors" => 2,
|
||||
"events" => 2,
|
||||
"conversion_rate" => 25
|
||||
}
|
||||
]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user