Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ All notable changes to this project will be documented in this file.
- Fixed incline/decline percentages not showing in top stats in comparison mode
- Fixed issue with timestamps being rendered incorrectly in segment menus and modals for some timezones
- Fixed main graph being clipped when the browser's root font size is smaller than the default 16px
- Fixed issue with users with billing role not being able to create personal segments

## v3.2.0 - 2026-01-16

Expand Down
6 changes: 3 additions & 3 deletions lib/plausible/segments/segments.ex
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ defmodule Plausible.Segments do
)
)}

site_role in @roles_with_personal_segments or site_role in @roles_with_maybe_site_segments ->
site_role in roles_with_personal_segments() or site_role in roles_with_maybe_site_segments() ->
fields = fields ++ [:owner_id]

{:ok,
Expand Down Expand Up @@ -456,8 +456,8 @@ defmodule Plausible.Segments do
|> Plausible.Times.to_naive_datetime!(timezone)
end

def roles_with_personal_segments(), do: [:viewer, :editor, :admin, :owner, :super_admin]
def roles_with_maybe_site_segments(), do: [:editor, :admin, :owner, :super_admin]
def roles_with_personal_segments(), do: @roles_with_personal_segments
def roles_with_maybe_site_segments(), do: @roles_with_maybe_site_segments

def site_segments_available?(%Plausible.Site{} = site),
do: Plausible.Billing.Feature.SiteSegments.check_availability(site.team) == :ok
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,15 +80,29 @@ defmodule PlausibleWeb.Api.Internal.SegmentsControllerTest do
) == 500
end

for %{role: role, type: type} <- [
%{role: :viewer, type: :personal},
%{role: :editor, type: :personal},
%{role: :editor, type: :site}
for %{role: role, type: type, membership_type: membership_type} <- [
%{membership_type: :site_guest, role: :viewer, type: :personal},
%{membership_type: :site_guest, role: :editor, type: :personal},
%{membership_type: :site_guest, role: :editor, type: :site},
%{membership_type: :team_member, role: :viewer, type: :personal},
%{membership_type: :team_member, role: :billing, type: :personal},
%{membership_type: :team_member, role: :editor, type: :personal},
%{membership_type: :team_member, role: :editor, type: :site},
%{membership_type: :team_member, role: :admin, type: :personal},
%{membership_type: :team_member, role: :admin, type: :site},
%{membership_type: :team_member, role: :owner, type: :personal},
%{membership_type: :team_member, role: :owner, type: :site}
] do
test "#{role} can create segment with type \"#{type}\" successfully",
test "#{role} (#{Phoenix.Naming.humanize(membership_type)}) can create segment with type \"#{type}\" successfully",
%{conn: conn, user: user} do
site = new_site()
add_guest(site, user: user, role: unquote(role))

add_site_guest_or_team_member(site,
user: user,
role: unquote(role),
membership_type: unquote(membership_type)
)

insert(:goal, site: site, event_name: "Conversion")

response =
Expand Down
Loading