use phoenix component modal
This commit is contained in:
parent
f517ffc8f8
commit
114f63b47a
@ -1,43 +0,0 @@
|
||||
defmodule CanneryWeb.Components.Modal do
|
||||
@moduledoc """
|
||||
Livecomponent that displays a floating modal window
|
||||
"""
|
||||
|
||||
use CanneryWeb, :live_component
|
||||
|
||||
@impl true
|
||||
def render(assigns) do
|
||||
~H"""
|
||||
<div
|
||||
id={@id}
|
||||
class="fixed z-10 left-0 top-0
|
||||
w-full h-full overflow-hidden
|
||||
p-8 flex flex-col justify-center items-center"
|
||||
style="opacity: 1 !important; background-color: rgba(0,0,0,0.4);"
|
||||
phx-capture-click="close"
|
||||
phx-window-keydown="close"
|
||||
phx-key="escape"
|
||||
phx-target={"#{@id}"}
|
||||
phx-page-loading
|
||||
>
|
||||
<div class="w-full max-w-3xl max-h-128 relative overflow-y-auto
|
||||
flex flex-col justify-start items-center
|
||||
bg-white border-2 rounded-lg">
|
||||
<%= live_patch to: @return_to,
|
||||
class:
|
||||
"absolute top-8 right-10 text-gray-500 hover:text-gray-800 transition-all duration-500 ease-in-out" do %>
|
||||
<i class="fa-fw fa-lg fas fa-times"></i>
|
||||
<% end %>
|
||||
<div class="p-8 flex flex-col space-y-4 justify-start items-center">
|
||||
<%= live_component(@component, @opts) %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_event("close", _, socket) do
|
||||
{:noreply, push_patch(socket, to: socket.assigns.return_to)}
|
||||
end
|
||||
end
|
@ -79,12 +79,15 @@
|
||||
</div>
|
||||
|
||||
<%= if @live_action in [:new, :edit] do %>
|
||||
<%= live_modal(CanneryWeb.AmmoGroupLive.FormComponent,
|
||||
id: @ammo_group.id || :new,
|
||||
title: @page_title,
|
||||
action: @live_action,
|
||||
ammo_group: @ammo_group,
|
||||
return_to: Routes.ammo_group_index_path(@socket, :index),
|
||||
current_user: @current_user
|
||||
) %>
|
||||
<.modal return_to={Routes.ammo_group_index_path(@socket, :index)}>
|
||||
<.live_component
|
||||
module={CanneryWeb.AmmoGroupLive.FormComponent}
|
||||
id={@ammo_group.id || :new}
|
||||
title={@page_title}
|
||||
action={@live_action}
|
||||
ammo_group={@ammo_group}
|
||||
return_to={Routes.ammo_group_index_path(@socket, :index)}
|
||||
current_user={@current_user}
|
||||
/>
|
||||
</.modal>
|
||||
<% end %>
|
||||
|
@ -53,12 +53,15 @@
|
||||
</div>
|
||||
|
||||
<%= if @live_action in [:edit] do %>
|
||||
<%= live_modal(CanneryWeb.AmmoGroupLive.FormComponent,
|
||||
id: @ammo_group.id,
|
||||
title: @page_title,
|
||||
action: @live_action,
|
||||
ammo_group: @ammo_group,
|
||||
return_to: Routes.ammo_group_show_path(@socket, :show, @ammo_group),
|
||||
current_user: @current_user
|
||||
) %>
|
||||
<.modal return_to={Routes.ammo_group_show_path(@socket, :show, @ammo_group)}>
|
||||
<.live_component
|
||||
module={CanneryWeb.AmmoGroupLive.FormComponent}
|
||||
id={@ammo_group.id}
|
||||
title={@page_title}
|
||||
action={@live_action}
|
||||
ammo_group={@ammo_group}
|
||||
return_to={Routes.ammo_group_show_path(@socket, :show, @ammo_group)}
|
||||
current_user={@current_user}
|
||||
/>
|
||||
</.modal>
|
||||
<% end %>
|
||||
|
@ -13,7 +13,7 @@ defmodule CanneryWeb.AmmoTypeLive.FormComponent do
|
||||
%{:ammo_type => AmmoType.t(), :current_user => User.t(), optional(any) => any},
|
||||
Socket.t()
|
||||
) :: {:ok, Socket.t()}
|
||||
def update(%{ammo_type: ammo_type} = assigns, socket) do
|
||||
def update(%{ammo_type: ammo_type, current_user: _current_user} = assigns, socket) do
|
||||
{:ok, socket |> assign(assigns) |> assign(:changeset, Ammo.change_ammo_type(ammo_type))}
|
||||
end
|
||||
|
||||
@ -186,9 +186,13 @@ defmodule CanneryWeb.AmmoTypeLive.FormComponent do
|
||||
{:noreply, socket}
|
||||
end
|
||||
|
||||
defp save_ammo_type(%{assigns: %{return_to: return_to}} = socket, :new, ammo_type_params) do
|
||||
defp save_ammo_type(
|
||||
%{assigns: %{current_user: current_user, return_to: return_to}} = socket,
|
||||
:new,
|
||||
ammo_type_params
|
||||
) do
|
||||
socket =
|
||||
case Ammo.create_ammo_type(ammo_type_params) do
|
||||
case Ammo.create_ammo_type(ammo_type_params, current_user) do
|
||||
{:ok, %{name: ammo_type_name}} ->
|
||||
prompt = dgettext("prompts", "%{name} created successfully", name: ammo_type_name)
|
||||
socket |> put_flash(:info, prompt) |> push_redirect(to: return_to)
|
||||
|
@ -5,8 +5,8 @@ defmodule CanneryWeb.AmmoTypeLive.Index do
|
||||
|
||||
use CanneryWeb, :live_view
|
||||
|
||||
alias Cannery.Ammo
|
||||
alias Cannery.Ammo.AmmoType
|
||||
alias Cannery.{Ammo, Ammo.AmmoType}
|
||||
alias CanneryWeb.Endpoint
|
||||
|
||||
@impl true
|
||||
def mount(_params, session, socket) do
|
||||
|
@ -115,11 +115,16 @@
|
||||
</div>
|
||||
|
||||
<%= if @live_action in [:new, :edit] do %>
|
||||
<%= live_modal(CanneryWeb.AmmoTypeLive.FormComponent,
|
||||
id: @ammo_type.id || :new,
|
||||
title: @page_title,
|
||||
action: @live_action,
|
||||
ammo_type: @ammo_type,
|
||||
return_to: Routes.ammo_type_index_path(@socket, :index)
|
||||
) %>
|
||||
<.modal return_to={Routes.ammo_type_index_path(Endpoint, :index)}>
|
||||
<.live_component
|
||||
module={CanneryWeb.AmmoTypeLive.FormComponent}
|
||||
id={@ammo_type.id || :new}
|
||||
title={@page_title}
|
||||
action={@live_action}
|
||||
ammo_type={@ammo_type}
|
||||
return_to={Routes.ammo_type_index_path(Endpoint, :index)}
|
||||
current_user={@current_user}
|
||||
}
|
||||
/>
|
||||
</.modal>
|
||||
<% end %>
|
||||
|
@ -6,6 +6,7 @@ defmodule CanneryWeb.AmmoTypeLive.Show do
|
||||
use CanneryWeb, :live_view
|
||||
import CanneryWeb.Components.AmmoGroupCard
|
||||
alias Cannery.Ammo
|
||||
alias CanneryWeb.Endpoint
|
||||
|
||||
@impl true
|
||||
def mount(_params, session, socket) do
|
||||
|
@ -106,11 +106,15 @@
|
||||
</div>
|
||||
|
||||
<%= if @live_action in [:edit] do %>
|
||||
<%= live_modal(CanneryWeb.AmmoTypeLive.FormComponent,
|
||||
id: @ammo_type.id,
|
||||
title: @page_title,
|
||||
action: @live_action,
|
||||
ammo_type: @ammo_type,
|
||||
return_to: Routes.ammo_type_show_path(@socket, :show, @ammo_type)
|
||||
) %>
|
||||
<.modal return_to={Routes.ammo_type_show_path(Endpoint, :show, @ammo_type)}>
|
||||
<.live_component
|
||||
module={CanneryWeb.AmmoTypeLive.FormComponent}
|
||||
id={@ammo_type.id}
|
||||
title={@page_title}
|
||||
action={@live_action}
|
||||
ammo_type={@ammo_type}
|
||||
return_to={Routes.ammo_type_show_path(Endpoint, :show, @ammo_type)}
|
||||
current_user={@current_user}
|
||||
/>
|
||||
</.modal>
|
||||
<% end %>
|
||||
|
@ -43,12 +43,15 @@
|
||||
</div>
|
||||
|
||||
<%= if @live_action in [:new, :edit] do %>
|
||||
<%= live_modal(CanneryWeb.ContainerLive.FormComponent,
|
||||
id: @container.id || :new,
|
||||
title: @page_title,
|
||||
action: @live_action,
|
||||
container: @container,
|
||||
return_to: Routes.container_index_path(@socket, :index),
|
||||
current_user: @current_user
|
||||
) %>
|
||||
<.modal return_to={Routes.container_index_path(@socket, :index)}>
|
||||
<.live_component
|
||||
module={CanneryWeb.ContainerLive.FormComponent}
|
||||
id={@container.id || :new}
|
||||
title={@page_title}
|
||||
action={@live_action}
|
||||
container={@container}
|
||||
return_to={Routes.container_index_path(@socket, :index)}
|
||||
current_user={@current_user}
|
||||
/>
|
||||
</.modal>
|
||||
<% end %>
|
||||
|
@ -92,23 +92,29 @@
|
||||
</div>
|
||||
|
||||
<%= if @live_action in [:edit] do %>
|
||||
<%= live_modal(CanneryWeb.ContainerLive.FormComponent,
|
||||
id: @container.id,
|
||||
title: @page_title,
|
||||
action: @live_action,
|
||||
container: @container,
|
||||
return_to: Routes.container_show_path(Endpoint, :show, @container),
|
||||
current_user: @current_user
|
||||
) %>
|
||||
<.modal return_to={Routes.container_show_path(Endpoint, :show, @container)}>
|
||||
<.live_component
|
||||
module={CanneryWeb.ContainerLive.FormComponent}
|
||||
id={@container.id}
|
||||
title={@page_title}
|
||||
action={@live_action}
|
||||
container={@container}
|
||||
return_to={Routes.container_show_path(Endpoint, :show, @container)}
|
||||
current_user={@current_user}
|
||||
/>
|
||||
</.modal>
|
||||
<% end %>
|
||||
|
||||
<%= if @live_action == :add_tag do %>
|
||||
<%= live_modal(CanneryWeb.ContainerLive.AddTagComponent,
|
||||
id: @container.id,
|
||||
title: @page_title,
|
||||
action: @live_action,
|
||||
container: @container,
|
||||
return_to: Routes.container_show_path(Endpoint, :show, @container),
|
||||
current_user: @current_user
|
||||
) %>
|
||||
<.modal return_to={Routes.container_show_path(Endpoint, :show, @container)}>
|
||||
<.live_component
|
||||
module={CanneryWeb.ContainerLive.AddTagComponent}
|
||||
id={@container.id}
|
||||
title={@page_title}
|
||||
action={@live_action}
|
||||
container={@container}
|
||||
return_to={Routes.container_show_path(Endpoint, :show, @container)}
|
||||
current_user={@current_user}
|
||||
/>
|
||||
</.modal>
|
||||
<% end %>
|
||||
|
@ -125,12 +125,15 @@
|
||||
</div>
|
||||
|
||||
<%= if @live_action in [:new, :edit] do %>
|
||||
<%= live_modal(CanneryWeb.InviteLive.FormComponent,
|
||||
id: @invite.id || :new,
|
||||
title: @page_title,
|
||||
action: @live_action,
|
||||
invite: @invite,
|
||||
return_to: Routes.invite_index_path(@socket, :index),
|
||||
current_user: @current_user
|
||||
) %>
|
||||
<.modal return_to={Routes.invite_index_path(@socket, :index)}>
|
||||
<.live_component
|
||||
module={CanneryWeb.InviteLive.FormComponent}
|
||||
id={@invite.id || :new}
|
||||
title={@page_title}
|
||||
action={@live_action}
|
||||
invite={@invite}
|
||||
return_to={Routes.invite_index_path(@socket, :index)}
|
||||
current_user={@current_user}
|
||||
/>
|
||||
</.modal>
|
||||
<% end %>
|
||||
|
@ -3,29 +3,10 @@ defmodule CanneryWeb.LiveHelpers do
|
||||
Contains common helper functions for liveviews
|
||||
"""
|
||||
|
||||
import Phoenix.LiveView
|
||||
import Phoenix.LiveView.Helpers
|
||||
import Phoenix.LiveView, only: [assign_new: 3]
|
||||
alias Cannery.Accounts
|
||||
alias CanneryWeb.Components.Modal
|
||||
|
||||
@doc """
|
||||
Renders a component inside the `Modal` component.
|
||||
|
||||
The rendered modal receives a `:return_to` option to properly update
|
||||
the URL when the modal is closed.
|
||||
|
||||
## Examples
|
||||
|
||||
<%= live_modal CanneryWeb.TagLive.FormComponent,
|
||||
id: @tag.id || :new,
|
||||
action: @live_action,
|
||||
tag: @tag,
|
||||
return_to: Routes.tag_index_path(@socket, :index) %>
|
||||
"""
|
||||
def live_modal(component, opts) do
|
||||
path = Keyword.fetch!(opts, :return_to)
|
||||
live_component(Modal, id: :modal, return_to: path, component: component, opts: opts)
|
||||
end
|
||||
alias Phoenix.LiveView.JS
|
||||
|
||||
def assign_defaults(socket, %{"user_token" => user_token} = _session) do
|
||||
socket
|
||||
@ -35,4 +16,77 @@ defmodule CanneryWeb.LiveHelpers do
|
||||
def assign_defaults(socket, _session) do
|
||||
socket
|
||||
end
|
||||
|
||||
@doc """
|
||||
Renders a live component inside a modal.
|
||||
|
||||
The rendered modal receives a `:return_to` option to properly update
|
||||
the URL when the modal is closed.
|
||||
|
||||
## Examples
|
||||
|
||||
<.modal return_to={Routes.<%= schema.singular %>_index_path(@socket, :index)}>
|
||||
<.live_component
|
||||
module={<%= inspect context.web_module %>.<%= inspect Module.concat(schema.web_namespace, schema.alias) %>Live.FormComponent}
|
||||
id={@<%= schema.singular %>.id || :new}
|
||||
title={@page_title}
|
||||
action={@live_action}
|
||||
return_to={Routes.<%= schema.singular %>_index_path(@socket, :index)}
|
||||
<%= schema.singular %>: @<%= schema.singular %>
|
||||
/>
|
||||
</.modal>
|
||||
"""
|
||||
def modal(assigns) do
|
||||
assigns = assign_new(assigns, :return_to, fn -> nil end)
|
||||
|
||||
~H"""
|
||||
<div
|
||||
id="modal"
|
||||
class="fade-in fixed z-10 left-0 top-0
|
||||
w-full h-full overflow-hidden
|
||||
p-8 flex flex-col justify-center items-center"
|
||||
style="opacity: 1 !important; background-color: rgba(0,0,0,0.4);"
|
||||
phx-remove={hide_modal()}
|
||||
>
|
||||
<div
|
||||
id="modal-content"
|
||||
class="fade-in-scale w-full max-w-3xl max-h-128 relative overflow-y-auto
|
||||
flex flex-col justify-start items-center
|
||||
bg-white border-2 rounded-lg"
|
||||
phx-click-away={hide_modal()}
|
||||
phx-window-keydown={hide_modal()}
|
||||
phx-key="escape"
|
||||
>
|
||||
<%= if @return_to do %>
|
||||
<%= live_patch to: @return_to,
|
||||
id: "close",
|
||||
class:
|
||||
"absolute top-8 right-10 text-gray-500 hover:text-gray-800 transition-all duration-500 ease-in-out",
|
||||
phx_click: hide_modal() do %>
|
||||
<i class="fa-fw fa-lg fas fa-times"></i>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<a
|
||||
id="close"
|
||||
href="#"
|
||||
class="absolute top-8 right-10 text-gray-500 hover:text-gray-800 transition-all duration-500 ease-in-out"
|
||||
phx-click={hide_modal()}
|
||||
>
|
||||
<i class="fa-fw fa-lg fas fa-times"></i>
|
||||
</a>
|
||||
<% end %>
|
||||
|
||||
<div class="p-8 flex flex-col space-y-4 justify-start items-center">
|
||||
<%= render_slot(@inner_block) %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
def hide_modal(js \\ %JS{}) do
|
||||
js
|
||||
|> JS.hide(to: "#modal", transition: "fade-out")
|
||||
|> JS.hide(to: "#modal-content", transition: "fade-out-scale")
|
||||
end
|
||||
end
|
||||
|
@ -43,12 +43,15 @@
|
||||
</div>
|
||||
|
||||
<%= if @live_action in [:new, :edit] do %>
|
||||
<%= live_modal(CanneryWeb.TagLive.FormComponent,
|
||||
id: @tag.id || :new,
|
||||
title: @page_title,
|
||||
action: @live_action,
|
||||
tag: @tag,
|
||||
return_to: Routes.tag_index_path(@socket, :index),
|
||||
current_user: @current_user
|
||||
) %>
|
||||
<.modal return_to={Routes.tag_index_path(@socket, :index)}>
|
||||
<.live_component
|
||||
module={CanneryWeb.TagLive.FormComponent}
|
||||
id={@tag.id || :new}
|
||||
title={@page_title}
|
||||
action={@live_action}
|
||||
tag={@tag}
|
||||
return_to={Routes.tag_index_path(@socket, :index)}
|
||||
current_user={@current_user}
|
||||
/>
|
||||
</.modal>
|
||||
<% end %>
|
||||
|
@ -65,8 +65,7 @@ msgid "Invite someone new!"
|
||||
msgstr ""
|
||||
|
||||
#, elixir-format, ex-autogen
|
||||
#: lib/cannery_web/components/topbar.ex:96
|
||||
#: lib/cannery_web/templates/layout/topbar.html.heex:36
|
||||
#: lib/cannery_web/components/topbar.ex:102
|
||||
#: lib/cannery_web/templates/user_confirmation/new.html.heex:26
|
||||
#: lib/cannery_web/templates/user_registration/new.html.heex:39
|
||||
#: lib/cannery_web/templates/user_reset_password/edit.html.heex:41
|
||||
@ -102,8 +101,7 @@ msgid "New Tag"
|
||||
msgstr ""
|
||||
|
||||
#, elixir-format, ex-autogen
|
||||
#: lib/cannery_web/components/topbar.ex:89
|
||||
#: lib/cannery_web/templates/layout/topbar.html.heex:28
|
||||
#: lib/cannery_web/components/topbar.ex:95
|
||||
#: lib/cannery_web/templates/user_confirmation/new.html.heex:21
|
||||
#: lib/cannery_web/templates/user_registration/new.html.heex:3
|
||||
#: lib/cannery_web/templates/user_registration/new.html.heex:34
|
||||
|
@ -154,7 +154,7 @@ msgstr ""
|
||||
|
||||
#, elixir-format, ex-autogen
|
||||
#: lib/cannery_web/live/ammo_type_live/index.ex:23
|
||||
#: lib/cannery_web/live/ammo_type_live/show.ex:46
|
||||
#: lib/cannery_web/live/ammo_type_live/show.ex:47
|
||||
msgid "Edit Ammo type"
|
||||
msgstr ""
|
||||
|
||||
@ -218,7 +218,7 @@ msgid "Invite Only"
|
||||
msgstr ""
|
||||
|
||||
#, elixir-format, ex-autogen
|
||||
#: lib/cannery_web/components/topbar.ex:60
|
||||
#: lib/cannery_web/components/topbar.ex:66
|
||||
msgid "Invites"
|
||||
msgstr ""
|
||||
|
||||
@ -451,7 +451,7 @@ msgid "Show Ammo group"
|
||||
msgstr ""
|
||||
|
||||
#, elixir-format, ex-autogen
|
||||
#: lib/cannery_web/live/ammo_type_live/show.ex:45
|
||||
#: lib/cannery_web/live/ammo_type_live/show.ex:46
|
||||
msgid "Show Ammo type"
|
||||
msgstr ""
|
||||
|
||||
|
@ -11,7 +11,7 @@ msgid ""
|
||||
msgstr ""
|
||||
|
||||
#, elixir-format, ex-autogen
|
||||
#: lib/cannery_web/live/ammo_type_live/form_component.ex:193
|
||||
#: lib/cannery_web/live/ammo_type_live/form_component.ex:197
|
||||
#: lib/cannery_web/live/container_live/form_component.ex:126
|
||||
#: lib/cannery_web/live/invite_live/form_component.ex:98
|
||||
#: lib/cannery_web/live/tag_live/form_component.ex:101
|
||||
@ -20,7 +20,7 @@ msgstr ""
|
||||
|
||||
#, elixir-format, ex-autogen
|
||||
#: lib/cannery_web/live/ammo_type_live/index.ex:41
|
||||
#: lib/cannery_web/live/ammo_type_live/show.ex:39
|
||||
#: lib/cannery_web/live/ammo_type_live/show.ex:40
|
||||
#: lib/cannery_web/live/invite_live/index.ex:54
|
||||
#: lib/cannery_web/live/invite_live/index.ex:120
|
||||
#: lib/cannery_web/live/tag_live/index.ex:41
|
||||
@ -109,8 +109,7 @@ msgid "Are you sure you want to delete your account?"
|
||||
msgstr ""
|
||||
|
||||
#, elixir-format, ex-autogen
|
||||
#: lib/cannery_web/components/topbar.ex:75
|
||||
#: lib/cannery_web/templates/layout/topbar.html.heex:21
|
||||
#: lib/cannery_web/components/topbar.ex:81
|
||||
msgid "Are you sure you want to log out?"
|
||||
msgstr ""
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user