From 73986a839ef1719bf5ea79af2a9550ff7d55764b Mon Sep 17 00:00:00 2001 From: Eddie Maldonado Date: Thu, 31 Oct 2024 11:20:04 -0400 Subject: [PATCH] wip: migrate shuttle page to LiveView --- .../controllers/shuttle_controller.ex | 73 ------- lib/arrow_web/controllers/shuttle_html.ex | 10 - .../controllers/shuttle_html/edit.html.heex | 12 -- .../shuttle_html/shuttle_form.html.heex | 80 -------- .../live/shuttle_live/shuttle_live.ex | 180 ++++++++++++++++++ .../shuttle_live/shuttle_view_live.html.heex} | 7 +- lib/arrow_web/router.ex | 5 +- 7 files changed, 188 insertions(+), 179 deletions(-) delete mode 100644 lib/arrow_web/controllers/shuttle_html/edit.html.heex delete mode 100644 lib/arrow_web/controllers/shuttle_html/shuttle_form.html.heex create mode 100644 lib/arrow_web/live/shuttle_live/shuttle_live.ex rename lib/arrow_web/{controllers/shuttle_html/new.html.heex => live/shuttle_live/shuttle_view_live.html.heex} (66%) diff --git a/lib/arrow_web/controllers/shuttle_controller.ex b/lib/arrow_web/controllers/shuttle_controller.ex index 587ddad1..14120d55 100644 --- a/lib/arrow_web/controllers/shuttle_controller.ex +++ b/lib/arrow_web/controllers/shuttle_controller.ex @@ -2,87 +2,14 @@ defmodule ArrowWeb.ShuttleController do use ArrowWeb, :controller alias Arrow.Shuttles - alias Arrow.Shuttles.Shuttle def index(conn, _params) do shuttles = Shuttles.list_shuttles() render(conn, :index, shuttles: shuttles) end - def new(conn, _params) do - changeset = - Shuttles.change_shuttle(%Shuttle{ - status: :draft, - routes: [%Shuttles.Route{direction_id: :"0"}, %Shuttles.Route{direction_id: :"1"}] - }) - - gtfs_disruptable_routes = Shuttles.list_disruptable_routes() - shapes = Shuttles.list_shapes() - - render(conn, :new, - changeset: changeset, - gtfs_disruptable_routes: gtfs_disruptable_routes, - shapes: shapes - ) - end - - def create(conn, %{"shuttle" => shuttle_params}) do - case Shuttles.create_shuttle(shuttle_params) do - {:ok, shuttle} -> - conn - |> put_flash(:info, "Shuttle created successfully.") - |> redirect(to: ~p"/shuttles/#{shuttle}") - - {:error, %Ecto.Changeset{} = changeset} -> - gtfs_disruptable_routes = Shuttles.list_disruptable_routes() - shapes = Shuttles.list_shapes() - - render(conn, :new, - changeset: changeset, - gtfs_disruptable_routes: gtfs_disruptable_routes, - shapes: shapes - ) - end - end - def show(conn, %{"id" => id}) do shuttle = Shuttles.get_shuttle!(id) render(conn, :show, shuttle: shuttle) end - - def edit(conn, %{"id" => id}) do - shuttle = Shuttles.get_shuttle!(id) - changeset = Shuttles.change_shuttle(shuttle) - gtfs_disruptable_routes = Shuttles.list_disruptable_routes() - shapes = Shuttles.list_shapes() - - render(conn, :edit, - shuttle: shuttle, - changeset: changeset, - gtfs_disruptable_routes: gtfs_disruptable_routes, - shapes: shapes - ) - end - - def update(conn, %{"id" => id, "shuttle" => shuttle_params}) do - shuttle = Shuttles.get_shuttle!(id) - - case Shuttles.update_shuttle(shuttle, shuttle_params) do - {:ok, shuttle} -> - conn - |> put_flash(:info, "Shuttle updated successfully.") - |> redirect(to: ~p"/shuttles/#{shuttle}") - - {:error, %Ecto.Changeset{} = changeset} -> - gtfs_disruptable_routes = Shuttles.list_disruptable_routes() - shapes = Shuttles.list_shapes() - - render(conn, :edit, - shuttle: shuttle, - changeset: changeset, - gtfs_disruptable_routes: gtfs_disruptable_routes, - shapes: shapes - ) - end - end end diff --git a/lib/arrow_web/controllers/shuttle_html.ex b/lib/arrow_web/controllers/shuttle_html.ex index de4bbcf2..4f1d79dd 100644 --- a/lib/arrow_web/controllers/shuttle_html.ex +++ b/lib/arrow_web/controllers/shuttle_html.ex @@ -2,14 +2,4 @@ defmodule ArrowWeb.ShuttleView do use ArrowWeb, :html embed_templates "shuttle_html/*" - - @doc """ - Renders a shuttle form. - """ - attr :changeset, Ecto.Changeset, required: true - attr :action, :string, required: true - attr :gtfs_disruptable_routes, :list, required: true - attr :shapes, :list, required: true - - def shuttle_form(assigns) end diff --git a/lib/arrow_web/controllers/shuttle_html/edit.html.heex b/lib/arrow_web/controllers/shuttle_html/edit.html.heex deleted file mode 100644 index 76e66294..00000000 --- a/lib/arrow_web/controllers/shuttle_html/edit.html.heex +++ /dev/null @@ -1,12 +0,0 @@ -<.header> - edit shuttle <%= @shuttle.id %> - - -<.shuttle_form - changeset={@changeset} - action={~p"/shuttles/#{@shuttle}"} - gtfs_disruptable_routes={@gtfs_disruptable_routes} - shapes={@shapes} -/> - -<.back navigate={~p"/shuttles"}>Back to shuttles diff --git a/lib/arrow_web/controllers/shuttle_html/shuttle_form.html.heex b/lib/arrow_web/controllers/shuttle_html/shuttle_form.html.heex deleted file mode 100644 index 0cfcd2fb..00000000 --- a/lib/arrow_web/controllers/shuttle_html/shuttle_form.html.heex +++ /dev/null @@ -1,80 +0,0 @@ -<.simple_form :let={f} for={@changeset} action={@action}> -
- - View Shuttle Definition Conventions - -
- <.error :if={@changeset.action}> - Oops, something went wrong! Please check the errors below. - -
-
- <.input field={f[:shuttle_name]} type="text" label="Shuttle Name" /> -
-
- <.input - field={f[:disrupted_route_id]} - type="select" - label="Disrupted Route" - prompt="Choose a route" - options={Enum.map(@gtfs_disruptable_routes, &{&1.long_name, &1.id})} - /> -
-
- <.input - field={f[:status]} - type="select" - label="Status" - prompt="Choose a value" - options={Ecto.Enum.values(Arrow.Shuttles.Shuttle, :status)} - /> -
-
-
-

define route

- <.inputs_for :let={f_route} field={f[:routes]}> -

direction <%= input_value(f_route, :direction_id) %>

-
- -
- <.input field={f_route[:direction_desc]} type="text" label="Direction desc" /> -
-
- <.input - field={f_route[:shape_id]} - type="select" - label="Shape" - prompt="Choose a shape" - options={Enum.map(@shapes, &{&1.name, &1.id})} - /> -
-
-
-
- <.input field={f_route[:destination]} type="text" label="Destination" /> -
-
-
- via -
-
-
- <.input field={f_route[:waypoint]} type="text" label="Waypoint" /> -
-
-
-
- <.input field={f_route[:suffix]} type="text" label="Suffix" /> -
-
- - <:actions> - <.button>Save Shuttle - - diff --git a/lib/arrow_web/live/shuttle_live/shuttle_live.ex b/lib/arrow_web/live/shuttle_live/shuttle_live.ex new file mode 100644 index 00000000..1f214857 --- /dev/null +++ b/lib/arrow_web/live/shuttle_live/shuttle_live.ex @@ -0,0 +1,180 @@ +defmodule ArrowWeb.ShuttleViewLive do + use ArrowWeb, :live_view + import Phoenix.HTML.Form + alias Arrow.Shuttles + alias Arrow.Shuttles.Shuttle + + embed_templates "shuttle_live/*" + + @doc """ + Renders a shuttle route form + """ + attr :form, :any, required: true + attr :action, :string, required: true + attr :http_action, :string + attr :gtfs_disruptable_routes, :list, required: true + attr :shapes, :list, required: true + + def shuttle_form(assigns) do + ~H""" + <.simple_form :let={f} for={@form} as={:shuttle_route} action={@http_action} phx-submit={@action}> +
+ + View Shuttle Definition Conventions + +
+ <.error :if={@form.action}> + Oops, something went wrong! Please check the errors below. + +
+
+ <.input field={f[:shuttle_name]} type="text" label="Shuttle Name" /> +
+
+ <.input + field={f[:disrupted_route_id]} + type="select" + label="Disrupted Route" + prompt="Choose a route" + options={Enum.map(@gtfs_disruptable_routes, &{&1.long_name, &1.id})} + /> +
+
+ <.input + field={f[:status]} + type="select" + label="Status" + prompt="Choose a value" + options={Ecto.Enum.values(Arrow.Shuttles.Shuttle, :status)} + /> +
+
+
+

define route

+ <.inputs_for :let={f_route} field={f[:routes]} as={:routes}> +

direction <%= input_value(f_route, :direction_id) %>

+
+ +
+ <.input field={f_route[:direction_desc]} type="text" label="Direction desc" /> +
+
+ <.input + field={f_route[:shape_id]} + type="select" + label="Shape" + prompt="Choose a shape" + options={Enum.map(@shapes, &{&1.name, &1.id})} + /> +
+
+
+
+ <.input field={f_route[:destination]} type="text" label="Destination" /> +
+
+
+ via +
+
+
+ <.input field={f_route[:waypoint]} type="text" label="Waypoint" /> +
+
+
+
+ <.input field={f_route[:suffix]} type="text" label="Suffix" /> +
+
+ + <:actions> + <.button>Save Shuttle + + + """ + end + + def mount(%{"id" => id} = _params, session, socket) do + logout_url = session["logout_url"] + shuttle = Shuttles.get_shuttle!(id) + changeset = Shuttles.change_shuttle(shuttle) + gtfs_disruptable_routes = Shuttles.list_disruptable_routes() + shapes = Shuttles.list_shapes() + form = to_form(changeset) + + socket = + socket + |> assign(:form, form) + |> assign(:form_action, "edit") + |> assign(:http_action, ~p"/shuttles/#{id}") + |> assign(:shuttle_route, shuttle) + |> assign(:title, "edit shuttle") + |> assign(:gtfs_disruptable_routes, gtfs_disruptable_routes) + |> assign(:shapes, shapes) + |> assign(:logout_url, logout_url) + + {:ok, socket} + end + + def mount(%{} = _params, session, socket) do + logout_url = session["logout_url"] + + changeset = + Shuttles.change_shuttle(%Shuttle{ + status: :draft, + routes: [%Shuttles.Route{direction_id: :"0"}, %Shuttles.Route{direction_id: :"1"}] + }) + + gtfs_disruptable_routes = Shuttles.list_disruptable_routes() + shapes = Shuttles.list_shapes() + form = to_form(changeset) + + socket = + socket + |> assign(:form, form) + |> assign(:form_action, "create") + |> assign(:http_action, ~p"/shuttles") + |> assign(:title, "create new replacement service shuttle") + |> assign(:gtfs_disruptable_routes, gtfs_disruptable_routes) + |> assign(:shapes, shapes) + |> assign(:logout_url, logout_url) + + {:ok, socket} + end + + defp handle_changeset(socket, changeset) do + case Ecto.Changeset.apply_action(changeset, :validate) do + {:ok, _} -> + {:noreply, assign(socket, form: to_form(changeset), trigger_submit: true)} + + {:error, applied_changeset} -> + {:noreply, assign(socket, form: to_form(applied_changeset), trigger_submit: false)} + end + end + + def handle_event("validate", %{"shuttle_route" => shuttle_route_params}, socket) do + form = + %Shuttle{} |> Shuttles.change_shuttle(shuttle_route_params) |> to_form(action: :validate) + + {:noreply, assign(socket, form: form, shuttle_route: shuttle_route_params)} + end + + def handle_event("edit", %{"shuttle_route" => shuttle_route_params}, socket) do + shuttle = Shuttles.get_shuttle!(socket.assigns.shuttle_route.id) + changeset = Shuttles.change_shuttle(shuttle, shuttle_route_params) + + handle_changeset(socket, changeset) + end + + def handle_event("create", %{"shuttle_route" => shuttle_route_params}, socket) do + changeset = Shuttles.change_shuttle(%Shuttle{}, shuttle_route_params) + + handle_changeset(socket, changeset) + end +end diff --git a/lib/arrow_web/controllers/shuttle_html/new.html.heex b/lib/arrow_web/live/shuttle_live/shuttle_view_live.html.heex similarity index 66% rename from lib/arrow_web/controllers/shuttle_html/new.html.heex rename to lib/arrow_web/live/shuttle_live/shuttle_view_live.html.heex index eff21ff7..9648e3a5 100644 --- a/lib/arrow_web/controllers/shuttle_html/new.html.heex +++ b/lib/arrow_web/live/shuttle_live/shuttle_view_live.html.heex @@ -1,10 +1,11 @@ <.header> - new shuttle + <%= @title %> <.shuttle_form - changeset={@changeset} - action={~p"/shuttles"} + form={@form} + action={@form_action} + http_action={@http_action} gtfs_disruptable_routes={@gtfs_disruptable_routes} shapes={@shapes} /> diff --git a/lib/arrow_web/router.ex b/lib/arrow_web/router.ex index 8a95d276..1a8d921f 100644 --- a/lib/arrow_web/router.ex +++ b/lib/arrow_web/router.ex @@ -60,7 +60,10 @@ defmodule ArrowWeb.Router do get("/shapes_upload", ShapeController, :new) post("/shapes_upload", ShapeController, :create) get("/shapes/:id/download", ShapeController, :download) - resources("/shuttles", ShuttleController, except: [:delete]) + live("/shuttles/new", ShuttleViewLive, :new) + live("/shuttles/:id/edit", ShuttleViewLive, :edit) + get("/shuttles", ShuttleController, :index) + get("/shuttles/:id", ShuttleController, :show) live_dashboard "/dashboard", ecto_repos: [Arrow.Repo], metrics: ArrowWeb.Telemetry end