Skip to content

Commit

Permalink
feat: display shape on map in shuttle definition pages
Browse files Browse the repository at this point in the history
  • Loading branch information
Whoops committed Nov 13, 2024
1 parent c48ea51 commit 3e2d75b
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 7 deletions.
8 changes: 8 additions & 0 deletions lib/arrow/shuttles.ex
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,14 @@ defmodule Arrow.Shuttles do
"""
def get_shape!(id), do: Repo.get!(Shape, id)

@doc """
Gets the shapes specifiied by a list of ids. Does not raise if any of the ids are missing,
meaning the resulting list may be shorter than the input list.
"""
def get_shapes(ids) do
Repo.all(from s in Shape, where: s.id in ^ids)
end

@doc """
Gets a shapes upload struct associated with a given shape.
Expand Down
55 changes: 49 additions & 6 deletions lib/arrow_web/live/shuttle_live/shuttle_live.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ defmodule ArrowWeb.ShuttleViewLive do
import Phoenix.HTML.Form
alias Arrow.Shuttles
alias Arrow.Shuttles.Shuttle
alias ArrowWeb.ShapeView

embed_templates "shuttle_live/*"

Expand All @@ -14,6 +15,7 @@ defmodule ArrowWeb.ShuttleViewLive do
attr :http_action, :string
attr :gtfs_disruptable_routes, :list, required: true
attr :shapes, :list, required: true
attr :map_props, :map, required: false, default: %{}

def shuttle_form(assigns) do
~H"""
Expand Down Expand Up @@ -60,6 +62,7 @@ defmodule ArrowWeb.ShuttleViewLive do
/>
</div>
</div>
<%= live_react_component("Components.ShapeViewMap", @map_props, id: "shuttle-view-map") %>
<hr />
<h2>define route</h2>
<.inputs_for :let={f_route} field={f[:routes]}>
Expand Down Expand Up @@ -107,6 +110,14 @@ defmodule ArrowWeb.ShuttleViewLive do
"""
end

defp shapes_to_shapeviews(shapes) do
shapes
|> Enum.map(&Shuttles.get_shapes_upload/1)
|> Enum.reject(&(&1 == {:ok, :disabled}))
|> Enum.map(&ShapeView.shapes_map_view/1)
|> Enum.map(&List.first(&1.shapes))
end

def mount(%{"id" => id} = _params, session, socket) do
logout_url = session["logout_url"]
shuttle = Shuttles.get_shuttle!(id)
Expand All @@ -115,6 +126,14 @@ defmodule ArrowWeb.ShuttleViewLive do
shapes = Shuttles.list_shapes()
form = to_form(changeset)

shuttle_shapes =
shuttle
|> Map.get(:routes)
|> Enum.map(&Map.get(&1, :shape))
|> Enum.reject(&is_nil/1)

shapes_map_view = shapes_to_shapeviews(shuttle_shapes)

socket =
socket
|> assign(:form, form)
Expand All @@ -125,6 +144,7 @@ defmodule ArrowWeb.ShuttleViewLive do
|> assign(:gtfs_disruptable_routes, gtfs_disruptable_routes)
|> assign(:shapes, shapes)
|> assign(:logout_url, logout_url)
|> assign(:map_props, %{shapes: shapes_map_view})

{:ok, socket}
end
Expand All @@ -151,17 +171,31 @@ defmodule ArrowWeb.ShuttleViewLive do
|> assign(:gtfs_disruptable_routes, gtfs_disruptable_routes)
|> assign(:shapes, shapes)
|> assign(:logout_url, logout_url)
|> assign(:map_props, %{shapes: []})

{:ok, socket}
end

def handle_event("validate", %{"shuttle" => shuttle_params}, socket) do
form =
socket.assigns.shuttle
|> Shuttles.change_shuttle(shuttle_params)
|> to_form(action: :validate)
# A new shape is selected
def handle_event(
"validate",
%{"_target" => ["shuttle", "routes", _direction_id, "shape_id"]} = params,
socket
) do
shapes =
[
params["shuttle"]["routes"]["0"]["shape_id"],
params["shuttle"]["routes"]["1"]["shape_id"]
]
|> Enum.reject(&(&1 == ""))
|> Shuttles.get_shapes()
|> shapes_to_shapeviews()

validate(params, assign(socket, :map_props, %{socket.assigns.map_props | shapes: shapes}))
end

{:noreply, assign(socket, form: form)}
def handle_event("validate", params, socket) do
validate(params, socket)
end

def handle_event("edit", %{"shuttle" => shuttle_params}, socket) do
Expand Down Expand Up @@ -191,4 +225,13 @@ defmodule ArrowWeb.ShuttleViewLive do
{:noreply, assign(socket, form: to_form(changeset))}
end
end

defp validate(%{"shuttle" => shuttle_params}, socket) do
form =
socket.assigns.shuttle
|> Shuttles.change_shuttle(shuttle_params)
|> to_form(action: :validate)

{:noreply, assign(socket, form: form)}
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
http_action={@http_action}
gtfs_disruptable_routes={@gtfs_disruptable_routes}
shapes={@shapes}
map_props={@map_props}
/>

<.back navigate={~p"/shuttles"}>Back to shuttles</.back>
13 changes: 12 additions & 1 deletion test/arrow/shuttles_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ defmodule Arrow.ShuttlesTest do
end

test "create_shape/1 with name that does not end in -S adds it" do
Application.put_env(:arrow, :shape_storage_enabled?, true)
reassign_env(:shape_storage_enabled?, true)
Application.put_env(:arrow, :shape_storage_prefix, "prefix/#{Ecto.UUID.generate()}/")

assert {:ok, %Shape{} = shape} =
Expand Down Expand Up @@ -62,6 +62,17 @@ defmodule Arrow.ShuttlesTest do
assert Shuttles.get_shape!(shape.id) == shape
end

test "get_shapes returns all shapes with matching ids" do
shapes = [shape_fixture(), shape_fixture()]
shape_ids = Enum.map(shapes, fn shape -> shape.id end)
assert MapSet.new(Shuttles.get_shapes(shape_ids)) == MapSet.new(shapes)
end

test "get_shapes returns empty list when no shapes match" do
shape_ids = [1, 2, 3]
assert [] == Shuttles.get_shapes(shape_ids)
end

test "create_shapes/1 with valid data creates a shape" do
assert {:ok, [{:ok, %Shape{} = shape}]} = Shuttles.create_shapes([@valid_attrs])
assert shape.name == "some name-S"
Expand Down

0 comments on commit 3e2d75b

Please sign in to comment.