Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(TripPlanner): add itinerary tags #1883

Merged
merged 13 commits into from
Feb 14, 2024
16 changes: 15 additions & 1 deletion assets/css/_trip-plan-results.scss
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,28 @@
}
}

&-tag {
background-color: $brand-primary-darkest;
border-radius: 0 0 8px;
color: $white;
font-weight: bold;
grid-column-end: 3;
grid-column-start: 1;
margin-bottom: 1rem;
margin-left: -1rem;
margin-top: -1rem;
padding: .5rem 1rem;
width: fit-content;
}

/* stylelint-disable property-no-vendor-prefix */
&-header {
background-color: $brand-primary-lightest-contrast;
border: 1px solid $brand-primary;
border-bottom: 0;
display: -ms-grid;
display: grid;
-ms-grid-columns: 1fr 1fr;
-ms-grid-columns: 1fr 1fr 1fr;
grid-template-columns: 1fr 1fr;
line-height: 1.5;
margin-top: 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ it("it renders", () => {
tab_html,
fare_calculator_html,
id: 1,
map
map,
tag: null
}
]}
/>
Expand All @@ -61,7 +62,8 @@ it("it renders", () => {
tab_html,
fare_calculator_html,
id: 1,
map
map,
tag: null
}
]}
/>
Expand All @@ -81,7 +83,8 @@ it("it renders ItineraryBody when clicking to expand", () => {
tab_html,
fare_calculator_html,
id: 1,
map
map,
tag: null
}
]}
/>
Expand Down
5 changes: 5 additions & 0 deletions assets/ts/trip-plan-results/components/Itinerary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ const ItineraryAccordion = ({
}: Props): ReactElement<HTMLElement> => (
<div className="m-trip-plan-results__itinerary">
<div className="m-trip-plan-results__itinerary-header">
{itinerary.tag && (
<div className="m-trip-plan-results__itinerary-tag u-small-caps">
{itinerary.tag}
</div>
)}
<div className="m-trip-plan-results__itinerary-header-content">
<div
className="m-trip-plan-results__itinerary-summary"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Itinerary from "./Itinerary";
export interface Itinerary {
id: number;
html: string;
tag: string | null;
// eslint-disable-next-line
map: MapData;
tab_html: string;
Expand Down
3 changes: 3 additions & 0 deletions config/deps/deps.exs
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,6 @@ if config_env() == :test do
],
js_errors: true
end

config :open_trip_planner_client,
timezone: "America/New_York"
4 changes: 1 addition & 3 deletions config/dotcom/trip_planner.exs
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import Config

config :dotcom, TripPlanApi, module: TripPlan.Api.OpenTripPlanner

config :dotcom, TripPlanGeocode, module: TripPlan.Geocode

if config_env() == :test do
config :dotcom, TripPlanApi, module: TripPlan.Api.MockPlanner
config :dotcom, :trip_planner, OpenTripPlannerClient.Mock

config :dotcom, TripPlanGeocode, module: TripPlan.Geocode.MockGeocode
end
5 changes: 5 additions & 0 deletions config/runtime.exs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,11 @@ config :dotcom, OpenTripPlanner,
wiremock_proxy: System.get_env("WIREMOCK_PROXY", "false"),
wiremock_proxy_url: System.get_env("WIREMOCK_TRIP_PLAN_PROXY_URL")

if config_env() != :test and System.get_env("OPEN_TRIP_PLANNER_URL") != "" do
config :open_trip_planner_client,
otp_url: System.get_env("OPEN_TRIP_PLANNER_URL")
end

if config_env() != :test do
config :dotcom,
drupal: [
Expand Down
46 changes: 30 additions & 16 deletions lib/dotcom/trip_plan/query.ex
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
defmodule Dotcom.TripPlan.Query do
@moduledoc "Fetch trip plan via OTP and handle response"

alias OpenTripPlannerClient.ItineraryTag.{EarliestArrival, LeastWalking, ShortestTrip}
alias TripPlan.{Itinerary, NamedPosition}

defstruct [
Expand All @@ -9,30 +10,34 @@ defmodule Dotcom.TripPlan.Query do
:itineraries,
errors: MapSet.new(),
time: :unknown,
wheelchair_accessible?: false
wheelchair: false
]

@otp_depart_at_tags [EarliestArrival, LeastWalking, ShortestTrip]
@otp_arrive_by_tags [LeastWalking, ShortestTrip]

@type query_itineraries :: {:ok, [Itinerary.t()]} | {:error, any()}
@type position_error :: TripPlan.Geocode.error() | :same_address
@type position :: NamedPosition.t() | {:error, position_error} | nil
@type t :: %__MODULE__{
from: position,
to: position,
time: :unknown | Dotcom.TripPlan.DateTime.date_time(),
errors: MapSet.t(atom),
wheelchair_accessible?: boolean,
itineraries: TripPlan.Api.t() | nil
wheelchair: boolean,
itineraries: query_itineraries() | nil
}

@spec from_query(map, TripPlan.Api.connection_opts(), Keyword.t()) :: t
def from_query(params, connection_opts, date_opts) do
@spec from_query(map, Keyword.t(), Keyword.t()) :: t
def from_query(params, _connection_opts, date_opts) do
opts = get_query_options(params)

%__MODULE__{
wheelchair_accessible?: match?(%{"wheelchair" => "true"}, params)
wheelchair: match?(%{"wheelchair" => "true"}, params)
}
|> Dotcom.TripPlan.DateTime.validate(params, date_opts)
|> Dotcom.TripPlan.Location.validate(params)
|> maybe_fetch_itineraries(connection_opts, opts)
|> maybe_fetch_itineraries(opts)
end

@spec get_query_options(map) :: keyword()
Expand All @@ -43,38 +48,47 @@ defmodule Dotcom.TripPlan.Query do
|> opts_from_query
end

@spec maybe_fetch_itineraries(t, TripPlan.Api.connection_opts(), Keyword.t()) :: t
@spec maybe_fetch_itineraries(t, Keyword.t()) :: t
defp maybe_fetch_itineraries(
%__MODULE__{
to: %NamedPosition{},
from: %NamedPosition{}
} = query,
connection_opts,
opts
) do
if Enum.empty?(query.errors) do
query
|> fetch_itineraries(connection_opts, [query.time | opts])
|> fetch_itineraries([query.time | opts])
|> parse_itinerary_result(query)
else
query
end
end

defp maybe_fetch_itineraries(%__MODULE__{} = query, _conn_opts, _opts) do
defp maybe_fetch_itineraries(%__MODULE__{} = query, _opts) do
query
end

@spec fetch_itineraries(t, TripPlan.Api.connection_opts(), Keyword.t()) :: TripPlan.Api.t()
@spec fetch_itineraries(t, Keyword.t()) :: OpenTripPlannerClient.Behaviour.plan()
defp fetch_itineraries(
%__MODULE__{from: %NamedPosition{} = from, to: %NamedPosition{} = to},
connection_opts,
opts
) do
TripPlan.plan(from, to, connection_opts, opts)
opts =
Keyword.put_new(
opts,
:tags,
if Keyword.has_key?(opts, :arrive_by) do
@otp_arrive_by_tags
else
@otp_depart_at_tags
end
)

TripPlan.Api.OpenTripPlanner.plan(from, to, opts)
end

@spec parse_itinerary_result(TripPlan.Api.t(), t) :: t
@spec parse_itinerary_result(OpenTripPlannerClient.Behaviour.plan(), t) :: t
defp parse_itinerary_result({:ok, _} = result, %__MODULE__{} = query) do
%{query | itineraries: result}
end
Expand All @@ -100,7 +114,7 @@ defmodule Dotcom.TripPlan.Query do
def opts_from_query(%{"wheelchair" => "true"} = query, opts) do
opts_from_query(
Map.delete(query, "wheelchair"),
Keyword.put(opts, :wheelchair_accessible?, true)
Keyword.put(opts, :wheelchair, true)
)
end

Expand Down
6 changes: 3 additions & 3 deletions lib/dotcom_web/controllers/trip_plan_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -249,10 +249,10 @@ defmodule DotcomWeb.TripPlanController do
end

@spec render_plan(Plug.Conn.t(), map) :: Plug.Conn.t()
defp render_plan(conn, plan) do
defp render_plan(conn, plan_params) do
query =
Query.from_query(
plan,
plan_params,
get_conn_opts(conn),
now: conn.assigns.date_time,
end_of_rating: Map.get(conn.assigns, :end_of_rating, Schedules.Repo.end_of_rating())
Expand All @@ -266,7 +266,7 @@ defmodule DotcomWeb.TripPlanController do

route_map = routes_for_query(itineraries)
route_mapper = &Map.get(route_map, &1)
itinerary_row_lists = itinerary_row_lists(itineraries, route_mapper, plan)
itinerary_row_lists = itinerary_row_lists(itineraries, route_mapper, plan_params)

conn
|> render(
Expand Down
3 changes: 1 addition & 2 deletions lib/dotcom_web/templates/trip_plan/_itinerary_tab.html.eex
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
<h2>Itinerary <%= @index %></h2>
<div>
<%= if @itinerary_row_list.alerts? do %>
<span class="m-trip-plan-results__itinerary-alerts">
<%= fa "exclamation-triangle" %>
</span>
<% end %>
<span class="m-trip-plan-results__itinerary-length-time">
<span class="m-trip-plan-results__itinerary-length-time h3">
<%= Timex.format!(@itinerary.start, "{h12}:{m} {AM}") %> - <%= Timex.format!(@itinerary.stop, "{h12}:{m} {AM}") %>
</span>
<span class="m-trip-plan-results__itinerary-length-duration">
Expand Down
13 changes: 11 additions & 2 deletions lib/dotcom_web/views/trip_plan_view.ex
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ defmodule DotcomWeb.TripPlanView do
]
end

defp trip_explanation(%{wheelchair_accessible?: false}) do
defp trip_explanation(%{wheelchair: false}) do
"Trips"
end

defp trip_explanation(%{wheelchair_accessible?: true}) do
defp trip_explanation(%{wheelchair: true}) do
"Wheelchair accessible trips"
end

Expand Down Expand Up @@ -519,13 +519,22 @@ defmodule DotcomWeb.TripPlanView do
tab_html: tab_html,
id: index,
map: itinerary_map(map),
tag: tag_string(i.tag),
access_html: access_html,
fares_estimate_html: fares_estimate_html,
fare_calculator_html: fare_calculator_html
}
end
end

defp tag_string(nil), do: nil

defp tag_string(tag),
do:
tag
|> Atom.to_string()
|> String.replace("_", " ")

@spec render_react(map) :: HTML.safe()
def render_react(assigns) do
Util.log_duration(__MODULE__, :do_render_react, [assigns])
Expand Down
20 changes: 0 additions & 20 deletions lib/trip_plan.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,6 @@ defmodule TripPlan do
@moduledoc """
Plan transit trips from one place to another.
"""
alias Util.Position

@doc """
Tries to describe how to get between two places.
"""
@spec plan(
Position.t(),
Position.t(),
TripPlan.Api.connection_opts(),
TripPlan.Api.plan_opts()
) :: TripPlan.Api.t()
def plan(from, to, connection_opts, opts) do
apply(module(TripPlanApi), :plan, [
from,
to,
connection_opts,
opts
])
end

@doc """
Finds the latitude/longitude for a given address.
"""
Expand Down
39 changes: 0 additions & 39 deletions lib/trip_plan/api.ex

This file was deleted.

Loading
Loading