Skip to content
Open
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
3 changes: 3 additions & 0 deletions lib/plausible_web/components/layouts.ex
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ defmodule PlausibleWeb.Layouts do
attr :footer?, :boolean, default: true
attr :global_notices?, :boolean, default: true
attr :trial_badge?, :boolean, default: true
attr :team_switcher?, :boolean, default: true
attr :embedded?, :boolean, default: false
attr :load_dashboard_js?, :boolean, default: false
attr :flash, :map, default: %{}
Expand All @@ -38,6 +39,7 @@ defmodule PlausibleWeb.Layouts do
current_team={@current_team}
current_team_role={@current_team_role}
trial_badge?={@trial_badge?}
team_switcher?={@team_switcher?}
teams={@teams}
my_team={@my_team}
/>
Expand Down Expand Up @@ -152,6 +154,7 @@ defmodule PlausibleWeb.Layouts do
footer?={false}
global_notices?={false}
trial_badge?={false}
team_switcher?={false}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added this so we don't show the team switcher during onboarding.

current_user={@current_user}
flash={@flash}
>
Expand Down
14 changes: 2 additions & 12 deletions lib/plausible_web/components/layouts/header.html.heex
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@
</p>
</.dropdown_item>
<PlausibleWeb.LayoutView.team_switcher
:if={@team_switcher?}
current_user={@current_user}
teams={@teams}
my_team={@my_team}
current_team={@current_team}
Expand All @@ -72,18 +74,6 @@
Account settings
</.dropdown_item>

<div :if={@my_team && @my_team.id == @current_team.id}>
<.dropdown_item
class="flex"
href={~p"/team/setup"}
>
<span data-test="create-a-team-cta" class="flex-1">
Create a team
</span>
</.dropdown_item>
<.dropdown_divider />
</div>

<div :if={Plausible.Teams.setup?(@current_team)}>
<.dropdown_item
class="flex"
Expand Down
97 changes: 43 additions & 54 deletions lib/plausible_web/views/layout_view.ex
Original file line number Diff line number Diff line change
Expand Up @@ -164,73 +164,62 @@ defmodule PlausibleWeb.LayoutView do
end
end

attr :current_user, :any, required: true
attr :teams, :list, required: true
attr :my_team, :any, default: nil
attr :current_team, :any, default: nil

def team_switcher(assigns) do
teams = assigns[:teams]
personal_team =
assigns.my_team || %Teams.Team{identifier: "none", name: Teams.default_name()}

if teams && teams != [] do
current_team = assigns[:current_team]
my_team = assigns[:my_team]
current_included? = current_team && Enum.any?(teams, &(&1.id == current_team.id))
current_is_my? = current_team && my_team && current_team.id == my_team.id
current_team = assigns.current_team || personal_team

teams =
if current_team && !current_included? && !current_is_my? do
[current_team | teams]
else
teams
end

teams =
if my_team do
teams ++ [my_team]
else
teams ++ [%Teams.Team{identifier: "none", name: Teams.default_name()}]
end
other_teams =
[personal_team | Enum.sort_by(assigns.teams, &String.downcase(&1.name))]
|> Enum.reject(&(&1.id == current_team.id))

selected_id = current_team && current_team.id
{pinned_team, other_teams} = Enum.split_with(teams, &(&1.id == selected_id))
assigns =
assigns
|> assign(:current_team, current_team)
|> assign(:personal_team, personal_team)
|> assign(:other_teams, other_teams)

assigns =
assigns
|> assign(:pinned_team, List.first(pinned_team))
|> assign(:other_teams, other_teams)

~H"""
<.dropdown_item>
<div class="text-xs text-gray-500 dark:text-gray-400">Teams</div>
</.dropdown_item>
~H"""
<.dropdown_item>
<div class="text-xs text-gray-500 dark:text-gray-400">Teams</div>
</.dropdown_item>
<.dropdown_item href={~p"/sites?#{[__team: @current_team.identifier]}"}>
<div class="flex items-center justify-between gap-2" role="none">
<p class="font-semibold truncate min-w-0 text-gray-900 dark:text-gray-100">
{Teams.name(@current_team)}
</p>
<Heroicons.check class="size-4 shrink-0 stroke-2 text-gray-500 dark:text-gray-400" />
</div>
</.dropdown_item>
<div class="max-h-[200px] overflow-y-auto">
<.dropdown_item
:if={@pinned_team}
href={~p"/sites?#{[__team: @pinned_team.identifier]}"}
:for={team <- @other_teams}
href={~p"/sites?#{[__team: team.identifier]}"}
>
<div class="flex items-center justify-between gap-2" role="none">
<p class="font-semibold truncate min-w-0 text-gray-900 dark:text-gray-100">
{Teams.name(@pinned_team)}
</p>
<Heroicons.check class="size-4 shrink-0 stroke-2 text-gray-500 dark:text-gray-400" />
</div>
</.dropdown_item>
<div class="max-h-[200px] overflow-y-auto">
<.dropdown_item
:for={team <- @other_teams}
href={~p"/sites?#{[__team: team.identifier]}"}
<p
class="truncate text-gray-900 dark:text-gray-100 pr-4"
role="none"
>
<p
class="font-medium truncate text-gray-900 dark:text-gray-100 pr-4"
role="none"
>
{Teams.name(team)}
</p>
</.dropdown_item>
{Teams.name(team)}
</p>
</.dropdown_item>
</div>
<.dropdown_item
:if={Plausible.Users.type(@current_user) == :standard}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SSO users can't create teams, so we hide the option.

href={~p"/team/setup?#{[__team: @personal_team.identifier]}"}
>
<div class="flex items-center justify-between gap-2" role="none">
<span data-test="create-a-team-cta">Create new team</span>
<Heroicons.plus class="size-4 shrink-0 stroke-2 text-gray-500 dark:text-gray-400" />
</div>
"""
else
~H""
end
</.dropdown_item>
"""
end

def trial_notification(team) do
Expand Down
60 changes: 48 additions & 12 deletions test/plausible_web/controllers/settings_controller_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -1561,7 +1561,7 @@ defmodule PlausibleWeb.SettingsControllerTest do
%{conn: conn} do
conn = get(conn, ~p"/settings/preferences")
html = html_response(conn, 200)
refute html =~ "Team"
refute html =~ "Team settings"

expected_account_menu =
if(ee?(),
Expand Down Expand Up @@ -1700,11 +1700,21 @@ defmodule PlausibleWeb.SettingsControllerTest do
end

test "does not render team settings, when team not set up", %{conn: conn, user: user} do
{:ok, team} = Plausible.Teams.get_or_create(user)
{:ok, _team} = Plausible.Teams.get_or_create(user)
conn = get(conn, ~p"/settings/preferences")
html = html_response(conn, 200)
refute html =~ ~r/Team.*#{Regex.escape(team.name)}/s
refute html =~ team.name
refute html =~ "Team settings"

expected_account_menu =
if(ee?(),
do: [:preferences, :security, :subscription, :api_keys, :danger_zone],
else: [:preferences, :security, :api_keys, :danger_zone]
)

html
|> LazyHTML.from_document()
|> assert_sidebar_menu(expected_account_menu)
|> assert_mobile_menu(expected_account_menu)
end

test "GET /settings/team/general", %{conn: conn, user: user} do
Expand Down Expand Up @@ -2236,22 +2246,48 @@ defmodule PlausibleWeb.SettingsControllerTest do
describe "account dropdown menu (_header.html)" do
setup [:create_user, :log_in]

test "renders the 'Create a team' option", %{conn: conn, user: user} do
test "renders the 'Create new team' option", %{conn: conn, user: user} do
subscribe_to_growth_plan(user)
conn = get(conn, ~p"/settings/preferences")
html = html_response(conn, 200)
assert text_of_element(html, ~s/[data-test="create-a-team-cta"]/) == "Create a team"
assert text_of_element(html, ~s/[data-test="create-a-team-cta"]/) == "Create new team"
end

test "does not render the 'Create a team' option if a team is already set up", %{
conn: conn,
user: user
} do
test "renders the 'Create new team' option for the personal team when a team is already set up",
%{conn: conn, user: user} do
{:ok, team} = Plausible.Teams.get_or_create(user)
Plausible.Teams.complete_setup(team)
conn = get(conn, ~p"/settings/preferences")
conn = get(set_current_team(conn, team), ~p"/settings/preferences")
html = html_response(conn, 200)

assert html |> find(~s|a[href^="/team/setup"]|) |> LazyHTML.attribute("href") == [
"/team/setup?__team=none"
]
end

test "renders the 'Create new team' option for the existing personal team when another team is selected",
%{conn: conn, user: user} do
site = new_site(owner: user)
other_team = insert(:team, name: "Zeta", identifier: Ecto.UUID.generate())
add_member(other_team, user: user, role: :viewer)
conn = get(set_current_team(conn, other_team), ~p"/settings/preferences")
html = html_response(conn, 200)
refute element_exists?(html, ~s/[data-test="create-a-team-cta"]/)

assert html |> find(~s|a[href^="/team/setup"]|) |> LazyHTML.attribute("href") == [
"/team/setup?__team=#{site.team.identifier}"
]
end
end

on_ee do
describe "account dropdown menu (_header.html) - SSO user" do
setup [:create_user, :create_site, :create_team, :setup_sso, :provision_sso_user, :log_in]

test "does not render the 'Create new team' option", %{conn: conn} do
conn = get(conn, ~p"/settings/preferences")
html = html_response(conn, 200)
refute element_exists?(html, ~s/[data-test="create-a-team-cta"]/)
end
end
end

Expand Down
32 changes: 32 additions & 0 deletions test/plausible_web/live/sites_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,38 @@ defmodule PlausibleWeb.Live.SitesTest do
)
end

test "lists personal sites in team switcher when the user has no other teams", %{
conn: conn,
user: user
} do
new_site(owner: user)

{:ok, _lv, html} = live(conn, "/sites")

assert text_of_element(html, ~s|a[href^="/sites?__team="]|) == "My personal sites"
end

test "lists current team first, personal sites second, then other teams by name", %{
conn: conn,
user: user
} do
[zeta, beta, alpha] =
for name <- ["Zeta", "Beta", "Alpha"] do
team = insert(:team, name: name, identifier: Ecto.UUID.generate())
add_member(team, user: user, role: :viewer)
team
end

{:ok, _lv, html} = live(set_current_team(conn, zeta), "/sites")

assert html |> find(~s|a[href^="/sites?__team="]|) |> LazyHTML.attribute("href") == [
"/sites?__team=#{zeta.identifier}",
"/sites?__team=none",
"/sites?__team=#{alpha.identifier}",
"/sites?__team=#{beta.identifier}"
]
end

test "renders settings link when current team is set", %{user: user, conn: conn} do
{:ok, _lv, html} = live(conn, "/sites")

Expand Down
6 changes: 6 additions & 0 deletions test/plausible_web/live/team_setup_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ defmodule PlausibleWeb.Live.TeamSetupTest do
"Set up team"
end

test "does not render the team switcher", %{conn: conn, site: site} do
{:ok, _lv, html} = live(conn, onboarding_url(site.domain))

refute html =~ "Create new team"
end

test "suggests a team name based on the site domain", %{conn: conn, user: user} do
site = new_site(owner: user, domain: "shop.my-company.co.uk")

Expand Down
Loading