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(ts/hooks/usePanelState): add setTabMode API #2275

Merged
merged 7 commits into from
Nov 16, 2023
22 changes: 18 additions & 4 deletions assets/src/components/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import LadderPage from "./ladderPage"
import Modal from "./modal"
import SettingsPage from "./settingsPage"
import ShuttleMapPage from "./shuttleMapPage"
import LateView from "./lateView"
import { allOpenRouteIds } from "../models/routeTab"
import Nav from "./nav"
import RightPanel from "./rightPanel"
Expand All @@ -28,6 +27,8 @@ import MapPage from "./mapPage"
import SearchPage from "./searchPage"
import { OpenView, isPagePath } from "../state/pagePanelState"
import { usePanelStateFromStateDispatchContext } from "../hooks/usePanelState"
import PropertiesPanel from "./propertiesPanel"
import { isGhost, isVehicle } from "../models/vehicle"

export const AppRoutes = () => {
useAppcues()
Expand All @@ -37,7 +38,9 @@ export const AppRoutes = () => {

const {
setPath,
currentView: { openView, selectedVehicleOrGhost },
setTabMode,
closeView,
currentView: { openView, selectedVehicleOrGhost, vppTabMode },
} = usePanelStateFromStateDispatchContext()

// Keep panel in sync with current path
Expand Down Expand Up @@ -74,9 +77,20 @@ export const AppRoutes = () => {
<>
<Outlet />
<RightPanel
selectedVehicleOrGhost={selectedVehicleOrGhost}
openView={openView}
propertiesPanel={
selectedVehicleOrGhost &&
(isVehicle(selectedVehicleOrGhost) ||
isGhost(selectedVehicleOrGhost)) ? (
<PropertiesPanel
selectedVehicleOrGhost={selectedVehicleOrGhost}
tabMode={vppTabMode ?? "status"}
onChangeTabMode={setTabMode}
onClosePanel={closeView}
/>
) : undefined
}
/>
{openView === OpenView.Late ? <LateView /> : null}
</>
}
>
Expand Down
45 changes: 35 additions & 10 deletions assets/src/components/propertiesPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,22 @@ import StaleDataPropertiesPanel from "./propertiesPanel/staleDataPropertiesPanel
import VehiclePropertiesPanel from "./propertiesPanel/vehiclePropertiesPanel"
import { TabMode } from "./propertiesPanel/tabPanels"

interface Props {
interface Props extends IndividualPropertiesPanelProps {
selectedVehicleOrGhost: Vehicle | Ghost
initialTab?: TabMode
onClosePanel: () => void
}

export type IndividualPropertiesPanelProps = {
export type TabModeProps = {
tabMode: TabMode
onChangeTabMode: React.Dispatch<React.SetStateAction<TabMode>>
onChangeTabMode: (tabMode: TabMode) => void
onClosePanel: () => void
}

export type ClosePanelProps = {
onClosePanel: () => void
}

export type IndividualPropertiesPanelProps = TabModeProps & ClosePanelProps

export const hideMeIfNoCrowdingTooltip = (hideMe: () => void) => {
const noTooltipOpen =
document.getElementsByClassName("c-crowding-diagram__crowding-tooltip")
Expand All @@ -31,15 +35,15 @@ export const hideMeIfNoCrowdingTooltip = (hideMe: () => void) => {

const PropertiesPanel = ({
selectedVehicleOrGhost,
initialTab = "status",
tabMode,
onChangeTabMode,
onClosePanel,
}: Props) => {
const { socket } = useSocket()
const liveVehicle = useVehicleForId(socket, selectedVehicleOrGhost.id)
const [mostRecentVehicle, setMostRecentVehicle] = useState<Vehicle | Ghost>(
liveVehicle || selectedVehicleOrGhost
)
const [tabMode, setTabMode] = useState<TabMode>(initialTab)

useEffect(() => {
if (liveVehicle) {
Expand All @@ -55,21 +59,21 @@ const PropertiesPanel = ({
<StaleDataPropertiesPanel
selectedVehicle={mostRecentVehicle}
tabMode={tabMode}
onChangeTabMode={setTabMode}
onChangeTabMode={onChangeTabMode}
onClosePanel={onClosePanel}
/>
) : isVehicle(mostRecentVehicle) ? (
<VehiclePropertiesPanel
selectedVehicle={mostRecentVehicle}
tabMode={tabMode}
onChangeTabMode={setTabMode}
onChangeTabMode={onChangeTabMode}
onClosePanel={onClosePanel}
/>
) : (
<GhostPropertiesPanel
selectedGhost={mostRecentVehicle}
tabMode={tabMode}
onChangeTabMode={setTabMode}
onChangeTabMode={onChangeTabMode}
onClosePanel={onClosePanel}
/>
)}
Expand All @@ -86,4 +90,25 @@ const PropertiesPanel = ({
)
}

interface PropertiesPanelWithTabsStateProps extends Props {
initialTab?: TabMode
}

const PropertiesPanelWithTabState = ({
initialTab = "status",
...props
}: Omit<PropertiesPanelWithTabsStateProps, "tabMode" | "onChangeTabMode">) => {
const [tabMode, setTabMode] = useState<TabMode>(initialTab)

return (
<PropertiesPanel
{...props}
tabMode={tabMode}
onChangeTabMode={setTabMode}
/>
)
}

PropertiesPanel.WithTabState = PropertiesPanelWithTabState

export default PropertiesPanel
9 changes: 3 additions & 6 deletions assets/src/components/propertiesPanel/header.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { Dispatch, SetStateAction, useContext } from "react"
import React, { useContext } from "react"
import { useRoute } from "../../contexts/routesContext"
import { StateDispatchContext } from "../../contexts/stateDispatchContext"
import { joinClasses } from "../../helpers/dom"
Expand All @@ -20,16 +20,13 @@ import { Ghost, Vehicle, VehicleInScheduledService } from "../../realtime"
import { RouteVariantName } from "../routeVariantName"
import VehicleIcon, { Size, vehicleOrientation } from "../vehicleIcon"
import TabList from "./tabList"
import { TabMode } from "./tabPanels"
import { currentRouteTab } from "../../models/routeTab"
import ViewHeader from "../viewHeader"
import { usePanelStateFromStateDispatchContext } from "../../hooks/usePanelState"
import { ClosePanelProps, TabModeProps } from "../propertiesPanel"

interface Props {
interface Props extends TabModeProps, ClosePanelProps {
vehicle: Vehicle | Ghost
tabMode: TabMode
onChangeTabMode: Dispatch<SetStateAction<TabMode>>
onClosePanel: () => void
}

const ScheduleAdherenceStatusIcon = () => (
Expand Down
23 changes: 11 additions & 12 deletions assets/src/components/propertiesPanel/staleDataPropertiesPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React, { Dispatch, SetStateAction, useContext } from "react"
import React, { useContext } from "react"
import { hasBlockWaiver } from "../../models/blockWaiver"
import { Vehicle } from "../../realtime"
import BlockWaiverList from "./blockWaiverList"
import TabPanels, { TabMode } from "./tabPanels"
import TabPanels from "./tabPanels"
import { Card, CardBody } from "../card"
import VehicleIcon, { Orientation, Size } from "../vehicleIcon"
import { StateDispatchContext } from "../../contexts/stateDispatchContext"
Expand All @@ -28,8 +28,8 @@ const StaleDataPropertiesPanel: React.FC<Props> = ({
<StaleDataHeader
vehicle={selectedVehicle}
tabMode={tabMode}
setTabMode={onChangeTabMode}
closePanel={onClosePanel}
onChangeTabMode={onChangeTabMode}
onClosePanel={onClosePanel}
/>
{isVehicleInScheduledService(selectedVehicle) ? (
<TabPanels
Expand All @@ -44,12 +44,11 @@ const StaleDataPropertiesPanel: React.FC<Props> = ({
)
}

const StaleDataHeader: React.FC<{
vehicle: Vehicle
tabMode: TabMode
setTabMode: Dispatch<SetStateAction<TabMode>>
closePanel: () => void
}> = ({ vehicle, tabMode, setTabMode, closePanel }) => {
const StaleDataHeader: React.FC<
{
vehicle: Vehicle
} & IndividualPropertiesPanelProps
> = ({ vehicle, tabMode, onChangeTabMode, onClosePanel }) => {
const [{ userSettings }] = useContext(StateDispatchContext)
const {
currentView: { previousView },
Expand All @@ -60,7 +59,7 @@ const StaleDataHeader: React.FC<{
<div className="c-properties-panel__header-wrapper">
<ViewHeader
title="Vehicles"
closeView={closePanel}
closeView={onClosePanel}
backlinkToView={previousView}
followBacklink={openPreviousView}
/>
Expand All @@ -81,7 +80,7 @@ const StaleDataHeader: React.FC<{
</div>
</div>
{vehicle.isShuttle || (
<TabList activeTab={tabMode} setActiveTab={setTabMode} />
<TabList activeTab={tabMode} setActiveTab={onChangeTabMode} />
)}
</div>
)
Expand Down
6 changes: 3 additions & 3 deletions assets/src/components/propertiesPanel/tabList.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React, { Dispatch, SetStateAction } from "react"
import React from "react"

import { TabMode } from "./tabPanels"

interface Props {
activeTab: TabMode
setActiveTab: Dispatch<SetStateAction<TabMode>>
setActiveTab: (tabMode: TabMode) => void
}

const TabStatusIcon = () => (
Expand All @@ -31,7 +31,7 @@ const Tab = ({
}: {
tabName: TabMode
activeTab: TabMode
setActiveTab: Dispatch<SetStateAction<TabMode>>
setActiveTab: (tabMode: TabMode) => void
}) => {
const classes =
tabName === activeTab ? "c-tabs__tab c-tabs__tab--selected" : "c-tabs__tab"
Expand Down
38 changes: 16 additions & 22 deletions assets/src/components/rightPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,29 @@
import React, { ReactElement } from "react"
import { Ghost, Vehicle } from "../realtime.d"
import React, { ReactElement, ReactNode } from "react"
import NotificationDrawer from "./notificationDrawer"
import PropertiesPanel from "./propertiesPanel"
import SwingsView from "./swingsView"
import { OpenView } from "../state/pagePanelState"
import { usePanelStateFromStateDispatchContext } from "../hooks/usePanelState"
import LateView from "./lateView"

const RightPanel = ({
selectedVehicleOrGhost,
}: {
selectedVehicleOrGhost?: Vehicle | Ghost | null
}): ReactElement<HTMLElement> | null => {
const {
currentView: { openView },
closeView,
} = usePanelStateFromStateDispatchContext()
type RightPanelProps = {
openView: OpenView
propertiesPanel?: ReactNode
}

if (selectedVehicleOrGhost) {
return (
<PropertiesPanel
selectedVehicleOrGhost={selectedVehicleOrGhost}
onClosePanel={closeView}
/>
)
const RightPanel = ({
openView,
propertiesPanel,
}: RightPanelProps): ReactElement | null => {
if (propertiesPanel !== undefined) {
return <>{propertiesPanel}</>
} else if (openView === OpenView.Swings) {
return <SwingsView />
} else if (openView === OpenView.Late) {
return <LateView />
} else if (openView === OpenView.NotificationDrawer) {
return <NotificationDrawer />
} else {
return null
}

return null
}

export default RightPanel
8 changes: 4 additions & 4 deletions assets/src/hooks/usePanelState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
openSwingsView,
selectVehicle,
setPath,
setTabMode,
} from "../state/pagePanelState"

/**
Expand Down Expand Up @@ -43,10 +44,9 @@ export const usePanelStateForViewState = (
dispatch(setPath(path))
}
},
openVehiclePropertiesPanel: (
vehicle: VehicleType,
_initialView?: TabMode
) => dispatch(selectVehicle(vehicle)),
setTabMode: (tabMode: TabMode) => dispatch(setTabMode(tabMode)),
openVehiclePropertiesPanel: (vehicle: VehicleType, initialView?: TabMode) =>
dispatch(selectVehicle(vehicle, initialView ?? "status")),
openLateView: () => dispatch(openLateView()),
openSwingsView: () => dispatch(openSwingsView()),
openNotificationDrawer: () => dispatch(openNotificaitonDrawer()),
Expand Down
Loading