Skip to content

Commit 73347e9

Browse files
committed
Use new tile component for funnels, goals, imports and custom properties
- Update the settings live views to use the new tile component - Ensure tile component is updated when feature visibility is toggled - Extract `no_search_results` and `empty_state` components for better readability - Extract `highlighted` component - Update tests
1 parent 7f68d17 commit 73347e9

24 files changed

+444
-416
lines changed

extra/lib/plausible_web/live/funnel_settings.ex

Lines changed: 62 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ defmodule PlausibleWeb.Live.FunnelSettings do
2525
]
2626
)
2727
end)
28+
|> assign_new(:site_role, fn %{site: site, current_user: current_user} ->
29+
{:ok, {_, site_role}} = Plausible.Teams.Memberships.site_role(site, current_user)
30+
site_role
31+
end)
2832
|> assign_new(:all_funnels, fn %{site: %{id: ^site_id} = site} ->
2933
Funnels.list(site)
3034
end)
@@ -50,45 +54,62 @@ defmodule PlausibleWeb.Live.FunnelSettings do
5054
<div id="funnel-settings-main">
5155
<.flash_messages flash={@flash} />
5256
53-
<%= if @setup_funnel? do %>
54-
{live_render(
55-
@socket,
56-
PlausibleWeb.Live.FunnelSettings.Form,
57-
id: "funnels-form",
58-
session: %{
59-
"domain" => @domain,
60-
"funnel_id" => @funnel_id
61-
}
62-
)}
63-
<% end %>
64-
<div :if={@goal_count >= Funnel.min_steps()}>
65-
<.live_component
66-
module={PlausibleWeb.Live.FunnelSettings.List}
67-
id="funnels-list"
68-
funnels={@displayed_funnels}
69-
filter_text={@filter_text}
70-
/>
71-
</div>
72-
73-
<div
74-
:if={@goal_count < Funnel.min_steps()}
75-
class="flex flex-col items-center justify-center pt-5 pb-6 max-w-md mx-auto"
57+
<.tile
58+
docs="funnel-analysis"
59+
feature_mod={Plausible.Billing.Feature.Funnels}
60+
feature_toggle?={true}
61+
show_content?={!Plausible.Billing.Feature.Funnels.opted_out?(@site)}
62+
site={@site}
63+
current_user={@current_user}
64+
current_role={@site_role}
65+
current_team={@current_team}
7666
>
77-
<h3 class="text-center text-base font-medium text-gray-900 dark:text-gray-100 leading-7">
78-
Ready to dig into user flows?
79-
</h3>
80-
<p class="text-center text-sm mt-1 text-gray-500 dark:text-gray-400 leading-5 text-pretty">
81-
Set up a few goals like <span class="font-medium text-indigo-600 dark:text-gray-100">Signup</span>, <span class="font-medium text-indigo-600 dark:text-gray-100">Visit /</span>, or
82-
<span class="font-medium text-indigo-600 dark:text-gray-100">Scroll 50% on /blog/*</span>
83-
first, then return here to build your first funnel.
84-
</p>
85-
<.button_link
86-
class="mt-4"
87-
href={PlausibleWeb.Router.Helpers.site_path(@socket, :settings_goals, @domain)}
67+
<:title>
68+
Funnels
69+
</:title>
70+
<:subtitle :if={Enum.count(@all_funnels) > 0}>
71+
Compose goals into funnels to track user flows and conversion rates.
72+
</:subtitle>
73+
<%= if @setup_funnel? do %>
74+
{live_render(
75+
@socket,
76+
PlausibleWeb.Live.FunnelSettings.Form,
77+
id: "funnels-form",
78+
session: %{
79+
"domain" => @domain,
80+
"funnel_id" => @funnel_id
81+
}
82+
)}
83+
<% end %>
84+
<div :if={@goal_count >= Funnel.min_steps()}>
85+
<.live_component
86+
module={PlausibleWeb.Live.FunnelSettings.List}
87+
id="funnels-list"
88+
funnels={@displayed_funnels}
89+
filter_text={@filter_text}
90+
/>
91+
</div>
92+
93+
<div
94+
:if={@goal_count < Funnel.min_steps()}
95+
class="flex flex-col items-center justify-center pt-5 pb-6 max-w-md mx-auto"
8896
>
89-
Set up goals →
90-
</.button_link>
91-
</div>
97+
<h3 class="text-center text-base font-medium text-gray-900 dark:text-gray-100 leading-7">
98+
Ready to dig into user flows?
99+
</h3>
100+
<p class="text-center text-sm mt-1 text-gray-500 dark:text-gray-400 leading-5 text-pretty">
101+
Set up a few goals like <.highlighted>Signup</.highlighted>, <.highlighted>Visit /</.highlighted>, or
102+
<.highlighted>Scroll 50% on /blog/*</.highlighted>
103+
first, then return here to build your first funnel.
104+
</p>
105+
<.button_link
106+
class="mt-4"
107+
href={PlausibleWeb.Router.Helpers.site_path(@socket, :settings_goals, @domain)}
108+
>
109+
Set up goals →
110+
</.button_link>
111+
</div>
112+
</.tile>
92113
</div>
93114
"""
94115
end
@@ -152,4 +173,8 @@ defmodule PlausibleWeb.Live.FunnelSettings do
152173
def handle_info(:cancel_setup_funnel, socket) do
153174
{:noreply, assign(socket, setup_funnel?: false, funnel_id: nil)}
154175
end
176+
177+
def handle_info({:site_updated, updated_site}, socket) do
178+
{:noreply, assign(socket, site: updated_site)}
179+
end
155180
end

extra/lib/plausible_web/live/funnel_settings/list.ex

Lines changed: 39 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@ defmodule PlausibleWeb.Live.FunnelSettings.List do
1010
use PlausibleWeb, :live_component
1111

1212
def render(assigns) do
13+
assigns = assign(assigns, :searching?, String.trim(assigns.filter_text) != "")
14+
1315
~H"""
1416
<div>
15-
<%= if String.trim(@filter_text) != "" || Enum.count(@funnels) > 0 do %>
17+
<%= if @searching? or Enum.count(@funnels) > 0 do %>
1618
<.filter_bar filter_text={@filter_text} placeholder="Search Funnels">
1719
<.button id="add-funnel-button" phx-click="add-funnel" mt?={false}>
1820
Add funnel
@@ -44,35 +46,44 @@ defmodule PlausibleWeb.Live.FunnelSettings.List do
4446
</:tbody>
4547
</.table>
4648
<% else %>
47-
<%= if String.trim(@filter_text) != "" do %>
48-
<p class="mt-12 mb-8 text-sm text-center">
49-
No funnels found for this site. Please refine or
50-
<.styled_link phx-click="reset-filter-text" id="reset-filter-hint">
51-
reset your search.
52-
</.styled_link>
53-
</p>
54-
<% else %>
55-
<div class="flex flex-col items-center justify-center pt-5 pb-6 max-w-md mx-auto">
56-
<h3 class="text-center text-base font-medium text-gray-900 dark:text-gray-100 leading-7">
57-
Create your first funnel
58-
</h3>
59-
<p class="text-center text-sm mt-1 text-gray-500 dark:text-gray-400 leading-5 text-pretty">
60-
Compose goals into funnels to track user flows and conversion rates.
61-
<.styled_link href="https://plausible.io/docs/funnel-analysis" target="_blank">
62-
Learn more
63-
</.styled_link>
64-
</p>
65-
<.button
66-
id="add-funnel-button"
67-
phx-click="add-funnel"
68-
class="mt-4"
69-
>
70-
Add funnel
71-
</.button>
72-
</div>
73-
<% end %>
49+
<.no_search_results :if={@searching?} />
50+
<.empty_state :if={not @searching?} />
7451
<% end %>
7552
</div>
7653
"""
7754
end
55+
56+
defp no_search_results(assigns) do
57+
~H"""
58+
<p class="mt-12 mb-8 text-sm text-center">
59+
No funnels found for this site. Please refine or
60+
<.styled_link phx-click="reset-filter-text" id="reset-filter-hint">
61+
reset your search.
62+
</.styled_link>
63+
</p>
64+
"""
65+
end
66+
67+
defp empty_state(assigns) do
68+
~H"""
69+
<div class="flex flex-col items-center justify-center pt-5 pb-6 max-w-md mx-auto">
70+
<h3 class="text-center text-base font-medium text-gray-900 dark:text-gray-100 leading-7">
71+
Create your first funnel
72+
</h3>
73+
<p class="text-center text-sm mt-1 text-gray-500 dark:text-gray-400 leading-5 text-pretty">
74+
Compose goals into funnels to track user flows and conversion rates.
75+
<.styled_link href="https://plausible.io/docs/funnel-analysis" target="_blank">
76+
Learn more
77+
</.styled_link>
78+
</p>
79+
<.button
80+
id="add-funnel-button"
81+
phx-click="add-funnel"
82+
class="mt-4"
83+
>
84+
Add funnel
85+
</.button>
86+
</div>
87+
"""
88+
end
7889
end

lib/plausible_web/components/generic.ex

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1126,6 +1126,16 @@ defmodule PlausibleWeb.Components.Generic do
11261126
"""
11271127
end
11281128

1129+
slot :inner_block, required: true
1130+
1131+
def highlighted(assigns) do
1132+
~H"""
1133+
<span class="font-medium text-indigo-600 dark:text-gray-100">
1134+
{render_slot(@inner_block)}
1135+
</span>
1136+
"""
1137+
end
1138+
11291139
def settings_badge(%{type: :new} = assigns) do
11301140
~H"""
11311141
<span class="inline-block ml-2 bg-indigo-100 text-indigo-600 text-xs font-semibold py-1 px-2 rounded-md">

lib/plausible_web/components/site/feature.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ defmodule PlausibleWeb.Components.Site.Feature do
5353
"""
5454
end
5555

56-
defp target(site, setting, conn, set_to) when is_boolean(set_to) do
56+
def target(site, setting, conn, set_to) when is_boolean(set_to) do
5757
r = conn.request_path
5858
Routes.site_path(conn, :update_feature_visibility, site.domain, setting, r: r, set: set_to)
5959
end

lib/plausible_web/components/site/toggle_live.ex

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ defmodule PlausibleWeb.Components.Site.Feature.ToggleLive do
7878
"#{feature_mod.display_name()} are now hidden from your dashboard"
7979
end
8080

81+
send(self(), {:site_updated, updated_site})
82+
8183
{:noreply,
8284
socket
8385
|> assign(:site, updated_site)

lib/plausible_web/controllers/site_controller.ex

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -173,55 +173,26 @@ defmodule PlausibleWeb.SiteController do
173173
end
174174

175175
def settings_goals(conn, _params) do
176-
site = conn.assigns[:site]
177-
178-
has_goals? =
179-
Repo.exists?(
180-
from(g in Plausible.Goal,
181-
where: g.site_id == ^site.id
182-
)
183-
)
184-
185176
conn
186177
|> render("settings_goals.html",
187-
site: site,
188-
has_goals?: has_goals?,
189178
dogfood_page_path: "/:dashboard/settings/goals",
190179
connect_live_socket: true,
191180
layout: {PlausibleWeb.LayoutView, "site_settings.html"}
192181
)
193182
end
194183

195184
def settings_funnels(conn, _params) do
196-
site = conn.assigns[:site]
197-
198-
has_funnels? =
199-
Repo.exists?(
200-
from(f in Plausible.Funnel,
201-
where: f.site_id == ^site.id
202-
)
203-
)
204-
205185
conn
206186
|> render("settings_funnels.html",
207-
site: site,
208-
has_funnels?: has_funnels?,
209187
dogfood_page_path: "/:dashboard/settings/funnels",
210188
connect_live_socket: true,
211189
layout: {PlausibleWeb.LayoutView, "site_settings.html"}
212190
)
213191
end
214192

215193
def settings_props(conn, _params) do
216-
site = conn.assigns[:site]
217-
218-
has_props? =
219-
site.allowed_event_props && length(site.allowed_event_props) > 0
220-
221194
conn
222195
|> render("settings_props.html",
223-
site: site,
224-
has_props?: has_props?,
225196
dogfood_page_path: "/:dashboard/settings/properties",
226197
layout: {PlausibleWeb.LayoutView, "site_settings.html"},
227198
connect_live_socket: true
@@ -296,17 +267,9 @@ defmodule PlausibleWeb.SiteController do
296267
def settings_imports_exports(conn, _params) do
297268
site = conn.assigns.site
298269

299-
has_imports? =
300-
Repo.exists?(
301-
from(i in Plausible.Imported.SiteImport,
302-
where: i.site_id == ^site.id
303-
)
304-
)
305-
306270
conn
307271
|> render("settings_imports_exports.html",
308272
site: site,
309-
has_imports?: has_imports?,
310273
dogfood_page_path: "/:dashboard/settings/imports-exports",
311274
connect_live_socket: true,
312275
layout: {PlausibleWeb.LayoutView, "site_settings.html"}

0 commit comments

Comments
 (0)