Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 42 additions & 22 deletions lib/bob_web/live/artifacts_live.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,7 @@ defmodule BobWeb.ArtifactsLive do
@impl true
def mount(_params, _session, socket) do
socket =
socket
|> assign(
query: "",
kind: "",
arch: "",
os: "",
offset: 0,
assign(socket,
page: @page,
kinds: [],
arches: [],
Expand All @@ -22,35 +16,61 @@ defmodule BobWeb.ArtifactsLive do
results: []
)

socket = if connected?(socket), do: socket |> load_options() |> load(), else: socket

socket = if connected?(socket), do: load_options(socket), else: socket
{:ok, socket}
end

@impl true
def handle_event("search", params, socket) do
socket =
socket
|> assign(
query: params["query"] || "",
kind: params["kind"] || "",
arch: params["arch"] || "",
os: params["os"] || "",
offset: 0
)
|> load()

def handle_params(params, _uri, socket) do
socket = assign(socket, filter_assigns(params))
socket = if connected?(socket), do: load(socket), else: socket
{:noreply, socket}
end

@impl true
def handle_event("search", params, socket) do
filters = Keyword.delete(filter_assigns(params), :offset)
{:noreply, push_patch(socket, to: ~p"/artifacts?#{query(filters, 0)}", replace: true)}
end

def handle_event("page", %{"dir" => dir}, socket) do
offset = max(socket.assigns.offset + step(dir), 0)
{:noreply, socket |> assign(offset: offset) |> load()}

filters = [
query: socket.assigns.query,
kind: socket.assigns.kind,
arch: socket.assigns.arch,
os: socket.assigns.os
]

{:noreply, push_patch(socket, to: ~p"/artifacts?#{query(filters, offset)}")}
end

defp step("next"), do: @page
defp step("prev"), do: -@page

defp filter_assigns(params) do
[
query: params["query"] || "",
kind: params["kind"] || "",
arch: params["arch"] || "",
os: params["os"] || "",
offset: parse_offset(params)
]
end

defp query(filters, offset) do
filters = Enum.reject(filters, fn {_key, value} -> value in [nil, ""] end)
if offset > 0, do: filters ++ [offset: offset], else: filters
end

defp parse_offset(params) do
case Integer.parse(params["offset"] || "") do
{offset, ""} when offset > 0 -> offset
_ -> 0
end
end

defp load_options(socket) do
assign(socket,
kinds: Bob.Artifacts.distinct_kinds(),
Expand Down
62 changes: 45 additions & 17 deletions lib/bob_web/live/jobs_live.ex
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,24 @@ defmodule BobWeb.JobsLive do
past_more: false
)

socket =
if connected?(socket) do
socket |> assign(modules: load_modules()) |> load() |> schedule_tick()
else
socket
end
socket = if connected?(socket), do: assign(socket, modules: load_modules()), else: socket

{:ok, socket}
end

@impl true
def handle_params(params, _uri, socket) do
socket =
assign(socket,
selected: parse_modules(params),
queued_offset: parse_offset(params["queued"]),
past_offset: parse_offset(params["past"])
)

socket = if connected?(socket), do: socket |> load() |> schedule_tick(), else: socket
{:noreply, socket}
end

@impl true
def handle_info(:jobs_changed, %{assigns: %{refresh_scheduled: true}} = socket) do
{:noreply, socket}
Expand All @@ -67,33 +75,53 @@ defmodule BobWeb.JobsLive do
@impl true
def handle_event("queued_page", %{"dir" => dir}, socket) do
offset = max(socket.assigns.queued_offset + step(dir, @queued_page), 0)
{:noreply, socket |> assign(queued_offset: offset) |> load()}

{:noreply,
push_patch(socket,
to: ~p"/?#{jobs_query(socket.assigns.selected, offset, socket.assigns.past_offset)}"
)}
end

def handle_event("past_page", %{"dir" => dir}, socket) do
offset = max(socket.assigns.past_offset + step(dir, @past_page), 0)
{:noreply, socket |> assign(past_offset: offset) |> load()}

{:noreply,
push_patch(socket,
to: ~p"/?#{jobs_query(socket.assigns.selected, socket.assigns.queued_offset, offset)}"
)}
end

def handle_event("toggle_module", %{"module" => name}, socket) do
selected = socket.assigns.selected

selected =
if MapSet.member?(selected, name) do
MapSet.delete(selected, name)
if MapSet.member?(socket.assigns.selected, name) do
MapSet.delete(socket.assigns.selected, name)
else
MapSet.put(selected, name)
MapSet.put(socket.assigns.selected, name)
end

{:noreply,
socket
|> assign(selected: selected, queued_offset: 0, past_offset: 0)
|> load()}
{:noreply, push_patch(socket, to: ~p"/?#{jobs_query(selected, 0, 0)}")}
end

defp step("next", page), do: page
defp step("prev", page), do: -page

defp parse_modules(params) do
params |> Map.get("module", []) |> List.wrap() |> MapSet.new()
end

defp parse_offset(value) do
case Integer.parse(to_string(value || "")) do
{offset, ""} when offset > 0 -> offset
_ -> 0
end
end

defp jobs_query(selected, queued_offset, past_offset) do
query = if MapSet.size(selected) > 0, do: [module: MapSet.to_list(selected)], else: []
query = if queued_offset > 0, do: query ++ [queued: queued_offset], else: query
if past_offset > 0, do: query ++ [past: past_offset], else: query
end

defp load(socket) do
selected = socket.assigns.selected
filter = Enum.filter(socket.assigns.modules, &MapSet.member?(selected, module_name(&1)))
Expand Down
14 changes: 14 additions & 0 deletions test/bob_web/live/artifacts_live_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,18 @@ defmodule BobWeb.ArtifactsLiveTest do
assert html =~ "OTP-26.2"
refute html =~ "OTP-27.0"
end

test "applies filters from URL params on load", %{conn: conn} do
{:ok, _view, html} = live(conn, ~p"/artifacts?query=27.0")

assert html =~ "OTP-27.0"
refute html =~ "OTP-26.2"
end

test "searching patches the URL so filters survive a refresh", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/artifacts")

render_change(view, "search", %{"query" => "27.0", "kind" => "", "arch" => "", "os" => ""})
assert_patch(view, ~p"/artifacts?query=27.0")
end
end
20 changes: 20 additions & 0 deletions test/bob_web/live/jobs_live_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,26 @@ defmodule BobWeb.JobsLiveTest do
assert html =~ ":docker_done"
end

test "selecting a module patches the URL so the filter survives a re-mount", %{conn: conn} do
Bob.Queue.add(Bob.Job.OTPChecker, [:otp_queued])

{:ok, view, _html} = live(conn, ~p"/")

view |> element("button[phx-value-module='Bob.Job.OTPChecker']") |> render_click()
assert_patch(view, ~p"/?#{[module: ["Bob.Job.OTPChecker"]]}")
end

test "applies the module filter from URL params on load", %{conn: conn} do
Bob.Queue.add(Bob.Job.OTPChecker, [:otp_queued])
Bob.Queue.add(Bob.Job.DockerChecker, [:docker_queued])

{:ok, _view, html} = live(conn, ~p"/?#{[module: ["Bob.Job.OTPChecker"]]}")

assert html =~ ":otp_queued"
refute html =~ ":docker_queued"
assert html =~ "chip--active"
end

test "renders tuple module keys without inspect syntax", %{conn: conn} do
Bob.Queue.add({Bob.Job.BuildDockerElixir, "amd64"}, [:tuple_label])

Expand Down
Loading