analytics/lib/plausible_web/live/props_settings/form.ex

163 lines
4.5 KiB
Elixir

defmodule PlausibleWeb.Live.PropsSettings.Form do
@moduledoc """
Live view for the custom props creation form
"""
use PlausibleWeb, :live_view
import PlausibleWeb.Live.Components.Form
alias PlausibleWeb.Live.Components.ComboBox
def mount(
_params,
%{
"site_id" => _site_id,
"domain" => domain,
"rendered_by" => pid
},
socket
) do
socket =
socket
|> assign_new(:site, fn %{current_user: current_user} ->
Plausible.Sites.get_for_user!(current_user, domain,
roles: [
:owner,
:admin,
:editor,
:super_admin
]
)
end)
|> assign_new(:form, fn %{site: site} ->
new_form(site)
end)
{:ok,
assign(socket,
domain: domain,
rendered_by: pid,
prop_key_options_count: 0
)}
end
def render(assigns) do
~H"""
<div
class="fixed inset-0 bg-gray-500/75 transition-opacity z-50"
phx-window-keydown="cancel-allow-prop"
phx-key="Escape"
>
</div>
<div class="fixed inset-0 flex items-center justify-center mt-16 z-50 overflow-y-auto overflow-x-hidden">
<div class="w-1/2 h-full">
<.form
:let={f}
for={@form}
class="max-w-md w-full mx-auto bg-white dark:bg-gray-900 shadow-md rounded-sm px-8 pt-6 pb-8 mb-4 mt-8"
phx-submit="allow-prop"
phx-click-away="cancel-allow-prop"
>
<.title>Add property for {@domain}</.title>
<div class="mt-6">
<.label for="prop_input">
Property
</.label>
<.live_component
id="prop_input"
submit_name="prop"
class={[
"py-2"
]}
module={ComboBox}
suggest_fun={
pid = self()
fn
"", [] ->
options =
@site
|> Plausible.Props.suggest_keys_to_allow()
|> Enum.map(&{&1, &1})
send(pid, {:update_prop_key_options_count, Enum.count(options)})
options
input, options ->
ComboBox.StaticSearch.suggest(input, options)
end
}
creatable
/>
<.error :for={{msg, opts} <- f[:allowed_event_props].errors}>
{Enum.reduce(opts, msg, fn {key, value}, acc ->
String.replace(acc, "%{#{key}}", fn _ -> to_string(value) end)
end)}
</.error>
</div>
<.button type="submit" class="w-full">
Add property
</.button>
<button
:if={@prop_key_options_count > 0}
title="Use this to add any existing properties from your past events into your settings. This allows you to set up properties without having to manually enter each item."
class="mt-4 text-sm hover:underline text-indigo-600 dark:text-indigo-400 text-left"
phx-click="allow-existing-props"
>
Already sending custom properties? Click to add {@prop_key_options_count} existing properties we found.
</button>
</.form>
</div>
</div>
"""
end
def handle_info({:update_prop_key_options_count, count}, socket) do
{:noreply, assign(socket, prop_key_options_count: count)}
end
def handle_event("allow-prop", %{"prop" => prop}, socket) do
case Plausible.Props.allow(socket.assigns.site, prop) do
{:ok, site} ->
send(socket.assigns.rendered_by, {:prop_allowed, prop})
{:noreply,
assign(socket,
site: site,
form: new_form(site)
)}
{:error, changeset} ->
{:noreply,
assign(socket,
form: to_form(Map.put(changeset, :action, :validate))
)}
end
end
def handle_event("allow-existing-props", _params, socket) do
{:ok, site} = Plausible.Props.allow_existing_props(socket.assigns.site)
send(socket.assigns.rendered_by, {:props_allowed, site.allowed_event_props})
{:noreply,
assign(socket,
site: site,
form: new_form(site),
prop_key_options_count: 0
)}
end
def handle_event("cancel-allow-prop", _value, socket) do
send(socket.assigns.rendered_by, :cancel_add_prop)
{:noreply, socket}
end
defp new_form(site) do
to_form(Plausible.Props.allow_changeset(site, []))
end
end