Skip to content

Commit 6ffea4a

Browse files
committed
Update goal settings design
- Replace the `Add goal` button in goal settings with a dropdown button to directly select the goal type. This way, a modal opens with the correct form for the selected goal type. The tabs in the modal have been removed. - Add a new `pill` component to show the goal type in the table in a more distinct way. The `settings_badge` component is replaced with the `pill` component. The `pill` component that was used in `plan_box.ex` is renamed to `highlight_pill`. - Replaced `Belongs to funnel` text with a funnel icon in the goal settings list. - Some small tweaks like increasing the search bar width, the padding of the table cells, and adding a header to the goal settings list.
1 parent 024e6bb commit 6ffea4a

File tree

8 files changed

+192
-197
lines changed

8 files changed

+192
-197
lines changed

lib/plausible_web/components/billing/plan_box.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ defmodule PlausibleWeb.Components.Billing.PlanBox do
3939
]}>
4040
{String.capitalize(to_string(@kind))}
4141
</h3>
42-
<.pill :if={@highlight} text={@highlight} />
42+
<.highlight_pill :if={@highlight} text={@highlight} />
4343
</div>
4444
<div>
4545
<div class={@price_container_class}>
@@ -95,7 +95,7 @@ defmodule PlausibleWeb.Components.Billing.PlanBox do
9595
"""
9696
end
9797

98-
defp pill(assigns) do
98+
defp highlight_pill(assigns) do
9999
~H"""
100100
<div class="flex items-center justify-between gap-x-4">
101101
<p

lib/plausible_web/components/generic.ex

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -786,7 +786,7 @@ defmodule PlausibleWeb.Components.Generic do
786786
<td
787787
class={[
788788
@height,
789-
"text-sm px-6 py-3 first:pl-0 last:pr-0 whitespace-nowrap",
789+
"text-sm px-6 py-4 first:pl-0 last:pr-0 whitespace-nowrap",
790790
@truncate && "truncate",
791791
@max_width,
792792
@actions && "flex text-right justify-end",
@@ -1020,18 +1020,23 @@ defmodule PlausibleWeb.Components.Generic do
10201020

10211021
def filter_bar(assigns) do
10221022
~H"""
1023-
<div class="flex items-center justify-between" x-data>
1024-
<div :if={@filtering_enabled?} class="relative rounded-md flex">
1025-
<form id="filter-form" phx-change="filter" phx-submit="filter" class="flex items-center">
1026-
<div class="text-gray-800 inline-flex items-center">
1023+
<div class="flex items-center justify-between gap-2" x-data>
1024+
<div :if={@filtering_enabled?} class="relative rounded-md flex flex-grow-1 w-full">
1025+
<form
1026+
id="filter-form"
1027+
phx-change="filter"
1028+
phx-submit="filter"
1029+
class="flex items-center w-full"
1030+
>
1031+
<div class="text-gray-800 inline-flex items-center w-full">
10271032
<div class="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3">
10281033
<Heroicons.magnifying_glass class="feather mr-1 dark:text-gray-300" />
10291034
</div>
10301035
<input
10311036
type="text"
10321037
name="filter-text"
10331038
id="filter-text"
1034-
class="w-full max-w-64 pl-8 text-sm dark:bg-gray-750 dark:text-gray-300 focus:ring-indigo-500 focus:border-indigo-500 block border-gray-300 dark:border-gray-750 rounded-md dark:placeholder:text-gray-400 focus:outline-none focus:ring-3 focus:ring-indigo-500/20 dark:focus:ring-indigo-500/25 focus:border-indigo-500"
1039+
class="w-full max-w-80 pl-8 text-sm dark:bg-gray-750 dark:text-gray-300 focus:ring-indigo-500 focus:border-indigo-500 block border-gray-300 dark:border-gray-750 rounded-md dark:placeholder:text-gray-400 focus:outline-none focus:ring-3 focus:ring-indigo-500/20 dark:focus:ring-indigo-500/25 focus:border-indigo-500"
10351040
placeholder="Press / to search"
10361041
x-ref="filter_text"
10371042
phx-debounce={200}
@@ -1123,13 +1128,41 @@ defmodule PlausibleWeb.Components.Generic do
11231128
"""
11241129
end
11251130

1126-
def settings_badge(%{type: :new} = assigns) do
1131+
attr(:class, :string, default: "")
1132+
attr(:color, :atom, default: :gray, values: [:gray, :indigo, :yellow, :green])
1133+
attr(:rest, :global)
1134+
slot(:inner_block, required: true)
1135+
1136+
def pill(assigns) do
1137+
color_classes = get_pill_color_classes(assigns.color)
1138+
11271139
~H"""
1128-
<span class="inline-block ml-2 bg-indigo-100 text-indigo-600 text-xs font-semibold py-1 px-2 rounded-md">
1129-
NEW 🔥
1140+
<span
1141+
class={[
1142+
"inline-flex items-center text-xs font-medium py-1 px-2 rounded-md",
1143+
color_classes,
1144+
@class
1145+
]}
1146+
{@rest}
1147+
>
1148+
{render_slot(@inner_block)}
11301149
</span>
11311150
"""
11321151
end
11331152

1134-
def settings_badge(assigns), do: ~H""
1153+
defp get_pill_color_classes(:gray) do
1154+
"bg-gray-100 text-gray-800 dark:bg-gray-750 dark:text-gray-200"
1155+
end
1156+
1157+
defp get_pill_color_classes(:indigo) do
1158+
"bg-indigo-100/60 text-indigo-600 dark:bg-indigo-900/50 dark:text-indigo-300"
1159+
end
1160+
1161+
defp get_pill_color_classes(:yellow) do
1162+
"bg-yellow-100/80 text-yellow-800 dark:bg-yellow-900/40 dark:text-yellow-300"
1163+
end
1164+
1165+
defp get_pill_color_classes(:green) do
1166+
"bg-green-100/70 text-green-800 dark:bg-green-900/40 dark:text-green-300"
1167+
end
11351168
end

lib/plausible_web/components/layout.ex

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,9 @@ defmodule PlausibleWeb.Components.Layout do
140140
class="size-5 mr-2"
141141
/>
142142
{@text}
143-
<PlausibleWeb.Components.Generic.settings_badge type={@badge} />
143+
<PlausibleWeb.Components.Generic.pill :if={@badge == :new} color={:indigo} class="ml-2">
144+
NEW 🔥
145+
</PlausibleWeb.Components.Generic.pill>
144146
<Heroicons.chevron_down
145147
:if={is_nil(@value)}
146148
class="h-3 w-3 ml-2 text-gray-400 dark:text-gray-500"

lib/plausible_web/components/prima_dropdown.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ defmodule PlausibleWeb.Components.PrimaDropdown do
3333
<Dropdown.dropdown_item
3434
as={@as}
3535
disabled={@disabled}
36-
class="group/item z-50 flex items-center gap-x-2 min-w-max rounded-md px-4 py-2 text-gray-700 text-sm dark:text-gray-300 data-focus:bg-gray-100 dark:data-focus:bg-gray-700 data-focus:text-gray-900 dark:data-focus:text-gray-100"
36+
class="group/item z-50 flex items-center gap-x-2 min-w-max w-full rounded-md pl-3 pr-5 py-2 text-gray-700 text-sm dark:text-gray-300 data-focus:bg-gray-100 dark:data-focus:bg-gray-700 data-focus:text-gray-900 dark:data-focus:text-gray-100"
3737
{@rest}
3838
>
3939
{render_slot(@inner_block)}

lib/plausible_web/live/goal_settings.ex

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ defmodule PlausibleWeb.Live.GoalSettings do
5151
domain: domain,
5252
displayed_goals: socket.assigns.all_goals,
5353
filter_text: "",
54-
form_goal: nil
54+
form_goal: nil,
55+
goal_type: nil
5556
)}
5657
end
5758

@@ -75,6 +76,7 @@ defmodule PlausibleWeb.Live.GoalSettings do
7576
site_team={@site_team}
7677
existing_goals={@all_goals}
7778
goal={@form_goal}
79+
goal_type={@goal_type}
7880
on_save_goal={
7981
fn goal, socket ->
8082
send(self(), {:goal_added, goal})
@@ -123,8 +125,12 @@ defmodule PlausibleWeb.Live.GoalSettings do
123125
{:noreply, socket}
124126
end
125127

126-
def handle_event("add-goal", _, socket) do
127-
socket = socket |> assign(form_goal: nil) |> Modal.open("goals-form-modal")
128+
def handle_event("add-goal", %{"goal-type" => goal_type}, socket) do
129+
socket =
130+
socket
131+
|> assign(form_goal: nil, goal_type: goal_type)
132+
|> Modal.open("goals-form-modal")
133+
128134
{:noreply, socket}
129135
end
130136

@@ -167,7 +173,8 @@ defmodule PlausibleWeb.Live.GoalSettings do
167173
event_name_options:
168174
Enum.reject(socket.assigns.event_name_options, &(&1 == goal.event_name)),
169175
displayed_goals: all_goals,
170-
form_goal: nil
176+
form_goal: nil,
177+
goal_type: nil
171178
)
172179
|> put_live_flash(:success, "Goal saved successfully")
173180

lib/plausible_web/live/goal_settings/form.ex

Lines changed: 26 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,15 @@ defmodule PlausibleWeb.Live.GoalSettings.Form do
1919
|> Plausible.Goal.changeset()
2020
|> to_form()
2121

22-
selected_tab =
23-
case assigns.goal do
24-
%{page_path: p, scroll_threshold: s} when not is_nil(p) and s > -1 -> "scroll"
25-
%{page_path: p} when not is_nil(p) -> "pageviews"
26-
_goal_or_nil -> "custom_events"
22+
form_type =
23+
if assigns.goal do
24+
case assigns.goal do
25+
%{page_path: p, scroll_threshold: s} when not is_nil(p) and s > -1 -> "scroll"
26+
%{page_path: p} when not is_nil(p) -> "pageviews"
27+
_ -> "custom_events"
28+
end
29+
else
30+
assigns[:goal_type] || "custom_events"
2731
end
2832

2933
socket =
@@ -38,14 +42,14 @@ defmodule PlausibleWeb.Live.GoalSettings.Form do
3842
site_role: assigns.site_role,
3943
site_team: assigns.site_team,
4044
domain: assigns.domain,
41-
selected_tab: selected_tab,
42-
tab_sequence_id: 0,
45+
form_type: form_type,
4346
site: site,
4447
has_access_to_revenue_goals?: has_access_to_revenue_goals?,
4548
existing_goals: assigns.existing_goals,
4649
on_save_goal: assigns.on_save_goal,
4750
on_autoconfigure: assigns.on_autoconfigure,
48-
goal: assigns.goal
51+
goal: assigns.goal,
52+
goal_type: assigns[:goal_type]
4953
)
5054

5155
{:ok, socket}
@@ -69,7 +73,7 @@ defmodule PlausibleWeb.Live.GoalSettings.Form do
6973
<.title>Edit goal for {@domain}</.title>
7074
7175
<.custom_event_fields
72-
:if={@selected_tab == "custom_events"}
76+
:if={@form_type == "custom_events"}
7377
f={f}
7478
suffix={@context_unique_id}
7579
site_role={@site_role}
@@ -81,14 +85,14 @@ defmodule PlausibleWeb.Live.GoalSettings.Form do
8185
has_access_to_revenue_goals?={@has_access_to_revenue_goals?}
8286
/>
8387
<.pageview_fields
84-
:if={@selected_tab == "pageviews"}
88+
:if={@form_type == "pageviews"}
8589
f={f}
8690
goal={@goal}
8791
suffix={@context_unique_id}
8892
site={@site}
8993
/>
9094
<.scroll_fields
91-
:if={@selected_tab == "scroll"}
95+
:if={@form_type == "scroll"}
9296
f={f}
9397
goal={@goal}
9498
suffix={@context_unique_id}
@@ -104,58 +108,41 @@ defmodule PlausibleWeb.Live.GoalSettings.Form do
104108

105109
def create_form(assigns) do
106110
~H"""
107-
<.form
108-
:let={f}
109-
x-data="{ tabSelectionInProgress: false }"
110-
for={@form}
111-
phx-submit="save-goal"
112-
phx-target={@myself}
113-
>
111+
<.form :let={f} for={@form} phx-submit="save-goal" phx-target={@myself}>
114112
<.title>
115113
Add goal for {Plausible.Sites.display_name(@site)}
116114
</.title>
117115
118-
<.tabs current_user={@current_user} site={@site} selected_tab={@selected_tab} myself={@myself} />
119-
120116
<.custom_event_fields
121-
:if={@selected_tab == "custom_events"}
122-
x-show="!tabSelectionInProgress"
117+
:if={@form_type == "custom_events"}
123118
f={f}
124-
suffix={suffix(@context_unique_id, @tab_sequence_id)}
119+
suffix={@context_unique_id}
125120
site_role={@site_role}
126121
site_team={@site_team}
127122
site={@site}
128123
existing_goals={@existing_goals}
129124
goal_options={@event_name_options}
130125
has_access_to_revenue_goals?={@has_access_to_revenue_goals?}
131-
x-init="tabSelectionInProgress = false"
132126
/>
133127
<.pageview_fields
134-
:if={@selected_tab == "pageviews"}
135-
x-show="!tabSelectionInProgress"
128+
:if={@form_type == "pageviews"}
136129
f={f}
137-
suffix={suffix(@context_unique_id, @tab_sequence_id)}
130+
suffix={@context_unique_id}
138131
site={@site}
139-
x-init="tabSelectionInProgress = false"
140132
/>
141133
<.scroll_fields
142-
:if={@selected_tab == "scroll"}
143-
x-show="!tabSelectionInProgress"
134+
:if={@form_type == "scroll"}
144135
f={f}
145-
suffix={suffix(@context_unique_id, @tab_sequence_id)}
136+
suffix={@context_unique_id}
146137
site={@site}
147-
x-init="tabSelectionInProgress = false"
148138
/>
149139
150-
<div x-show="!tabSelectionInProgress">
151-
<.button type="submit" class="w-full">
152-
Add goal
153-
</.button>
154-
</div>
140+
<.button type="submit" class="w-full">
141+
Add goal
142+
</.button>
155143
156144
<button
157-
:if={@selected_tab == "custom_events" && @event_name_options_count > 0}
158-
x-show="!tabSelectionInProgress"
145+
:if={@form_type == "custom_events" && @event_name_options_count > 0}
159146
class="mt-4 text-sm hover:underline text-indigo-600 dark:text-indigo-400 text-left"
160147
phx-click="autoconfigure"
161148
phx-target={@myself}
@@ -442,73 +429,6 @@ defmodule PlausibleWeb.Live.GoalSettings.Form do
442429
"""
443430
end
444431

445-
def tabs(assigns) do
446-
~H"""
447-
<div class="text-sm mt-6 font-medium dark:text-gray-100">Goal trigger</div>
448-
<div class="my-2 p-1 text-sm w-full flex gap-1 overflow-hidden rounded-lg border border-gray-300 dark:border-gray-700">
449-
<.tab
450-
id="event-tab"
451-
tab_value="custom_events"
452-
selected?={@selected_tab == "custom_events"}
453-
myself={@myself}
454-
>
455-
Custom event
456-
</.tab>
457-
<.tab
458-
id="pageview-tab"
459-
tab_value="pageviews"
460-
selected?={@selected_tab == "pageviews"}
461-
myself={@myself}
462-
>
463-
Pageview
464-
</.tab>
465-
<.tab
466-
id="scroll-tab"
467-
tab_value="scroll"
468-
selected?={@selected_tab == "scroll"}
469-
myself={@myself}
470-
>
471-
Scroll depth
472-
</.tab>
473-
</div>
474-
"""
475-
end
476-
477-
attr(:id, :string, required: true)
478-
attr(:tab_value, :string, required: true)
479-
attr(:selected?, :boolean, required: true)
480-
attr(:myself, :any, required: true)
481-
slot(:inner_block, required: true)
482-
483-
defp tab(assigns) do
484-
~H"""
485-
<a
486-
class={[
487-
"flex-1 text-center py-2 px-3 rounded-md font-medium hover:bg-gray-100 dark:hover:bg-gray-750 transition-colors duration-150",
488-
"cursor-pointer",
489-
@selected? && "bg-gray-150 dark:bg-gray-700 text-gray-800 dark:text-white",
490-
!@selected? && "dark:text-gray-200 text-gray-600 hover:text-gray-800 dark:hover:text-white"
491-
]}
492-
id={@id}
493-
x-on:click={!@selected? && "tabSelectionInProgress = true"}
494-
phx-click="switch-tab"
495-
phx-value-tab={@tab_value}
496-
phx-target={@myself}
497-
>
498-
{render_slot(@inner_block)}
499-
</a>
500-
"""
501-
end
502-
503-
def handle_event("switch-tab", %{"tab" => tab}, socket) do
504-
socket =
505-
socket
506-
|> assign(:selected_tab, tab)
507-
|> update(:tab_sequence_id, &(&1 + 1))
508-
509-
{:noreply, socket}
510-
end
511-
512432
def handle_event("save-goal", %{"goal" => goal_params}, %{assigns: %{goal: nil}} = socket) do
513433
case Plausible.Goals.create(socket.assigns.site, goal_params) do
514434
{:ok, goal} ->
@@ -573,10 +493,6 @@ defmodule PlausibleWeb.Live.GoalSettings.Form do
573493
|> Enum.map(fn name -> {name, name} end)
574494
end
575495

576-
defp suffix(context_unique_id, tab_sequence_id) do
577-
"#{context_unique_id}-tabseq#{tab_sequence_id}"
578-
end
579-
580496
on_ee do
581497
defp currency_option(nil), do: nil
582498

0 commit comments

Comments
 (0)