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