Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 50 additions & 5 deletions lib/plausible_web/components/generic.ex
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ defmodule PlausibleWeb.Components.Generic do
~H"""
<.link
class={[
"inline-flex items-center gap-x-0.5",
"inline-flex items-center gap-x-1",
@class
]}
href={@href}
Expand All @@ -401,7 +401,7 @@ defmodule PlausibleWeb.Components.Generic do
{@rest}
>
{render_slot(@inner_block)}
<Heroicons.arrow_top_right_on_square class={["opacity-60", @icon_class]} />
<Heroicons.arrow_top_right_on_square class={["stroke-2", @icon_class]} />
</.link>
"""
else
Expand Down Expand Up @@ -469,6 +469,51 @@ defmodule PlausibleWeb.Components.Generic do
"""
end

attr :id, :string, required: true
attr :js_active_var, :string, required: true
attr :id_suffix, :string, default: ""
attr :disabled, :boolean, default: false
attr :label, :string, required: true
attr :help_text, :string, default: nil
attr :help_text_conditional, :boolean, default: false
attr :mt?, :boolean, default: true

attr(:rest, :global)

def toggle_field(assigns) do
help_text_conditional = assigns[:help_text_conditional] || false

assigns = assign(assigns, help_text_conditional: help_text_conditional)

~H"""
<div class={["flex items-start justify-between gap-5 w-full", @mt? && "mt-6"]}>
<div class="flex-1">
<span
x-on:click={"#{@js_active_var} = !#{@js_active_var}"}
class="text-sm font-medium text-gray-900 dark:text-gray-100 cursor-pointer"
>
{@label}
</span>
<p
:if={@help_text}
class="text-gray-500 dark:text-gray-400 text-sm text-pretty"
x-show={if @help_text_conditional, do: @js_active_var, else: "true"}
x-cloak={@help_text_conditional}
>
{@help_text}
</p>
</div>
<PlausibleWeb.Components.Generic.toggle_switch
id={@id}
id_suffix={@id_suffix}
js_active_var={@js_active_var}
disabled={@disabled}
{@rest}
/>
</div>
"""
end

def settings_tiles(assigns) do
~H"""
<div class="text-gray-900 leading-5 dark:text-gray-100">
Expand Down Expand Up @@ -676,9 +721,9 @@ defmodule PlausibleWeb.Components.Generic do

if String.contains?(classes, "text-sm") or
String.contains?(classes, "text-xs") do
["w-3 h-3"]
["size-3"]
else
["w-4 h-4"]
["size-4"]
end
end

Expand Down Expand Up @@ -786,7 +831,7 @@ defmodule PlausibleWeb.Components.Generic do
<td
class={[
@height,
"text-sm px-6 py-3 first:pl-0 last:pr-0 whitespace-nowrap",
"text-sm px-6 py-3 first:pl-0 last:pr-0 whitespace-nowrap overflow-visible",
@truncate && "truncate",
@max_width,
@actions && "flex text-right justify-end",
Expand Down
23 changes: 18 additions & 5 deletions lib/plausible_web/live/components/form.ex
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ defmodule PlausibleWeb.Live.Components.Form do
attr(:max_one_error, :boolean, default: false)
slot(:help_content)
slot(:inner_block)
slot(:link)

def input(%{field: %Phoenix.HTML.FormField{} = field} = assigns) do
errors = if Phoenix.Component.used_input?(field), do: field.errors, else: []
Expand All @@ -74,8 +75,14 @@ defmodule PlausibleWeb.Live.Components.Form do

def input(%{type: "select"} = assigns) do
~H"""
<div class={@mt? && "mt-4"}>
<.label for={@id} class={if @help_text, do: "mb-0.5", else: "mb-1.5"}>{@label}</.label>
<div class={@mt? && "mt-6"}>
<.label
:if={@label != nil and @label != ""}
for={@id}
class={if @help_text, do: "mb-0.5", else: "mb-1.5"}
>
{@label}
</.label>

<p :if={@help_text} class="text-gray-500 dark:text-gray-400 mb-2 text-sm">
{@help_text}
Expand All @@ -84,6 +91,9 @@ defmodule PlausibleWeb.Live.Components.Form do
<option :if={@prompt} value="">{@prompt}</option>
{Phoenix.HTML.Form.options_for_select(@options, @value)}
</select>
<div :if={@link != [] && Enum.empty?(@errors)} class="mt-1">
{render_slot(@link)}
</div>
<.error :for={msg <- @errors}>{msg}</.error>
</div>
"""
Expand Down Expand Up @@ -138,7 +148,7 @@ defmodule PlausibleWeb.Live.Components.Form do

<span
:if={@help_text || @help_content != []}
class="text-gray-500 dark:text-gray-400 mb-2 text-sm"
class="text-gray-500 dark:text-gray-400 mb-2 text-sm text-pretty"
>
{@help_text}
{render_slot(@help_content)}
Expand All @@ -150,7 +160,7 @@ defmodule PlausibleWeb.Live.Components.Form do

def input(%{type: "textarea"} = assigns) do
~H"""
<div class={@mt? && "mt-4"}>
<div class={@mt? && "mt-6"}>
<.label class="mb-1.5" for={@id}>{@label}</.label>
<textarea
id={@id}
Expand All @@ -176,7 +186,7 @@ defmodule PlausibleWeb.Live.Components.Form do
assigns = assign(assigns, :errors, errors)

~H"""
<div class={@mt? && "mt-4"}>
<div class={@mt? && "mt-6"}>
<.label
:if={@label != nil and @label != ""}
for={@id}
Expand All @@ -196,6 +206,9 @@ defmodule PlausibleWeb.Live.Components.Form do
{@rest}
/>
{render_slot(@inner_block)}
<div :if={@link != [] && Enum.empty?(@errors)} class="mt-0.5">
{render_slot(@link)}
</div>
<.error :for={msg <- @errors}>
{msg}
</.error>
Expand Down
24 changes: 21 additions & 3 deletions lib/plausible_web/live/shared_link_settings.ex
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,27 @@ defmodule PlausibleWeb.Live.SharedLinkSettings do
</:thead>
<:tbody :let={link}>
<.td truncate hide_on_mobile>
{link.name}
<Heroicons.lock_closed :if={link.password_hash} class="feather ml-2 mb-0.5" />
<Heroicons.lock_open :if={!link.password_hash} class="feather ml-2 mb-0.5" />
<div class="flex items-center">
{link.name}
<.tooltip :if={link.password_hash} enabled?={true} centered?={true}>
<:tooltip_content>
Password protected
</:tooltip_content>
<Heroicons.lock_closed class="feather ml-2 mb-0.5" />
</.tooltip>
<.tooltip :if={!link.password_hash} enabled?={true} centered?={true}>
<:tooltip_content>
No password protection
</:tooltip_content>
<Heroicons.lock_open class="feather ml-2 mb-0.5" />
</.tooltip>
<.tooltip enabled?={true} centered?={true}>
<:tooltip_content>
Limited view
</:tooltip_content>
<Heroicons.eye_slash class="feather ml-1" />
</.tooltip>
</div>
</.td>
<.td>
<.input_with_clipboard
Expand Down
121 changes: 114 additions & 7 deletions lib/plausible_web/live/shared_link_settings/form.ex
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,46 @@ defmodule PlausibleWeb.Live.SharedLinkSettings.Form do

<.input field={f[:name]} label="Name" required="required" autocomplete="off" />

<div
x-data="{ limitViewEnabled: false }"
x-effect={"
const select = document.getElementById('segment_id');
if (select && !limitViewEnabled) {
select.value = '';
}
"}
class="flex flex-col gap-y-2"
>
<PlausibleWeb.Components.Generic.toggle_field
id="limit-view"
id_suffix=""
js_active_var="limitViewEnabled"
label="Limit view"
help_text="Filter your dashboard to show only a segment."
/>
<div x-show="limitViewEnabled" x-cloak>
<.input
name="segment_id"
id="segment_id"
type="select"
value=""
options={[{"Filter by segment", ""}]}
prompt="Filter by segment"
mt?={false}
>
<:link>
<PlausibleWeb.Components.Generic.unstyled_link
href="https://plausible.io/docs/segments"
new_tab
class="text-xs text-indigo-600 dark:text-indigo-400"
>
Learn about segments
</PlausibleWeb.Components.Generic.unstyled_link>
</:link>
</.input>
</div>
</div>

<.button type="submit" class="w-full">
Update shared link
</.button>
Expand All @@ -55,13 +95,80 @@ defmodule PlausibleWeb.Live.SharedLinkSettings.Form do
<.form :let={f} for={@form} phx-submit="save-shared-link" phx-target={@myself}>
<.title>New shared link</.title>
<.input field={f[:name]} label="Name" required="required" autocomplete="off" />
<.input
field={f[:password]}
label="Password (optional)"
help_text="Store the password securely, as it can't be viewed again."
type="password"
autocomplete="new-password"
/>

<div
x-data="{ passwordProtectEnabled: false }"
x-effect={"
const input = document.getElementById('#{f[:password].id}');
if (input) {
if (passwordProtectEnabled) {
setTimeout(() => input.focus(), 50);
} else {
input.value = '';
}
}
"}
class="flex flex-col gap-y-2"
>
<PlausibleWeb.Components.Generic.toggle_field
id="password-protect"
id_suffix=""
js_active_var="passwordProtectEnabled"
label="Password protect"
help_text="Keep this password safe. You won't be able to see it again."
help_text_conditional={true}
/>
<div x-show="passwordProtectEnabled" x-cloak>
<.input
field={f[:password]}
type="password"
placeholder="Enter password"
autocomplete="new-password"
mt?={false}
/>
</div>
</div>

<div
x-data="{ limitViewEnabled: false }"
x-effect={"
const select = document.getElementById('segment_id');
if (select && !limitViewEnabled) {
select.value = '';
}
"}
class="flex flex-col gap-y-2"
>
<PlausibleWeb.Components.Generic.toggle_field
id="limit-view"
id_suffix=""
js_active_var="limitViewEnabled"
label="Limit view"
help_text="Filter your dashboard to show only a segment."
/>
<div x-show="limitViewEnabled" x-cloak>
<.input
name="segment_id"
id="segment_id"
type="select"
value=""
options={[{"Filter by segment", ""}]}
prompt="Filter by segment"
mt?={false}
>
<:link>
<PlausibleWeb.Components.Generic.unstyled_link
href="https://plausible.io/docs/filters-segments#how-to-save-a-segment"
new_tab
class="text-xs text-indigo-600 dark:text-indigo-400"
>
Learn about segments
</PlausibleWeb.Components.Generic.unstyled_link>
</:link>
</.input>
</div>
</div>

<.button type="submit" class="w-full">
Create shared link
</.button>
Expand Down
Loading