diff --git a/assets/src/components/shuttleMapPage.tsx b/assets/src/components/shuttleMapPage.tsx index 9f1b1b1f7..f6e8f2c1b 100644 --- a/assets/src/components/shuttleMapPage.tsx +++ b/assets/src/components/shuttleMapPage.tsx @@ -15,8 +15,8 @@ const findSelectedVehicle = ( const ShuttleMapPage = ({}): ReactElement => { const [state] = useContext(StateDispatchContext) - const shuttles = useContext(ShuttleVehiclesContext) - const selectedShuttles = shuttles.filter(shuttle => + const shuttles: Vehicle[] | null = useContext(ShuttleVehiclesContext) + const selectedShuttles: Vehicle[] = (shuttles || []).filter(shuttle => state.selectedShuttleRunIds.includes(shuttle.runId!) ) const selectedVehicle = findSelectedVehicle( diff --git a/assets/src/components/shuttlePicker.tsx b/assets/src/components/shuttlePicker.tsx index 9e2b74df9..635a14742 100644 --- a/assets/src/components/shuttlePicker.tsx +++ b/assets/src/components/shuttlePicker.tsx @@ -4,6 +4,7 @@ import { StateDispatchContext } from "../contexts/stateDispatchContext" import { uniq } from "../helpers/array" import { RunId, Vehicle } from "../realtime" import { deselectShuttleRun, selectShuttleRun } from "../state" +import Loading from "./loading" interface KnownShuttle { name: string @@ -42,35 +43,50 @@ const KNOWN_RUN_IDS: RunId[] = KNOWN_SHUTTLES.map( ) const ShuttlePicker = ({}): ReactElement => { - const shuttles: Vehicle[] = useContext(ShuttleVehiclesContext) + const shuttles: Vehicle[] | null = useContext(ShuttleVehiclesContext) + + return ( +
+ {shuttles === null ? ( + + ) : ( + <> +
Run #
+
    + +
+ + )} +
+ ) +} + +const RunIdButtons = ({ shuttles }: { shuttles: Vehicle[] }) => { const activeRunIds: RunId[] = uniq(shuttles .map(v => v.runId) .filter(runId => runId !== null) as RunId[]) return ( -
-
Run #
-
    - {KNOWN_SHUTTLES.map(knownShuttle => ( + <> + {KNOWN_SHUTTLES.map(knownShuttle => ( + + ))} + {activeRunIds.map(runId => + KNOWN_RUN_IDS.includes(runId) ? null : ( - ))} - {activeRunIds.map(runId => - KNOWN_RUN_IDS.includes(runId) ? null : ( - - ) - )} -
-
+ ) + )} + ) } diff --git a/assets/src/contexts/shuttleVehiclesContext.tsx b/assets/src/contexts/shuttleVehiclesContext.tsx index c641ad89a..b80f73678 100644 --- a/assets/src/contexts/shuttleVehiclesContext.tsx +++ b/assets/src/contexts/shuttleVehiclesContext.tsx @@ -2,13 +2,13 @@ import React, { Context, createContext, ReactElement } from "react" import { Vehicle } from "../realtime" interface Props { - shuttles: Vehicle[] + shuttles: Vehicle[] | null children: ReactElement } -export const ShuttleVehiclesContext: Context = createContext( - [] as Vehicle[] -) +export const ShuttleVehiclesContext: Context = createContext< + Vehicle[] | null +>(null) export const ShuttleVehiclesProvider = ({ shuttles, children }: Props) => ( diff --git a/assets/src/hooks/useShuttleVehicles.ts b/assets/src/hooks/useShuttleVehicles.ts index 816d7b673..44f8437c1 100644 --- a/assets/src/hooks/useShuttleVehicles.ts +++ b/assets/src/hooks/useShuttleVehicles.ts @@ -4,7 +4,7 @@ import { VehicleData, vehicleFromData } from "../models/vehicleData" import { Vehicle } from "../realtime" interface State { - shuttles: Vehicle[] + shuttles: Vehicle[] | null channel?: Channel } @@ -19,7 +19,7 @@ const reducer = (state: State, action: Action): State => { } const initialState: State = { - shuttles: [], + shuttles: null, } interface SetShuttlesAction { @@ -76,7 +76,7 @@ const subscribe = (socket: Socket, dispatch: Dispatch): Channel => { return channel } -const useShuttleVehicles = (socket: Socket | undefined): Vehicle[] => { +const useShuttleVehicles = (socket: Socket | undefined): Vehicle[] | null => { const [state, dispatch] = useReducer(reducer, initialState) const { channel, shuttles } = state useEffect(() => { diff --git a/assets/tests/components/__snapshots__/shuttlePicker.test.tsx.snap b/assets/tests/components/__snapshots__/shuttlePicker.test.tsx.snap index f67939e42..3d2a338ed 100644 --- a/assets/tests/components/__snapshots__/shuttlePicker.test.tsx.snap +++ b/assets/tests/components/__snapshots__/shuttlePicker.test.tsx.snap @@ -87,3 +87,11 @@ exports[`ShuttlePicker renders 1`] = ` `; + +exports[`ShuttlePicker renders loading state 1`] = ` +
+ loading... +
+`; diff --git a/assets/tests/components/shuttlePicker.test.tsx b/assets/tests/components/shuttlePicker.test.tsx index 715af433c..2262603ef 100644 --- a/assets/tests/components/shuttlePicker.test.tsx +++ b/assets/tests/components/shuttlePicker.test.tsx @@ -54,6 +54,15 @@ const vehicle: Vehicle = { } describe("ShuttlePicker", () => { + test("renders loading state", () => { + const tree = renderer.create( + + + + ) + expect(tree).toMatchSnapshot() + }) + test("renders", () => { /* 999-0501: known, no active shuttles, unselected diff --git a/assets/tests/hooks/useShuttles.test.ts b/assets/tests/hooks/useShuttleRoutes.test.ts similarity index 100% rename from assets/tests/hooks/useShuttles.test.ts rename to assets/tests/hooks/useShuttleRoutes.test.ts diff --git a/assets/tests/hooks/useShuttleVehicles.test.ts b/assets/tests/hooks/useShuttleVehicles.test.ts index 1dedf1a2b..5e43d6b6b 100644 --- a/assets/tests/hooks/useShuttleVehicles.test.ts +++ b/assets/tests/hooks/useShuttleVehicles.test.ts @@ -189,9 +189,9 @@ const shuttles: Vehicle[] = [ ] describe("useShuttleVehicles", () => { - test("shuttle list is empty to start with", () => { + test("returns null while loading", () => { const { result } = renderHook(() => useShuttleVehicles(undefined)) - expect(result.current).toEqual([]) + expect(result.current).toEqual(null) }) test("initializing the hook subscribes to the shuttles channel", () => {