Added test button to apprise input (#226)

This commit is contained in:
Kieran 2024-05-03 15:42:22 -07:00 committed by GitHub
parent 5427c6247f
commit 944d26b57d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 196 additions and 38 deletions

View file

@ -266,6 +266,7 @@ defmodule PinchflatWeb.CoreComponents do
multiple pattern placeholder readonly required rows size step)
slot :inner_block
slot :input_append
def input(%{field: %Phoenix.HTML.FormField{} = field} = assigns) do
assigns
@ -424,20 +425,23 @@ defmodule PinchflatWeb.CoreComponents do
<.label for={@id}>
<%= @label %><span :if={@label_suffix} class="text-xs text-bodydark"><%= @label_suffix %></span>
</.label>
<input
type={@type}
name={@name}
id={@id}
value={Phoenix.HTML.Form.normalize_value(@type, @value)}
class={[
"w-full rounded-lg border-[1.5px] border-stroke bg-transparent px-5 py-3 font-normal text-black",
"outline-none transition focus:border-primary active:border-primary disabled:cursor-default disabled:bg-whiter",
"dark:border-form-strokedark dark:bg-form-input dark:text-white dark:focus:border-primary",
@inputclass,
@errors != [] && "border-rose-400 focus:border-rose-400"
]}
{@rest}
/>
<div class="flex items-center">
<input
type={@type}
name={@name}
id={@id}
value={Phoenix.HTML.Form.normalize_value(@type, @value)}
class={[
"w-full rounded-lg border-[1.5px] px-5 py-3 font-normal border-form-strokedark bg-form-input",
"outline-none transition active:border-primary disabled:cursor-default disabled:bg-whiter",
"text-white focus:border-primary",
@inputclass,
@errors != [] && "border-rose-400 focus:border-rose-400"
]}
{@rest}
/>
<%= render_slot(@input_append) %>
</div>
<.help :if={@help}><%= if @html_help, do: Phoenix.HTML.raw(@help), else: @help %></.help>
<.error :for={msg <- @errors}><%= msg %></.error>
</div>

View file

@ -89,4 +89,46 @@ defmodule PinchflatWeb.CustomComponents.ButtonComponents do
</div>
"""
end
@doc """
Render a button with an icon. Optionally include a tooltip.
## Examples
<.icon_button icon_name="hero-check" tooltip="Complete" />
"""
attr :icon_name, :string, required: true
attr :class, :string, default: ""
attr :tooltip, :string, default: nil
attr :rest, :global
def icon_button(assigns) do
~H"""
<div class="group relative inline-block">
<button
class={[
"flex justify-center items-center rounded-lg ",
"bg-form-input border-2 border-strokedark",
"hover:bg-meta-4 hover:border-form-strokedark",
@class
]}
type="button"
{@rest}
>
<CoreComponents.icon name={@icon_name} class="text-stroke" />
</button>
<div
:if={@tooltip}
class={[
"hidden absolute left-1/2 top-full z-20 mt-3 -translate-x-1/2 whitespace-nowrap rounded-md",
"px-4.5 py-1.5 text-sm font-medium opacity-0 drop-shadow-4 group-hover:opacity-100 group-hover:block bg-meta-4"
]}
>
<span class="border-light absolute -top-1 left-1/2 -z-10 h-2 w-2 -translate-x-1/2 rotate-45 rounded-sm bg-meta-4">
</span>
<span><%= @tooltip %></span>
</div>
</div>
"""
end
end

View file

@ -6,6 +6,7 @@ defmodule PinchflatWeb.Settings.SettingHTML do
@doc """
Renders a setting form.
"""
attr :conn, Plug.Conn, required: true
attr :changeset, Ecto.Changeset, required: true
attr :action, :string, required: true

View file

@ -0,0 +1,55 @@
defmodule Pinchflat.Settings.AppriseServerLive do
use PinchflatWeb, :live_view
alias PinchflatWeb.Settings.SettingHTML
def render(assigns) do
~H"""
<.input
type="text"
id="setting_apprise_server"
name="setting[apprise_server]"
value={@value}
label="Apprise Server"
help={SettingHTML.apprise_server_help()}
html_help={true}
inputclass="font-mono text-sm mr-4"
placeholder="https://discordapp.com/api/webhooks/{WebhookID}/{WebhookToken}"
phx-change="apprise_server_changed"
>
<:input_append>
<.icon_button icon_name={@icon_name} class="h-12 w-12" phx-click="send_apprise_test" tooltip={@tooltip} />
</:input_append>
</.input>
"""
end
def mount(_params, session, socket) do
new_assigns = %{
value: session["value"],
icon_name: "hero-paper-airplane",
tooltip: "Send Test"
}
{:ok, assign(socket, new_assigns)}
end
def handle_event("send_apprise_test", _params, %{assigns: assigns} = socket) do
backend_runner().run([assigns.value], title: "Pinchflat Test", body: "This is a test message from Pinchflat")
Process.send_after(self(), :reset_button_icon, 4_000)
{:noreply, assign(socket, %{icon_name: "hero-check", tooltip: "Sent!"})}
end
def handle_event("apprise_server_changed", %{"setting" => setting}, socket) do
{:noreply, assign(socket, %{value: setting["apprise_server"]})}
end
def handle_info(:reset_button_icon, socket) do
{:noreply, assign(socket, %{icon_name: "hero-paper-airplane", tooltip: "Send Test"})}
end
defp backend_runner do
Application.get_env(:pinchflat, :apprise_runner)
end
end

View file

@ -7,15 +7,13 @@
Notification Settings
</h3>
<.input
field={f[:apprise_server]}
type="text"
label="Apprise Server"
help={apprise_server_help()}
html_help={true}
inputclass="font-mono text-sm"
placeholder="https://discordapp.com/api/webhooks/{WebhookID}/{WebhookToken}"
/>
<section>
<%= live_render(
@conn,
Pinchflat.Settings.AppriseServerLive,
session: %{"value" => f[:apprise_server].value}
) %>
</section>
<.button class="mt-10 mb-4 sm:mb-8 w-full sm:w-auto" rounding="rounded-lg">Save Settings</.button>
</.simple_form>

View file

@ -7,6 +7,6 @@
</div>
<div class="rounded-sm border border-stroke bg-white px-5 py-5 shadow-default dark:border-strokedark dark:bg-boxdark sm:px-7.5">
<div class="max-w-full">
<.setting_form changeset={@changeset} action={~p"/settings"} />
<.setting_form conn={@conn} changeset={@changeset} action={~p"/settings"} />
</div>
</div>

View file

@ -12,13 +12,7 @@ defmodule Pinchflat.Sources.MediaItemTableLive do
def render(%{records: []} = assigns) do
~H"""
<div class="mb-4 flex items-center">
<button
class="flex justify-center items-center rounded-lg bg-form-input border-2 border-strokedark h-10 w-10"
phx-click="reload_page"
type="button"
>
<.icon name="hero-arrow-path" class="text-stroke" />
</button>
<.icon_button icon_name="hero-arrow-path" class="h-10 w-10" phx-click="reload_page" />
<p class="ml-2">Nothing Here!</p>
</div>
"""
@ -28,13 +22,7 @@ defmodule Pinchflat.Sources.MediaItemTableLive do
~H"""
<div>
<span class="mb-4 flex items-center">
<button
class="flex justify-center items-center rounded-lg bg-form-input border-2 border-strokedark h-10 w-10"
phx-click="reload_page"
type="button"
>
<.icon name="hero-arrow-path" class="text-stroke" />
</button>
<.icon_button icon_name="hero-arrow-path" class="h-10 w-10" phx-click="reload_page" tooltip="Refresh" />
<span class="ml-2">Showing <%= length(@records) %> of <%= @total_record_count %></span>
</span>
<.table rows={@records} table_class="text-white">

View file

@ -0,0 +1,70 @@
defmodule PinchflatWeb.Settings.AppriseServerLiveTest do
use PinchflatWeb.ConnCase
import Mox
import Phoenix.LiveViewTest
alias Pinchflat.Settings.AppriseServerLive
setup :verify_on_exit!
describe "initial rendering" do
test "renders the input", %{conn: conn} do
{:ok, _view, html} = live_isolated(conn, AppriseServerLive, session: create_session(""))
assert html =~ ~s(input type="text" name="setting[apprise_server]")
end
test "sets the initial value from the session", %{conn: conn} do
{:ok, _view, html} = live_isolated(conn, AppriseServerLive, session: create_session("cool-value"))
assert html =~ ~s(value="cool-value")
end
test "shows a relevant button icon", %{conn: conn} do
{:ok, _view, html} = live_isolated(conn, AppriseServerLive, session: create_session(""))
assert html =~ "hero-paper-airplane"
refute html =~ "hero-check"
end
end
describe "pressing the button" do
setup do
stub(AppriseRunnerMock, :run, fn _, _ -> {:ok, ""} end)
:ok
end
test "sends a test message to the specified server", %{conn: conn} do
expect(AppriseRunnerMock, :run, fn servers, args ->
assert servers == ["cool-value"]
assert args == [title: "Pinchflat Test", body: "This is a test message from Pinchflat"]
{:ok, ""}
end)
{:ok, view, _html} = live_isolated(conn, AppriseServerLive, session: create_session("cool-value"))
assert view
|> element("button")
|> render_click()
end
test "sets the button icon to a checkmark", %{conn: conn} do
{:ok, view, _html} = live_isolated(conn, AppriseServerLive, session: create_session("cool-value"))
result =
view
|> element("button")
|> render_click()
refute result =~ "hero-paper-airplane"
assert result =~ "hero-check"
end
end
defp create_session(value) do
%{"value" => value}
end
end