forked from shibao/cannery
allow filtering ammo types when creating new packs and fix some form errors not displaying on create
This commit is contained in:
@ -9,7 +9,11 @@ defmodule CanneryWeb.PackLive.FormComponent do
|
||||
alias Ecto.Changeset
|
||||
alias Phoenix.LiveView.Socket
|
||||
|
||||
@pack_create_limit 10_000
|
||||
@impl true
|
||||
@spec mount(Socket.t()) :: {:ok, Socket.t()}
|
||||
def mount(socket) do
|
||||
{:ok, socket |> assign(:class, :all)}
|
||||
end
|
||||
|
||||
@impl true
|
||||
@spec update(
|
||||
@ -24,7 +28,6 @@ defmodule CanneryWeb.PackLive.FormComponent do
|
||||
def update(%{assigns: %{current_user: current_user}} = socket) do
|
||||
socket =
|
||||
socket
|
||||
|> assign(:pack_create_limit, @pack_create_limit)
|
||||
|> assign(:types, Ammo.list_types(current_user))
|
||||
|> assign_new(:containers, fn -> Containers.list_containers(current_user) end)
|
||||
|
||||
@ -33,7 +36,20 @@ defmodule CanneryWeb.PackLive.FormComponent do
|
||||
|
||||
@impl true
|
||||
def handle_event("validate", %{"pack" => pack_params}, socket) do
|
||||
{:noreply, socket |> assign_changeset(pack_params, :validate)}
|
||||
matched_class =
|
||||
case pack_params["class"] do
|
||||
"rifle" -> :rifle
|
||||
"shotgun" -> :shotgun
|
||||
"pistol" -> :pistol
|
||||
_other -> :all
|
||||
end
|
||||
|
||||
socket =
|
||||
socket
|
||||
|> assign_changeset(pack_params, :validate)
|
||||
|> assign(:class, matched_class)
|
||||
|
||||
{:noreply, socket}
|
||||
end
|
||||
|
||||
def handle_event(
|
||||
@ -51,11 +67,18 @@ defmodule CanneryWeb.PackLive.FormComponent do
|
||||
containers |> Enum.map(fn %{id: id, name: name} -> {name, id} end)
|
||||
end
|
||||
|
||||
@spec type_options([Type.t()]) :: [{String.t(), Type.id()}]
|
||||
defp type_options(types) do
|
||||
@spec type_options([Type.t()], Type.class() | :all) ::
|
||||
[{String.t(), Type.id()}]
|
||||
defp type_options(types, :all) do
|
||||
types |> Enum.map(fn %{id: id, name: name} -> {name, id} end)
|
||||
end
|
||||
|
||||
defp type_options(types, selected_class) do
|
||||
types
|
||||
|> Enum.filter(fn %{class: class} -> class == selected_class end)
|
||||
|> Enum.map(fn %{id: id, name: name} -> {name, id} end)
|
||||
end
|
||||
|
||||
# Save Helpers
|
||||
|
||||
defp assign_changeset(
|
||||
@ -126,53 +149,15 @@ defmodule CanneryWeb.PackLive.FormComponent do
|
||||
end
|
||||
|
||||
defp save_pack(
|
||||
%{assigns: %{changeset: changeset}} = socket,
|
||||
%{assigns: %{changeset: changeset, current_user: current_user, return_to: return_to}} =
|
||||
socket,
|
||||
action,
|
||||
%{"multiplier" => multiplier_str} = pack_params
|
||||
)
|
||||
when action in [:new, :clone] do
|
||||
socket =
|
||||
case multiplier_str |> Integer.parse() do
|
||||
{multiplier, _remainder}
|
||||
when multiplier >= 1 and multiplier <= @pack_create_limit ->
|
||||
socket |> create_multiple(pack_params, multiplier)
|
||||
|
||||
{multiplier, _remainder} ->
|
||||
error_msg =
|
||||
dgettext(
|
||||
"errors",
|
||||
"Invalid number of copies, must be between 1 and %{max}. Was %{multiplier}",
|
||||
max: @pack_create_limit,
|
||||
multiplier: multiplier
|
||||
)
|
||||
|
||||
save_multiplier_error(socket, changeset, error_msg)
|
||||
|
||||
:error ->
|
||||
error_msg = dgettext("errors", "Could not parse number of copies")
|
||||
save_multiplier_error(socket, changeset, error_msg)
|
||||
end
|
||||
|
||||
{:noreply, socket}
|
||||
end
|
||||
|
||||
@spec save_multiplier_error(Socket.t(), Changeset.t(), String.t()) :: Socket.t()
|
||||
defp save_multiplier_error(socket, changeset, error_msg) do
|
||||
{:error, changeset} =
|
||||
changeset
|
||||
|> Changeset.add_error(:multiplier, error_msg)
|
||||
|> Changeset.apply_action(:insert)
|
||||
|
||||
socket |> assign(:changeset, changeset)
|
||||
end
|
||||
|
||||
defp create_multiple(
|
||||
%{assigns: %{current_user: current_user, return_to: return_to}} = socket,
|
||||
pack_params,
|
||||
multiplier
|
||||
) do
|
||||
case Ammo.create_packs(pack_params, multiplier, current_user) do
|
||||
{:ok, {count, _packs}} ->
|
||||
with {multiplier, _remainder} <- multiplier_str |> Integer.parse(),
|
||||
{:ok, {count, _packs}} <- Ammo.create_packs(pack_params, multiplier, current_user) do
|
||||
prompt =
|
||||
dngettext(
|
||||
"prompts",
|
||||
@ -182,9 +167,21 @@ defmodule CanneryWeb.PackLive.FormComponent do
|
||||
)
|
||||
|
||||
socket |> put_flash(:info, prompt) |> push_navigate(to: return_to)
|
||||
else
|
||||
{:error, %Changeset{} = changeset} ->
|
||||
socket |> assign(changeset: changeset)
|
||||
|
||||
{:error, %Changeset{} = changeset} ->
|
||||
socket |> assign(changeset: changeset)
|
||||
end
|
||||
:error ->
|
||||
error_msg = dgettext("errors", "Could not parse number of copies")
|
||||
|
||||
{:error, changeset} =
|
||||
changeset
|
||||
|> Changeset.add_error(:multiplier, error_msg)
|
||||
|> Changeset.apply_action(:insert)
|
||||
|
||||
socket |> assign(:changeset, changeset)
|
||||
end
|
||||
|
||||
{:noreply, socket}
|
||||
end
|
||||
end
|
||||
|
@ -19,8 +19,23 @@
|
||||
<%= changeset_errors(@changeset) %>
|
||||
</div>
|
||||
|
||||
<%= label(f, :class, gettext("Class"), class: "title text-lg text-primary-600") %>
|
||||
<%= select(
|
||||
f,
|
||||
:class,
|
||||
[
|
||||
{gettext("Any"), :all},
|
||||
{gettext("Rifle"), :rifle},
|
||||
{gettext("Shotgun"), :shotgun},
|
||||
{gettext("Pistol"), :pistol}
|
||||
],
|
||||
class: "text-center col-span-2 input input-primary",
|
||||
value: @class
|
||||
) %>
|
||||
<%= error_tag(f, :class, "col-span-3 text-center") %>
|
||||
|
||||
<%= label(f, :type_id, gettext("Type"), class: "title text-lg text-primary-600") %>
|
||||
<%= select(f, :type_id, type_options(@types),
|
||||
<%= select(f, :type_id, type_options(@types, @class),
|
||||
class: "text-center col-span-2 input input-primary",
|
||||
id: "pack-form-type-select",
|
||||
phx_hook: "SlimSelect"
|
||||
@ -80,7 +95,6 @@
|
||||
|
||||
<%= label(f, :multiplier, gettext("Copies"), class: "title text-lg text-primary-600") %>
|
||||
<%= number_input(f, :multiplier,
|
||||
max: @pack_create_limit,
|
||||
class: "text-center input input-primary",
|
||||
value: 1,
|
||||
phx_update: "ignore"
|
||||
|
Reference in New Issue
Block a user