Add live filter configuration

This commit is contained in:
Shadowfacts 2020-07-18 10:25:43 -04:00
parent 0884bf3f32
commit a10f1bea30
Signed by: shadowfacts
GPG Key ID: 94A5AB95422746E5
7 changed files with 184 additions and 3 deletions

View File

@ -0,0 +1,78 @@
defmodule FrenzyWeb.ConfigureStage.FilterStageLive do
use FrenzyWeb, :live_component
@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_filter", %{"mode" => mode, "score" => score}, socket) do
new_opts =
socket.assigns.opts
|> Map.put("mode", mode)
|> Map.put("score", 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["rules"] ++
[%{"mode" => "text", "param" => "", "property" => "title", "weight" => 1}]
new_opts = Map.put(socket.assigns.opts, "rules", new_rules)
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("delete_rule", %{"index" => index}, socket) do
index = String.to_integer(index)
new_rules = List.delete_at(socket.assigns.opts["rules"], index)
new_opts = Map.put(socket.assigns.opts, "rules", new_rules)
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_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["rules"], index)
|> Map.put("mode", mode)
|> Map.put("param", param)
|> Map.put("property", property)
|> Map.put("weight", weight)
new_stage =
Frenzy.Keypath.set(
socket.assigns.stage,
socket.assigns.keypath ++ ["rules", index],
new_rule
)
send(self(), {:update_stage, socket.assigns.index, new_stage})
{:noreply, socket}
end
end

View File

@ -0,0 +1,6 @@
<div id="<%= @id %>">
<%= if Mix.env == :dev do %>
<pre><%= Jason.encode!(@opts, pretty: true) %></pre>
<% end %>
<%= live_component @socket, FrenzyWeb.FilterLive, id: "#{@id}-filter", parent_id: @id, filter: @opts %>
</div>

View File

@ -9,6 +9,8 @@ defmodule FrenzyWeb.EditPipelineLive do
{"Conditional Stage", "Frenzy.Pipeline.ConditionalStage"}
]
def stages, do: @stages
@impl true
def mount(%{"id" => pipeline_id}, _session, socket) do
pipeline = Repo.get(Pipeline, pipeline_id)
@ -76,9 +78,6 @@ defmodule FrenzyWeb.EditPipelineLive do
@impl true
def handle_info({:update_stage, index, new_stage}, socket) do
pipeline = socket.assigns.pipeline
# stages = pipeline.stages
# stage = Enum.at(stages, index)
# new_stage = Map.put(stage, "options", new_opts)
new_stages = List.replace_at(pipeline.stages, index, new_stage)
changeset = Pipeline.changeset(pipeline, %{stages: new_stages})
{:ok, pipeline} = Repo.update(changeset)
@ -91,6 +90,9 @@ defmodule FrenzyWeb.EditPipelineLive do
"Frenzy.Pipeline.ScrapeStage" ->
FrenzyWeb.ConfigureStage.ScrapeStageLive
"Frenzy.Pipeline.FilterStage" ->
FrenzyWeb.ConfigureStage.FilterStageLive
"Frenzy.Pipeline.ConditionalStage" ->
FrenzyWeb.ConfigureStage.ConditionalStageLive

View File

@ -0,0 +1,13 @@
defmodule FrenzyWeb.FilterLive do
use FrenzyWeb, :live_component
@filter_modes [
{"Accept", "accept"},
{"Reject", "reject"}
]
@impl true
def mount(socket) do
{:ok, assign(socket, modes: @filter_modes)}
end
end

View File

@ -0,0 +1,22 @@
<div id="<%= @id %>">
<%= f = form_for @filter, "#", [phx_change: :update_filter, phx_target: "##{@parent_id}"] %>
<div class="form-group row">
<label class="col-sm-2 col-form-label" for="<%= @id %>-mode">Mode</label>
<div class="col-sm-10">
<%= select f, :mode, @modes, id: "#{@id}-mode", class: "custom-select" %>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label" for="<%= @id %>-score">Score</label>
<div class="col-sm-10">
<%= number_input f, :score, id: "#{@id}-score", class: "form-control" %>
</div>
</div>
</form>
<%= for {rule, index} <- Enum.with_index(@filter["rules"]) do %>
<%= live_component @socket, FrenzyWeb.FilterRuleLive, id: "#{@id}-rule-#{index}", parent_id: @parent_id, rule: rule, index: index %>
<% end %>
<%= f = form_for :rule, "#", class: "mt-2", phx_submit: :add_rule, phx_target: "##{@parent_id}" %>
<%= submit "Add Rule", class: "btn btn-primary" %>
</form>
</div>

View File

@ -0,0 +1,19 @@
defmodule FrenzyWeb.FilterRuleLive do
use FrenzyWeb, :live_component
@modes [
{"Contains Substring", "contains_string"},
{"Matches Regex", "matches_regex"}
]
@properties [
{"Title", "title"},
{"URL", "url"},
{"Author", "author"}
]
@impl true
def mount(socket) do
{:ok, assign(socket, modes: @modes, properties: @properties)}
end
end

View File

@ -0,0 +1,41 @@
<div id="<%= @id %>" class="card mt-2">
<div class="card-header container-fluid">
<div class="row">
<div class="col">
<h5 class="m-0">Rule <%= @index %></h5>
</div>
<div class="col text-right">
<button phx-click="delete_rule" phx-value-index="<%= @index %>" phx-target="#<%= @parent_id %>">Delete</button>
</div>
</div>
</div>
<div class="card-body">
<%= f = form_for @rule, "#", [phx_change: :update_rule, phx_target: "##{@parent_id}"] %>
<%= hidden_input f, :index, value: @index %>
<div class="form-group row mb-2">
<label class="col-sm-2 col-form-label" for="<%= @id %>-property">Item Property</label>
<div class="col-sm-10">
<%= select f, :property, @properties, id: "#{@id}-property", class: "custom-select" %>
</div>
</div>
<div class="form-group row mb-2">
<label class="col-sm-2 col-form-label" for="<%= @id %>-mode">Mode</label>
<div class="col-sm-10">
<%= select f, :mode, @modes, id: "#{@id}-mode", class: "custom-select" %>
</div>
</div>
<div class="form-group row mb-2">
<label class="col-sm-2 col-form-label" for="<%= @id %>-param">Value</label>
<div class="col-sm-10">
<%= text_input f, :param, id: "#{@id}-param", placeholder: if(@rule["mode"] == "contains_string", do: "substring", else: "regex"), class: "form-control text-monospace" %>
</div>
</div>
<div class="form-group row mb-0">
<label class="col-sm-2 col-form-label" for="<%= @id %>-weight">Rule Weight</label>
<div class="col-sm-10">
<%= number_input f, :weight, id: "#{@id}-weight", class: "form-control" %>
</div>
</div>
</form>
</div>
</div>