<.dropdown_item
class="flex"
diff --git a/lib/plausible_web/views/layout_view.ex b/lib/plausible_web/views/layout_view.ex
index 210e886c4fe0..5f79de807fe5 100644
--- a/lib/plausible_web/views/layout_view.ex
+++ b/lib/plausible_web/views/layout_view.ex
@@ -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>
-
+
+ <.dropdown_item href={~p"/sites?#{[__team: @current_team.identifier]}"}>
+
<.dropdown_item
- :if={@pinned_team}
- href={~p"/sites?#{[__team: @pinned_team.identifier]}"}
+ :for={team <- @other_teams}
+ href={~p"/sites?#{[__team: team.identifier]}"}
>
-
-
- {Teams.name(@pinned_team)}
-
-
-
-
-
- <.dropdown_item
- :for={team <- @other_teams}
- href={~p"/sites?#{[__team: team.identifier]}"}
+
-
- {Teams.name(team)}
-
-
+ {Teams.name(team)}
+
+
+
+ <.dropdown_item
+ :if={Plausible.Users.type(@current_user) == :standard}
+ href={~p"/team/setup?#{[__team: @personal_team.identifier]}"}
+ >
+
+ Create new team
+
- """
- else
- ~H""
- end
+
+ """
end
def trial_notification(team) do
diff --git a/test/plausible_web/controllers/settings_controller_test.exs b/test/plausible_web/controllers/settings_controller_test.exs
index a2583dafae82..3d9a297c3bdf 100644
--- a/test/plausible_web/controllers/settings_controller_test.exs
+++ b/test/plausible_web/controllers/settings_controller_test.exs
@@ -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?(),
@@ -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
@@ -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
diff --git a/test/plausible_web/live/sites_test.exs b/test/plausible_web/live/sites_test.exs
index 259c5877bbf0..90432976a82f 100644
--- a/test/plausible_web/live/sites_test.exs
+++ b/test/plausible_web/live/sites_test.exs
@@ -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")
diff --git a/test/plausible_web/live/team_setup_test.exs b/test/plausible_web/live/team_setup_test.exs
index 989832899721..c103b3af7c5c 100644
--- a/test/plausible_web/live/team_setup_test.exs
+++ b/test/plausible_web/live/team_setup_test.exs
@@ -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")