frenzy/lib/frenzy_web/live/configure_stage/conditional_stage_live.ex

214 lines
5.6 KiB
Elixir

defmodule FrenzyWeb.ConfigureStage.ConditionalStageLive do
use FrenzyWeb, :live_component
alias Frenzy.{Keypath, JSONSchema}
@stages FrenzyWeb.EditPipelineLive.stages()
@impl true
def mount(socket) do
{:ok, assign(socket, stages: @stages, confirm_convert_to_rule: false)}
end
@impl true
def update(assigns, socket) do
assigns = Map.put(assigns, :opts, Frenzy.Keypath.get(assigns.stage, assigns.keypath))
{:ok, assign(socket, assigns)}
end
@impl true
def handle_event("update_stage", %{"opts" => %{"stage" => ""}}, socket) do
{:noreply, socket}
end
@impl true
def handle_event("update_stage", %{"opts" => %{"stage" => module}}, socket) do
default_options = apply(String.to_existing_atom("Elixir." <> module), :default_opts, [])
new_opts =
socket.assigns.opts
|> Map.put("stage", module)
|> Map.put("opts", default_options)
new_stage = Frenzy.Keypath.set(socket.assigns.stage, socket.assigns.keypath, new_opts)
send(self(), {:update_stage, socket.assigns.index, new_stage})
{:noreply, socket}
end
@impl true
def handle_event("update_filter", %{"mode" => mode, "score" => score}, socket) do
new_opts =
socket.assigns.opts
|> Keypath.set(["condition", "mode"], mode)
|> Keypath.set(["condition", "score"], JSONSchema.coerce(:integer, score))
new_stage = Frenzy.Keypath.set(socket.assigns.stage, socket.assigns.keypath, new_opts)
send(self(), {:update_stage, socket.assigns.index, new_stage})
{:noreply, socket}
end
@impl true
def handle_event("add_rule", _params, socket) do
new_rules =
socket.assigns.opts["condition"]["rules"] ++
[%{"mode" => "text", "param" => "", "property" => "title", "weight" => 1}]
new_stage =
Frenzy.Keypath.set(
socket.assigns.stage,
socket.assigns.keypath ++ ["condition", "rules"],
new_rules
)
send(self(), {:update_stage, socket.assigns.index, new_stage})
{:noreply, socket}
end
@impl true
def handle_event("delete_rule", %{"index" => index}, socket) do
index = String.to_integer(index)
new_rules =
socket.assigns.opts
|> Frenzy.Keypath.get(["condition", "rules"])
|> List.delete_at(index)
new_stage =
Frenzy.Keypath.set(
socket.assigns.stage,
socket.assigns.keypath ++ ["condition", "rules"],
new_rules
)
send(self(), {:update_stage, socket.assigns.index, new_stage})
{:noreply, socket}
end
@impl true
def handle_event(
"update_rule",
%{
"index" => "no_index",
"mode" => mode,
"param" => param,
"property" => property,
"weight" => weight
},
socket
) do
new_rule =
socket.assigns.opts["condition"]
|> Map.put("mode", mode)
|> Map.put("param", param)
|> Map.put("property", property)
|> Map.put("weight", JSONSchema.coerce(:integer, weight))
new_stage =
Frenzy.Keypath.set(
socket.assigns.stage,
socket.assigns.keypath ++ ["condition"],
new_rule
)
send(self(), {:update_stage, socket.assigns.index, new_stage})
{:noreply, socket}
end
@impl true
def handle_event(
"update_rule",
%{
"index" => index,
"mode" => mode,
"param" => param,
"property" => property,
"weight" => weight
},
socket
) do
index = String.to_integer(index)
new_rule =
Enum.at(socket.assigns.opts["condition"]["rules"], index)
|> Map.put("mode", mode)
|> Map.put("param", param)
|> Map.put("property", property)
|> Map.put("weight", JSONSchema.coerce(:integer, weight))
new_stage =
Frenzy.Keypath.set(
socket.assigns.stage,
socket.assigns.keypath ++ ["condition", "rules", index],
new_rule
)
send(self(), {:update_stage, socket.assigns.index, new_stage})
{:noreply, socket}
end
@impl true
def handle_event("convert_to_filter", _value, socket) do
rule = socket.assigns.opts["condition"]
filter = %{"mode" => "accept", "score" => 1, "rules" => [rule]}
new_stage =
Keypath.set(
socket.assigns.stage,
socket.assigns.keypath ++ ["condition"],
filter
)
send(self(), {:update_stage, socket.assigns.index, new_stage})
{:noreply, socket}
end
@impl true
def handle_event("convert_to_rule", _value, socket) do
rules = socket.assigns.opts["condition"]["rules"]
case length(rules) do
0 ->
new_stage =
Keypath.set(
socket.assigns.stage,
socket.assigns.keypath ++ ["condition"],
%{"mode" => "text", "param" => "", "property" => "title", "weight" => 1}
)
send(self(), {:update_stage, socket.assigns.index, new_stage})
{:noreply, socket}
1 ->
handle_event("confirm_convert_to_rule", nil, socket)
_count ->
{:noreply, assign(socket, confirm_convert_to_rule: true)}
end
end
@impl true
def handle_event("cancel_convert_to_rule", _value, socket) do
{:noreply, assign(socket, confirm_convert_to_rule: false)}
end
@impl true
def handle_event("confirm_convert_to_rule", _value, socket) do
rule = socket.assigns.opts["condition"]["rules"] |> List.first()
new_stage =
Keypath.set(
socket.assigns.stage,
socket.assigns.keypath ++ ["condition"],
rule
)
send(self(), {:update_stage, socket.assigns.index, new_stage})
{:noreply, assign(socket, confirm_convert_to_rule: false)}
end
def component_module(name) do
FrenzyWeb.EditPipelineLive.component_module(name)
end
end