Skip to content

Commit 5e9f8c8

Browse files
committed
Propagate filters during navigation
When navigating from the dashboard to the error detail page we now propagate the active filters so users can navigate back and fort without losing them.
1 parent c108b23 commit 5e9f8c8

File tree

6 files changed

+85
-48
lines changed

6 files changed

+85
-48
lines changed

lib/error_tracker/web/live/dashboard.ex

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,28 @@ defmodule ErrorTracker.Web.Live.Dashboard do
77

88
alias ErrorTracker.Error
99
alias ErrorTracker.Repo
10+
alias ErrorTracker.Web.Search
1011

1112
@per_page 10
1213

1314
@impl Phoenix.LiveView
1415
def handle_params(params, uri, socket) do
15-
{search, search_form} = search_terms(params)
16-
1716
path = struct(URI, uri |> URI.parse() |> Map.take([:path, :query]))
1817

1918
{:noreply,
2019
socket
21-
|> assign(path: path, search: search, page: 1, search_form: search_form)
20+
|> assign(
21+
path: path,
22+
search: Search.from_params(params),
23+
page: 1,
24+
search_form: Search.to_form(params)
25+
)
2226
|> paginate_errors()}
2327
end
2428

2529
@impl Phoenix.LiveView
2630
def handle_event("search", params, socket) do
27-
{search, _search_form} = search_terms(params["search"] || %{})
31+
search = Search.from_params(params["search"] || %{})
2832

2933
path_w_filters = %URI{socket.assigns.path | query: URI.encode_query(search)}
3034

@@ -109,15 +113,6 @@ defmodule ErrorTracker.Web.Live.Dashboard do
109113
)
110114
end
111115

112-
defp search_terms(params) do
113-
data = %{}
114-
types = %{reason: :string, source_line: :string, source_function: :string, status: :string}
115-
116-
changeset = Ecto.Changeset.cast({data, types}, params, Map.keys(types))
117-
118-
{Ecto.Changeset.apply_changes(changeset), to_form(changeset, as: :search)}
119-
end
120-
121116
defp filter(query, search) do
122117
Enum.reduce(search, query, &do_filter/2)
123118
end

lib/error_tracker/web/live/dashboard.html.heex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
class="border-b bg-gray-400/10 border-y border-gray-900 hover:bg-gray-800/60 last-of-type:border-b-0"
6464
>
6565
<td scope="row" class="px-4 py-4 font-medium text-white relative">
66-
<.link navigate={error_path(@socket, error)} class="absolute inset-1">
66+
<.link navigate={error_path(@socket, error, @search)} class="absolute inset-1">
6767
<span class="sr-only">(<%= sanitize_module(error.kind) %>) <%= error.reason %></span>
6868
</.link>
6969
<p class="whitespace-nowrap text-ellipsis overflow-hidden">

lib/error_tracker/web/live/show.ex

Lines changed: 30 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,52 +7,55 @@ defmodule ErrorTracker.Web.Live.Show do
77
alias ErrorTracker.Error
88
alias ErrorTracker.Occurrence
99
alias ErrorTracker.Repo
10+
alias ErrorTracker.Web.Search
1011

1112
@occurrences_to_navigate 50
1213

1314
@impl Phoenix.LiveView
14-
def mount(%{"id" => id}, _session, socket) do
15+
def mount(params = %{"id" => id}, _session, socket) do
1516
error = Repo.get!(Error, id)
16-
{:ok, assign(socket, error: error, app: Application.fetch_env!(:error_tracker, :otp_app))}
17+
18+
{:ok,
19+
assign(socket,
20+
error: error,
21+
app: Application.fetch_env!(:error_tracker, :otp_app),
22+
search: Search.from_params(params)
23+
)}
1724
end
1825

1926
@impl Phoenix.LiveView
20-
def handle_params(%{"occurrence_id" => occurrence_id}, _uri, socket) do
27+
def handle_params(params, _uri, socket) do
2128
occurrence =
22-
socket.assigns.error
23-
|> Ecto.assoc(:occurrences)
24-
|> Repo.get!(occurrence_id)
25-
26-
socket =
27-
socket
28-
|> assign(:occurrence, occurrence)
29-
|> load_related_occurrences()
30-
31-
{:noreply, socket}
32-
end
33-
34-
def handle_params(_, _uri, socket) do
35-
[occurrence] =
36-
socket.assigns.error
37-
|> Ecto.assoc(:occurrences)
38-
|> order_by([o], desc: o.id)
39-
|> limit(1)
40-
|> Repo.all()
29+
if occurrence_id = params["occurrence_id"] do
30+
socket.assigns.error
31+
|> Ecto.assoc(:occurrences)
32+
|> Repo.get!(occurrence_id)
33+
else
34+
socket.assigns.error
35+
|> Ecto.assoc(:occurrences)
36+
|> order_by([o], desc: o.id)
37+
|> limit(1)
38+
|> Repo.one()
39+
end
4140

4241
socket =
4342
socket
44-
|> assign(:occurrence, occurrence)
43+
|> assign(occurrence: occurrence)
4544
|> load_related_occurrences()
4645

4746
{:noreply, socket}
4847
end
4948

5049
@impl Phoenix.LiveView
5150
def handle_event("occurrence_navigation", %{"occurrence_id" => id}, socket) do
52-
{:noreply,
53-
push_patch(socket,
54-
to: occurrence_path(socket, %Occurrence{error_id: socket.assigns.error.id, id: id})
55-
)}
51+
occurrence_path =
52+
occurrence_path(
53+
socket,
54+
%Occurrence{error_id: socket.assigns.error.id, id: id},
55+
socket.assigns.search
56+
)
57+
58+
{:noreply, push_patch(socket, to: occurrence_path)}
5659
end
5760

5861
@impl Phoenix.LiveView

lib/error_tracker/web/live/show.html.heex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<div class="my-6">
2-
<.button type="link" href={dashboard_path(@socket)}>« Back to the dashboard</.button>
2+
<.button type="link" href={dashboard_path(@socket, @search)}>« Back to the dashboard</.button>
33
</div>
44

55
<div id="header">

lib/error_tracker/web/router/routes.ex

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,36 @@ defmodule ErrorTracker.Web.Router.Routes do
88
@doc """
99
Returns the dashboard path
1010
"""
11-
def dashboard_path(socket = %Socket{}) do
12-
socket.private[:dashboard_path]
11+
def dashboard_path(socket = %Socket{}, params \\ %{}) do
12+
socket
13+
|> dashboard_uri(params)
14+
|> URI.to_string()
1315
end
1416

1517
@doc """
1618
Returns the path to see the details of an error
1719
"""
18-
def error_path(socket = %Socket{}, %Error{id: id}) do
19-
dashboard_path(socket) <> "/#{id}"
20+
def error_path(socket = %Socket{}, %Error{id: id}, params \\ %{}) do
21+
socket
22+
|> dashboard_uri(params)
23+
|> URI.append_path("/#{id}")
24+
|> URI.to_string()
2025
end
2126

2227
@doc """
2328
Returns the path to see the details of an occurrence
2429
"""
25-
def occurrence_path(socket = %Socket{}, %Occurrence{id: id, error_id: error_id}) do
26-
dashboard_path(socket) <> "/#{error_id}/#{id}"
30+
def occurrence_path(socket = %Socket{}, %Occurrence{id: id, error_id: error_id}, params \\ %{}) do
31+
socket
32+
|> dashboard_uri(params)
33+
|> URI.append_path("/#{error_id}/#{id}")
34+
|> URI.to_string()
35+
end
36+
37+
defp dashboard_uri(socket = %Socket{}, params) do
38+
%URI{
39+
path: socket.private[:dashboard_path],
40+
query: if(Enum.any?(params), do: URI.encode_query(params))
41+
}
2742
end
2843
end

lib/error_tracker/web/search.ex

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
defmodule ErrorTracker.Web.Search do
2+
@moduledoc false
3+
4+
@types %{
5+
reason: :string,
6+
source_line: :string,
7+
source_function: :string,
8+
status: :string
9+
}
10+
11+
defp changeset(params) do
12+
Ecto.Changeset.cast({%{}, @types}, params, Map.keys(@types))
13+
end
14+
15+
@spec from_params(map()) :: %{atom() => String.t()}
16+
def from_params(params) do
17+
params |> changeset() |> Ecto.Changeset.apply_changes()
18+
end
19+
20+
@spec to_form(map()) :: Phoenix.HTML.Form.t()
21+
def to_form(params) do
22+
params |> changeset() |> Phoenix.Component.to_form(as: :search)
23+
end
24+
end

0 commit comments

Comments
 (0)