Bring autoconfigure notification a step forwards in custom events cre… (#5912)
* Bring autoconfigure notification a step forwards in custom events creation flow - Rather than showing a notification that custom events have been detected at the bottom of the form, we now show a modal prior to the form, that allows the user to add them instantly or set them up manually. * Added tests for autoconfigure modal * Clean it up a little --------- Co-authored-by: Adam Rutkowski <hq@mtod.org>
This commit is contained in:
parent
12d818af8a
commit
98e0f7276b
|
|
@ -30,13 +30,24 @@ defmodule PlausibleWeb.Live.GoalSettings.Form do
|
|||
assigns[:goal_type] || "custom_events"
|
||||
end
|
||||
|
||||
event_name_options_count = length(assigns.event_name_options)
|
||||
|
||||
show_autoconfigure_modal? =
|
||||
case form_type do
|
||||
"custom_events" when event_name_options_count > 0 and is_nil(assigns.goal) ->
|
||||
true
|
||||
|
||||
_ ->
|
||||
Map.get(socket.assigns, :show_autoconfigure_modal?, false)
|
||||
end
|
||||
|
||||
socket =
|
||||
socket
|
||||
|> assign(
|
||||
id: assigns.id,
|
||||
context_unique_id: assigns.context_unique_id,
|
||||
form: form,
|
||||
event_name_options_count: length(assigns.event_name_options),
|
||||
event_name_options_count: event_name_options_count,
|
||||
event_name_options: Enum.map(assigns.event_name_options, &{&1, &1}),
|
||||
current_user: assigns.current_user,
|
||||
site_team: assigns.site_team,
|
||||
|
|
@ -48,7 +59,8 @@ defmodule PlausibleWeb.Live.GoalSettings.Form do
|
|||
on_save_goal: assigns.on_save_goal,
|
||||
on_autoconfigure: assigns.on_autoconfigure,
|
||||
goal: assigns.goal,
|
||||
goal_type: assigns[:goal_type]
|
||||
goal_type: assigns[:goal_type],
|
||||
show_autoconfigure_modal?: show_autoconfigure_modal?
|
||||
)
|
||||
|
||||
{:ok, socket}
|
||||
|
|
@ -61,7 +73,8 @@ defmodule PlausibleWeb.Live.GoalSettings.Form do
|
|||
~H"""
|
||||
<div id={@id}>
|
||||
{if @goal, do: edit_form(assigns)}
|
||||
{if is_nil(@goal), do: create_form(assigns)}
|
||||
{if is_nil(@goal) && @show_autoconfigure_modal?, do: autoconfigure_modal(assigns)}
|
||||
{if is_nil(@goal) && not @show_autoconfigure_modal?, do: create_form(assigns)}
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
|
@ -105,6 +118,41 @@ defmodule PlausibleWeb.Live.GoalSettings.Form do
|
|||
"""
|
||||
end
|
||||
|
||||
def autoconfigure_modal(assigns) do
|
||||
~H"""
|
||||
<div data-test-id="autoconfigure-modal">
|
||||
<.title>
|
||||
We detected {@event_name_options_count} custom {if @event_name_options_count == 1,
|
||||
do: "event",
|
||||
else: "events"}.
|
||||
</.title>
|
||||
|
||||
<p class="mt-2 py-2 text-sm text-gray-600 dark:text-gray-400 text-pretty">
|
||||
These events have been sent from your site in the past 6 months but aren't yet configured as goals. Add them instantly or set one up manually.
|
||||
</p>
|
||||
|
||||
<div class="flex justify-end gap-3">
|
||||
<.button
|
||||
theme="secondary"
|
||||
phx-click="add-manually"
|
||||
phx-target={@myself}
|
||||
>
|
||||
Add manually
|
||||
</.button>
|
||||
<.button
|
||||
phx-click="autoconfigure"
|
||||
phx-target={@myself}
|
||||
>
|
||||
<Heroicons.plus class="size-4" />
|
||||
Add {@event_name_options_count} {if @event_name_options_count == 1,
|
||||
do: "event",
|
||||
else: "events"}
|
||||
</.button>
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
def create_form(assigns) do
|
||||
~H"""
|
||||
<.form :let={f} for={@form} phx-submit="save-goal" phx-target={@myself}>
|
||||
|
|
@ -139,20 +187,6 @@ defmodule PlausibleWeb.Live.GoalSettings.Form do
|
|||
<.button type="submit" class="w-full">
|
||||
Add goal
|
||||
</.button>
|
||||
|
||||
<button
|
||||
:if={@form_type == "custom_events" && @event_name_options_count > 0}
|
||||
class="mt-4 text-sm hover:underline text-indigo-600 dark:text-indigo-400 text-left"
|
||||
phx-click="autoconfigure"
|
||||
phx-target={@myself}
|
||||
>
|
||||
<span :if={@event_name_options_count > 1}>
|
||||
Already sending custom events? We've found {@event_name_options_count} custom events from the last 6 months that are not yet configured as goals. Click here to add them.
|
||||
</span>
|
||||
<span :if={@event_name_options_count == 1}>
|
||||
Already sending custom events? We've found 1 custom event from the last 6 months that is not yet configured as a goal. Click here to add it.
|
||||
</span>
|
||||
</button>
|
||||
</.form>
|
||||
"""
|
||||
end
|
||||
|
|
@ -166,13 +200,14 @@ defmodule PlausibleWeb.Live.GoalSettings.Form do
|
|||
def pageview_fields(assigns) do
|
||||
~H"""
|
||||
<div id="pageviews-form" class="py-2" {@rest}>
|
||||
<div class="text-sm pb-6 text-gray-500 dark:text-gray-400 text-justify rounded-md">
|
||||
Pageview goals allow you to measure how many people visit a specific page or section of your site. Learn more in <.styled_link
|
||||
<div class="text-sm pb-6 text-gray-600 dark:text-gray-400 text-pretty">
|
||||
Pageview goals allow you to measure how many people visit a specific page or section of your site.
|
||||
<.styled_link
|
||||
href="https://plausible.io/docs/pageview-goals"
|
||||
new_tab={true}
|
||||
>
|
||||
our docs
|
||||
</.styled_link>.
|
||||
Learn more
|
||||
</.styled_link>
|
||||
</div>
|
||||
|
||||
<.label for={"page_path_input_#{@suffix}"}>
|
||||
|
|
@ -245,12 +280,13 @@ defmodule PlausibleWeb.Live.GoalSettings.Form do
|
|||
~H"""
|
||||
<div id="scroll-form" class="py-2" x-data={@js} {@rest}>
|
||||
<div class="text-sm pb-6 text-gray-500 dark:text-gray-400 text-justify rounded-md">
|
||||
Scroll Depth goals allow you to see how many people scroll beyond your desired scroll depth percentage threshold. Learn more in <.styled_link
|
||||
Scroll Depth goals allow you to see how many people scroll beyond your desired scroll depth percentage threshold.
|
||||
<.styled_link
|
||||
href="https://plausible.io/docs/scroll-depth"
|
||||
new_tab={true}
|
||||
>
|
||||
our docs
|
||||
</.styled_link>.
|
||||
Learn more
|
||||
</.styled_link>
|
||||
</div>
|
||||
|
||||
<.label for={"scroll_threshold_input_#{@suffix}"}>
|
||||
|
|
@ -460,9 +496,14 @@ defmodule PlausibleWeb.Live.GoalSettings.Form do
|
|||
end
|
||||
|
||||
def handle_event("autoconfigure", _params, socket) do
|
||||
socket = assign(socket, show_autoconfigure_modal?: false)
|
||||
{:noreply, socket.assigns.on_autoconfigure.(socket)}
|
||||
end
|
||||
|
||||
def handle_event("add-manually", _params, socket) do
|
||||
{:noreply, assign(socket, show_autoconfigure_modal?: false)}
|
||||
end
|
||||
|
||||
def suggest_page_paths(input, site) do
|
||||
query =
|
||||
Plausible.Stats.Query.parse_and_build!(
|
||||
|
|
@ -523,7 +564,7 @@ defmodule PlausibleWeb.Live.GoalSettings.Form do
|
|||
disabled={not @has_access_to_revenue_goals?}
|
||||
/>
|
||||
<span class={[
|
||||
"ml-3 text-sm font-medium",
|
||||
"ml-3 text-sm/6 font-medium",
|
||||
if(@has_access_to_revenue_goals?,
|
||||
do: "text-gray-900 dark:text-gray-100",
|
||||
else: "text-gray-500 dark:text-gray-400"
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ defmodule PlausibleWeb.Live.GoalSettings.FormTest do
|
|||
end
|
||||
|
||||
test "creates a custom event", %{conn: conn, site: site} do
|
||||
lv = get_liveview(conn, site)
|
||||
lv = get_liveview(conn, site) |> open_modal_with_goal_type("custom_events")
|
||||
refute render(lv) =~ "SampleCustomEvent"
|
||||
|
||||
lv = open_modal_with_goal_type(lv, "custom_events")
|
||||
|
|
@ -148,7 +148,7 @@ defmodule PlausibleWeb.Live.GoalSettings.FormTest do
|
|||
new_site(team: team)
|
||||
site = new_consolidated_view(team)
|
||||
|
||||
lv = get_liveview(conn, site)
|
||||
lv = get_liveview(conn, site) |> open_modal_with_goal_type("custom_events")
|
||||
|
||||
assert render(lv) =~ "Add goal for consolidated view"
|
||||
refute element_exists?(render(lv), @revenue_goal_settings)
|
||||
|
|
@ -165,7 +165,7 @@ defmodule PlausibleWeb.Live.GoalSettings.FormTest do
|
|||
|
||||
@tag :ee_only
|
||||
test "creates a revenue goal", %{conn: conn, site: site} do
|
||||
lv = get_liveview(conn, site)
|
||||
lv = get_liveview(conn, site) |> open_modal_with_goal_type("custom_events")
|
||||
refute render(lv) =~ "SampleRevenueGoal"
|
||||
|
||||
assert element_exists?(render(lv), @revenue_goal_settings)
|
||||
|
|
@ -188,7 +188,7 @@ defmodule PlausibleWeb.Live.GoalSettings.FormTest do
|
|||
end
|
||||
|
||||
test "creates a pageview goal", %{conn: conn, site: site} do
|
||||
lv = get_liveview(conn, site)
|
||||
lv = get_liveview(conn, site) |> open_modal_with_goal_type("pageviews")
|
||||
refute render(lv) =~ "Visit /page/**"
|
||||
|
||||
lv
|
||||
|
|
@ -205,7 +205,7 @@ defmodule PlausibleWeb.Live.GoalSettings.FormTest do
|
|||
test "fails to create a goal above limit", %{conn: conn, site: site} do
|
||||
for i <- 1..10, do: {:ok, _} = Plausible.Goals.create(site, %{"event_name" => "G#{i}"})
|
||||
|
||||
lv = get_liveview(conn, site)
|
||||
lv = get_liveview(conn, site) |> open_modal_with_goal_type("pageviews")
|
||||
refute render(lv) =~ "Visit /page/**"
|
||||
|
||||
lv
|
||||
|
|
@ -423,6 +423,10 @@ defmodule PlausibleWeb.Live.GoalSettings.FormTest do
|
|||
|
||||
lv = get_liveview(conn, site) |> open_modal_with_goal_type("custom_events")
|
||||
|
||||
lv
|
||||
|> element("button[phx-click='add-manually']")
|
||||
|> render_click()
|
||||
|
||||
type_into_combo(lv, "event_name_input_modalseq0", "One")
|
||||
html = render(lv)
|
||||
|
||||
|
|
@ -446,7 +450,11 @@ defmodule PlausibleWeb.Live.GoalSettings.FormTest do
|
|||
|
||||
# Delete the goal
|
||||
goal = Plausible.Repo.get_by(Plausible.Goal, site_id: site.id, event_name: "EventOne")
|
||||
html = lv |> element(~s/button#delete-goal-#{goal.id}/) |> render_click()
|
||||
|
||||
lv |> element(~s/button#delete-goal-#{goal.id}/) |> render_click()
|
||||
lv |> element("button[phx-click='add-manually']") |> render_click()
|
||||
|
||||
html = render(lv)
|
||||
|
||||
assert text_of_element(html, "#goals-form-modalseq0") =~ "EventOne"
|
||||
refute text_of_element(html, "#goals-form-modalseq0") =~ "EventTwo"
|
||||
|
|
@ -454,6 +462,105 @@ defmodule PlausibleWeb.Live.GoalSettings.FormTest do
|
|||
end
|
||||
end
|
||||
|
||||
describe "Autoconfigure goals from custom events modal" do
|
||||
setup [:create_user, :log_in, :create_site]
|
||||
|
||||
test "shows autoconfigure modal when opening custom events modal with available events", %{
|
||||
conn: conn,
|
||||
site: site
|
||||
} do
|
||||
populate_stats(site, [
|
||||
build(:pageview, pathname: "/go/home"),
|
||||
build(:event, name: "Signup"),
|
||||
build(:event, name: "Newsletter Signup"),
|
||||
build(:event, name: "Purchase")
|
||||
])
|
||||
|
||||
lv = get_liveview(conn, site) |> open_modal_with_goal_type("custom_events")
|
||||
|
||||
html = render(lv)
|
||||
assert html =~ "We detected 3 custom"
|
||||
assert html =~ "These events have been sent from your site in the past 6 months"
|
||||
end
|
||||
|
||||
test "clicking 'Add manually' shows the regular form", %{conn: conn, site: site} do
|
||||
populate_stats(site, [
|
||||
build(:pageview, pathname: "/go/home"),
|
||||
build(:event, name: "Signup"),
|
||||
build(:event, name: "Newsletter Signup"),
|
||||
build(:event, name: "Purchase")
|
||||
])
|
||||
|
||||
lv = get_liveview(conn, site) |> open_modal_with_goal_type("custom_events")
|
||||
|
||||
html = render(lv)
|
||||
assert html =~ "We detected 3 custom"
|
||||
|
||||
lv
|
||||
|> element("button[phx-click='add-manually']")
|
||||
|> render_click()
|
||||
|
||||
html = render(lv)
|
||||
refute html =~ "We detected"
|
||||
assert html =~ "Add goal for"
|
||||
end
|
||||
|
||||
test "autoconfigure button adds all events", %{conn: conn, site: site} do
|
||||
populate_stats(site, [
|
||||
build(:pageview, pathname: "/go/home"),
|
||||
build(:event, name: "Signup"),
|
||||
build(:event, name: "Newsletter Signup"),
|
||||
build(:event, name: "Purchase")
|
||||
])
|
||||
|
||||
lv = get_liveview(conn, site) |> open_modal_with_goal_type("custom_events")
|
||||
|
||||
lv
|
||||
|> element("button[phx-click='autoconfigure']")
|
||||
|> render_click()
|
||||
|
||||
# Render again to process the async :autoconfigure message
|
||||
_html = render(lv)
|
||||
|
||||
goals = Plausible.Goals.for_site(site)
|
||||
assert length(goals) == 3
|
||||
assert Enum.any?(goals, &(&1.event_name == "Signup"))
|
||||
assert Enum.any?(goals, &(&1.event_name == "Newsletter Signup"))
|
||||
assert Enum.any?(goals, &(&1.event_name == "Purchase"))
|
||||
end
|
||||
|
||||
test "autoconfigure modal does not show when all events are already goals", %{
|
||||
conn: conn,
|
||||
site: site
|
||||
} do
|
||||
populate_stats(site, [
|
||||
build(:pageview, pathname: "/go/home"),
|
||||
build(:event, name: "Signup"),
|
||||
build(:event, name: "Newsletter Signup"),
|
||||
build(:event, name: "Purchase")
|
||||
])
|
||||
|
||||
lv = get_liveview(conn, site)
|
||||
html = render(lv)
|
||||
|
||||
assert element_exists?(html, "[data-test-id='autoconfigure-modal']")
|
||||
|
||||
lv
|
||||
|> element("button[phx-click='autoconfigure']")
|
||||
|> render_click()
|
||||
|
||||
html = render(lv)
|
||||
refute element_exists?(html, "[data-test-id='autoconfigure-modal']")
|
||||
|
||||
lv = open_modal_with_goal_type(lv, "custom_events")
|
||||
html = render(lv)
|
||||
|
||||
refute element_exists?(html, "[data-test-id='autoconfigure-modal']")
|
||||
refute html =~ "We detected"
|
||||
refute html =~ "from the last 6 months"
|
||||
end
|
||||
end
|
||||
|
||||
defp type_into_combo(lv, id, text) do
|
||||
lv
|
||||
|> element("input##{id}")
|
||||
|
|
|
|||
|
|
@ -246,53 +246,6 @@ defmodule PlausibleWeb.Live.GoalSettingsTest do
|
|||
|
||||
refute html =~ "No goals found for this site. Please refine or"
|
||||
end
|
||||
|
||||
test "auto-configuring custom event goals", %{conn: conn, site: site} do
|
||||
populate_stats(site, [
|
||||
build(:event, name: "Signup"),
|
||||
build(:event, name: "Newsletter Signup"),
|
||||
build(:event, name: "Purchase")
|
||||
])
|
||||
|
||||
autoconfigure_button_selector = ~s/button[phx-click="autoconfigure"]/
|
||||
|
||||
assert_suggested_event_name_count = fn html, number ->
|
||||
assert text_of_element(html, autoconfigure_button_selector) =~
|
||||
"found #{number} custom events from the last 6 months that are not yet configured as goals"
|
||||
end
|
||||
|
||||
{lv, html} = get_liveview(conn, site, with_html?: true)
|
||||
|
||||
# At first, 3 event names are suggested
|
||||
assert_suggested_event_name_count.(html, 3)
|
||||
|
||||
# Add one goal
|
||||
lv
|
||||
|> element("#goals-form-modal form")
|
||||
|> render_submit(%{goal: %{event_name: "Signup"}})
|
||||
|
||||
html = render(lv)
|
||||
|
||||
# Now two goals are suggested because one is already added
|
||||
assert_suggested_event_name_count.(html, 2)
|
||||
|
||||
# Delete the goal
|
||||
goal = Plausible.Repo.get_by(Plausible.Goal, site_id: site.id, event_name: "Signup")
|
||||
html = lv |> element(~s/button#delete-goal-#{goal.id}/) |> render_click()
|
||||
|
||||
# Suggested event name count should be 3 again
|
||||
assert_suggested_event_name_count.(html, 3)
|
||||
|
||||
# Autoconfigure all custom event goals
|
||||
lv
|
||||
|> element(autoconfigure_button_selector)
|
||||
|> render_click()
|
||||
|
||||
html = render(lv)
|
||||
|
||||
# All possible goals exist - no suggestions anymore
|
||||
refute html =~ "from the last 6 months"
|
||||
end
|
||||
end
|
||||
|
||||
on_ee do
|
||||
|
|
|
|||
Loading…
Reference in New Issue