diff --git a/lib/arrow/stops.ex b/lib/arrow/stops.ex index 8b834cdd..de4ec990 100644 --- a/lib/arrow/stops.ex +++ b/lib/arrow/stops.ex @@ -17,8 +17,12 @@ defmodule Arrow.Stops do [%Stop{}, ...] """ - def list_stops do - Repo.all(Stop) + def list_stops(params \\ %{}) do + from( + s in Stop, + order_by: ^order_by(params["order_by"]) + ) + |> Repo.all() end @doc """ @@ -101,4 +105,36 @@ defmodule Arrow.Stops do def change_stop(%Stop{} = stop, attrs \\ %{}) do Stop.changeset(stop, attrs) end + + defp order_by("stop_id_desc"), do: [desc: :stop_id] + defp order_by("stop_id_asc"), do: [asc: :stop_id] + defp order_by("stop_name_desc"), do: [desc: :stop_name] + defp order_by("stop_name_asc"), do: [asc: :stop_name] + defp order_by("stop_desc_desc"), do: [desc: :stop_desc] + defp order_by("stop_desc_asc"), do: [asc: :stop_desc] + defp order_by("platform_code_desc"), do: [desc: :platform_code] + defp order_by("platform_code_asc"), do: [asc: :platform_code] + defp order_by("platform_name_desc"), do: [desc: :platform_name] + defp order_by("platform_name_asc"), do: [asc: :platform_name] + defp order_by("stop_lat_desc"), do: [desc: :stop_lat] + defp order_by("stop_lat_asc"), do: [asc: :stop_lat] + defp order_by("stop_lon_desc"), do: [desc: :stop_lon] + defp order_by("stop_lon_asc"), do: [asc: :stop_lon] + defp order_by("stop_address_desc"), do: [desc: :stop_address] + defp order_by("stop_address_asc"), do: [asc: :stop_address] + defp order_by("zone_id_desc"), do: [desc: :zone_id] + defp order_by("zone_id_asc"), do: [asc: :zone_id] + defp order_by("level_id_desc"), do: [desc: :level_id] + defp order_by("level_id_asc"), do: [asc: :level_id] + defp order_by("parent_station_desc"), do: [desc: :parent_station] + defp order_by("parent_station_asc"), do: [asc: :parent_station] + defp order_by("municipality_desc"), do: [desc: :municipality] + defp order_by("municipality_asc"), do: [asc: :municipality] + defp order_by("on_street_desc"), do: [desc: :on_street] + defp order_by("on_street_asc"), do: [asc: :on_street] + defp order_by("at_street_desc"), do: [desc: :at_street] + defp order_by("at_street_asc"), do: [asc: :at_street] + defp order_by("updated_at_desc"), do: [desc: :updated_at] + defp order_by("updated_at_asc"), do: [asc: :updated_at] + defp order_by(_), do: [] end diff --git a/lib/arrow_web/components/core_components.ex b/lib/arrow_web/components/core_components.ex index 3c4b7022..843d12f3 100644 --- a/lib/arrow_web/components/core_components.ex +++ b/lib/arrow_web/components/core_components.ex @@ -473,6 +473,7 @@ defmodule ArrowWeb.CoreComponents do slot :col, required: true do attr :label, :string + attr :link, :string end slot :action, doc: "the slot for showing user actions in the last table column" @@ -488,7 +489,20 @@ defmodule ArrowWeb.CoreComponents do - + diff --git a/lib/arrow_web/controllers/stop_controller.ex b/lib/arrow_web/controllers/stop_controller.ex index b164eb45..da4dbc67 100644 --- a/lib/arrow_web/controllers/stop_controller.ex +++ b/lib/arrow_web/controllers/stop_controller.ex @@ -6,9 +6,9 @@ defmodule ArrowWeb.StopController do alias Plug.Conn @spec index(Conn.t(), Conn.params()) :: Conn.t() - def index(conn, _params) do - stops = Stops.list_stops() - render(conn, :index, stops: stops) + def index(conn, params) do + stops = Stops.list_stops(params) + render(conn, :index, stops: stops, order_by: Map.get(params, "order_by")) end @spec new(Conn.t(), Conn.params()) :: Conn.t() diff --git a/lib/arrow_web/controllers/stop_html.ex b/lib/arrow_web/controllers/stop_html.ex index 26a0da33..1c52a0aa 100644 --- a/lib/arrow_web/controllers/stop_html.ex +++ b/lib/arrow_web/controllers/stop_html.ex @@ -16,4 +16,14 @@ defmodule ArrowWeb.StopView do |> DateTime.shift_zone!("America/New_York") |> Calendar.strftime("%Y-%m-%d %I:%M %p") end + + def sort_link(nil, field), do: ~p"/stops?#{%{order_by: "#{field}_desc"}}" + + def sort_link(sort_by, field) do + if sort_by == "#{field}_desc" do + ~p"/stops?#{%{order_by: "#{field}_asc"}}" + else + ~p"/stops?#{%{order_by: "#{field}_desc"}}" + end + end end diff --git a/lib/arrow_web/controllers/stop_html/index.html.heex b/lib/arrow_web/controllers/stop_html/index.html.heex index 18ff4685..48db27f4 100644 --- a/lib/arrow_web/controllers/stop_html/index.html.heex +++ b/lib/arrow_web/controllers/stop_html/index.html.heex @@ -8,21 +8,21 @@ <.table id="stops" rows={@stops} row_click={&JS.navigate(~p"/stops/#{&1}")}> - <:col :let={stop} label="Stop"><%= stop.stop_id %> - <:col :let={stop} label="Stop name"><%= stop.stop_name %> - <:col :let={stop} label="Stop desc"><%= stop.stop_desc %> - <:col :let={stop} label="Platform code"><%= stop.platform_code %> - <:col :let={stop} label="Platform name"><%= stop.platform_name %> - <:col :let={stop} label="Stop lat"><%= stop.stop_lat %> - <:col :let={stop} label="Stop long"><%= stop.stop_lon %> - <:col :let={stop} label="Stop address"><%= stop.stop_address %> - <:col :let={stop} label="Zone"><%= stop.zone_id %> - <:col :let={stop} label="Level"><%= stop.level_id %> - <:col :let={stop} label="Parent station"><%= stop.parent_station %> - <:col :let={stop} label="Municipality"><%= stop.municipality %> - <:col :let={stop} label="On street"><%= stop.on_street %> - <:col :let={stop} label="At street"><%= stop.at_street %> - <:col :let={stop} label="Last updated"><%= format_timestamp(stop.updated_at) %> + <:col :let={stop} label="Stop" link={sort_link(@order_by, "stop_id")}><%= stop.stop_id %> + <:col :let={stop} label="Stop name" link={sort_link(@order_by, "stop_name")}><%= stop.stop_name %> + <:col :let={stop} label="Stop desc" link={sort_link(@order_by, "stop_desc")}><%= stop.stop_desc %> + <:col :let={stop} label="Platform code" link={sort_link(@order_by, "platform_code")}><%= stop.platform_code %> + <:col :let={stop} label="Platform name" link={sort_link(@order_by, "platform_name")}><%= stop.platform_name %> + <:col :let={stop} label="Stop lat" link={sort_link(@order_by, "stop_lat")}><%= stop.stop_lat %> + <:col :let={stop} label="Stop long" link={sort_link(@order_by, "stop_lon")}><%= stop.stop_lon %> + <:col :let={stop} label="Stop address" link={sort_link(@order_by, "stop_address")}><%= stop.stop_address %> + <:col :let={stop} label="Zone" link={sort_link(@order_by, "zone_id")}><%= stop.zone_id %> + <:col :let={stop} label="Level" link={sort_link(@order_by, "level_id")}><%= stop.level_id %> + <:col :let={stop} label="Parent station" link={sort_link(@order_by, "parent_station")}><%= stop.parent_station %> + <:col :let={stop} label="Municipality" link={sort_link(@order_by, "municipality")}><%= stop.municipality %> + <:col :let={stop} label="On street" link={sort_link(@order_by, "on_street")}><%= stop.on_street %> + <:col :let={stop} label="At street" link={sort_link(@order_by, "at_street")}><%= stop.at_street %> + <:col :let={stop} label="Last updated" link={sort_link(@order_by, "updated_at")}><%= format_timestamp(stop.updated_at) %> <:action :let={stop}>
<.link navigate={~p"/stops/#{stop}"}>Show diff --git a/test/arrow/stops_test.exs b/test/arrow/stops_test.exs index 64c20cc9..a40dd1b3 100644 --- a/test/arrow/stops_test.exs +++ b/test/arrow/stops_test.exs @@ -31,6 +31,13 @@ defmodule Arrow.StopsTest do assert Stops.list_stops() == [stop] end + test "list_stops/1 returns all stops sorted by order_by param" do + stop_a = stop_fixture(%{stop_name: "Stop A"}) + stop_z = stop_fixture(%{stop_name: "Stop Z"}) + assert Stops.list_stops(%{"order_by" => "stop_name_desc"}) == [stop_z, stop_a] + assert Stops.list_stops(%{"order_by" => "stop_name_asc"}) == [stop_a, stop_z] + end + test "get_stop!/1 returns the stop with given id" do stop = stop_fixture() assert Stops.get_stop!(stop.id) == stop
<%= col[:label] %> + <%= if col[:link] do %> + <.link href={col[:link]}> + <%= if String.ends_with?(col[:link], "desc") do %> + <.icon name="hero-bars-arrow-down" class="h-4 w-4" /> + <% else %> + <.icon name="hero-bars-arrow-up" class="h-4 w-4" /> + <% end %> + <%= col[:label] %> + + <% else %> + <%= col[:label] %> + <% end %> + <%= gettext("Actions") %>