Building a Custom Page for Phoenix Live Dashboard

2 min read Original article ↗

We can now focus on implementing search, sorting and limits. Conceptually, we need to:

  • If specified, apply the search filter.
  • Always apply sort order.
  • Count the sorted elements, to return the correct total.
  • Always apply the limit clause to the sorted elements.

All of these operations have to be handled by the implementation of the row_fetcher function.

The params map has the following keys:

  • :search: the string representing the contents of the search input (or nil when empty).
  • :sort_by: the id of the column to sort by.
  • :sort_dir: the sort direction, expressed with the atoms :asc and :desc.
  • :limit: the integer value representing the amount of max items requested by the user.

The params map is very well thought out, as it has a fixed structure, applied defaults where available and values that play well with functions from the Enum module.

We can extend the fetch_sessions/2 function as follows:

defmodule TuneWeb.LiveDashboard.SpotifySessionsPage do
  # omitted

  defp fetch_sessions(params, _node) do
    sessions =
      Tune.Spotify.Supervisor.sessions()
      |> filter(params)

    {Enum.take(sessions, params[:limit]), length(sessions)}
  end

  defp filter(sessions, params) do
    sessions
    |> Enum.filter(fn session -> session_match?(session, params[:search]) end)
    |> Enum.sort_by(fn session -> session[params[:sort_by]] end, params[:sort_dir])
  end

  defp session_match?(_session, nil), do: true
  defp session_match?(session, search_string), do: String.contains?(session[:id], search_string)
end

As outlined above, we start by filtering by search, using a very simple logic that just checks if the session ID contains the searched string.

After search, we apply the sorting logic: the values of the :sort_by and :sort_dir perfectly fit using Enum.sort_by/3 (a really appreciated API design choice), making the implementation short and sweet.

When defining the returning tuple, we take care of applying the limit and returning the correct total count.

With these changes in place, the generated table behaves as expected:

A screenshot of the Spotify sessions table built in this blog post