mirror of
https://github.com/plausible/analytics.git
synced 2024-12-22 17:11:36 +03:00
Merge branch 'master' into stats-module
This commit is contained in:
commit
7e78157c4b
@ -15,6 +15,7 @@ All notable changes to this project will be documented in this file.
|
||||
- Menu (with auto-complete) to add new and edit existing filters directly plausible/analytics#1089
|
||||
- Added `CLICKHOUSE_FLUSH_INTERVAL_MS` and `CLICKHOUSE_MAX_BUFFER_SIZE` configuration parameters plausible/analytics#1073
|
||||
- Ability to invite users to sites with different roles plausible/analytics#1122
|
||||
- Option to configure a custom name for the script file
|
||||
|
||||
### Fixed
|
||||
- Fix weekly report time range plausible/analytics#951
|
||||
@ -23,7 +24,7 @@ All notable changes to this project will be documented in this file.
|
||||
- Crash when changing theme on a loaded dashboard plausible/analytics#1123
|
||||
- UI fix for details button overlapping content on mobile plausible/analytics#1114
|
||||
- UI fix for the main graph on mobile overlapping its tick items on both axis
|
||||
- UI fixes for text not showing properly in bars across multiple lines. This hides the totals on <768px and only shows the uniques and % to accommodate the goals text too.
|
||||
- UI fixes for text not showing properly in bars across multiple lines. This hides the totals on <768px and only shows the uniques and % to accommodate the goals text too. Larger screens still truncate as usual.
|
||||
- Turn off autocomplete for name and password inputs in the _New shared link_ form.
|
||||
|
||||
### Removed
|
||||
|
@ -59,14 +59,14 @@ export default class Conversions extends React.Component {
|
||||
|
||||
renderGoalText(goalName) {
|
||||
if (this.props.query.period === 'realtime') {
|
||||
return <span className="block px-2 py-1.5 relative z-9 break-words dark:text-gray-200">{goalName}</span>
|
||||
return <span className="block px-2 py-1.5 relative z-9 md:truncate break-all dark:text-gray-200">{goalName}</span>
|
||||
} else {
|
||||
const query = new URLSearchParams(window.location.search)
|
||||
query.set('goal', goalName)
|
||||
|
||||
return (
|
||||
<Link to={{pathname: window.location.pathname, search: query.toString()}} className="block px-2 py-1.5 hover:underline relative z-9 break-words dark:text-gray-200">
|
||||
{ goalName }
|
||||
<Link to={{pathname: window.location.pathname, search: query.toString()}} className="block px-2 py-1.5 hover:underline relative z-9 break-all lg:truncate dark:text-gray-200">
|
||||
{goalName}
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
|
@ -71,10 +71,10 @@ export default class PropertyBreakdown extends React.Component {
|
||||
|
||||
renderPropContent(value, query) {
|
||||
return (
|
||||
<span className="flex px-2 py-1.5 group dark:text-gray-300 relative z-9 break-words">
|
||||
<span className="flex px-2 py-1.5 group dark:text-gray-300 relative z-9 break-all">
|
||||
<Link
|
||||
to={{pathname: window.location.pathname, search: query.toString()}}
|
||||
className="hover:underline block"
|
||||
className="md:truncate hover:underline block"
|
||||
>
|
||||
{ value.name }
|
||||
</Link>
|
||||
|
@ -43,8 +43,8 @@ export default class Browsers extends React.Component {
|
||||
|
||||
renderBrowserContent(browser, query) {
|
||||
return (
|
||||
<span className="flex px-2 py-1.5 dark:text-gray-300 relative z-9 break-words">
|
||||
<Link className="block hover:underline" to={{search: query.toString()}}>
|
||||
<span className="flex px-2 py-1.5 dark:text-gray-300 relative z-9 break-all">
|
||||
<Link className="md:truncate block hover:underline" to={{search: query.toString()}}>
|
||||
{browser.name}
|
||||
</Link>
|
||||
</span>
|
||||
|
@ -86,7 +86,7 @@ class ScreenSizes extends React.Component {
|
||||
tooltip={EXPLANATION[size.name]}
|
||||
className="flex px-2 py-1.5 dark:text-gray-300"
|
||||
>
|
||||
<Link className="block hover:underline" to={{search: query.toString()}}>
|
||||
<Link className="md:truncate block hover:underline" to={{search: query.toString()}}>
|
||||
{iconFor(size.name)} {size.name}
|
||||
</Link>
|
||||
</span>
|
||||
|
@ -55,8 +55,8 @@ export default class OperatingSystems extends React.Component {
|
||||
bg="bg-green-50 dark:gray-500 dark:bg-opacity-15"
|
||||
maxWidthDeduction="6rem"
|
||||
>
|
||||
<span className="flex px-2 py-1.5 dark:text-gray-300 relative z-9 break-words">
|
||||
<Link className="block hover:underline" to={{search: query.toString()}}>
|
||||
<span className="flex px-2 py-1.5 dark:text-gray-300 relative z-9 break-all">
|
||||
<Link className="md:truncate block hover:underline" to={{search: query.toString()}}>
|
||||
{os.name}
|
||||
</Link>
|
||||
</span>
|
||||
|
@ -46,10 +46,10 @@ export default class EntryPages extends React.Component {
|
||||
bg="bg-orange-50 dark:bg-gray-500 dark:bg-opacity-15"
|
||||
maxWidthDeduction="4rem"
|
||||
>
|
||||
<span className="flex px-2 py-1.5 group dark:text-gray-300 relative break-words z-9">
|
||||
<span className="flex px-2 py-1.5 group dark:text-gray-300 relative break-all z-9">
|
||||
<Link
|
||||
to={{pathname: window.location.pathname, search: query.toString()}}
|
||||
className="block hover:underline"
|
||||
className="md:truncate block hover:underline"
|
||||
>
|
||||
{page.name}
|
||||
</Link>
|
||||
|
@ -46,10 +46,10 @@ export default class ExitPages extends React.Component {
|
||||
bg="bg-orange-50 dark:bg-gray-500 dark:bg-opacity-15"
|
||||
maxWidthDeduction="4rem"
|
||||
>
|
||||
<span className="flex px-2 py-1.5 group dark:text-gray-300 z-9 relative break-words">
|
||||
<span className="flex px-2 py-1.5 group dark:text-gray-300 z-9 relative break-all">
|
||||
<Link
|
||||
to={{pathname: window.location.pathname, search: query.toString()}}
|
||||
className="block hover:underline"
|
||||
className="md:truncate block hover:underline"
|
||||
>
|
||||
{page.name}
|
||||
</Link>
|
||||
|
@ -52,11 +52,11 @@ export default class Visits extends React.Component {
|
||||
maxWidthDeduction="4rem"
|
||||
>
|
||||
<span
|
||||
className="flex px-2 py-1.5 group dark:text-gray-300 relative z-9 break-words"
|
||||
className="flex px-2 py-1.5 group dark:text-gray-300 relative z-9 break-all"
|
||||
>
|
||||
<Link
|
||||
to={{pathname: window.location.pathname, search: query.toString()}}
|
||||
className="block hover:underline"
|
||||
className="md:truncate block hover:underline"
|
||||
>
|
||||
{page.name}
|
||||
</Link>
|
||||
|
@ -78,9 +78,9 @@ export default class Referrers extends React.Component {
|
||||
bg="bg-blue-50 dark:bg-gray-500 dark:bg-opacity-15"
|
||||
maxWidthDeduction="4rem"
|
||||
>
|
||||
<span className="flex px-2 py-1.5 z-9 relative break-words group">
|
||||
<span className="flex px-2 py-1.5 z-9 relative break-all group">
|
||||
<LinkOption
|
||||
className="block dark:text-gray-300"
|
||||
className="block md:truncate dark:text-gray-300"
|
||||
to={{search: query.toString()}}
|
||||
disabled={referrer.name === 'Direct / None'}
|
||||
>
|
||||
|
@ -42,8 +42,8 @@ export default class SearchTerms extends React.Component {
|
||||
bg="bg-blue-50 dark:bg-gray-500 dark:bg-opacity-15"
|
||||
maxWidthDeduction="4rem"
|
||||
>
|
||||
<span className="flex px-2 py-1.5 dark:text-gray-300 z-9 relative break-words">
|
||||
<span className="block">
|
||||
<span className="flex px-2 py-1.5 dark:text-gray-300 z-9 relative break-all">
|
||||
<span className="md:truncate block">
|
||||
{ term.name }
|
||||
</span>
|
||||
</span>
|
||||
|
@ -53,9 +53,9 @@ class AllSources extends React.Component {
|
||||
bg="bg-blue-50 dark:bg-gray-500 dark:bg-opacity-15"
|
||||
maxWidthDeduction="4rem"
|
||||
>
|
||||
<span className="flex px-2 py-1.5 dark:text-gray-300 relative z-9 break-words">
|
||||
<span className="flex px-2 py-1.5 dark:text-gray-300 relative z-9 break-all">
|
||||
<Link
|
||||
className="block hover:underline"
|
||||
className="md:truncate block hover:underline"
|
||||
to={{search: query.toString()}}
|
||||
>
|
||||
<img
|
||||
@ -171,9 +171,10 @@ class UTMSources extends React.Component {
|
||||
bg="bg-blue-50 dark:bg-gray-500 dark:bg-opacity-15"
|
||||
maxWidthDeduction="4rem"
|
||||
>
|
||||
<span className="flex px-2 py-1.5 dark:text-gray-300 relative z-9 break-words">
|
||||
<Link
|
||||
className="block hover:underline"
|
||||
|
||||
<span className="flex px-2 py-1.5 dark:text-gray-300 relative z-9 break-all">
|
||||
<Link
|
||||
className="md:truncate block hover:underline"
|
||||
to={{search: query.toString()}}
|
||||
>
|
||||
{ referrer.name }
|
||||
|
@ -136,6 +136,10 @@ is_selfhost =
|
||||
|> get_var_from_path_or_env("SELFHOST", "true")
|
||||
|> String.to_existing_atom()
|
||||
|
||||
custom_script_name =
|
||||
config_dir
|
||||
|> get_var_from_path_or_env("CUSTOM_SCRIPT_NAME", "script")
|
||||
|
||||
{site_limit, ""} =
|
||||
config_dir
|
||||
|> get_var_from_path_or_env("SITE_LIMIT", "50")
|
||||
@ -171,7 +175,8 @@ config :plausible,
|
||||
admin_user_ids: admin_user_ids,
|
||||
site_limit: site_limit,
|
||||
site_limit_exempt: site_limit_exempt,
|
||||
is_selfhost: is_selfhost
|
||||
is_selfhost: is_selfhost,
|
||||
custom_script_name: custom_script_name
|
||||
|
||||
config :plausible, :selfhost,
|
||||
disable_authentication: disable_auth,
|
||||
|
@ -2,7 +2,9 @@ defmodule PlausibleWeb.Tracker do
|
||||
import Plug.Conn
|
||||
use Agent
|
||||
|
||||
custom_script_name = Application.get_env(:plausible, :custom_script_name)
|
||||
base_variants = ["hash", "outbound-links", "exclusions", "compat"]
|
||||
base_filenames = ["plausible", custom_script_name]
|
||||
|
||||
# Generates Power Set of all variants
|
||||
variants =
|
||||
@ -24,8 +26,8 @@ defmodule PlausibleWeb.Tracker do
|
||||
String.split(x, ".")
|
||||
|> Combination.permutate()
|
||||
|> Enum.map(fn p -> Enum.join(p, ".") end)
|
||||
|> Enum.filter(fn permutation -> permutation != x end)
|
||||
|> Enum.map(fn v -> "plausible.#{v}.js" end)
|
||||
|> Enum.map(fn v -> Enum.map(base_filenames, fn filename -> "#{filename}.#{v}.js" end) end)
|
||||
|> List.flatten()
|
||||
|
||||
if Enum.count(variants) > 0 do
|
||||
{"plausible.#{x}.js", variants}
|
||||
@ -33,7 +35,7 @@ defmodule PlausibleWeb.Tracker do
|
||||
end)
|
||||
|> Enum.reject(fn x -> x == nil end)
|
||||
|> Enum.into(%{})
|
||||
|> Map.put("plausible.js", ["analytics.js"])
|
||||
|> Map.put("plausible.js", ["analytics.js", "#{custom_script_name}.js"])
|
||||
|
||||
@templates files_available
|
||||
@aliases aliases_available
|
||||
|
@ -0,0 +1,9 @@
|
||||
defmodule Plausible.Repo.Migrations.MakeInvitationEmailCaseInsensitive do
|
||||
use Ecto.Migration
|
||||
|
||||
def change do
|
||||
alter table(:invitations) do
|
||||
modify :email, :citext, null: false
|
||||
end
|
||||
end
|
||||
end
|
@ -44,6 +44,28 @@ defmodule PlausibleWeb.SiteControllerTest do
|
||||
assert html_response(conn, 200) =~ "<b>3</b> visitors in last 24h"
|
||||
end
|
||||
|
||||
test "shows invitations for user by email address", %{conn: conn, user: user} do
|
||||
site = insert(:site)
|
||||
insert(:invitation, email: user.email, site_id: site.id, inviter: build(:user))
|
||||
conn = get(conn, "/sites")
|
||||
|
||||
assert html_response(conn, 200) =~ site.domain
|
||||
end
|
||||
|
||||
test "invitations are case insensitive", %{conn: conn, user: user} do
|
||||
site = insert(:site)
|
||||
|
||||
insert(:invitation,
|
||||
email: String.upcase(user.email),
|
||||
site_id: site.id,
|
||||
inviter: build(:user)
|
||||
)
|
||||
|
||||
conn = get(conn, "/sites")
|
||||
|
||||
assert html_response(conn, 200) =~ site.domain
|
||||
end
|
||||
|
||||
test "paginates sites", %{conn: conn, user: user} do
|
||||
insert(:site, members: [user], domain: "test-site1.com")
|
||||
insert(:site, members: [user], domain: "test-site2.com")
|
||||
|
Loading…
Reference in New Issue
Block a user