mirror of
https://github.com/plausible/analytics.git
synced 2024-12-23 09:33:19 +03:00
Add data retention to the choose plan page (#3605)
* Add data retention field to plans * Display data retention as benefit when choosing plan * Split fields in two module attributes * Remove extra whitespace Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com> --------- Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
This commit is contained in:
parent
26809bfd2e
commit
45a763ab2b
@ -23,6 +23,7 @@ defmodule Plausible.Billing.Plan do
|
||||
field :site_limit, :integer
|
||||
field :team_member_limit, Plausible.Billing.Ecto.Limit
|
||||
field :volume, :string
|
||||
field :data_retention_in_years, :integer
|
||||
|
||||
field :monthly_cost
|
||||
field :monthly_product_id, :string
|
||||
@ -30,16 +31,16 @@ defmodule Plausible.Billing.Plan do
|
||||
field :yearly_product_id, :string
|
||||
end
|
||||
|
||||
@fields ~w(generation kind features monthly_pageview_limit site_limit team_member_limit volume monthly_cost monthly_product_id yearly_cost yearly_product_id)a
|
||||
@required_fields ~w(generation kind features monthly_pageview_limit site_limit team_member_limit volume)a
|
||||
@optional_fields ~w(monthly_cost yearly_cost monthly_product_id yearly_product_id data_retention_in_years)a
|
||||
@fields @required_fields ++ @optional_fields
|
||||
|
||||
def changeset(plan, attrs) do
|
||||
plan
|
||||
|> cast(attrs, @fields)
|
||||
|> put_volume()
|
||||
|> validate_required_either([:monthly_product_id, :yearly_product_id])
|
||||
|> validate_required(
|
||||
@fields -- [:monthly_cost, :yearly_cost, :monthly_product_id, :yearly_product_id]
|
||||
)
|
||||
|> validate_required(@required_fields)
|
||||
end
|
||||
|
||||
defp put_volume(changeset) do
|
||||
@ -51,9 +52,10 @@ defmodule Plausible.Billing.Plan do
|
||||
end
|
||||
|
||||
def validate_required_either(changeset, fields) do
|
||||
if Enum.any?(fields, &get_field(changeset, &1)),
|
||||
do: changeset,
|
||||
else:
|
||||
if Enum.any?(fields, &get_field(changeset, &1)) do
|
||||
changeset
|
||||
else
|
||||
add_error(changeset, hd(fields), "one of these fields must be present #{inspect(fields)}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -739,29 +739,34 @@ defmodule PlausibleWeb.Live.ChoosePlan do
|
||||
[
|
||||
team_member_limit_benefit(plan),
|
||||
site_limit_benefit(plan),
|
||||
data_retention_benefit(plan),
|
||||
"Intuitive, fast and privacy-friendly dashboard",
|
||||
"Email/Slack reports",
|
||||
"Google Analytics import"
|
||||
]
|
||||
|> Kernel.++(feature_benefits(plan))
|
||||
|> Enum.filter(& &1)
|
||||
end
|
||||
|
||||
defp business_benefits(plan, growth_benefits) do
|
||||
[
|
||||
"Everything in Growth",
|
||||
team_member_limit_benefit(plan),
|
||||
site_limit_benefit(plan)
|
||||
site_limit_benefit(plan),
|
||||
data_retention_benefit(plan)
|
||||
]
|
||||
|> Kernel.++(feature_benefits(plan))
|
||||
|> Kernel.--(growth_benefits)
|
||||
|> Kernel.++(["Priority support"])
|
||||
|> Enum.filter(& &1)
|
||||
end
|
||||
|
||||
defp enterprise_benefits(business_benefits) do
|
||||
team_members =
|
||||
if "Up to 10 team members" in business_benefits,
|
||||
do: "10+ team members",
|
||||
else: nil
|
||||
if "Up to 10 team members" in business_benefits, do: "10+ team members"
|
||||
|
||||
data_retention =
|
||||
if "5 years of data retention" in business_benefits, do: "5+ years of data retention"
|
||||
|
||||
[
|
||||
"Everything in Business",
|
||||
@ -769,11 +774,16 @@ defmodule PlausibleWeb.Live.ChoosePlan do
|
||||
"50+ sites",
|
||||
"600+ Stats API requests per hour",
|
||||
&sites_api_benefit/1,
|
||||
data_retention,
|
||||
"Technical onboarding"
|
||||
]
|
||||
|> Enum.filter(& &1)
|
||||
end
|
||||
|
||||
defp data_retention_benefit(%Plan{} = plan) do
|
||||
if plan.data_retention_in_years, do: "#{plan.data_retention_in_years} years of data retention"
|
||||
end
|
||||
|
||||
defp team_member_limit_benefit(%Plan{} = plan) do
|
||||
case plan.team_member_limit do
|
||||
:unlimited -> "Unlimited team members"
|
||||
|
@ -7,7 +7,8 @@
|
||||
"yearly_product_id":"857079",
|
||||
"site_limit":10,
|
||||
"team_member_limit":3,
|
||||
"features":["goals"]
|
||||
"features":["goals"],
|
||||
"data_retention_in_years": 3
|
||||
},
|
||||
{
|
||||
"kind":"growth",
|
||||
@ -17,7 +18,8 @@
|
||||
"yearly_product_id":"857080",
|
||||
"site_limit":10,
|
||||
"team_member_limit":3,
|
||||
"features":["goals"]
|
||||
"features":["goals"],
|
||||
"data_retention_in_years": 3
|
||||
},
|
||||
{
|
||||
"kind":"growth",
|
||||
@ -27,7 +29,8 @@
|
||||
"yearly_product_id":"857081",
|
||||
"site_limit":10,
|
||||
"team_member_limit":3,
|
||||
"features":["goals"]
|
||||
"features":["goals"],
|
||||
"data_retention_in_years": 3
|
||||
},
|
||||
{
|
||||
"kind":"growth",
|
||||
@ -37,7 +40,8 @@
|
||||
"yearly_product_id":"857082",
|
||||
"site_limit":10,
|
||||
"team_member_limit":3,
|
||||
"features":["goals"]
|
||||
"features":["goals"],
|
||||
"data_retention_in_years": 3
|
||||
},
|
||||
{
|
||||
"kind":"growth",
|
||||
@ -47,7 +51,8 @@
|
||||
"yearly_product_id":"857083",
|
||||
"site_limit":10,
|
||||
"team_member_limit":3,
|
||||
"features":["goals"]
|
||||
"features":["goals"],
|
||||
"data_retention_in_years": 3
|
||||
},
|
||||
{
|
||||
"kind":"growth",
|
||||
@ -57,7 +62,8 @@
|
||||
"yearly_product_id":"857084",
|
||||
"site_limit":10,
|
||||
"team_member_limit":3,
|
||||
"features":["goals"]
|
||||
"features":["goals"],
|
||||
"data_retention_in_years": 3
|
||||
},
|
||||
{
|
||||
"kind":"growth",
|
||||
@ -67,7 +73,8 @@
|
||||
"yearly_product_id":"857085",
|
||||
"site_limit":10,
|
||||
"team_member_limit":3,
|
||||
"features":["goals"]
|
||||
"features":["goals"],
|
||||
"data_retention_in_years": 3
|
||||
},
|
||||
{
|
||||
"kind":"growth",
|
||||
@ -77,7 +84,8 @@
|
||||
"yearly_product_id":"857086",
|
||||
"site_limit":10,
|
||||
"team_member_limit":3,
|
||||
"features":["goals"]
|
||||
"features":["goals"],
|
||||
"data_retention_in_years": 3
|
||||
},
|
||||
{
|
||||
"kind":"business",
|
||||
@ -87,7 +95,8 @@
|
||||
"yearly_product_id":"857087",
|
||||
"site_limit":50,
|
||||
"team_member_limit":10,
|
||||
"features":["goals","props","revenue_goals","funnels","stats_api"]
|
||||
"features":["goals","props","revenue_goals","funnels","stats_api"],
|
||||
"data_retention_in_years": 5
|
||||
},
|
||||
{
|
||||
"kind":"business",
|
||||
@ -97,7 +106,8 @@
|
||||
"yearly_product_id":"857088",
|
||||
"site_limit":50,
|
||||
"team_member_limit":10,
|
||||
"features":["goals","props","revenue_goals","funnels","stats_api"]
|
||||
"features":["goals","props","revenue_goals","funnels","stats_api"],
|
||||
"data_retention_in_years": 5
|
||||
},
|
||||
{
|
||||
"kind":"business",
|
||||
@ -107,7 +117,8 @@
|
||||
"yearly_product_id":"857089",
|
||||
"site_limit":50,
|
||||
"team_member_limit":10,
|
||||
"features":["goals","props","revenue_goals","funnels","stats_api"]
|
||||
"features":["goals","props","revenue_goals","funnels","stats_api"],
|
||||
"data_retention_in_years": 5
|
||||
},
|
||||
{
|
||||
"kind":"business",
|
||||
@ -117,7 +128,8 @@
|
||||
"yearly_product_id":"857090",
|
||||
"site_limit":50,
|
||||
"team_member_limit":10,
|
||||
"features":["goals","props","revenue_goals","funnels","stats_api"]
|
||||
"features":["goals","props","revenue_goals","funnels","stats_api"],
|
||||
"data_retention_in_years": 5
|
||||
},
|
||||
{
|
||||
"kind":"business",
|
||||
@ -127,7 +139,8 @@
|
||||
"yearly_product_id":"857091",
|
||||
"site_limit":50,
|
||||
"team_member_limit":10,
|
||||
"features":["goals","props","revenue_goals","funnels","stats_api"]
|
||||
"features":["goals","props","revenue_goals","funnels","stats_api"],
|
||||
"data_retention_in_years": 5
|
||||
},
|
||||
{
|
||||
"kind":"business",
|
||||
@ -137,7 +150,8 @@
|
||||
"yearly_product_id":"857092",
|
||||
"site_limit":50,
|
||||
"team_member_limit":10,
|
||||
"features":["goals","props","revenue_goals","funnels","stats_api"]
|
||||
"features":["goals","props","revenue_goals","funnels","stats_api"],
|
||||
"data_retention_in_years": 5
|
||||
},
|
||||
{
|
||||
"kind":"business",
|
||||
@ -147,7 +161,8 @@
|
||||
"yearly_product_id":"857093",
|
||||
"site_limit":50,
|
||||
"team_member_limit":10,
|
||||
"features":["goals","props","revenue_goals","funnels","stats_api"]
|
||||
"features":["goals","props","revenue_goals","funnels","stats_api"],
|
||||
"data_retention_in_years": 5
|
||||
},
|
||||
{
|
||||
"kind":"business",
|
||||
@ -157,6 +172,7 @@
|
||||
"yearly_product_id":"857094",
|
||||
"site_limit":50,
|
||||
"team_member_limit":10,
|
||||
"features":["goals","props","revenue_goals","funnels","stats_api"]
|
||||
"features":["goals","props","revenue_goals","funnels","stats_api"],
|
||||
"data_retention_in_years": 5
|
||||
}
|
||||
]
|
||||
|
@ -0,0 +1,11 @@
|
||||
defmodule Plausible.Repo.Migrations.AddDataRetentionInYearsToPlans do
|
||||
use Ecto.Migration
|
||||
|
||||
def change do
|
||||
if !Application.get_env(:plausible, :is_selfhost) do
|
||||
alter table(:plans) do
|
||||
add :data_retention_in_years, :integer, null: true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -37,7 +37,8 @@
|
||||
"yearly_product_id":"63862",
|
||||
"site_limit":10,
|
||||
"team_member_limit":3,
|
||||
"features":["goals"]
|
||||
"features":["goals"],
|
||||
"data_retention_in_years": 3
|
||||
},
|
||||
{
|
||||
"kind":"growth",
|
||||
@ -47,7 +48,8 @@
|
||||
"yearly_product_id":"63863",
|
||||
"site_limit":10,
|
||||
"team_member_limit":3,
|
||||
"features":["goals"]
|
||||
"features":["goals"],
|
||||
"data_retention_in_years": 3
|
||||
},
|
||||
{
|
||||
"kind":"growth",
|
||||
@ -57,7 +59,8 @@
|
||||
"yearly_product_id":"63864",
|
||||
"site_limit":10,
|
||||
"team_member_limit":3,
|
||||
"features":["goals"]
|
||||
"features":["goals"],
|
||||
"data_retention_in_years": 3
|
||||
},
|
||||
{
|
||||
"kind":"growth",
|
||||
@ -67,7 +70,8 @@
|
||||
"yearly_product_id":"63865",
|
||||
"site_limit":10,
|
||||
"team_member_limit":3,
|
||||
"features":["goals"]
|
||||
"features":["goals"],
|
||||
"data_retention_in_years": 3
|
||||
},
|
||||
{
|
||||
"kind":"growth",
|
||||
@ -77,7 +81,8 @@
|
||||
"yearly_product_id":"63866",
|
||||
"site_limit":10,
|
||||
"team_member_limit":3,
|
||||
"features":["goals"]
|
||||
"features":["goals"],
|
||||
"data_retention_in_years": 3
|
||||
},
|
||||
{
|
||||
"kind":"business",
|
||||
@ -117,7 +122,8 @@
|
||||
"yearly_product_id":"63870",
|
||||
"site_limit":50,
|
||||
"team_member_limit":10,
|
||||
"features":["goals","props", "revenue_goals", "funnels","stats_api"]
|
||||
"features":["goals","props", "revenue_goals", "funnels","stats_api"],
|
||||
"data_retention_in_years": 5
|
||||
},
|
||||
{
|
||||
"kind":"business",
|
||||
@ -127,7 +133,8 @@
|
||||
"yearly_product_id":"63871",
|
||||
"site_limit":50,
|
||||
"team_member_limit":10,
|
||||
"features":["goals","props", "revenue_goals", "funnels","stats_api"]
|
||||
"features":["goals","props", "revenue_goals", "funnels","stats_api"],
|
||||
"data_retention_in_years": 5
|
||||
},
|
||||
{
|
||||
"kind":"business",
|
||||
@ -137,7 +144,8 @@
|
||||
"yearly_product_id":"63872",
|
||||
"site_limit":50,
|
||||
"team_member_limit":10,
|
||||
"features":["goals","props", "revenue_goals", "funnels","stats_api"]
|
||||
"features":["goals","props", "revenue_goals", "funnels","stats_api"],
|
||||
"data_retention_in_years": 5
|
||||
},
|
||||
{
|
||||
"kind":"business",
|
||||
@ -147,7 +155,8 @@
|
||||
"yearly_product_id":"63873",
|
||||
"site_limit":50,
|
||||
"team_member_limit":10,
|
||||
"features":["goals","props", "revenue_goals", "funnels","stats_api"]
|
||||
"features":["goals","props", "revenue_goals", "funnels","stats_api"],
|
||||
"data_retention_in_years": 5
|
||||
},
|
||||
{
|
||||
"kind":"business",
|
||||
@ -157,6 +166,7 @@
|
||||
"yearly_product_id":"63874",
|
||||
"site_limit":50,
|
||||
"team_member_limit":10,
|
||||
"features":["goals","props", "revenue_goals", "funnels","stats_api"]
|
||||
"features":["goals","props", "revenue_goals", "funnels","stats_api"],
|
||||
"data_retention_in_years": 5
|
||||
}
|
||||
]
|
||||
|
@ -262,6 +262,7 @@ defmodule PlausibleWeb.Live.ChoosePlanTest do
|
||||
assert growth_box =~ "Email/Slack reports"
|
||||
assert growth_box =~ "Google Analytics import"
|
||||
assert growth_box =~ "Goals and custom events"
|
||||
assert growth_box =~ "3 years of data retention"
|
||||
|
||||
assert business_box =~ "Everything in Growth"
|
||||
assert business_box =~ "Up to 10 team members"
|
||||
@ -271,6 +272,7 @@ defmodule PlausibleWeb.Live.ChoosePlanTest do
|
||||
assert business_box =~ "Funnels"
|
||||
assert business_box =~ "Ecommerce revenue attribution"
|
||||
assert business_box =~ "Priority support"
|
||||
assert business_box =~ "5 years of data retention"
|
||||
|
||||
refute business_box =~ "Goals and custom events"
|
||||
|
||||
@ -280,6 +282,7 @@ defmodule PlausibleWeb.Live.ChoosePlanTest do
|
||||
assert enterprise_box =~ "600+ Stats API requests per hour"
|
||||
assert enterprise_box =~ "Sites API access for"
|
||||
assert enterprise_box =~ "Technical onboarding"
|
||||
assert enterprise_box =~ "5+ years of data retention"
|
||||
|
||||
assert text_of_attr(find(doc, "#{@enterprise_plan_box} p a"), "href") =~
|
||||
"https://plausible.io/white-label-web-analytics"
|
||||
|
Loading…
Reference in New Issue
Block a user