mirror of
https://github.com/plausible/analytics.git
synced 2024-11-26 23:27:54 +03:00
Fix custom property total conversions value not displayed & Export custom properties (#1456)
* Fix custom property total conversions value not displayed The custom property conversion metrics are not consistent with the other metrics resulting in the total conversions not being displayed in the dashboard. This fixes that. * Export custom props of current goal when filtering dashboard for goal This makes the CSV export also output a `prop_breakdown.csv` file which, for the currently filtered goal, contains the conversion data for each of its configured properties. * Add test for goal-filtered CSV export
This commit is contained in:
parent
7a02aae2a5
commit
3380685d40
@ -115,7 +115,8 @@ export default class PropertyBreakdown extends React.Component {
|
||||
return (
|
||||
<div className="flex items-center justify-between my-2" key={value.name}>
|
||||
<Bar
|
||||
count={value.visitors}
|
||||
count={value.unique_conversions}
|
||||
plot="unique_conversions"
|
||||
all={this.state.breakdown}
|
||||
bg="bg-red-50 dark:bg-gray-500 dark:bg-opacity-15"
|
||||
maxWidthDeduction={this.getBarMaxWidth()}
|
||||
@ -123,13 +124,13 @@ export default class PropertyBreakdown extends React.Component {
|
||||
{this.renderPropContent(value, query)}
|
||||
</Bar>
|
||||
<div className="dark:text-gray-200">
|
||||
<span className="font-medium inline-block w-20 text-right">{numberFormatter(value.visitors)}</span>
|
||||
<span className="font-medium inline-block w-20 text-right">{numberFormatter(value.unique_conversions)}</span>
|
||||
{
|
||||
viewport > MOBILE_UPPER_WIDTH ?
|
||||
(
|
||||
<span
|
||||
className="font-medium inline-block w-20 text-right"
|
||||
>{numberFormatter(value.total_count)}
|
||||
>{numberFormatter(value.total_conversions)}
|
||||
</span>
|
||||
)
|
||||
: null
|
||||
|
@ -611,13 +611,49 @@ defmodule PlausibleWeb.Api.StatsController do
|
||||
Stats.breakdown(site, query, prop_name, ["visitors", "events"], pagination)
|
||||
|> transform_keys(%{
|
||||
params["prop_name"] => "name",
|
||||
"events" => "total_conversions"
|
||||
"events" => "total_conversions",
|
||||
"visitors" => "unique_conversions"
|
||||
})
|
||||
|> Enum.map(fn prop ->
|
||||
Map.put(prop, "conversion_rate", calculate_cr(unique_visitors, prop["visitors"]))
|
||||
Map.put(
|
||||
prop,
|
||||
"conversion_rate",
|
||||
calculate_cr(unique_visitors, prop["unique_conversions"])
|
||||
)
|
||||
end)
|
||||
|
||||
json(conn, props)
|
||||
if params["csv"] do
|
||||
props
|
||||
else
|
||||
json(conn, props)
|
||||
end
|
||||
end
|
||||
|
||||
def all_props_breakdown(conn, params) do
|
||||
site = conn.assigns[:site]
|
||||
query = Query.from(site.timezone, params) |> Filters.add_prefix()
|
||||
|
||||
headers = ["prop", "name", "unique_conversions", "total_conversions"]
|
||||
|
||||
prop_names =
|
||||
if query.filters["event:goal"] do
|
||||
{_, _, goal} = query.filters["event:goal"]
|
||||
|
||||
Stats.props(site, query)
|
||||
|> Map.get(goal, [])
|
||||
else
|
||||
[]
|
||||
end
|
||||
|
||||
values =
|
||||
prop_names
|
||||
|> Enum.map(fn prop ->
|
||||
prop_breakdown(conn, Map.put(params, "prop_name", prop))
|
||||
|> Enum.map(&Map.put(&1, "prop", prop))
|
||||
end)
|
||||
|> Enum.concat()
|
||||
|
||||
to_csv(values, headers)
|
||||
end
|
||||
|
||||
def current_visitors(conn, _) do
|
||||
|
@ -71,7 +71,8 @@ defmodule PlausibleWeb.StatsController do
|
||||
{'browsers.csv', fn -> Api.StatsController.browsers(conn, params) end},
|
||||
{'operating_systems.csv', fn -> Api.StatsController.operating_systems(conn, params) end},
|
||||
{'devices.csv', fn -> Api.StatsController.screen_sizes(conn, params) end},
|
||||
{'conversions.csv', fn -> Api.StatsController.conversions(conn, params) end}
|
||||
{'conversions.csv', fn -> Api.StatsController.conversions(conn, params) end},
|
||||
{'prop_breakdown.csv', fn -> Api.StatsController.all_props_breakdown(conn, params) end}
|
||||
]
|
||||
|
||||
csvs =
|
||||
|
@ -1,2 +1,2 @@
|
||||
name,unique_conversions,total_conversions
|
||||
Visit /some-other-page,1,1
|
||||
Signup,1,1
|
|
@ -0,0 +1 @@
|
||||
name,visitors
|
|
@ -0,0 +1,2 @@
|
||||
name,unique_entrances,total_entrances,visit_duration
|
||||
/,1,1,0
|
|
@ -0,0 +1,2 @@
|
||||
name,unique_exits,total_exits,exit_rate
|
||||
/,1,1,
|
|
@ -0,0 +1,2 @@
|
||||
name,visitors,bounce_rate,time_on_page
|
||||
/,1,100,
|
|
@ -0,0 +1,2 @@
|
||||
prop,name,unique_conversions,total_conversions
|
||||
variant,A,1,1
|
|
@ -0,0 +1,32 @@
|
||||
date,visitors,pageviews,bounce_rate,visit_duration
|
||||
2021-09-20,0,0,100,0
|
||||
2021-09-21,0,0,,
|
||||
2021-09-22,0,0,,
|
||||
2021-09-23,0,0,,
|
||||
2021-09-24,0,0,,
|
||||
2021-09-25,0,0,,
|
||||
2021-09-26,0,0,,
|
||||
2021-09-27,0,0,,
|
||||
2021-09-28,0,0,,
|
||||
2021-09-29,0,0,,
|
||||
2021-09-30,0,0,,
|
||||
2021-10-01,0,0,,
|
||||
2021-10-02,0,0,,
|
||||
2021-10-03,0,0,,
|
||||
2021-10-04,0,0,,
|
||||
2021-10-05,0,0,,
|
||||
2021-10-06,0,0,,
|
||||
2021-10-07,0,0,,
|
||||
2021-10-08,0,0,,
|
||||
2021-10-09,0,0,,
|
||||
2021-10-10,0,0,,
|
||||
2021-10-11,0,0,,
|
||||
2021-10-12,0,0,,
|
||||
2021-10-13,0,0,,
|
||||
2021-10-14,0,0,,
|
||||
2021-10-15,0,0,,
|
||||
2021-10-16,0,0,,
|
||||
2021-10-17,0,0,,
|
||||
2021-10-18,0,0,,
|
||||
2021-10-19,1,0,100,0
|
||||
2021-10-20,0,0,0,60
|
|
@ -0,0 +1,2 @@
|
||||
name,visitors
|
||||
,1
|
|
@ -0,0 +1 @@
|
||||
name,unique_conversions,total_conversions
|
|
@ -0,0 +1,2 @@
|
||||
name,visitors
|
||||
,1
|
|
@ -0,0 +1,2 @@
|
||||
name,visitors
|
||||
,1
|
|
@ -0,0 +1 @@
|
||||
prop,name,unique_conversions,total_conversions
|
|
@ -0,0 +1 @@
|
||||
name,visitors,bounce_rate,visit_duration
|
|
@ -0,0 +1 @@
|
||||
name,visitors,bounce_rate,visit_duration
|
|
@ -0,0 +1 @@
|
||||
name,visitors,bounce_rate,visit_duration
|
|
@ -0,0 +1 @@
|
||||
name,visitors,bounce_rate,visit_duration
|
|
@ -1,2 +1,2 @@
|
||||
name,unique_conversions,total_conversions
|
||||
Visit /some-other-page,1,1
|
||||
Signup,1,1
|
||||
|
|
@ -0,0 +1 @@
|
||||
prop,name,unique_conversions,total_conversions
|
|
@ -1,2 +1,2 @@
|
||||
name,unique_conversions,total_conversions
|
||||
Visit /some-other-page,1,1
|
||||
Signup,1,1
|
||||
|
|
@ -0,0 +1 @@
|
||||
prop,name,unique_conversions,total_conversions
|
|
@ -4,4 +4,4 @@ date,visitors,pageviews,bounce_rate,visit_duration
|
||||
2021-07-01,0,0,,
|
||||
2021-08-01,0,0,,
|
||||
2021-09-01,1,1,100,0
|
||||
2021-10-01,2,3,50,30
|
||||
2021-10-01,2,3,67,20
|
||||
|
|
@ -112,13 +112,13 @@ defmodule PlausibleWeb.Api.StatsController.ConversionsTest do
|
||||
|
||||
assert json_response(conn, 200) == [
|
||||
%{
|
||||
"visitors" => 2,
|
||||
"unique_conversions" => 2,
|
||||
"name" => "B",
|
||||
"total_conversions" => 2,
|
||||
"conversion_rate" => 66.7
|
||||
},
|
||||
%{
|
||||
"visitors" => 1,
|
||||
"unique_conversions" => 1,
|
||||
"name" => "A",
|
||||
"total_conversions" => 1,
|
||||
"conversion_rate" => 33.3
|
||||
@ -148,13 +148,13 @@ defmodule PlausibleWeb.Api.StatsController.ConversionsTest do
|
||||
|
||||
assert json_response(conn, 200) == [
|
||||
%{
|
||||
"visitors" => 2,
|
||||
"unique_conversions" => 2,
|
||||
"name" => "(none)",
|
||||
"total_conversions" => 2,
|
||||
"conversion_rate" => 66.7
|
||||
},
|
||||
%{
|
||||
"visitors" => 1,
|
||||
"unique_conversions" => 1,
|
||||
"name" => "A",
|
||||
"total_conversions" => 1,
|
||||
"conversion_rate" => 33.3
|
||||
@ -182,7 +182,7 @@ defmodule PlausibleWeb.Api.StatsController.ConversionsTest do
|
||||
|
||||
assert json_response(conn, 200) == [
|
||||
%{
|
||||
"visitors" => 1,
|
||||
"unique_conversions" => 1,
|
||||
"name" => "B",
|
||||
"total_conversions" => 1,
|
||||
"conversion_rate" => 50.0
|
||||
|
@ -83,7 +83,7 @@ defmodule PlausibleWeb.StatsControllerTest do
|
||||
|
||||
filters = Jason.encode!(%{page: "/some-other-page"})
|
||||
conn = get(conn, "/#{site.domain}/export?date=2021-10-20&filters=#{filters}")
|
||||
assert_zip(conn, "30d-filtered")
|
||||
assert_zip(conn, "30d-filter-path")
|
||||
end
|
||||
end
|
||||
|
||||
@ -140,10 +140,27 @@ defmodule PlausibleWeb.StatsControllerTest do
|
||||
country_code: "EE",
|
||||
referrer_source: "Google",
|
||||
browser: "ABrowserName"
|
||||
),
|
||||
build(:event,
|
||||
timestamp: Timex.shift(~N[2021-10-20 12:00:00], days: -1),
|
||||
name: "Signup",
|
||||
"meta.key": ["variant"],
|
||||
"meta.value": ["A"]
|
||||
)
|
||||
])
|
||||
|
||||
insert(:goal, %{domain: site.domain, page_path: "/some-other-page"})
|
||||
insert(:goal, %{domain: site.domain, event_name: "Signup"})
|
||||
end
|
||||
|
||||
describe "GET /:website/export - with goal filter" do
|
||||
setup [:create_user, :create_new_site, :log_in]
|
||||
|
||||
test "exports goal-filtered data in zipped csvs", %{conn: conn, site: site} do
|
||||
populate_exported_stats(site)
|
||||
filters = Jason.encode!(%{goal: "Signup"})
|
||||
conn = get(conn, "/#{site.domain}/export?date=2021-10-20&filters=#{filters}")
|
||||
assert_zip(conn, "30d-filter-goal")
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /share/:slug" do
|
||||
|
Loading…
Reference in New Issue
Block a user