From 463c8868c1ec541a0b0ae02c389f629848a7086c Mon Sep 17 00:00:00 2001 From: Cristen Jones Date: Wed, 27 Sep 2023 12:06:22 -0400 Subject: [PATCH 1/4] feat(Line.Helpers): get either tree or list --- .../controllers/schedule/line/helpers.ex | 23 ++++++++++ .../schedule/line/helpers_test.exs | 44 ++++++++++++++++++- 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/apps/site/lib/site_web/controllers/schedule/line/helpers.ex b/apps/site/lib/site_web/controllers/schedule/line/helpers.ex index 7f2b9a17d8..f28b7a6edf 100644 --- a/apps/site/lib/site_web/controllers/schedule/line/helpers.ex +++ b/apps/site/lib/site_web/controllers/schedule/line/helpers.ex @@ -354,4 +354,27 @@ defmodule SiteWeb.ScheduleController.Line.Helpers do [i, j] end end + + @doc """ + Skip computing the branched tree structure for non-rail route types, because + the website doesn't show these in a branching format. + """ + @spec get_stop_tree_or_lists([RouteStops.t()], Route.type_int()) :: + {UnrootedPolytree.t() | nil, [[RouteStop.t()]] | nil} + + def get_stop_tree_or_lists(_, 4), do: {nil, nil} + + def get_stop_tree_or_lists(route_stops_lists, 3), + do: {nil, Enum.map(route_stops_lists, & &1.stops)} + + def get_stop_tree_or_lists([], _), do: {nil, []} + + def get_stop_tree_or_lists(route_stops_lists, _) do + tree = + route_stops_lists + |> Enum.map(&Enum.map(&1.stops, fn route_stop -> {route_stop.id, route_stop} end)) + |> UnrootedPolytree.from_lists() + + {tree, nil} + end end diff --git a/apps/site/test/site_web/controllers/schedule/line/helpers_test.exs b/apps/site/test/site_web/controllers/schedule/line/helpers_test.exs index f537cf89e9..6f62f0c4bc 100644 --- a/apps/site/test/site_web/controllers/schedule/line/helpers_test.exs +++ b/apps/site/test/site_web/controllers/schedule/line/helpers_test.exs @@ -3,7 +3,7 @@ defmodule SiteWeb.ScheduleController.Line.HelpersTest do alias Routes.{Route} alias SiteWeb.ScheduleController.Line.Helpers - alias Stops.{RouteStops, Stop} + alias Stops.{RouteStops, RouteStop, Stop} doctest Helpers @@ -878,6 +878,48 @@ defmodule SiteWeb.ScheduleController.Line.HelpersTest do end end + describe "get_stop_tree_or_lists/2" do + setup do + test_route_stops = [ + %RouteStops{ + branch: "Branch-A", + stops: [ + %RouteStop{id: "a"}, + %RouteStop{id: "b"}, + %RouteStop{id: "c"}, + %RouteStop{id: "d"} + ] + }, + %RouteStops{ + branch: "Branch-B", + stops: [ + %RouteStop{id: "a"}, + %RouteStop{id: "b"}, + %RouteStop{id: "e"}, + %RouteStop{id: "f"} + ] + } + ] + + {:ok, route_stops: test_route_stops} + end + + test "returns tree for rail route types", %{route_stops: route_stops} do + assert {%UnrootedPolytree{}, nil} = Helpers.get_stop_tree_or_lists(route_stops, 0) + assert {%UnrootedPolytree{}, nil} = Helpers.get_stop_tree_or_lists(route_stops, 1) + assert {%UnrootedPolytree{}, nil} = Helpers.get_stop_tree_or_lists(route_stops, 2) + end + + test "returns list for bus route type", %{route_stops: route_stops} do + assert {nil, stops_lists} = Helpers.get_stop_tree_or_lists(route_stops, 3) + assert [[%RouteStop{} | _], [%RouteStop{} | _]] = stops_lists + end + + test "returns neither for ferry route type", %{route_stops: route_stops} do + assert {nil, nil} = Helpers.get_stop_tree_or_lists(route_stops, 4) + end + end + def assert_stop_ids(actual, stop_ids) do assert Enum.map(actual, & &1.id) == stop_ids end From f84fa45694c45425bf0b597b68eb3f133e6b0e32 Mon Sep 17 00:00:00 2001 From: Cristen Jones Date: Wed, 27 Sep 2023 14:41:42 -0400 Subject: [PATCH 2/4] feat(LineController): return both tree and list --- .../schedule/components/ScheduleDirection.tsx | 16 +- .../ts/schedule/components/ScheduleLoader.tsx | 7 +- .../ts/schedule/components/__schedule.d.ts | 3 +- .../__tests__/ScheduleDirectionTest.tsx | 8 + .../__tests__/ScheduleLoaderTest.tsx | 20 + .../ScheduleDirectionTest.tsx.snap | 560 ++++++++++++++++++ .../lib/site_web/controllers/schedule/line.ex | 7 +- .../site_web/controllers/schedule/line_api.ex | 8 +- .../controllers/schedule/line_controller.ex | 1 + .../site_web/controllers/line_api_test.exs | 2 +- 10 files changed, 613 insertions(+), 19 deletions(-) diff --git a/apps/site/assets/ts/schedule/components/ScheduleDirection.tsx b/apps/site/assets/ts/schedule/components/ScheduleDirection.tsx index 0ca8dade14..e08821d3ac 100644 --- a/apps/site/assets/ts/schedule/components/ScheduleDirection.tsx +++ b/apps/site/assets/ts/schedule/components/ScheduleDirection.tsx @@ -3,7 +3,8 @@ import { Alert, DirectionId, EnhancedRoute } from "../../__v3api"; import { RoutePatternsByDirection, EnhancedRoutePattern, - StopTree + StopTree, + RouteStop } from "./__schedule"; import ScheduleDirectionMenu from "./direction/ScheduleDirectionMenu"; import ScheduleDirectionButton from "./direction/ScheduleDirectionButton"; @@ -26,7 +27,8 @@ export interface Props { routePatternsByDirection: RoutePatternsByDirection; mapData?: MapData; staticMapData?: StaticMapData; - stopTree: StopTree; + stopTree: StopTree | null; + routeStopLists: RouteStop[][] | null; alerts: Alert[]; busVariantId: string | null; } @@ -78,11 +80,11 @@ export const fetchLineData = ( if (response.ok) return response.json(); throw new Error(response.statusText); }) - .then(({ stop_tree }) => { - const stopTree: StopTree = fromStopTreeData(stop_tree); + .then(({ stop_tree, route_stop_lists }) => { + const stopTree = stop_tree ? fromStopTreeData(stop_tree) : null; dispatch({ type: "FETCH_COMPLETE", - payload: { stopTree } + payload: { stopTree, routeStopLists: route_stop_lists } }); }) // @ts-ignore @@ -97,6 +99,7 @@ const ScheduleDirection = ({ mapData, staticMapData, stopTree: initialStopTree, + routeStopLists: initialRouteStopLists, alerts, busVariantId }: Props): ReactElement => { @@ -186,7 +189,8 @@ const ScheduleDirection = ({ const [lineState, dispatchLineData] = useReducer(fetchReducer, { data: { - stopTree: initialStopTree + stopTree: initialStopTree, + routeStopLists: initialRouteStopLists }, isLoading: false, error: false diff --git a/apps/site/assets/ts/schedule/components/ScheduleLoader.tsx b/apps/site/assets/ts/schedule/components/ScheduleLoader.tsx index 187f7b4d31..32ea96c5aa 100644 --- a/apps/site/assets/ts/schedule/components/ScheduleLoader.tsx +++ b/apps/site/assets/ts/schedule/components/ScheduleLoader.tsx @@ -137,11 +137,13 @@ export const ScheduleLoader = ({ schedule_note: scheduleNote, today, stop_tree, + route_stop_lists: routeStopLists, alerts, variant: busVariantId } = schedulePageData; - const stopTree: StopTree = fromStopTreeData(stop_tree); - + const stopTree: StopTree | null = stop_tree + ? fromStopTreeData(stop_tree) + : null; const routeIsSuspended = Object.keys(routePatternsByDirection).length === 0; const currentState = getCurrentState(); @@ -319,6 +321,7 @@ export const ScheduleLoader = ({ directionId={readjustedDirectionId} route={route} routePatternsByDirection={routePatternsByDirection} + routeStopLists={routeStopLists} mapData={mapData} staticMapData={staticMapData} stopTree={stopTree} diff --git a/apps/site/assets/ts/schedule/components/__schedule.d.ts b/apps/site/assets/ts/schedule/components/__schedule.d.ts index 9d3560ea85..869fe0330b 100644 --- a/apps/site/assets/ts/schedule/components/__schedule.d.ts +++ b/apps/site/assets/ts/schedule/components/__schedule.d.ts @@ -44,7 +44,8 @@ export interface SchedulePageData { stops: SimpleStopMap; direction_id: DirectionId; route_patterns: RoutePatternsByDirection; - stop_tree: StopTreeData; + stop_tree: StopTreeData | null; + route_stop_lists: RouteStop[][]; alerts: Alert[]; today: string; variant: string | null; diff --git a/apps/site/assets/ts/schedule/components/__tests__/ScheduleDirectionTest.tsx b/apps/site/assets/ts/schedule/components/__tests__/ScheduleDirectionTest.tsx index af2a05be00..6c88536811 100644 --- a/apps/site/assets/ts/schedule/components/__tests__/ScheduleDirectionTest.tsx +++ b/apps/site/assets/ts/schedule/components/__tests__/ScheduleDirectionTest.tsx @@ -33,6 +33,7 @@ const { stop_tree } = (lineDiagramData as unknown) as { stop_tree: StopTreeData; }; const stopTree: StopTree = fromStopTreeData(stop_tree); +const testRouteStopList = Object.values(stopTree.byId).map(node => node.value); const route = { type: 3, @@ -170,6 +171,7 @@ const getComponent = () => ( routePatternsByDirection={routePatternsByDirection} mapData={mapData} stopTree={stopTree} + routeStopLists={[testRouteStopList]} alerts={[]} busVariantId={null} /> @@ -182,6 +184,7 @@ const getSingleDirectionComponent = () => ( routePatternsByDirection={routePatternsByDirection} mapData={mapData} stopTree={stopTree} + routeStopLists={[testRouteStopList]} alerts={[]} busVariantId={null} /> @@ -194,6 +197,7 @@ const getSubwayComponent = () => ( directionId={directionId} routePatternsByDirection={routePatternsByDirection} stopTree={stopTree} + routeStopLists={[testRouteStopList]} alerts={[]} busVariantId={null} /> @@ -206,6 +210,7 @@ const getCRComponent = () => ( routePatternsByDirection={routePatternsByDirection} mapData={mapData} stopTree={stopTree} + routeStopLists={[testRouteStopList]} alerts={[]} busVariantId={null} /> @@ -218,6 +223,7 @@ const getStaticMapComponent = () => ( directionId={directionId} routePatternsByDirection={routePatternsByDirection} stopTree={stopTree} + routeStopLists={[testRouteStopList]} alerts={[]} busVariantId={null} /> @@ -246,6 +252,7 @@ const getGreenLineComponent = () => { directionId={directionId} routePatternsByDirection={routePatternsByDirection} stopTree={stopTree} + routeStopLists={[testRouteStopList]} alerts={[]} busVariantId={null} /> @@ -259,6 +266,7 @@ const getVariantComponent = () => ( routePatternsByDirection={routePatternsByDirection} mapData={mapData} stopTree={stopTree} + routeStopLists={[testRouteStopList]} alerts={[]} busVariantId="pattern-3" /> diff --git a/apps/site/assets/ts/schedule/components/__tests__/ScheduleLoaderTest.tsx b/apps/site/assets/ts/schedule/components/__tests__/ScheduleLoaderTest.tsx index 8fad1adeeb..bcb97f6b50 100644 --- a/apps/site/assets/ts/schedule/components/__tests__/ScheduleLoaderTest.tsx +++ b/apps/site/assets/ts/schedule/components/__tests__/ScheduleLoaderTest.tsx @@ -71,6 +71,9 @@ const stops = { const { stop_tree: stopTreeData } = (lineDiagramData as unknown) as { stop_tree: StopTreeData; }; +const testRouteStopList = Object.values(stopTreeData.by_id).map( + node => node.value +); const fares = [ { @@ -243,6 +246,7 @@ describe("ScheduleLoader", () => { route_patterns: routePatternsByDirection, today: "2019-12-05", stop_tree: stopTreeData, + route_stop_lists: [testRouteStopList], alerts: [], variant: null }} @@ -275,6 +279,7 @@ describe("ScheduleLoader", () => { route_patterns: routePatternsByDirection, today: "2019-12-05", stop_tree: stopTreeData, + route_stop_lists: [testRouteStopList], alerts: [], variant: null }} @@ -319,6 +324,7 @@ describe("ScheduleLoader", () => { route_patterns: routePatternsByDirection, today: "2019-12-05", stop_tree: stopTreeData, + route_stop_lists: [testRouteStopList], alerts: [], variant: null }} @@ -352,6 +358,7 @@ describe("ScheduleLoader", () => { route_patterns: routePatternsByDirection, today: "2019-12-05", stop_tree: stopTreeData, + route_stop_lists: [testRouteStopList], alerts: [], variant: null }} @@ -395,6 +402,7 @@ describe("ScheduleLoader", () => { route_patterns: routePatternsByDirection, today: "2019-12-05", stop_tree: stopTreeData, + route_stop_lists: [testRouteStopList], alerts: [], variant: null }} @@ -435,6 +443,7 @@ describe("ScheduleLoader", () => { route_patterns: routePatternsByDirection, today: "2019-12-05", stop_tree: stopTreeData, + route_stop_lists: [testRouteStopList], alerts: [], variant: null }} @@ -468,6 +477,7 @@ describe("ScheduleLoader", () => { route_patterns: routePatternsByDirection, today: "2019-12-05", stop_tree: stopTreeData, + route_stop_lists: [testRouteStopList], alerts: [], variant: null }} @@ -520,6 +530,7 @@ describe("ScheduleLoader", () => { route_patterns: routePatternsByDirection, today: "2019-12-05", stop_tree: stopTreeData, + route_stop_lists: [testRouteStopList], alerts: [], variant: null }} @@ -587,6 +598,7 @@ describe("ScheduleLoader", () => { route_patterns: routePatternsByDirection, today: "2019-12-05", stop_tree: stopTreeData, + route_stop_lists: [testRouteStopList], alerts: [], variant: null }} @@ -633,6 +645,7 @@ describe("ScheduleLoader", () => { route_patterns: routePatternsByDirection, today: "2019-12-05", stop_tree: stopTreeData, + route_stop_lists: [testRouteStopList], alerts: [], variant: null }} @@ -688,6 +701,7 @@ describe("ScheduleLoader", () => { route_patterns: routePatternsByDirection, today: "2019-12-05", stop_tree: stopTreeData, + route_stop_lists: [testRouteStopList], alerts: [], variant: null }} @@ -727,6 +741,7 @@ describe("ScheduleLoader", () => { route_patterns: routePatternsByDirection, today: "2019-12-05", stop_tree: stopTreeData, + route_stop_lists: [testRouteStopList], alerts: [], variant: null }} @@ -784,6 +799,7 @@ describe("ScheduleLoader", () => { route_patterns: routePatternsByDirection, today: "2019-12-05", stop_tree: stopTreeData, + route_stop_lists: [testRouteStopList], alerts: [], variant: null }} @@ -831,6 +847,7 @@ describe("ScheduleLoader", () => { route_patterns: routePatternsByDirection, today: "2019-12-05", stop_tree: stopTreeData, + route_stop_lists: [testRouteStopList], alerts: [], variant: null }} @@ -876,6 +893,7 @@ describe("ScheduleLoader", () => { route_patterns: routes, today: "2019-12-05", stop_tree: stopTreeData, + route_stop_lists: [testRouteStopList], alerts: [], variant: null }} @@ -1006,6 +1024,7 @@ describe("ScheduleLoader", () => { route_patterns: routePatternsByDirection, today: "2019-12-05", stop_tree: stopTreeData, + route_stop_lists: [testRouteStopList], alerts: [], variant: null }} @@ -1049,6 +1068,7 @@ describe("ScheduleLoader", () => { route_patterns: routePatternsByDirection, today: "2019-12-05", stop_tree: stopTreeData, + route_stop_lists: [testRouteStopList], alerts: [], variant: null }} diff --git a/apps/site/assets/ts/schedule/components/__tests__/__snapshots__/ScheduleDirectionTest.tsx.snap b/apps/site/assets/ts/schedule/components/__tests__/__snapshots__/ScheduleDirectionTest.tsx.snap index ce34dd1e5a..0061a54c2a 100644 --- a/apps/site/assets/ts/schedule/components/__tests__/__snapshots__/ScheduleDirectionTest.tsx.snap +++ b/apps/site/assets/ts/schedule/components/__tests__/__snapshots__/ScheduleDirectionTest.tsx.snap @@ -56,6 +56,96 @@ exports[`can render green line 1`] = ` + + +
+ + + +
+
+ + +
+ + + + Line diagram for + Green Line + + + 0 stops going Eastbound to Park Street / Government Center / North Station / Lechmere + + + + + + + + +
    +
+
+
+
`; @@ -100,6 +190,101 @@ exports[`renders a CR component 1`] = ` + +

+ Stations +

+ +
+ + + +
+
+ + +
+ + + + Line diagram for + route 1 + + + 0 stops going Inbound to End + + + + + + + + +
    +
+
+
+
`; @@ -149,6 +334,101 @@ exports[`renders a bus component 1`] = ` + +

+ Stops +

+ +
+ + + +
+
+ + +
+ + + + Line diagram for + route 1 + + + 0 stops going Inbound to End + + + + + + + + +
    +
+
+
+
`; @@ -193,6 +473,96 @@ exports[`renders a subway component 1`] = ` + + +
+ + + +
+
+ + +
+ + + + Line diagram for + route 1 + + + 0 stops going Inbound to End + + + + + + + + +
    +
+
+
+
`; @@ -253,6 +623,101 @@ exports[`renders with a static map 1`] = ` /> View map as a PDF + +

+ Stops +

+ +
+ + + +
+
+ + +
+ + + + Line diagram for + route 1 + + + 0 stops going Inbound to End + + + + + + + + +
    +
+
+
+
`; @@ -313,5 +778,100 @@ exports[`respects the initially selected pattern ID, if specified 1`] = ` + +

+ Stops +

+ +
+ + + +
+
+ + +
+ + + + Line diagram for + route 1 + + + 0 stops going Outbound to Begin + + + + + + + + +
    +
+
+
+
`; diff --git a/apps/site/lib/site_web/controllers/schedule/line.ex b/apps/site/lib/site_web/controllers/schedule/line.ex index e4d4bbad14..62efa3c073 100644 --- a/apps/site/lib/site_web/controllers/schedule/line.ex +++ b/apps/site/lib/site_web/controllers/schedule/line.ex @@ -135,15 +135,14 @@ defmodule SiteWeb.ScheduleController.Line do branch_route_stops = LineHelpers.get_branch_route_stops(route, direction_id) - stop_tree = - branch_route_stops - |> Enum.map(&Enum.map(&1.stops, fn route_stop -> {route_stop.id, route_stop} end)) - |> UnrootedPolytree.from_lists() + {stop_tree, route_stop_lists} = + LineHelpers.get_stop_tree_or_lists(branch_route_stops, route.type) conn |> assign(:route_patterns, route_patterns_map) |> assign(:direction_id, direction_id) |> assign(:stop_tree, stop_tree) + |> assign(:route_stop_lists, route_stop_lists) |> assign(:branches, static_branches) |> assign(:map_img_src, map_img_src) |> assign(:dynamic_map_data, dynamic_map_data) diff --git a/apps/site/lib/site_web/controllers/schedule/line_api.ex b/apps/site/lib/site_web/controllers/schedule/line_api.ex index 8c9498863b..2423b81f65 100644 --- a/apps/site/lib/site_web/controllers/schedule/line_api.ex +++ b/apps/site/lib/site_web/controllers/schedule/line_api.ex @@ -34,14 +34,12 @@ defmodule SiteWeb.ScheduleController.LineApi do conn.query_params["route_pattern"] ) - stop_tree = - branch_route_stops - |> Enum.map(&Enum.map(&1.stops, fn route_stop -> {route_stop.id, route_stop} end)) - |> UnrootedPolytree.from_lists() + {stop_tree, route_stop_lists} = + LineHelpers.get_stop_tree_or_lists(branch_route_stops, route.type) json( conn, - %{stop_tree: stop_tree} + %{stop_tree: stop_tree, route_stop_lists: route_stop_lists} ) :not_found -> diff --git a/apps/site/lib/site_web/controllers/schedule/line_controller.ex b/apps/site/lib/site_web/controllers/schedule/line_controller.ex index 99a8aae100..914d3fe5d5 100644 --- a/apps/site/lib/site_web/controllers/schedule/line_controller.ex +++ b/apps/site/lib/site_web/controllers/schedule/line_controller.ex @@ -68,6 +68,7 @@ defmodule SiteWeb.ScheduleController.LineController do direction_id: conn.assigns.direction_id, route_patterns: conn.assigns.route_patterns, stop_tree: conn.assigns.stop_tree, + route_stop_lists: conn.assigns.route_stop_lists, alerts: conn.assigns.alerts, today: conn.assigns.date_time |> DateTime.to_date() |> Date.to_iso8601(), variant: conn.assigns.variant diff --git a/apps/site/test/site_web/controllers/line_api_test.exs b/apps/site/test/site_web/controllers/line_api_test.exs index d1e2f22b44..272eb9a5c5 100644 --- a/apps/site/test/site_web/controllers/line_api_test.exs +++ b/apps/site/test/site_web/controllers/line_api_test.exs @@ -1,5 +1,5 @@ defmodule SiteWeb.LineApiTest do - use SiteWeb.ConnCase + use SiteWeb.ConnCase, async: true describe "show" do test "success response", %{conn: conn} do From 6d7ff5f0c01dd5b2111a5051ff0c8cc75c0cc8f5 Mon Sep 17 00:00:00 2001 From: Cristen Jones Date: Wed, 27 Sep 2023 15:27:57 -0400 Subject: [PATCH 3/4] refactor(ScheduleDirection): permit null stopTree --- .../schedule/components/ScheduleDirection.tsx | 18 ++-- .../line-diagram/ExpandableBranch.tsx | 1 + .../components/line-diagram/LineDiagram.tsx | 16 ++-- .../line-diagram/LineDiagramWithStops.tsx | 68 ++++++++++---- .../components/line-diagram/StopCard.tsx | 46 ++++++---- .../line-diagram/__tests__/DiagramTest.tsx | 2 +- .../__tests__/LineDiagramTest.tsx | 7 +- .../__tests__/LineDiagramWithStopsTest.tsx | 5 ++ .../line-diagram/__tests__/LineTest.tsx | 2 +- .../line-diagram/__tests__/StopCardTest.tsx | 14 +++ .../__snapshots__/DiagramTest.tsx.snap | 26 +++--- .../__snapshots__/LineDiagramTest.tsx.snap | 16 ++-- .../LineDiagramWithStopsTest.tsx.snap | 50 +++++------ .../__snapshots__/StopCardTest.tsx.snap | 2 +- .../line-diagram/graphics/Diagram.tsx | 89 ++++++++++++++++--- .../components/line-diagram/graphics/Line.tsx | 35 +++++++- .../line-diagram/graphics/Merges.tsx | 2 +- .../graphics/useTreeStopPositions.ts | 20 +++-- 18 files changed, 303 insertions(+), 116 deletions(-) diff --git a/apps/site/assets/ts/schedule/components/ScheduleDirection.tsx b/apps/site/assets/ts/schedule/components/ScheduleDirection.tsx index e08821d3ac..760b9741f4 100644 --- a/apps/site/assets/ts/schedule/components/ScheduleDirection.tsx +++ b/apps/site/assets/ts/schedule/components/ScheduleDirection.tsx @@ -19,7 +19,6 @@ import { } from "../../models/route"; import LineDiagram from "./line-diagram/LineDiagram"; import { fromStopTreeData } from "./ScheduleLoader"; -import { isEmptyTree } from "../../helpers/stop-tree"; export interface Props { route: EnhancedRoute; @@ -204,7 +203,12 @@ const ScheduleDirection = ({ ); }, [route, state.directionId, busVariantId, currentRoutePatternIdForData]); - const hasValidTree = lineState.data && !isEmptyTree(lineState.data.stopTree); + const routeStopList = + lineState.data && lineState.data.routeStopLists + ? (lineState.data.routeStopLists as RouteStop[][]).find( + rsList => !!rsList.find(rs => rs.branch === state.routePattern.name) + ) || [] + : []; return ( <>
@@ -225,9 +229,10 @@ const ScheduleDirection = ({ ) : null}
- {isSubwayRoute(route) && hasValidTree && ( + {isSubwayRoute(route) && ( )} - {!isSubwayRoute(route) && hasValidTree && ( + {!isSubwayRoute(route) && ( { const LineDiagram = ({ stopTree, + routeStopList, route, directionId, alerts }: Props): ReactElement => { - const stopTreeCoordStore = createStopTreeCoordStore(stopTree); + const stopTreeCoordStore = stopTree + ? createStopTreeCoordStore(stopTree) + : createStopTreeCoordStore(routeStopList); const liveData = useRealtime(route, directionId, true); const [query, setQuery] = useState(""); - const allStops: RouteStop[] = stopIds(stopTree).map(stopId => - stopForId(stopTree, stopId) - ); + const allStops: RouteStop[] = stopTree + ? stopIds(stopTree).map(stopId => stopForId(stopTree, stopId)) + : routeStopList; const filteredStops: RouteStop[] = allStops.filter(stop => stop.name.toLowerCase().includes(query.toLowerCase()) ); @@ -97,6 +101,7 @@ const LineDiagram = ({ key={stop.id} stopTree={stopTree} stopId={stop.id} + routeStopList={routeStopList} alerts={alertsByStop(alerts, stop.id)} onClick={handleStopClick} liveData={liveData?.[stop.id]} @@ -116,6 +121,7 @@ const LineDiagram = ({ => { // create a ref for each stop - we will use this to track the location of the stop so we can place the line diagram bubbles - const [stopRefsMap, updateAllStopCoords] = useTreeStopPositions(stopTree); + const [stopRefsMap, updateAllStopCoords] = useTreeStopPositions( + stopTree || routeStopList + ); const anyCrowding = Object.values( liveData || {} @@ -273,23 +282,50 @@ const LineDiagramWithStops = ({ !anyCrowding ? "u-no-crowding-data" : "" }`} > - -
    - + ) : ( + + )} +
      + {stopTree ? ( + + ) : ( + <> + {routeStopList.map((routeStop, index) => ( + + ))} + + )}
    diff --git a/apps/site/assets/ts/schedule/components/line-diagram/StopCard.tsx b/apps/site/assets/ts/schedule/components/line-diagram/StopCard.tsx index e4fd9100cd..b41d8cada3 100644 --- a/apps/site/assets/ts/schedule/components/line-diagram/StopCard.tsx +++ b/apps/site/assets/ts/schedule/components/line-diagram/StopCard.tsx @@ -30,7 +30,8 @@ import { StopRefContext } from "./LineDiagramWithStops"; import { LiveData } from "./__line-diagram"; interface Props { - stopTree: StopTree; + stopTree: StopTree | null; + routeStopList: RouteStop[]; stopId: StopId; alerts: Alert[]; onClick: (stop: RouteStop) => void; @@ -62,11 +63,6 @@ const lineName = ({ name, route: routeStopRoute }: RouteStop): string => { const hasLivePredictions = (liveData?: LiveData): boolean => !!liveData && liveData.headsigns.some(hasPredictionTime); -const showPrediction = ( - stopTree: StopTree, - stopId: StopId, - liveData?: LiveData -): boolean => hasLivePredictions(liveData) && !isEndNode(stopTree, stopId); const connectionsFor = ( routeStop: RouteStop, @@ -107,8 +103,7 @@ const hasUpcomingDeparturesIfSubway = ( return !!liveData && liveData.headsigns.length > 0; }; -const schedulesButtonLabel = (stopTree: StopTree, stopId: StopId): string => { - const route = routeForStop(stopTree, stopId); +const schedulesButtonLabel = (route: RouteStopRoute | null): string => { return route && isSubwayRoute(route) ? "View upcoming departures" : "View schedule"; @@ -125,29 +120,40 @@ const Alert = (): JSX.Element => ( const StopCard = ({ stopTree, stopId, + routeStopList, alerts, onClick, liveData, searchQuery }: Props): ReactElement => { const refs = useContext(StopRefContext)[0]; - const routeStop: RouteStop = stopForId(stopTree, stopId); + const routeStop = stopTree + ? stopForId(stopTree, stopId) + : routeStopList.find(rs => rs.id === stopId)!; + const routeStopIndex = routeStopList.indexOf(routeStop); + const isEnd = stopTree + ? isEndNode(stopTree, stopId) + : routeStopIndex === routeStopList.length - 1; const diversionAlert = alerts.find(isActiveDiversion); const showDiversion = - diversionAlert && - !(hasLivePredictions(liveData) && isEndNode(stopTree, stopId)); + diversionAlert && !(hasLivePredictions(liveData) && isEnd); + + const left = stopTree ? width(stopTree, stopId) : diagramWidth(1); + const connections = stopTree + ? connectionsFor(routeStop, stopTree) + : routeStop.connections; return (
  1. - {hasBranchLabel(stopTree, stopId) && ( + {stopTree && hasBranchLabel(stopTree, stopId) && (
    {lineName(routeStop)}
    )}
    - {StopConnections(stopId, connectionsFor(routeStop, stopTree))} - {showPrediction(stopTree, stopId, liveData) ? ( + {StopConnections(stopId, connections)} + {hasLivePredictions(liveData) && !isEnd ? ( - {!isEndNode(stopTree, stopId) && - hasUpcomingDeparturesIfSubway(stopTree, stopId, liveData) && ( + {!isEnd && + (stopTree + ? hasUpcomingDeparturesIfSubway(stopTree, stopId, liveData) + : true) && (
    )} diff --git a/apps/site/assets/ts/schedule/components/line-diagram/__tests__/DiagramTest.tsx b/apps/site/assets/ts/schedule/components/line-diagram/__tests__/DiagramTest.tsx index 5d9d480eef..27fff6470f 100644 --- a/apps/site/assets/ts/schedule/components/line-diagram/__tests__/DiagramTest.tsx +++ b/apps/site/assets/ts/schedule/components/line-diagram/__tests__/DiagramTest.tsx @@ -3,7 +3,7 @@ import * as redux from "react-redux"; import { mount, ReactWrapper } from "enzyme"; import { RouteStop, StopTree } from "../../__schedule"; import { createStopTreeCoordStore } from "../graphics/useTreeStopPositions"; -import Diagram from "../graphics/Diagram"; +import { Diagram } from "../graphics/Diagram"; import { Route, RouteType } from "../../../../__v3api"; import Stop from "../graphics/Stop"; import { LiveDataByStop } from "../__line-diagram"; diff --git a/apps/site/assets/ts/schedule/components/line-diagram/__tests__/LineDiagramTest.tsx b/apps/site/assets/ts/schedule/components/line-diagram/__tests__/LineDiagramTest.tsx index b418cf6a21..f084e2a0b0 100644 --- a/apps/site/assets/ts/schedule/components/line-diagram/__tests__/LineDiagramTest.tsx +++ b/apps/site/assets/ts/schedule/components/line-diagram/__tests__/LineDiagramTest.tsx @@ -48,7 +48,7 @@ const stopTree: StopTree = { }, startingNodes: ["a"] }; - +const testRouteStopList = Object.values(stopTree.byId).map(node => node.value); const route = { type: 3 as RouteType, name: "route 1", @@ -80,6 +80,7 @@ describe("LineDiagram", () => { wrapper = mount( { const subwayWrapper = mount( { render( { render( { render( node.value); const store = UseTreeStopPositions.createStopTreeCoordStore(stopTree); const route = { @@ -187,6 +189,7 @@ describe("LineDiagramWithStops", () => { { { node.value); const alertA: Alert = { id: "MOCK-ALERT-A", @@ -124,6 +125,7 @@ describe("StopCard", () => { { { { { { { { { {}} @@ -361,6 +371,7 @@ describe("StopCard", () => { {}} @@ -376,6 +387,7 @@ describe("StopCard", () => { {}} @@ -391,6 +403,7 @@ describe("StopCard", () => { {}} @@ -409,6 +422,7 @@ describe("StopCard", () => { - + - - - - - - - - - - - - + + + + + + + + + + + + Line diagram for diff --git a/apps/site/assets/ts/schedule/components/line-diagram/__tests__/__snapshots__/LineDiagramTest.tsx.snap b/apps/site/assets/ts/schedule/components/line-diagram/__tests__/__snapshots__/LineDiagramTest.tsx.snap index 57f840ddb5..ce6031c5aa 100644 --- a/apps/site/assets/ts/schedule/components/line-diagram/__tests__/__snapshots__/LineDiagramTest.tsx.snap +++ b/apps/site/assets/ts/schedule/components/line-diagram/__tests__/__snapshots__/LineDiagramTest.tsx.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`LineDiagram renders and matches snapshot 1`] = ` -" +"

    Stops

    @@ -17,12 +17,12 @@ exports[`LineDiagram renders and matches snapshot 1`] = ` - +
    - - - + + + Line diagram for @@ -55,7 +55,7 @@ exports[`LineDiagram renders and matches snapshot 1`] = `
      - +
    1. @@ -83,7 +83,7 @@ exports[`LineDiagram renders and matches snapshot 1`] = `
    2. - +
    3. @@ -111,7 +111,7 @@ exports[`LineDiagram renders and matches snapshot 1`] = `
    4. - +
    5. diff --git a/apps/site/assets/ts/schedule/components/line-diagram/__tests__/__snapshots__/LineDiagramWithStopsTest.tsx.snap b/apps/site/assets/ts/schedule/components/line-diagram/__tests__/__snapshots__/LineDiagramWithStopsTest.tsx.snap index 93b08bb5a3..8deccc5407 100644 --- a/apps/site/assets/ts/schedule/components/line-diagram/__tests__/__snapshots__/LineDiagramWithStopsTest.tsx.snap +++ b/apps/site/assets/ts/schedule/components/line-diagram/__tests__/__snapshots__/LineDiagramWithStopsTest.tsx.snap @@ -2,22 +2,22 @@ exports[`LineDiagramWithStops renders and matches snapshot 1`] = ` " - +
      - - - - - - - - - - - - - + + + + + + + + + + + + + Line diagram for @@ -111,7 +111,7 @@ exports[`LineDiagramWithStops renders and matches snapshot 1`] = `
        - +
      1. @@ -143,7 +143,7 @@ exports[`LineDiagramWithStops renders and matches snapshot 1`] = `
      2. - +
      3. @@ -175,7 +175,7 @@ exports[`LineDiagramWithStops renders and matches snapshot 1`] = `
      4. - +
      5. @@ -207,7 +207,7 @@ exports[`LineDiagramWithStops renders and matches snapshot 1`] = `
      6. - +
      7. @@ -271,7 +271,7 @@ exports[`LineDiagramWithStops renders and matches snapshot 1`] = ` - +
      8. @@ -303,7 +303,7 @@ exports[`LineDiagramWithStops renders and matches snapshot 1`] = `
      9. - +
      10. @@ -367,7 +367,7 @@ exports[`LineDiagramWithStops renders and matches snapshot 1`] = ` - +
      11. @@ -399,7 +399,7 @@ exports[`LineDiagramWithStops renders and matches snapshot 1`] = `
      12. - +
      13. @@ -431,7 +431,7 @@ exports[`LineDiagramWithStops renders and matches snapshot 1`] = `
      14. - +
      15. @@ -458,7 +458,7 @@ exports[`LineDiagramWithStops renders and matches snapshot 1`] = `
      16. - +
      17. @@ -490,7 +490,7 @@ exports[`LineDiagramWithStops renders and matches snapshot 1`] = `
      18. - +
      19. diff --git a/apps/site/assets/ts/schedule/components/line-diagram/__tests__/__snapshots__/StopCardTest.tsx.snap b/apps/site/assets/ts/schedule/components/line-diagram/__tests__/__snapshots__/StopCardTest.tsx.snap index 155552f0c9..39b9c91fc1 100644 --- a/apps/site/assets/ts/schedule/components/line-diagram/__tests__/__snapshots__/StopCardTest.tsx.snap +++ b/apps/site/assets/ts/schedule/components/line-diagram/__tests__/__snapshots__/StopCardTest.tsx.snap @@ -2,7 +2,7 @@ exports[`StopCard renders and matches snapshot 1`] = ` " - +
      20. diff --git a/apps/site/assets/ts/schedule/components/line-diagram/graphics/Diagram.tsx b/apps/site/assets/ts/schedule/components/line-diagram/graphics/Diagram.tsx index a91beaf6e3..f36931cf9c 100644 --- a/apps/site/assets/ts/schedule/components/line-diagram/graphics/Diagram.tsx +++ b/apps/site/assets/ts/schedule/components/line-diagram/graphics/Diagram.tsx @@ -19,7 +19,7 @@ import VehicleIcons from "../VehicleIcons"; import { LiveDataByStop } from "../__line-diagram"; import { BASE_LINE_WIDTH, DiagonalHatchPattern } from "./graphic-helpers"; import Stop from "./Stop"; -import Line from "./Line"; +import { Line, SimpleLine } from "./Line"; import Merges from "./Merges"; interface Props { @@ -34,11 +34,11 @@ const routeName = (route: Route): string => isAGreenLineRoute(route) ? "Green Line" : route.name; const diagramDescription = ( - stopTree: StopTree, + pathLength: number, route: Route, directionId: DirectionId ): string => { - const text = `${longestPathLength(stopTree)} stops`; + const text = `${pathLength} stops`; const { direction_destinations: destinations, direction_names: names @@ -71,30 +71,93 @@ const branchingDescription = (stopTree: StopTree): string => { }; const LiveVehicleIconSet = ({ - stopTree, - stopId, + isStart, + stop, liveData }: { - stopTree: StopTree; - stopId: StopId; + isStart: boolean; + stop: RouteStop; liveData?: LiveDataByStop; }): ReactElement | null => { + const stopId = stop.id; if (!liveData || !liveData[stopId]) return null; const vehicles = uniqBy(liveData[stopId].vehicles, "id"); // Hide vehicles arriving to the origin from 'off the line' - const vehicleData = isStartNode(stopTree, stopId) + const vehicleData = isStart ? vehicles.filter(vehicle => vehicle.status === "stopped") : vehicles; return ( ); }; +interface SimpleProps { + routeStopList: RouteStop[]; + route: Route; + directionId: DirectionId; + alerts: Alert[]; + liveData?: LiveDataByStop; +} + +const SimpleDiagram = ({ + routeStopList, + route, + directionId, + alerts, + liveData +}: SimpleProps): ReactElement => ( + <> + {routeStopList.map((routeStop, index) => ( + + ))} + + Line diagram for {routeName(route)} + + {diagramDescription(routeStopList.length, route, directionId)} + + {DiagonalHatchPattern()} + {/* Draw lines between stops */ + routeStopList.map((routeStop, index) => { + const nextStop = routeStopList[index + 1]; + if (!nextStop) return null; + return ( + + ); + })} + + {/* Draw circles for each stop */ + routeStopList.map((routeStop, index) => ( + // eslint-disable-next-line react/no-array-index-key + + ))} + + +); + const Diagram = ({ stopTree, route, @@ -106,8 +169,8 @@ const Diagram = ({ {stopIds(stopTree).map(stopId => ( ))} @@ -122,7 +185,7 @@ const Diagram = ({ > Line diagram for {routeName(route)} - {diagramDescription(stopTree, route, directionId)} + {diagramDescription(longestPathLength(stopTree), route, directionId)} {hasBranchLines(stopTree) && branchingDescription(stopTree)} {DiagonalHatchPattern()} @@ -153,4 +216,4 @@ const Diagram = ({ ); -export default Diagram; +export { Diagram, SimpleDiagram }; diff --git a/apps/site/assets/ts/schedule/components/line-diagram/graphics/Line.tsx b/apps/site/assets/ts/schedule/components/line-diagram/graphics/Line.tsx index 0997b788f9..e9c3191638 100644 --- a/apps/site/assets/ts/schedule/components/line-diagram/graphics/Line.tsx +++ b/apps/site/assets/ts/schedule/components/line-diagram/graphics/Line.tsx @@ -97,4 +97,37 @@ const Line = ({ ); }; -export default Line; +const SimpleLine = ({ + fromId, + toId, + alerts +}: Omit): ReactElement | null => { + const fromCoords: StopCoord | null = useSelector( + (state: CoordState) => state[fromId] + ); + const toCoords: StopCoord | null = useSelector( + (state: CoordState) => state[toId] + ); + if (!fromCoords || !toCoords) return null; + + const x = BASE_LINE_WIDTH + 1; + const [, y1] = fromCoords; + const [, y2] = toCoords; + const strokeProp = + hasAnActiveDiversion(fromId, alerts) && hasAnActiveDiversion(toId, alerts) + ? { stroke: "url(#diagonalHatch)" } + : {}; + return ( + + ); +}; + +export { Line, SimpleLine }; diff --git a/apps/site/assets/ts/schedule/components/line-diagram/graphics/Merges.tsx b/apps/site/assets/ts/schedule/components/line-diagram/graphics/Merges.tsx index fb98485621..e902f7ad09 100644 --- a/apps/site/assets/ts/schedule/components/line-diagram/graphics/Merges.tsx +++ b/apps/site/assets/ts/schedule/components/line-diagram/graphics/Merges.tsx @@ -16,7 +16,7 @@ import { MERGE_RADIUS, StopCoord } from "./graphic-helpers"; -import Line from "./Line"; +import { Line } from "./Line"; interface Props { stopTree: StopTree; diff --git a/apps/site/assets/ts/schedule/components/line-diagram/graphics/useTreeStopPositions.ts b/apps/site/assets/ts/schedule/components/line-diagram/graphics/useTreeStopPositions.ts index 69777bdf6d..535672e0f1 100644 --- a/apps/site/assets/ts/schedule/components/line-diagram/graphics/useTreeStopPositions.ts +++ b/apps/site/assets/ts/schedule/components/line-diagram/graphics/useTreeStopPositions.ts @@ -2,7 +2,7 @@ import { useCallback, useEffect, useRef } from "react"; import { useDispatch } from "react-redux"; import { createStore, Store } from "redux"; import { stopIds } from "../../../../helpers/stop-tree"; -import { StopId, StopTree } from "../../__schedule"; +import { RouteStop, StopId, StopTree } from "../../__schedule"; import { branchPosition } from "../line-diagram-helpers"; import { BASE_LINE_WIDTH, @@ -14,10 +14,16 @@ import { export type RefMap = Map; +const isRouteStopList = ( + stopOrList: StopTree | RouteStop[] +): stopOrList is RouteStop[] => Array.isArray(stopOrList); + export const createStopTreeCoordStore = ( - stopTree: StopTree + stopTreeOrList: StopTree | RouteStop[] ): Store => { - const ids: StopId[] = stopIds(stopTree); + const ids: StopId[] = isRouteStopList(stopTreeOrList) + ? stopTreeOrList.map(rs => rs.id) + : stopIds(stopTreeOrList); const initialCoordState: CoordState = ids.reduce( (acc, id) => ({ ...acc, [id]: null }), @@ -39,14 +45,16 @@ const xCoordForStop = (stopTree: StopTree, id: StopId): number => BRANCH_SPACING * (branchPosition(stopTree, id) - 1) + BASE_LINE_WIDTH + 1; export default function useTreeStopPositions( - stopTree: StopTree + stopTreeOrList: StopTree | RouteStop[] ): [RefMap, () => void] { const stopRefsMap = useRef(new Map() as RefMap); const dispatchStopCoords = useDispatch(); const updateAllStops = useCallback((): void => { stopRefsMap.current.forEach((el, stopId) => { - const x = xCoordForStop(stopTree, stopId); + const x = isRouteStopList(stopTreeOrList) + ? BASE_LINE_WIDTH + 1 + : xCoordForStop(stopTreeOrList, stopId); let coordinates = null; if (el) { const { offsetTop, offsetHeight } = el; @@ -60,7 +68,7 @@ export default function useTreeStopPositions( coords: coordinates }); }); - }, [dispatchStopCoords, stopRefsMap, stopTree]); + }, [dispatchStopCoords, stopRefsMap, stopTreeOrList]); useEffect(() => { updateAllStops(); From 559e74ce57123189d59cd9db2d15fbfbd0c92b5a Mon Sep 17 00:00:00 2001 From: Cristen Jones Date: Thu, 28 Sep 2023 14:02:39 -0400 Subject: [PATCH 4/4] fixup: add index attribute to stops in list --- apps/site/assets/ts/app/helpers/testUtils.ts | 12 ++++++++++++ .../schedule/components/ScheduleDirection.tsx | 10 +++++++--- .../ts/schedule/components/__schedule.d.ts | 4 ++++ .../__tests__/ScheduleDirectionTest.tsx | 9 +++++---- .../components/line-diagram/LineDiagram.tsx | 9 +++++++-- .../line-diagram/LineDiagramWithStops.tsx | 9 ++++----- .../line-diagram/__tests__/LineDiagramTest.tsx | 3 ++- .../__tests__/LineDiagramWithStopsTest.tsx | 3 ++- .../line-diagram/__tests__/StopCardTest.tsx | 3 ++- .../line-diagram/graphics/Diagram.tsx | 17 ++++++++++------- 10 files changed, 55 insertions(+), 24 deletions(-) diff --git a/apps/site/assets/ts/app/helpers/testUtils.ts b/apps/site/assets/ts/app/helpers/testUtils.ts index e20620b8f9..480c1dfb79 100644 --- a/apps/site/assets/ts/app/helpers/testUtils.ts +++ b/apps/site/assets/ts/app/helpers/testUtils.ts @@ -1,6 +1,18 @@ /* eslint-disable */ import toJson, { Json } from "enzyme-to-json"; import { ReactWrapper } from "enzyme"; +import { + IndexedRouteStop, + StopTree +} from "../../schedule/components/__schedule"; + +export const testRouteStopListFromStopTree = ( + tree: StopTree +): IndexedRouteStop[] => + Object.values(tree.byId).map((node, index) => ({ + ...node.value, + routeIndex: index + })); export const createReactRoot = (): void => { document.body.innerHTML = diff --git a/apps/site/assets/ts/schedule/components/ScheduleDirection.tsx b/apps/site/assets/ts/schedule/components/ScheduleDirection.tsx index 760b9741f4..e3142964a4 100644 --- a/apps/site/assets/ts/schedule/components/ScheduleDirection.tsx +++ b/apps/site/assets/ts/schedule/components/ScheduleDirection.tsx @@ -4,7 +4,8 @@ import { RoutePatternsByDirection, EnhancedRoutePattern, StopTree, - RouteStop + RouteStop, + IndexedRouteStop } from "./__schedule"; import ScheduleDirectionMenu from "./direction/ScheduleDirectionMenu"; import ScheduleDirectionButton from "./direction/ScheduleDirectionButton"; @@ -81,9 +82,12 @@ export const fetchLineData = ( }) .then(({ stop_tree, route_stop_lists }) => { const stopTree = stop_tree ? fromStopTreeData(stop_tree) : null; + const routeStopListsWithIndices: IndexedRouteStop[][] = (route_stop_lists as RouteStop[][]).map( + rs_list => rs_list.map((rs, index) => ({ ...rs, routeIndex: index })) + ); dispatch({ type: "FETCH_COMPLETE", - payload: { stopTree, routeStopLists: route_stop_lists } + payload: { stopTree, routeStopLists: routeStopListsWithIndices } }); }) // @ts-ignore @@ -205,7 +209,7 @@ const ScheduleDirection = ({ const routeStopList = lineState.data && lineState.data.routeStopLists - ? (lineState.data.routeStopLists as RouteStop[][]).find( + ? (lineState.data.routeStopLists as IndexedRouteStop[][]).find( rsList => !!rsList.find(rs => rs.branch === state.routePattern.name) ) || [] : []; diff --git a/apps/site/assets/ts/schedule/components/__schedule.d.ts b/apps/site/assets/ts/schedule/components/__schedule.d.ts index 869fe0330b..a75e1e1ef5 100644 --- a/apps/site/assets/ts/schedule/components/__schedule.d.ts +++ b/apps/site/assets/ts/schedule/components/__schedule.d.ts @@ -115,6 +115,10 @@ export interface RouteStop { closed_stop_info: ClosedStopInfo | null; } +export interface IndexedRouteStop extends RouteStop { + routeIndex: number; +} + export interface SimpleStopMap { [key: string]: SimpleStop[]; } diff --git a/apps/site/assets/ts/schedule/components/__tests__/ScheduleDirectionTest.tsx b/apps/site/assets/ts/schedule/components/__tests__/ScheduleDirectionTest.tsx index 6c88536811..289b0f2876 100644 --- a/apps/site/assets/ts/schedule/components/__tests__/ScheduleDirectionTest.tsx +++ b/apps/site/assets/ts/schedule/components/__tests__/ScheduleDirectionTest.tsx @@ -1,7 +1,8 @@ import React from "react"; import { createReactRoot, - enzymeToJsonWithoutProps + enzymeToJsonWithoutProps, + testRouteStopListFromStopTree } from "../../../app/helpers/testUtils"; import { mount } from "enzyme"; import { @@ -33,7 +34,7 @@ const { stop_tree } = (lineDiagramData as unknown) as { stop_tree: StopTreeData; }; const stopTree: StopTree = fromStopTreeData(stop_tree); -const testRouteStopList = Object.values(stopTree.byId).map(node => node.value); +const testRouteStopList = testRouteStopListFromStopTree(stopTree); const route = { type: 3, @@ -546,7 +547,7 @@ describe("fetchLineData", () => { () => new Promise((resolve: Function) => resolve({ - json: () => lineDiagramData, + json: () => ({ stop_tree, route_stop_lists: [] }), ok: true, status: 200, statusText: "OK" @@ -563,7 +564,7 @@ describe("fetchLineData", () => { }); expect(spy).toHaveBeenCalledWith({ type: "FETCH_COMPLETE", - payload: { stopTree } + payload: { stopTree, routeStopLists: [] } }); }); }); diff --git a/apps/site/assets/ts/schedule/components/line-diagram/LineDiagram.tsx b/apps/site/assets/ts/schedule/components/line-diagram/LineDiagram.tsx index 00e62ccf76..f94baf391e 100644 --- a/apps/site/assets/ts/schedule/components/line-diagram/LineDiagram.tsx +++ b/apps/site/assets/ts/schedule/components/line-diagram/LineDiagram.tsx @@ -8,7 +8,12 @@ import { isSubwayRoute } from "../../../models/route"; import { Alert, DirectionId, Route } from "../../../__v3api"; import { getCurrentState, storeHandler } from "../../store/ScheduleStore"; import { changeOrigin } from "../ScheduleLoader"; -import { RouteStop, SelectedOrigin, StopTree } from "../__schedule"; +import { + IndexedRouteStop, + RouteStop, + SelectedOrigin, + StopTree +} from "../__schedule"; import { createStopTreeCoordStore } from "./graphics/useTreeStopPositions"; import LineDiagramWithStops from "./LineDiagramWithStops"; import StopCard from "./StopCard"; @@ -17,7 +22,7 @@ import { alertsByStop } from "../../../models/alert"; interface Props { stopTree: StopTree | null; route: Route; - routeStopList: RouteStop[]; + routeStopList: IndexedRouteStop[]; directionId: DirectionId; alerts: Alert[]; } diff --git a/apps/site/assets/ts/schedule/components/line-diagram/LineDiagramWithStops.tsx b/apps/site/assets/ts/schedule/components/line-diagram/LineDiagramWithStops.tsx index 7d8f5a7c85..c5e919a62a 100644 --- a/apps/site/assets/ts/schedule/components/line-diagram/LineDiagramWithStops.tsx +++ b/apps/site/assets/ts/schedule/components/line-diagram/LineDiagramWithStops.tsx @@ -8,7 +8,7 @@ import { } from "../../../helpers/stop-tree"; import { hasPredictionTime } from "../../../models/prediction"; import { Alert, DirectionId, Route } from "../../../__v3api"; -import { RouteStop, StopId, StopTree } from "../__schedule"; +import { IndexedRouteStop, RouteStop, StopId, StopTree } from "../__schedule"; import { Diagram, SimpleDiagram } from "./graphics/Diagram"; import useTreeStopPositions, { RefMap } from "./graphics/useTreeStopPositions"; import ExpandableBranch from "./ExpandableBranch"; @@ -18,7 +18,7 @@ import { alertsByStop } from "../../../models/alert"; interface Props { stopTree: StopTree | null; - routeStopList: RouteStop[]; + routeStopList: IndexedRouteStop[]; route: Route; directionId: DirectionId; alerts: Alert[]; @@ -312,10 +312,9 @@ const LineDiagramWithStops = ({ /> ) : ( <> - {routeStopList.map((routeStop, index) => ( + {routeStopList.map(routeStop => ( node.value); +const testRouteStopList = testRouteStopListFromStopTree(stopTree); const route = { type: 3 as RouteType, name: "route 1", diff --git a/apps/site/assets/ts/schedule/components/line-diagram/__tests__/LineDiagramWithStopsTest.tsx b/apps/site/assets/ts/schedule/components/line-diagram/__tests__/LineDiagramWithStopsTest.tsx index d33bd319e8..be17e102c2 100644 --- a/apps/site/assets/ts/schedule/components/line-diagram/__tests__/LineDiagramWithStopsTest.tsx +++ b/apps/site/assets/ts/schedule/components/line-diagram/__tests__/LineDiagramWithStopsTest.tsx @@ -9,6 +9,7 @@ import { cloneDeep } from "lodash"; import * as simpleLiveData from "./lineDiagramData/live-data.json"; import { LiveDataByStop } from "../__line-diagram"; import { Alert, InformedEntitySet, RouteType } from "../../../../__v3api"; +import { testRouteStopListFromStopTree } from "../../../../app/helpers/testUtils"; const stopTree: StopTree = { byId: { @@ -148,7 +149,7 @@ const stopTree: StopTree = { startingNodes: ["a1", "b1", "c1"] }; -const testRouteStopList = Object.values(stopTree.byId).map(node => node.value); +const testRouteStopList = testRouteStopListFromStopTree(stopTree); const store = UseTreeStopPositions.createStopTreeCoordStore(stopTree); const route = { diff --git a/apps/site/assets/ts/schedule/components/line-diagram/__tests__/StopCardTest.tsx b/apps/site/assets/ts/schedule/components/line-diagram/__tests__/StopCardTest.tsx index 9b088b382f..8d3542e3ec 100644 --- a/apps/site/assets/ts/schedule/components/line-diagram/__tests__/StopCardTest.tsx +++ b/apps/site/assets/ts/schedule/components/line-diagram/__tests__/StopCardTest.tsx @@ -18,6 +18,7 @@ import StopCard from "../StopCard"; import { LiveData } from "../__line-diagram"; import { render, screen, waitFor } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; +import { testRouteStopListFromStopTree } from "../../../../app/helpers/testUtils"; const stopTree: StopTree = { byId: { @@ -90,7 +91,7 @@ const stopTree: StopTree = { startingNodes: ["a"] }; const store = createStopTreeCoordStore(stopTree); -const testRouteStopList = Object.values(stopTree.byId).map(node => node.value); +const testRouteStopList = testRouteStopListFromStopTree(stopTree); const alertA: Alert = { id: "MOCK-ALERT-A", diff --git a/apps/site/assets/ts/schedule/components/line-diagram/graphics/Diagram.tsx b/apps/site/assets/ts/schedule/components/line-diagram/graphics/Diagram.tsx index f36931cf9c..347b3e00d1 100644 --- a/apps/site/assets/ts/schedule/components/line-diagram/graphics/Diagram.tsx +++ b/apps/site/assets/ts/schedule/components/line-diagram/graphics/Diagram.tsx @@ -13,7 +13,12 @@ import { } from "../../../../helpers/stop-tree"; import { isAGreenLineRoute } from "../../../../models/route"; import { Alert, DirectionId, Route } from "../../../../__v3api"; -import { RouteStop, StopId, StopTree } from "../../__schedule"; +import { + IndexedRouteStop, + RouteStop, + StopId, + StopTree +} from "../../__schedule"; import { diagramWidth } from "../line-diagram-helpers"; import VehicleIcons from "../VehicleIcons"; import { LiveDataByStop } from "../__line-diagram"; @@ -97,7 +102,7 @@ const LiveVehicleIconSet = ({ }; interface SimpleProps { - routeStopList: RouteStop[]; + routeStopList: IndexedRouteStop[]; route: Route; directionId: DirectionId; alerts: Alert[]; @@ -114,8 +119,7 @@ const SimpleDiagram = ({ <> {routeStopList.map((routeStop, index) => ( ( - // eslint-disable-next-line react/no-array-index-key - + routeStopList.map(routeStop => ( + ))}