Add Browser/Version breakdown to CSV (#3599)
* Add csv for browser versions * add changelog * Fixup - ensure the dashboard browser version breakdown still works * Update CHANGELOG --------- Co-authored-by: Ekaterina Krivich <ekaterinak@heathmont.net>
This commit is contained in:
parent
906b06ae84
commit
b96319321c
|
|
@ -55,6 +55,7 @@ plausible-report.xml
|
||||||
*.iml
|
*.iml
|
||||||
*.log
|
*.log
|
||||||
*.code-workspace
|
*.code-workspace
|
||||||
|
.vscode
|
||||||
|
|
||||||
# Dializer
|
# Dializer
|
||||||
/priv/plts/*.plt
|
/priv/plts/*.plt
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
## Unreleased
|
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
- Add `referrers.csv` to CSV export
|
- Add `referrers.csv` to CSV export
|
||||||
- Add a new Properties section in the dashboard to break down by custom properties
|
- Add a new Properties section in the dashboard to break down by custom properties
|
||||||
|
|
@ -17,6 +15,7 @@ All notable changes to this project will be documented in this file.
|
||||||
- Add site pinning to /sites view
|
- Add site pinning to /sites view
|
||||||
- Add support for JSON logger, via LOG_FORMAT=json environment variable
|
- Add support for JSON logger, via LOG_FORMAT=json environment variable
|
||||||
- Add support for 2FA authentication
|
- Add support for 2FA authentication
|
||||||
|
- Add 'browser_versions.csv' to CSV export
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
- Removed the nested custom event property breakdown UI when filtering by a goal in Goal Conversions
|
- Removed the nested custom event property breakdown UI when filtering by a goal in Goal Conversions
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ function Browsers({ query, site }) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFilterFor(listItem) {
|
function getFilterFor(listItem) {
|
||||||
return { browser: listItem['name']}
|
return { browser: listItem['name'] }
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -35,7 +35,7 @@ function BrowserVersions({ query, site }) {
|
||||||
if (query.filters.browser === '(not set)') {
|
if (query.filters.browser === '(not set)') {
|
||||||
return {}
|
return {}
|
||||||
}
|
}
|
||||||
return { browser_version: listItem['name']}
|
return { browser_version: listItem['name'] }
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -56,7 +56,7 @@ function OperatingSystems({ query, site }) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFilterFor(listItem) {
|
function getFilterFor(listItem) {
|
||||||
return { os: listItem['name']}
|
return { os: listItem['name'] }
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -79,7 +79,7 @@ function OperatingSystemVersions({ query, site }) {
|
||||||
if (query.filters.os === '(not set)') {
|
if (query.filters.os === '(not set)') {
|
||||||
return {}
|
return {}
|
||||||
}
|
}
|
||||||
return { os_version: listItem['name']}
|
return { os_version: listItem['name'] }
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -104,7 +104,7 @@ function ScreenSizes({ query, site }) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFilterFor(listItem) {
|
function getFilterFor(listItem) {
|
||||||
return { screen: listItem['name']}
|
return { screen: listItem['name'] }
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -649,8 +649,9 @@ defmodule Plausible.Stats.Breakdown do
|
||||||
defp do_group_by(q, "visit:browser_version") do
|
defp do_group_by(q, "visit:browser_version") do
|
||||||
from(
|
from(
|
||||||
s in q,
|
s in q,
|
||||||
group_by: s.browser_version,
|
group_by: [s.browser, s.browser_version],
|
||||||
select_merge: %{
|
select_merge: %{
|
||||||
|
browser: fragment("if(empty(?), ?, ?)", s.browser, @not_set, s.browser),
|
||||||
browser_version:
|
browser_version:
|
||||||
fragment("if(empty(?), ?, ?)", s.browser_version, @not_set, s.browser_version)
|
fragment("if(empty(?), ?, ?)", s.browser_version, @not_set, s.browser_version)
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1061,7 +1061,23 @@ defmodule PlausibleWeb.Api.StatsController do
|
||||||
|> transform_keys(%{browser_version: :name})
|
|> transform_keys(%{browser_version: :name})
|
||||||
|> add_percentages(site, query)
|
|> add_percentages(site, query)
|
||||||
|
|
||||||
json(conn, versions)
|
if params["csv"] do
|
||||||
|
if Map.has_key?(query.filters, "event:goal") do
|
||||||
|
versions
|
||||||
|
|> transform_keys(%{
|
||||||
|
name: :version,
|
||||||
|
browser: :name,
|
||||||
|
visitors: :conversions
|
||||||
|
})
|
||||||
|
|> to_csv([:name, :version, :conversions, :conversion_rate])
|
||||||
|
else
|
||||||
|
versions
|
||||||
|
|> transform_keys(%{name: :version, browser: :name})
|
||||||
|
|> to_csv([:name, :version, :visitors])
|
||||||
|
end
|
||||||
|
else
|
||||||
|
json(conn, versions)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def operating_systems(conn, params) do
|
def operating_systems(conn, params) do
|
||||||
|
|
|
||||||
|
|
@ -155,6 +155,7 @@ defmodule PlausibleWeb.StatsController do
|
||||||
~c"regions.csv" => fn -> Api.StatsController.regions(conn, params) end,
|
~c"regions.csv" => fn -> Api.StatsController.regions(conn, params) end,
|
||||||
~c"cities.csv" => fn -> Api.StatsController.cities(conn, params) end,
|
~c"cities.csv" => fn -> Api.StatsController.cities(conn, params) end,
|
||||||
~c"browsers.csv" => fn -> Api.StatsController.browsers(conn, params) end,
|
~c"browsers.csv" => fn -> Api.StatsController.browsers(conn, params) end,
|
||||||
|
~c"browser_versions.csv" => fn -> Api.StatsController.browser_versions(conn, params) end,
|
||||||
~c"operating_systems.csv" => fn -> Api.StatsController.operating_systems(conn, params) end,
|
~c"operating_systems.csv" => fn -> Api.StatsController.operating_systems(conn, params) end,
|
||||||
~c"devices.csv" => fn -> Api.StatsController.screen_sizes(conn, params) end,
|
~c"devices.csv" => fn -> Api.StatsController.screen_sizes(conn, params) end,
|
||||||
~c"conversions.csv" => fn -> Api.StatsController.conversions(conn, params) end,
|
~c"conversions.csv" => fn -> Api.StatsController.conversions(conn, params) end,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
name,version,conversions,conversion_rate
|
||||||
|
(not set),(not set),1,50.0
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
name,version,visitors
|
||||||
|
(not set),(not set),1
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
name,version,visitors
|
||||||
|
Firefox,120,2
|
||||||
|
(not set),(not set),2
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
name,visitors
|
name,visitors
|
||||||
ABrowserName,2
|
Firefox,2
|
||||||
(not set),2
|
(not set),2
|
||||||
|
|
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
name,version,visitors
|
||||||
|
Firefox,120,2
|
||||||
|
(not set),(not set),2
|
||||||
|
FirefoxNoVersion,(not set),1
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
name,visitors
|
name,visitors
|
||||||
ABrowserName,3
|
Firefox,2
|
||||||
(not set),2
|
(not set),2
|
||||||
|
FirefoxNoVersion,1
|
||||||
|
|
|
||||||
|
|
|
@ -517,8 +517,8 @@ defmodule PlausibleWeb.Api.ExternalStatsController.BreakdownTest do
|
||||||
|
|
||||||
assert json_response(conn, 200) == %{
|
assert json_response(conn, 200) == %{
|
||||||
"results" => [
|
"results" => [
|
||||||
%{"browser_version" => "56", "visitors" => 2},
|
%{"browser_version" => "56", "visitors" => 2, "browser" => "(not set)"},
|
||||||
%{"browser_version" => "57", "visitors" => 1}
|
%{"browser_version" => "57", "visitors" => 1, "browser" => "(not set)"}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -188,8 +188,8 @@ defmodule PlausibleWeb.Api.StatsController.BrowsersTest do
|
||||||
)
|
)
|
||||||
|
|
||||||
assert json_response(conn, 200) == [
|
assert json_response(conn, 200) == [
|
||||||
%{"name" => "78.0", "visitors" => 2, "percentage" => 66.7},
|
%{"name" => "78.0", "visitors" => 2, "percentage" => 66.7, "browser" => "Chrome"},
|
||||||
%{"name" => "77.0", "visitors" => 1, "percentage" => 33.3}
|
%{"name" => "77.0", "visitors" => 1, "percentage" => 33.3, "browser" => "Chrome"}
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -207,7 +207,12 @@ defmodule PlausibleWeb.Api.StatsController.BrowsersTest do
|
||||||
)
|
)
|
||||||
|
|
||||||
assert json_response(conn, 200) == [
|
assert json_response(conn, 200) == [
|
||||||
%{"name" => "(not set)", "visitors" => 1, "percentage" => 100}
|
%{
|
||||||
|
"name" => "(not set)",
|
||||||
|
"visitors" => 1,
|
||||||
|
"percentage" => 100,
|
||||||
|
"browser" => "(not set)"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -373,13 +373,15 @@ defmodule PlausibleWeb.StatsControllerTest do
|
||||||
utm_term: "term",
|
utm_term: "term",
|
||||||
timestamp:
|
timestamp:
|
||||||
Timex.shift(~N[2021-10-20 12:00:00], days: -1) |> NaiveDateTime.truncate(:second),
|
Timex.shift(~N[2021-10-20 12:00:00], days: -1) |> NaiveDateTime.truncate(:second),
|
||||||
browser: "ABrowserName"
|
browser: "Firefox",
|
||||||
|
browser_version: "120"
|
||||||
),
|
),
|
||||||
build(:pageview,
|
build(:pageview,
|
||||||
timestamp:
|
timestamp:
|
||||||
Timex.shift(~N[2021-10-20 12:00:00], months: -1) |> NaiveDateTime.truncate(:second),
|
Timex.shift(~N[2021-10-20 12:00:00], months: -1) |> NaiveDateTime.truncate(:second),
|
||||||
country_code: "EE",
|
country_code: "EE",
|
||||||
browser: "ABrowserName"
|
browser: "Firefox",
|
||||||
|
browser_version: "120"
|
||||||
),
|
),
|
||||||
build(:pageview,
|
build(:pageview,
|
||||||
timestamp:
|
timestamp:
|
||||||
|
|
@ -387,7 +389,7 @@ defmodule PlausibleWeb.StatsControllerTest do
|
||||||
utm_campaign: "ads",
|
utm_campaign: "ads",
|
||||||
country_code: "EE",
|
country_code: "EE",
|
||||||
referrer_source: "Google",
|
referrer_source: "Google",
|
||||||
browser: "ABrowserName"
|
browser: "FirefoxNoVersion"
|
||||||
),
|
),
|
||||||
build(:event,
|
build(:event,
|
||||||
timestamp:
|
timestamp:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue