diff --git a/extra/lib/plausible_web/live/customer_support/live.ex b/extra/lib/plausible_web/live/customer_support/live.ex index fecf2f8b7743..363838b0277c 100644 --- a/extra/lib/plausible_web/live/customer_support/live.ex +++ b/extra/lib/plausible_web/live/customer_support/live.ex @@ -4,7 +4,7 @@ defmodule PlausibleWeb.CustomerSupport.Live do Provides: - Standard mount/3 and handle_info/2 implementations - - Tab navigation components and routing utilities + - Tab navigation components and routing utilities - Common aliases and imports for Customer Support LiveViews - Convenience API for flashes and redirects """ @@ -84,7 +84,7 @@ defmodule PlausibleWeb.CustomerSupport.Live do patch={"?tab=#{@to}"} class={[ @link_class, - "group relative min-w-0 flex-1 overflow-hidden bg-white dark:bg-gray-800 py-4 px-6 text-center text-sm font-medium hover:bg-gray-50 dark:hover:bg-gray-750 focus:z-10 first:rounded-l-lg last:rounded-r-lg" + "group relative min-w-0 flex-1 overflow-hidden bg-white dark:bg-gray-800 py-4 px-6 text-center text-sm font-medium hover:bg-gray-50 dark:hover:bg-gray-700 focus:z-10 first:rounded-l-lg last:rounded-r-lg" ]} > {render_slot(@inner_block)} diff --git a/extra/lib/plausible_web/live/customer_support/team/components/consolidated_views.ex b/extra/lib/plausible_web/live/customer_support/team/components/consolidated_views.ex index 2e43bd811986..4d469eb721d9 100644 --- a/extra/lib/plausible_web/live/customer_support/team/components/consolidated_views.ex +++ b/extra/lib/plausible_web/live/customer_support/team/components/consolidated_views.ex @@ -29,6 +29,7 @@ defmodule PlausibleWeb.CustomerSupport.Team.Components.ConsolidatedViews do <.th>Domain <.th>Timezone <.th invisible>Dashboard + <.th invisible>Settings <.th invisible>Delete @@ -43,6 +44,21 @@ defmodule PlausibleWeb.CustomerSupport.Team.Components.ConsolidatedViews do Dashboard + <.td> + <.styled_link + new_tab={true} + href={ + Routes.site_path( + PlausibleWeb.Endpoint, + :settings_general, + consolidated_view.domain, + [] + ) + } + > + Settings + + <.td> <.delete_button phx-click="delete-consolidated-view" @@ -63,8 +79,8 @@ defmodule PlausibleWeb.CustomerSupport.Team.Components.ConsolidatedViews do success("Consolidated view created") {:noreply, assign(socket, consolidated_views: [consolidated_view])} - {:error, _} -> - failure("Could not create consolidated view") + {:error, reason} -> + failure("Could not create consolidated view. Reason: #{inspect(reason)}") {:noreply, socket} end end diff --git a/lib/plausible_web/components/generic.ex b/lib/plausible_web/components/generic.ex index 4e3586e18996..624ed39783df 100644 --- a/lib/plausible_web/components/generic.ex +++ b/lib/plausible_web/components/generic.ex @@ -484,7 +484,7 @@ defmodule PlausibleWeb.Components.Generic do def tile(assigns) do ~H""" -
Define actions that you want your users to take, like visiting a certain page, submitting a form, etc.
-+
You can also <.styled_link href={Routes.site_path(@conn, :settings_funnels, @site.domain)}> compose goals into funnels. diff --git a/lib/plausible_web/views/layout_view.ex b/lib/plausible_web/views/layout_view.ex index 3840f01fd97a..b966bbd1e183 100644 --- a/lib/plausible_web/views/layout_view.ex +++ b/lib/plausible_web/views/layout_view.ex @@ -52,29 +52,41 @@ defmodule PlausibleWeb.LayoutView do end def site_settings_sidebar(conn) do + regular_site? = Plausible.Sites.regular?(conn.assigns.site) + [ %{key: "General", value: "general", icon: :rocket_launch}, - %{key: "People", value: "people", icon: :users}, - %{key: "Visibility", value: "visibility", icon: :eye}, + if regular_site? do + %{key: "People", value: "people", icon: :users} + end, + if regular_site? do + %{key: "Visibility", value: "visibility", icon: :eye} + end, %{key: "Goals", value: "goals", icon: :check_circle}, on_ee do - %{key: "Funnels", value: "funnels", icon: :funnel} + if regular_site? do + %{key: "Funnels", value: "funnels", icon: :funnel} + end end, %{key: "Custom properties", value: "properties", icon: :document_text}, %{key: "Integrations", value: "integrations", icon: :puzzle_piece}, - %{key: "Imports & exports", value: "imports-exports", icon: :arrow_down_tray}, - %{ - key: "Shields", - icon: :shield_exclamation, - value: [ - %{key: "IP addresses", value: "shields/ip_addresses"}, - %{key: "Countries", value: "shields/countries"}, - %{key: "Pages", value: "shields/pages"}, - %{key: "Hostnames", value: "shields/hostnames"} - ] - }, + if regular_site? do + %{key: "Imports & exports", value: "imports-exports", icon: :arrow_down_tray} + end, + if regular_site? do + %{ + key: "Shields", + icon: :shield_exclamation, + value: [ + %{key: "IP addresses", value: "shields/ip_addresses"}, + %{key: "Countries", value: "shields/countries"}, + %{key: "Pages", value: "shields/pages"}, + %{key: "Hostnames", value: "shields/hostnames"} + ] + } + end, %{key: "Email reports", value: "email-reports", icon: :envelope}, - if conn.assigns[:site_role] in [:owner, :admin] do + if regular_site? and conn.assigns[:site_role] in [:owner, :admin] do %{key: "Danger zone", value: "danger-zone", icon: :exclamation_triangle} end ] diff --git a/test/plausible_web/controllers/site_controller_test.exs b/test/plausible_web/controllers/site_controller_test.exs index cb89dd73926b..d41080d66fba 100644 --- a/test/plausible_web/controllers/site_controller_test.exs +++ b/test/plausible_web/controllers/site_controller_test.exs @@ -510,6 +510,16 @@ defmodule PlausibleWeb.SiteControllerTest do assert resp =~ "Site installation" end + @tag :ee_only + test "renders only timezone section for a consolidated site", %{conn: conn, user: user} do + consolidated_view = user |> team_of() |> new_consolidated_view() + conn = get(conn, "/#{consolidated_view.domain}/settings/general") + resp = html_response(conn, 200) + + assert [tile_element] = find(resp, ~s|div[data-test-id="settings-tile"]|) + assert text(tile_element) =~ "Site timezone" + end + @tag :ee_only test "all site settings sidebar items are working links", %{ conn: conn, @@ -575,6 +585,30 @@ defmodule PlausibleWeb.SiteControllerTest do ] end + @tag :ee_only + test "consolidated view settings sidebar items", %{ + conn: conn, + user: user + } do + team = user |> team_of() + site = new_consolidated_view(team) + conn = get(conn, "/#{site.domain}/settings/general") + resp = html_response(conn, 200) + + items = + resp + |> find("[data-testid=site_settings_sidebar] a") + |> Enum.map(fn a -> {text(a), text_of_attr(a, "href")} end) + + assert items == [ + {"General", "/#{site.domain}/settings/general"}, + {"Goals", "/#{site.domain}/settings/goals"}, + {"Custom properties", "/#{site.domain}/settings/properties"}, + {"Integrations", "/#{site.domain}/settings/integrations"}, + {"Email reports", "/#{site.domain}/settings/email-reports"} + ] + end + test "header and footer are shown", %{conn: conn, site: site, user: user} do conn = get(conn, "/#{site.domain}/settings/general") resp = html_response(conn, 200) @@ -1861,6 +1895,19 @@ defmodule PlausibleWeb.SiteControllerTest do end end + describe "/:domain/settings/general" do + setup [:create_user, :log_in] + + test "shows domain change in the settings form", %{conn: conn, site: site} do + conn = get(conn, Routes.site_path(conn, :settings_general, site.domain)) + resp = html_response(conn, 200) + + assert resp =~ "Site domain" + assert resp =~ "Change domain" + assert resp =~ Routes.site_path(conn, :change_domain, site.domain) + end + end + describe "domain change" do setup [:create_user, :log_in, :create_site] diff --git a/test/plausible_web/live/customer_support/teams_test.exs b/test/plausible_web/live/customer_support/teams_test.exs index 305c5c8c4463..f718b6e0bc8d 100644 --- a/test/plausible_web/live/customer_support/teams_test.exs +++ b/test/plausible_web/live/customer_support/teams_test.exs @@ -218,6 +218,7 @@ defmodule PlausibleWeb.Live.CustomerSupport.TeamsTest do assert table_text =~ team.identifier assert table_text =~ "Dashboard" + assert table_text =~ "Settings" assert element_exists?(html, @delete_consolidated_view_button) end diff --git a/test/plausible_web/live/goal_settings_test.exs b/test/plausible_web/live/goal_settings_test.exs index 060ed21ce76c..496bc0f9fbb6 100644 --- a/test/plausible_web/live/goal_settings_test.exs +++ b/test/plausible_web/live/goal_settings_test.exs @@ -4,6 +4,8 @@ defmodule PlausibleWeb.Live.GoalSettingsTest do import Phoenix.LiveViewTest import Plausible.Test.Support.HTML + @funnels_cta ~s|p[data-test-id="setup-funnels-cta"]| + describe "GET /:domain/settings/goals" do setup [:create_user, :log_in, :create_site] @@ -14,8 +16,11 @@ defmodule PlausibleWeb.Live.GoalSettingsTest do resp = html_response(conn, 200) assert resp =~ "Define actions that you want your users to take" - assert resp =~ "compose goals into funnels" - assert resp =~ "/#{URI.encode_www_form(site.domain)}/settings/funnels" + assert text_of_element(resp, @funnels_cta) =~ "compose goals into funnels" + + assert text_of_element(resp, @funnels_cta) =~ + "/#{URI.encode_www_form(site.domain)}/settings/funnels" + assert element_exists?(resp, ~s|a[href="https://plausible.io/docs/goal-conversions"]|) assert resp =~ to_string(g1) @@ -98,6 +103,51 @@ defmodule PlausibleWeb.Live.GoalSettingsTest do end end + on_ee do + describe "GET /:domain/settings/goals - consolidated views" do + setup [:create_user, :create_team, :log_in] + + setup %{team: team} = context do + new_site(team: team) + new_site(team: team) + + {:ok, Map.put(context, :consolidated_view, new_consolidated_view(team))} + end + + test "no goals exist", %{conn: conn, consolidated_view: consolidated_view} do + conn = get(conn, "/#{consolidated_view.domain}/settings/goals") + + assert resp = html_response(conn, 200) + assert resp =~ "Define actions that you want your users to take" + assert resp =~ "No goals configured for this site" + assert element_exists?(resp, ~s|a[href="https://plausible.io/docs/goal-conversions"]|) + end + + test "lists goals", %{conn: conn, consolidated_view: consolidated_view} do + {:ok, g1} = Plausible.Goals.create(consolidated_view, %{"page_path" => "/go/to/blog/**"}) + {:ok, g2} = Plausible.Goals.create(consolidated_view, %{"event_name" => "Register"}) + + conn = get(conn, "/#{consolidated_view.domain}/settings/goals") + + assert resp = html_response(conn, 200) + assert resp =~ "Define actions that you want your users to take" + assert element_exists?(resp, ~s|a[href="https://plausible.io/docs/goal-conversions"]|) + + assert resp =~ to_string(g1) + assert resp =~ "Pageview" + assert resp =~ to_string(g2) + assert resp =~ "Custom Event" + end + + test "does not render funnels cta", %{conn: conn, consolidated_view: consolidated_view} do + conn = get(conn, "/#{consolidated_view.domain}/settings/goals") + + assert resp = html_response(conn, 200) + refute element_exists?(resp, @funnels_cta) + end + end + end + describe "GoalSettings live view" do setup [:create_user, :log_in, :create_site] @@ -213,6 +263,51 @@ defmodule PlausibleWeb.Live.GoalSettingsTest do end end + describe "GoalSettings live view - consolidated views" do + setup [:create_user, :create_team, :log_in] + + setup %{team: team} = context do + new_site(team: team) + new_site(team: team) + + {:ok, Map.put(context, :consolidated_view, new_consolidated_view(team))} + end + + test "allows goal deletion", %{conn: conn, consolidated_view: consolidated_view} do + {:ok, g1} = Plausible.Goals.create(consolidated_view, %{"page_path" => "/go/to/blog/**"}) + {:ok, g2} = Plausible.Goals.create(consolidated_view, %{"event_name" => "Register"}) + + {lv, html} = get_liveview(conn, consolidated_view, with_html?: true) + + assert html =~ to_string(g1) + assert html =~ to_string(g2) + + html = lv |> element(~s/button#delete-goal-#{g1.id}/) |> render_click() + + refute html =~ to_string(g1) + assert html =~ to_string(g2) + + html = get(conn, "/#{consolidated_view.domain}/settings/goals") |> html_response(200) + + refute html =~ to_string(g1) + assert html =~ to_string(g2) + end + + test "allows list filtering / search", %{conn: conn, consolidated_view: consolidated_view} do + {:ok, g1} = Plausible.Goals.create(consolidated_view, %{"page_path" => "/go/to/blog/**"}) + {:ok, g2} = Plausible.Goals.create(consolidated_view, %{"event_name" => "Register"}) + {lv, html} = get_liveview(conn, consolidated_view, with_html?: true) + + assert html =~ to_string(g1) + assert html =~ to_string(g2) + + html = type_into_search(lv, to_string(g2)) + + refute html =~ to_string(g1) + assert html =~ to_string(g2) + end + end + defp setup_goals(site) do {:ok, g1} = Plausible.Goals.create(site, %{"page_path" => "/go/to/blog/**"}) {:ok, g2} = Plausible.Goals.create(site, %{"event_name" => "Register"})