defmodule FrenzyWeb.EditPipelineLive do use FrenzyWeb, :live_view use Phoenix.HTML alias Frenzy.{Repo, Pipeline} @stages [ {"Filter Stage", "Frenzy.Pipeline.FilterStage"}, {"Scrape Stage", "Frenzy.Pipeline.ScrapeStage"}, {"Conditional Stage", "Frenzy.Pipeline.ConditionalStage"}, {"Gemini Scrape Stage", "Frenzy.Pipeline.GeminiScrapeStage"}, {"Render Gemini Stage", "Frenzy.Pipeline.RenderGeminiStage"} ] def stages, do: @stages @impl true def mount(_, %{"pipeline_id" => pipeline_id}, socket) do pipeline = Repo.get(Pipeline, pipeline_id) {:ok, assign(socket, pipeline: pipeline, stages: @stages )} end @impl true def handle_event("add_stage", %{"stage" => %{"module_name" => module}}, socket) do pipeline = socket.assigns[:pipeline] default_options = apply(String.to_existing_atom("Elixir." <> module), :default_opts, []) changeset = Pipeline.changeset(pipeline, %{ stages: pipeline.stages ++ [%{"module_name" => module, "options" => default_options}] }) {:ok, pipeline} = Repo.update(changeset) {:noreply, assign(socket, pipeline: pipeline)} end def handle_event("delete_stage", %{"index" => index}, socket) do pipeline = socket.assigns.pipeline index = String.to_integer(index) changeset = Pipeline.changeset(pipeline, %{ stages: List.delete_at(pipeline.stages, index) }) {:ok, pipeline} = Repo.update(changeset) {:noreply, assign(socket, pipeline: pipeline)} end def handle_event(event, %{"index" => index}, socket) when event in ["move_up", "move_down"] do index = String.to_integer(index) offset = case event do "move_up" -> -1 "move_down" -> 1 end pipeline = socket.assigns.pipeline stage = Enum.at(pipeline.stages, index) changeset = Pipeline.changeset(pipeline, %{ stages: pipeline.stages |> List.delete_at(index) |> List.insert_at(index + offset, stage) }) {:ok, pipeline} = Repo.update(changeset) {:noreply, assign(socket, pipeline: pipeline)} end @impl true def handle_info({:update_stage, index, new_stage}, socket) do pipeline = socket.assigns.pipeline new_stages = List.replace_at(pipeline.stages, index, new_stage) changeset = Pipeline.changeset(pipeline, %{stages: new_stages}) {:ok, pipeline} = Repo.update(changeset) {:noreply, assign(socket, pipeline: pipeline)} end def component_module(module_name) do case module_name do "Frenzy.Pipeline.ScrapeStage" -> FrenzyWeb.ConfigureStage.ScrapeStageLive "Frenzy.Pipeline.FilterStage" -> FrenzyWeb.ConfigureStage.FilterStageLive "Frenzy.Pipeline.ConditionalStage" -> FrenzyWeb.ConfigureStage.ConditionalStageLive _ -> nil end end def component_for(socket, %{"module_name" => module} = stage, index) do case component_module(module) do nil -> nil component -> live_component(socket, component, index: index, id: "stage-#{index}", stage: stage, keypath: ["options"] ) end end end