Skip to content

Commit

Permalink
refactor(ScheduleDirection): permit null stopTree
Browse files Browse the repository at this point in the history
  • Loading branch information
thecristen committed Sep 27, 2023
1 parent f84fa45 commit 6d7ff5f
Show file tree
Hide file tree
Showing 18 changed files with 303 additions and 116 deletions.
18 changes: 12 additions & 6 deletions apps/site/assets/ts/schedule/components/ScheduleDirection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 (
<>
<div className="m-schedule-direction">
Expand All @@ -225,9 +229,10 @@ const ScheduleDirection = ({
<ScheduleDirectionButton dispatch={dispatch} />
) : null}
</div>
{isSubwayRoute(route) && hasValidTree && (
{isSubwayRoute(route) && (
<LineDiagram
stopTree={lineState.data.stopTree}
stopTree={lineState.data && lineState.data.stopTree}
routeStopList={routeStopList}
route={route}
directionId={state.directionId}
alerts={alerts}
Expand Down Expand Up @@ -259,9 +264,10 @@ const ScheduleDirection = ({
</a>
</>
)}
{!isSubwayRoute(route) && hasValidTree && (
{!isSubwayRoute(route) && (
<LineDiagram
stopTree={lineState.data.stopTree}
stopTree={lineState.data && lineState.data.stopTree}
routeStopList={routeStopList}
route={route}
directionId={state.directionId}
alerts={alerts}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ const ExpandableBranch = ({
<StopCard
key={stopId}
stopTree={stopTree}
routeStopList={[]}
stopId={stopId}
alerts={alertsByStop(alerts, stopId)}
onClick={handleStopClick}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ import StopCard from "./StopCard";
import { alertsByStop } from "../../../models/alert";

interface Props {
stopTree: StopTree;
stopTree: StopTree | null;
route: Route;
routeStopList: RouteStop[];
directionId: DirectionId;
alerts: Alert[];
}
Expand All @@ -41,17 +42,20 @@ const updateURL = (origin: SelectedOrigin, direction?: DirectionId): void => {

const LineDiagram = ({
stopTree,
routeStopList,
route,
directionId,
alerts
}: Props): ReactElement<HTMLElement> => {
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())
);
Expand Down Expand Up @@ -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]}
Expand All @@ -116,6 +121,7 @@ const LineDiagram = ({
<Provider store={stopTreeCoordStore}>
<LineDiagramWithStops
stopTree={stopTree}
routeStopList={routeStopList}
route={route}
directionId={directionId}
alerts={alerts}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,16 @@ import {
import { hasPredictionTime } from "../../../models/prediction";
import { Alert, DirectionId, Route } from "../../../__v3api";
import { RouteStop, StopId, StopTree } from "../__schedule";
import Diagram from "./graphics/Diagram";
import { Diagram, SimpleDiagram } from "./graphics/Diagram";
import useTreeStopPositions, { RefMap } from "./graphics/useTreeStopPositions";
import ExpandableBranch from "./ExpandableBranch";
import StopCard from "./StopCard";
import { LiveDataByStop } from "./__line-diagram";
import { alertsByStop } from "../../../models/alert";

interface Props {
stopTree: StopTree;
stopTree: StopTree | null;
routeStopList: RouteStop[];
route: Route;
directionId: DirectionId;
alerts: Alert[];
Expand Down Expand Up @@ -93,6 +94,7 @@ const NextStopOrBranch = ({
<StopCard
key={`stop-card-${terminalStopId}`}
stopTree={stopTree}
routeStopList={[]}
stopId={terminalStopId}
alerts={alertsByStop(alerts, terminalStopId)}
onClick={handleStopClick}
Expand Down Expand Up @@ -146,6 +148,7 @@ const NextStopOrBranch = ({
<StopCard
key={`stop-card-${startingId}`}
stopTree={stopTree}
routeStopList={[]}
stopId={startingId}
alerts={alertsByStop(alerts, startingId)}
onClick={handleStopClick}
Expand Down Expand Up @@ -181,6 +184,7 @@ const NextStopOrBranch = ({
<StopCard
key={stopId}
stopTree={stopTree}
routeStopList={[]}
stopId={stopId}
alerts={alertsByStop(alerts, stopId)}
onClick={handleStopClick}
Expand Down Expand Up @@ -210,6 +214,7 @@ const NextStopOrBranch = ({
<StopCard
key={stopId}
stopTree={stopTree}
routeStopList={[]}
stopId={stopId}
alerts={alertsByStop(alerts, stopId)}
onClick={handleStopClick}
Expand All @@ -234,6 +239,7 @@ const NextStopOrBranch = ({
<StopCard
key={stopId}
stopTree={stopTree}
routeStopList={[]}
stopId={stopId}
alerts={alertsByStop(alerts, stopId)}
onClick={handleStopClick}
Expand All @@ -244,14 +250,17 @@ const NextStopOrBranch = ({

const LineDiagramWithStops = ({
stopTree,
routeStopList,
route,
directionId,
alerts,
handleStopClick,
liveData
}: Props): ReactElement<HTMLElement> => {
// 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 || {}
Expand All @@ -273,23 +282,50 @@ const LineDiagramWithStops = ({
!anyCrowding ? "u-no-crowding-data" : ""
}`}
>
<Diagram
stopTree={stopTree}
route={route}
directionId={directionId}
alerts={alerts}
liveData={liveData}
/>
<ol>
<NextStopOrBranch
{stopTree ? (
<Diagram
stopTree={stopTree}
stopId={longestPathStartingId(stopTree)}
route={route}
directionId={directionId}
alerts={alerts}
liveData={liveData}
/>
) : (
<SimpleDiagram
routeStopList={routeStopList}
route={route}
directionId={directionId}
alerts={alerts}
mergingInBranches={[]}
splittingOffBranches={[]}
handleStopClick={handleStopClick}
liveData={liveData}
/>
)}
<ol>
{stopTree ? (
<NextStopOrBranch
stopTree={stopTree}
stopId={longestPathStartingId(stopTree)}
alerts={alerts}
mergingInBranches={[]}
splittingOffBranches={[]}
handleStopClick={handleStopClick}
liveData={liveData}
/>
) : (
<>
{routeStopList.map((routeStop, index) => (
<StopCard
// eslint-disable-next-line react/no-array-index-key
key={`stop-card-${index}-${routeStop.id}`}
stopTree={null}
routeStopList={routeStopList}
stopId={routeStop.id}
alerts={alertsByStop(alerts, routeStop.id)}
onClick={handleStopClick}
liveData={liveData?.[routeStop.id]}
/>
))}
</>
)}
</ol>
</div>
</StopRefContext.Provider>
Expand Down
46 changes: 28 additions & 18 deletions apps/site/assets/ts/schedule/components/line-diagram/StopCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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";
Expand All @@ -125,29 +120,40 @@ const Alert = (): JSX.Element => (
const StopCard = ({
stopTree,
stopId,
routeStopList,
alerts,
onClick,
liveData,
searchQuery
}: Props): ReactElement<HTMLElement> => {
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 (
<li
className="m-schedule-diagram__stop"
style={{
paddingLeft: searchQuery ? "0.5rem" : `${width(stopTree, stopId)}px`
paddingLeft: searchQuery ? "0.5rem" : `${left}px`
}}
>
<section className="m-schedule-diagram__content">
<GlxOpen pageType="line-diagram" stopId={stopId} />
{hasBranchLabel(stopTree, stopId) && (
{stopTree && hasBranchLabel(stopTree, stopId) && (
<div className="u-bold u-small-caps">{lineName(routeStop)}</div>
)}
<header
Expand All @@ -164,8 +170,8 @@ const StopCard = ({
</header>

<div className="m-schedule-diagram__stop-details">
{StopConnections(stopId, connectionsFor(routeStop, stopTree))}
{showPrediction(stopTree, stopId, liveData) ? (
{StopConnections(stopId, connections)}
{hasLivePredictions(liveData) && !isEnd ? (
<StopPredictions
headsigns={liveData!.headsigns}
isCommuterRail={
Expand All @@ -181,15 +187,19 @@ const StopCard = ({
)}
</div>

{!isEndNode(stopTree, stopId) &&
hasUpcomingDeparturesIfSubway(stopTree, stopId, liveData) && (
{!isEnd &&
(stopTree
? hasUpcomingDeparturesIfSubway(stopTree, stopId, liveData)
: true) && (
<footer className="m-schedule-diagram__footer">
<button
className="btn btn-link"
type="button"
onClick={() => onClick(routeStop)}
>
{schedulesButtonLabel(stopTree, stopId)}
{schedulesButtonLabel(
stopTree ? routeForStop(stopTree, stopId) : routeStop.route
)}
</button>
</footer>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down
Loading

0 comments on commit 6d7ff5f

Please sign in to comment.