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:
hq1 2023-12-12 14:39:08 +01:00 committed by GitHub
parent 906b06ae84
commit b96319321c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 56 additions and 19 deletions

1
.gitignore vendored
View File

@ -55,6 +55,7 @@ plausible-report.xml
*.iml
*.log
*.code-workspace
.vscode
# Dializer
/priv/plts/*.plt

View File

@ -1,8 +1,6 @@
# Changelog
All notable changes to this project will be documented in this file.
## Unreleased
### Added
- Add `referrers.csv` to CSV export
- 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 support for JSON logger, via LOG_FORMAT=json environment variable
- Add support for 2FA authentication
- Add 'browser_versions.csv' to CSV export
### Removed
- Removed the nested custom event property breakdown UI when filtering by a goal in Goal Conversions

View File

@ -12,7 +12,7 @@ function Browsers({ query, site }) {
}
function getFilterFor(listItem) {
return { browser: listItem['name']}
return { browser: listItem['name'] }
}
return (
@ -35,7 +35,7 @@ function BrowserVersions({ query, site }) {
if (query.filters.browser === '(not set)') {
return {}
}
return { browser_version: listItem['name']}
return { browser_version: listItem['name'] }
}
return (
@ -56,7 +56,7 @@ function OperatingSystems({ query, site }) {
}
function getFilterFor(listItem) {
return { os: listItem['name']}
return { os: listItem['name'] }
}
return (
@ -79,7 +79,7 @@ function OperatingSystemVersions({ query, site }) {
if (query.filters.os === '(not set)') {
return {}
}
return { os_version: listItem['name']}
return { os_version: listItem['name'] }
}
return (
@ -104,7 +104,7 @@ function ScreenSizes({ query, site }) {
}
function getFilterFor(listItem) {
return { screen: listItem['name']}
return { screen: listItem['name'] }
}
return (

View File

@ -649,8 +649,9 @@ defmodule Plausible.Stats.Breakdown do
defp do_group_by(q, "visit:browser_version") do
from(
s in q,
group_by: s.browser_version,
group_by: [s.browser, s.browser_version],
select_merge: %{
browser: fragment("if(empty(?), ?, ?)", s.browser, @not_set, s.browser),
browser_version:
fragment("if(empty(?), ?, ?)", s.browser_version, @not_set, s.browser_version)
},

View File

@ -1061,7 +1061,23 @@ defmodule PlausibleWeb.Api.StatsController do
|> transform_keys(%{browser_version: :name})
|> 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
def operating_systems(conn, params) do

View File

@ -155,6 +155,7 @@ defmodule PlausibleWeb.StatsController do
~c"regions.csv" => fn -> Api.StatsController.regions(conn, params) end,
~c"cities.csv" => fn -> Api.StatsController.cities(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"devices.csv" => fn -> Api.StatsController.screen_sizes(conn, params) end,
~c"conversions.csv" => fn -> Api.StatsController.conversions(conn, params) end,

View File

@ -0,0 +1,2 @@
name,version,conversions,conversion_rate
(not set),(not set),1,50.0
1 name version conversions conversion_rate
2 (not set) (not set) 1 50.0

View File

@ -0,0 +1,2 @@
name,version,visitors
(not set),(not set),1
1 name version visitors
2 (not set) (not set) 1

View File

@ -0,0 +1,3 @@
name,version,visitors
Firefox,120,2
(not set),(not set),2
1 name version visitors
2 Firefox 120 2
3 (not set) (not set) 2

View File

@ -1,3 +1,3 @@
name,visitors
ABrowserName,2
Firefox,2
(not set),2

1 name visitors
2 ABrowserName Firefox 2
3 (not set) 2

View File

@ -0,0 +1,4 @@
name,version,visitors
Firefox,120,2
(not set),(not set),2
FirefoxNoVersion,(not set),1
1 name version visitors
2 Firefox 120 2
3 (not set) (not set) 2
4 FirefoxNoVersion (not set) 1

View File

@ -1,3 +1,4 @@
name,visitors
ABrowserName,3
Firefox,2
(not set),2
FirefoxNoVersion,1

1 name visitors
2 ABrowserName Firefox 3 2
3 (not set) 2
4 FirefoxNoVersion 1

View File

@ -517,8 +517,8 @@ defmodule PlausibleWeb.Api.ExternalStatsController.BreakdownTest do
assert json_response(conn, 200) == %{
"results" => [
%{"browser_version" => "56", "visitors" => 2},
%{"browser_version" => "57", "visitors" => 1}
%{"browser_version" => "56", "visitors" => 2, "browser" => "(not set)"},
%{"browser_version" => "57", "visitors" => 1, "browser" => "(not set)"}
]
}
end

View File

@ -188,8 +188,8 @@ defmodule PlausibleWeb.Api.StatsController.BrowsersTest do
)
assert json_response(conn, 200) == [
%{"name" => "78.0", "visitors" => 2, "percentage" => 66.7},
%{"name" => "77.0", "visitors" => 1, "percentage" => 33.3}
%{"name" => "78.0", "visitors" => 2, "percentage" => 66.7, "browser" => "Chrome"},
%{"name" => "77.0", "visitors" => 1, "percentage" => 33.3, "browser" => "Chrome"}
]
end
@ -207,7 +207,12 @@ defmodule PlausibleWeb.Api.StatsController.BrowsersTest do
)
assert json_response(conn, 200) == [
%{"name" => "(not set)", "visitors" => 1, "percentage" => 100}
%{
"name" => "(not set)",
"visitors" => 1,
"percentage" => 100,
"browser" => "(not set)"
}
]
end
end

View File

@ -373,13 +373,15 @@ defmodule PlausibleWeb.StatsControllerTest do
utm_term: "term",
timestamp:
Timex.shift(~N[2021-10-20 12:00:00], days: -1) |> NaiveDateTime.truncate(:second),
browser: "ABrowserName"
browser: "Firefox",
browser_version: "120"
),
build(:pageview,
timestamp:
Timex.shift(~N[2021-10-20 12:00:00], months: -1) |> NaiveDateTime.truncate(:second),
country_code: "EE",
browser: "ABrowserName"
browser: "Firefox",
browser_version: "120"
),
build(:pageview,
timestamp:
@ -387,7 +389,7 @@ defmodule PlausibleWeb.StatsControllerTest do
utm_campaign: "ads",
country_code: "EE",
referrer_source: "Google",
browser: "ABrowserName"
browser: "FirefoxNoVersion"
),
build(:event,
timestamp: