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

Link VPC run number to VPP #2263

Merged
merged 20 commits into from
Oct 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
02c4a1f
chore: add search-maps-on-mobile feature flag
lemald Oct 16, 2023
c7ccf89
refactor: start lifting tab state into PropertiesPanel component
lemald Oct 16, 2023
12c1453
refactor: move GhostPropertiesPanel tabmode to props
lemald Oct 17, 2023
7349e6a
refactor: StaleDataPropertiesPanel tabmode refactor
lemald Oct 17, 2023
abfcb05
refactor: move closing of properties panel into callback prop
lemald Oct 17, 2023
aef5254
test: more tests for setTabMode callbacks
lemald Oct 17, 2023
10b4831
refactor: remove some reliance on useState / useEffect
lemald Oct 17, 2023
42a2a0e
refactor: modify mapModeForUser to prevent recursive import
lemald Oct 19, 2023
66f0f1c
feat: ability to select VPP from VPC run number
lemald Oct 18, 2023
a4f57d6
test: more tests for closePanel callback
lemald Oct 20, 2023
f3bb22c
refactor: better name for selected vehicle state variable in MapPage
lemald Oct 20, 2023
6effc1b
refactor: consistent tense in callback names
lemald Oct 20, 2023
f879b5c
refactor(tests): better query for selected VPP tab
lemald Oct 20, 2023
b9e6237
refactor(tests): clean up default mocks in mapPage.test.tsx
lemald Oct 23, 2023
e22580c
refactor(tests): clean up default mocks in propertiesPanel.test.tsx
lemald Oct 23, 2023
2f4137f
refactor: common type for shared properties panel props
lemald Oct 23, 2023
4d699b6
refactor: rename setTabMode to onChangeTabMode
lemald Oct 23, 2023
2642ff9
refactor: rename closePanel to onClosePanel
lemald Oct 23, 2023
c105b6e
refactor: also rename props on properties panel header component
lemald Oct 23, 2023
dbe26ee
fix: focus state for run number in VPC
lemald Oct 26, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions assets/css/_skate_ui.scss
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,22 @@ $font-weights: (
color: var(--font-color-on-light-700);
}

.kv-value--clickable {
color: var(--font-color-text-clickable);
font-weight: var(--font-weight-semi);
text-decoration: underline;

&:hover {
color: $color-eggplant-500;
}

&:focus {
color: $color-eggplant-500;
border: 1px solid $color-eggplant-700;
border-radius: 3px;
}
}

.headsign {
font-weight: var(--font-weight-semi);
font-size: var(--font-size-m);
Expand Down
8 changes: 6 additions & 2 deletions assets/src/components/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import Nav from "./nav"
import RightPanel from "./rightPanel"
import { mapModeForUser } from "../util/mapMode"
import { Ghost, VehicleInScheduledService } from "../realtime"
import MapPage from "./mapPage"
import SearchPage from "./searchPage"

export const AppRoutes = () => {
useAppcues()
Expand All @@ -48,6 +50,8 @@ export const AppRoutes = () => {

const mapMode = mapModeForUser()

const mapElement = mapMode.path === "/map" ? <MapPage /> : <SearchPage />

return (
<div className="l-app">
<div className="l-app__banner">
Expand Down Expand Up @@ -79,12 +83,12 @@ export const AppRoutes = () => {
/>
<BrowserRoute path="/settings" element={<SettingsPage />} />
{mapMode.supportsRightPanel ? (
<BrowserRoute path={mapMode.path} element={mapMode.element} />
<BrowserRoute path={mapMode.path} element={mapElement} />
) : null}
</Route>
<Route>
{!mapMode.supportsRightPanel ? (
<BrowserRoute path={mapMode.path} element={mapMode.element} />
<BrowserRoute path={mapMode.path} element={mapElement} />
) : null}
</Route>
</Routes>
Expand Down
115 changes: 71 additions & 44 deletions assets/src/components/mapPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ import { LocationSearchResult } from "../models/locationSearchResult"
import LocationCard from "./mapPage/locationCard"
import { useLocationSearchResultById } from "../hooks/useLocationSearchResultById"
import { fullStoryEvent } from "../helpers/fullStory"
import PropertiesPanel from "./propertiesPanel"
import inTestGroup, { TestGroups } from "../userInTestGroup"

const SearchMode = ({
onSelectVehicleResult,
Expand Down Expand Up @@ -74,9 +76,11 @@ const SearchMode = ({
const SelectedVehicle = ({
vehicleId,
setSelection,
onRunClicked,
}: {
vehicleId: VehicleId
setSelection: (selectedEntity: SelectedEntity | null) => void
onRunClicked?: (vehicleOrGhost: Vehicle | Ghost) => void
}) => {
// TODO: When using socket from context, this doesn't work as-is
// Presumably because the useMostRecentVehicleById hook is being used twice, but
Expand Down Expand Up @@ -106,6 +110,7 @@ const SelectedVehicle = ({
vehicleOrGhost={selectedVehicleOrGhost}
key={selectedVehicleOrGhost.id}
onRouteVariantNameClicked={onRouteClicked || undefined}
onRunClick={onRunClicked}
/>
)
}
Expand Down Expand Up @@ -134,10 +139,12 @@ const Selection = ({
selectedEntity,
setSelection,
fetchedSelectedLocation,
onVehicleRunClicked,
}: {
selectedEntity: SelectedEntity
setSelection: (selectedEntity: SelectedEntity | null) => void
fetchedSelectedLocation: LocationSearchResult | null
onVehicleRunClicked?: (vehicleOrGhost: Vehicle | Ghost) => void
}): ReactElement => {
const [{ searchPageState }, dispatch] = useContext(StateDispatchContext)
const selectRoutePattern = (routePattern: RoutePattern) => {
Expand Down Expand Up @@ -186,6 +193,7 @@ const Selection = ({
<SelectedVehicle
vehicleId={selectedEntity.vehicleId}
setSelection={setSelection}
onRunClicked={onVehicleRunClicked}
/>
) : selectedEntity.type === SelectedEntityType.RoutePattern ? (
<SelectedRoute
Expand All @@ -211,6 +219,10 @@ const MapPage = (): ReactElement<HTMLDivElement> => {
const [{ searchPageState, openView }, dispatch] =
useContext(StateDispatchContext),
{ selectedEntity = null } = searchPageState
const [
selectedRightPanelVehicleOrGhost,
setSelectedRightPanelVehicleOrGhost,
] = useState<Vehicle | Ghost | null>(null)

useEffect(() => {
// don't dispatch closeView if the VPP is open
Expand Down Expand Up @@ -286,61 +298,76 @@ const MapPage = (): ReactElement<HTMLDivElement> => {
}

return (
<div
className="c-map-page inherit-box border-box"
aria-label="Search Map Page"
>
<>
<div
className={joinClasses([
"c-map-page__input-and-results",
searchOpen
? "c-map-page__input-and-results--visible"
: "c-map-page__input-and-results--hidden",
])}
aria-label="Map Search Panel"
className="c-map-page inherit-box border-box"
aria-label="Search Map Page"
>
<DrawerTab
isVisible={searchOpen}
toggleVisibility={toggleSearchDrawer}
/>
{selectedEntity ? (
<Selection
<div
className={joinClasses([
"c-map-page__input-and-results",
searchOpen
? "c-map-page__input-and-results--visible"
: "c-map-page__input-and-results--hidden",
])}
aria-label="Map Search Panel"
>
<DrawerTab
isVisible={searchOpen}
toggleVisibility={toggleSearchDrawer}
/>
{selectedEntity ? (
<Selection
selectedEntity={selectedEntity}
setSelection={(...args) => {
setFollowerShouldSetZoomLevel(false)
setVehicleSelection(...args)
}}
fetchedSelectedLocation={fetchedSelectedLocation}
onVehicleRunClicked={
inTestGroup(TestGroups.SearchMapsOnMobile)
? (vehicleOrGhost: Vehicle | Ghost) =>
setSelectedRightPanelVehicleOrGhost(vehicleOrGhost)
: undefined
}
/>
) : (
<SearchMode
onSelectVehicleResult={(...args) => {
setFollowerShouldSetZoomLevel(true)
selectVehicleResult(...args)
}}
onSelectLocationResult={selectLocationResult}
/>
)}
</div>
<div className="c-map-page__map">
<MapDisplay
selectedEntity={selectedEntity}
setSelection={(...args) => {
setFollowerShouldSetZoomLevel(false)
setVehicleSelection(...args)
}}
fetchedSelectedLocation={fetchedSelectedLocation}
initializeRouteFollowerEnabled={followerShouldSetZoomLevel === true}
vehicleUseCurrentZoom={followerShouldSetZoomLevel === false}
onInterruptVehicleFollower={
(followerShouldSetZoomLevel === false || undefined) &&
(() => {
setFollowerShouldSetZoomLevel(false)
})
}
/>
) : (
<SearchMode
onSelectVehicleResult={(...args) => {
setFollowerShouldSetZoomLevel(true)
selectVehicleResult(...args)
}}
onSelectLocationResult={selectLocationResult}
/>
)}
</div>
</div>
<div className="c-map-page__map">
<MapDisplay
selectedEntity={selectedEntity}
setSelection={(...args) => {
setFollowerShouldSetZoomLevel(false)
setVehicleSelection(...args)
}}
fetchedSelectedLocation={fetchedSelectedLocation}
initializeRouteFollowerEnabled={followerShouldSetZoomLevel === true}
vehicleUseCurrentZoom={followerShouldSetZoomLevel === false}
onInterruptVehicleFollower={
(followerShouldSetZoomLevel === false || undefined) &&
(() => {
setFollowerShouldSetZoomLevel(false)
})
}
{selectedRightPanelVehicleOrGhost && (
<PropertiesPanel
selectedVehicleOrGhost={selectedRightPanelVehicleOrGhost}
onClosePanel={() => setSelectedRightPanelVehicleOrGhost(null)}
initialTab="run"
/>
</div>
</div>
)}
</>
)
}

Expand Down
33 changes: 28 additions & 5 deletions assets/src/components/mapPage/vehiclePropertiesCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ interface TrNameValueProps {
children: ReactNode
idPrefix?: string
sensitivity?: HideSensitiveInfo
onValueClick?: () => void
}

const maskClass = "fs-mask"
Expand All @@ -84,6 +85,7 @@ const TrNameValue = ({
children: value,
idPrefix,
sensitivity: sensitive = HideSensitiveInfo.None,
onValueClick,
}: TrNameValueProps): React.ReactElement => {
const id = (idPrefix ?? name) + useId()
return (
Expand All @@ -102,15 +104,28 @@ const TrNameValue = ({
])}
aria-labelledby={id}
>
{value}
{onValueClick ? (
<button className="kv-value--clickable" onClick={onValueClick}>
{value}
</button>
) : (
<>{value}</>
)}
</td>
</tr>
)
}

type VehicleWorkInfoEventProps = {
onRunClick?: (vehicleOrGhost: Vehicle | Ghost) => void
}

type VehicleWorkInfoProps = VehicleOrGhostProp & VehicleWorkInfoEventProps

const VehicleWorkInfo = ({
vehicleOrGhost,
}: VehicleOrGhostProp): React.ReactElement => {
onRunClick,
}: VehicleWorkInfoProps): React.ReactElement => {
const isLoggedOutVehicle =
isVehicle(vehicleOrGhost) && isLoggedOut(vehicleOrGhost)
const noRunText = isLoggedOutVehicle ? "No run logged in" : "N/A"
Expand All @@ -120,7 +135,10 @@ const VehicleWorkInfo = ({
<>
<table className="c-vehicle-work-info">
<tbody className="c-vehicle-work-info__items">
<TrNameValue name="run">
<TrNameValue
name="run"
onValueClick={onRunClick && (() => onRunClick(vehicleOrGhost))}
>
{vehicleOrGhost.runId || noRunText}
</TrNameValue>
<TrNameValue name="vehicle">
Expand Down Expand Up @@ -193,11 +211,13 @@ const VehicleLocationStreetViewButton = ({ vehicle }: { vehicle: Vehicle }) => (

// #region Vehicle Properties Card
export type VehiclePropertiesCardProps = VehicleOrGhostProp &
VehicleRouteSummaryEventProps
VehicleRouteSummaryEventProps &
VehicleWorkInfoEventProps

const VehiclePropertiesCard = ({
vehicleOrGhost,
onRouteVariantNameClicked,
onRunClick,
}: VehiclePropertiesCardProps): React.ReactElement => {
return (
<div
Expand All @@ -224,7 +244,10 @@ const VehiclePropertiesCard = ({

<div className="c-vehicle-properties-card__body">
<div className="c-vehicle-properties-card__properties c-vehicle-properties-card__info-section">
<VehicleWorkInfo vehicleOrGhost={vehicleOrGhost} />
<VehicleWorkInfo
vehicleOrGhost={vehicleOrGhost}
onRunClick={onRunClick}
/>
</div>

<div
Expand Down
Loading
Loading