From beda60418f866584b6cdf886670a5954db1f0dce Mon Sep 17 00:00:00 2001 From: crbelaus Date: Wed, 26 Mar 2025 18:18:08 +0100 Subject: [PATCH 1/3] 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. --- lib/error_tracker/web/live/dashboard.ex | 21 +++---- .../web/live/dashboard.html.heex | 2 +- lib/error_tracker/web/live/show.ex | 57 ++++++++++--------- lib/error_tracker/web/live/show.html.heex | 2 +- lib/error_tracker/web/router/routes.ex | 27 +++++++-- lib/error_tracker/web/search.ex | 24 ++++++++ 6 files changed, 85 insertions(+), 48 deletions(-) create mode 100644 lib/error_tracker/web/search.ex diff --git a/lib/error_tracker/web/live/dashboard.ex b/lib/error_tracker/web/live/dashboard.ex index da66a31..f372fed 100644 --- a/lib/error_tracker/web/live/dashboard.ex +++ b/lib/error_tracker/web/live/dashboard.ex @@ -7,24 +7,28 @@ defmodule ErrorTracker.Web.Live.Dashboard do alias ErrorTracker.Error alias ErrorTracker.Repo + alias ErrorTracker.Web.Search @per_page 10 @impl Phoenix.LiveView def handle_params(params, uri, socket) do - {search, search_form} = search_terms(params) - path = struct(URI, uri |> URI.parse() |> Map.take([:path, :query])) {:noreply, socket - |> assign(path: path, search: search, page: 1, search_form: search_form) + |> assign( + path: path, + search: Search.from_params(params), + page: 1, + search_form: Search.to_form(params) + ) |> paginate_errors()} end @impl Phoenix.LiveView def handle_event("search", params, socket) do - {search, _search_form} = search_terms(params["search"] || %{}) + search = Search.from_params(params["search"] || %{}) path_w_filters = %URI{socket.assigns.path | query: URI.encode_query(search)} @@ -109,15 +113,6 @@ defmodule ErrorTracker.Web.Live.Dashboard do ) end - defp search_terms(params) do - data = %{} - types = %{reason: :string, source_line: :string, source_function: :string, status: :string} - - changeset = Ecto.Changeset.cast({data, types}, params, Map.keys(types)) - - {Ecto.Changeset.apply_changes(changeset), to_form(changeset, as: :search)} - end - defp filter(query, search) do Enum.reduce(search, query, &do_filter/2) end diff --git a/lib/error_tracker/web/live/dashboard.html.heex b/lib/error_tracker/web/live/dashboard.html.heex index 77474cc..b9f76ae 100644 --- a/lib/error_tracker/web/live/dashboard.html.heex +++ b/lib/error_tracker/web/live/dashboard.html.heex @@ -63,7 +63,7 @@ class="border-b bg-gray-400/10 border-y border-gray-900 hover:bg-gray-800/60 last-of-type:border-b-0" > - <.link navigate={error_path(@socket, error)} class="absolute inset-1"> + <.link navigate={error_path(@socket, error, @search)} class="absolute inset-1"> (<%= sanitize_module(error.kind) %>) <%= error.reason %>

diff --git a/lib/error_tracker/web/live/show.ex b/lib/error_tracker/web/live/show.ex index c39d347..7a54b2e 100644 --- a/lib/error_tracker/web/live/show.ex +++ b/lib/error_tracker/web/live/show.ex @@ -7,41 +7,40 @@ defmodule ErrorTracker.Web.Live.Show do alias ErrorTracker.Error alias ErrorTracker.Occurrence alias ErrorTracker.Repo + alias ErrorTracker.Web.Search @occurrences_to_navigate 50 @impl Phoenix.LiveView - def mount(%{"id" => id}, _session, socket) do + def mount(params = %{"id" => id}, _session, socket) do error = Repo.get!(Error, id) - {:ok, assign(socket, error: error, app: Application.fetch_env!(:error_tracker, :otp_app))} + + {:ok, + assign(socket, + error: error, + app: Application.fetch_env!(:error_tracker, :otp_app), + search: Search.from_params(params) + )} end @impl Phoenix.LiveView - def handle_params(%{"occurrence_id" => occurrence_id}, _uri, socket) do + def handle_params(params, _uri, socket) do occurrence = - socket.assigns.error - |> Ecto.assoc(:occurrences) - |> Repo.get!(occurrence_id) - - socket = - socket - |> assign(:occurrence, occurrence) - |> load_related_occurrences() - - {:noreply, socket} - end - - def handle_params(_, _uri, socket) do - [occurrence] = - socket.assigns.error - |> Ecto.assoc(:occurrences) - |> order_by([o], desc: o.id) - |> limit(1) - |> Repo.all() + if occurrence_id = params["occurrence_id"] do + socket.assigns.error + |> Ecto.assoc(:occurrences) + |> Repo.get!(occurrence_id) + else + socket.assigns.error + |> Ecto.assoc(:occurrences) + |> order_by([o], desc: o.id) + |> limit(1) + |> Repo.one() + end socket = socket - |> assign(:occurrence, occurrence) + |> assign(occurrence: occurrence) |> load_related_occurrences() {:noreply, socket} @@ -49,10 +48,14 @@ defmodule ErrorTracker.Web.Live.Show do @impl Phoenix.LiveView def handle_event("occurrence_navigation", %{"occurrence_id" => id}, socket) do - {:noreply, - push_patch(socket, - to: occurrence_path(socket, %Occurrence{error_id: socket.assigns.error.id, id: id}) - )} + occurrence_path = + occurrence_path( + socket, + %Occurrence{error_id: socket.assigns.error.id, id: id}, + socket.assigns.search + ) + + {:noreply, push_patch(socket, to: occurrence_path)} end @impl Phoenix.LiveView diff --git a/lib/error_tracker/web/live/show.html.heex b/lib/error_tracker/web/live/show.html.heex index c72ddb4..38e1b42 100644 --- a/lib/error_tracker/web/live/show.html.heex +++ b/lib/error_tracker/web/live/show.html.heex @@ -1,5 +1,5 @@

- <.button type="link" href={dashboard_path(@socket)}>« Back to the dashboard + <.button type="link" href={dashboard_path(@socket, @search)}>« Back to the dashboard