Skip to content

Commit

Permalink
Merge branch 'main' of github.com:hasadna/open-bus-map-search
Browse files Browse the repository at this point in the history
  • Loading branch information
NoamGaash committed Jun 14, 2024
2 parents f95e769 + 32fbd70 commit b5b72cc
Show file tree
Hide file tree
Showing 11 changed files with 1,484 additions and 573 deletions.
1,930 changes: 1,371 additions & 559 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@
]
},
"devDependencies": {
"@babel/preset-env": "^7.23.9",
"@babel/preset-env": "^7.24.7",
"@babel/preset-react": "^7.24.1",
"@eslint/eslintrc": "^3.0.2",
"@eslint/js": "~8.57.0",
Expand All @@ -97,7 +97,7 @@
"@storybook/addon-interactions": "^7.6.17",
"@storybook/addon-links": "^7.6.17",
"@storybook/addon-onboarding": "^1.0.11",
"@storybook/blocks": "^7.5.3",
"@storybook/blocks": "^8.1.6",
"@storybook/react": "^7.5.3",
"@storybook/react-vite": "^8.0.5",
"@storybook/testing-library": "^0.2.2",
Expand Down
38 changes: 31 additions & 7 deletions src/pages/components/map-related/MapContent.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Marker, Polyline, Popup, TileLayer } from 'react-leaflet'
import { Icon, IconOptions } from 'leaflet'
import { useRef } from 'react'
import { Marker, Polyline, Popup, TileLayer, useMap } from 'react-leaflet'
import { Icon, IconOptions, Marker as LeafletMarker } from 'leaflet'
import { useAgencyList } from 'src/api/agencyList'
import { busIcon, busIconPath } from '../utils/BusIcon'
import { BusToolTip } from './MapLayers/BusToolTip'
Expand All @@ -8,12 +9,13 @@ import '../../Map.scss'
import { MapProps } from './map-types'
import { useRecenterOnDataChange } from './useRecenterOnDataChange'
import { MapIndex } from './MapIndex'
import MapFooterButtons from './MapFooterButtons/MapFooterButtons'

export function MapContent({ positions, plannedRouteStops }: MapProps) {
export function MapContent({ positions, plannedRouteStops, showNavigationButtons }: MapProps) {
useRecenterOnDataChange({ positions, plannedRouteStops })

const markerRef = useRef<{ [key: number]: LeafletMarker | null }>({})
const map = useMap()
const agencyList = useAgencyList()

const getIcon = (path: string, width: number = 10, height: number = 10): Icon<IconOptions> => {
return new Icon<IconOptions>({
iconUrl: path,
Expand All @@ -28,6 +30,16 @@ export function MapContent({ positions, plannedRouteStops }: MapProps) {
const actualRouteStopMarker = getIcon(actualRouteStopMarkerPath, 20, 20)
const plannedRouteStopMarker = getIcon(plannedRouteStopMarkerPath, 20, 25)

const navigateMarkers = (positionId: number) => {
const loc = positions[positionId]?.loc
if (!map || !loc) return
const marker = markerRef?.current && markerRef?.current[positionId]
if (marker) {
map.flyTo(loc, map.getZoom())
marker.openPopup()
}
}

return (
<>
<TileLayer
Expand Down Expand Up @@ -56,9 +68,21 @@ export function MapContent({ positions, plannedRouteStops }: MapProps) {
})
: actualRouteStopMarker
return (
<Marker position={pos.loc} icon={icon} key={i}>
<Marker
ref={(ref) => (markerRef.current[i] = ref)}
position={pos.loc}
icon={icon}
key={i}>
<Popup minWidth={300} maxWidth={700}>
<BusToolTip position={pos} icon={busIconPath(pos.operator!)} />
<BusToolTip position={pos} icon={busIconPath(pos.operator!)}>
{showNavigationButtons && (
<MapFooterButtons
index={i}
positions={positions}
navigateMarkers={navigateMarkers}
/>
)}
</BusToolTip>
</Popup>
</Marker>
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.map-footer-buttons {
display: flex;
justify-content: space-between;

.disabled {
pointer-events: none;
opacity: 0.5;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { LeftOutlined, RightOutlined } from '@ant-design/icons'
import { Point } from 'src/pages/timeBasedMap'
import './MapFooterButtons.scss'

type TMapFooterButtons = {
index: number
positions: Point[]
navigateMarkers: (id: number) => void
}

function MapFooterButtons({ index, positions, navigateMarkers }: TMapFooterButtons) {
const rightStep = index + 1
const leftStep = index - 1

const checkIfValidStep = (i: number) => {
return Boolean(positions.at(i))
}

return (
<div className="map-footer-buttons">
<RightOutlined
title={'right-chevron'}
className={`${checkIfValidStep(rightStep) ? '' : 'disabled'}`}
onClick={() => navigateMarkers(rightStep)}
/>
<LeftOutlined
title={'left-chevron'}
className={`${checkIfValidStep(leftStep) ? '' : 'disabled'}`}
onClick={() => navigateMarkers(leftStep)}
/>
</div>
)
}

export default MapFooterButtons
7 changes: 4 additions & 3 deletions src/pages/components/map-related/MapLayers/BusToolTip.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect, useState } from 'react'
import { ReactNode, useEffect, useState } from 'react'
import { Link } from 'react-router-dom'
import { Point } from 'src/pages/timeBasedMap'
import { Button } from '@mui/material'
Expand All @@ -11,9 +11,9 @@ import CircularProgress from '@mui/material/CircularProgress'
import cn from 'classnames'
import CustomTreeView from '../../CustomTreeView'

export type BusToolTipProps = { position: Point; icon: string }
export type BusToolTipProps = { position: Point; icon: string; children?: ReactNode }

export function BusToolTip({ position, icon }: BusToolTipProps) {
export function BusToolTip({ position, icon, children }: BusToolTipProps) {
const [siriRide, setSiriRide] = useState<SiriRideWithRelatedPydanticModel | undefined>()
const [isLoading, setIsLoading] = useState(false)
const [showJson, setShowJson] = useState(false)
Expand Down Expand Up @@ -110,6 +110,7 @@ export function BusToolTip({ position, icon }: BusToolTipProps) {
</div>
)}
</div>
{children}
</>
)}
</div>
Expand Down
12 changes: 10 additions & 2 deletions src/pages/components/map-related/MapWithLocationsAndPath.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ const position: Point = {
color: 0,
}

export function MapWithLocationsAndPath({ positions, plannedRouteStops }: MapProps) {
export function MapWithLocationsAndPath({
positions,
plannedRouteStops,
showNavigationButtons,
}: MapProps) {
const [isExpanded, setIsExpanded] = useState<boolean>(false)
const toggleExpanded = useCallback(() => setIsExpanded((expanded) => !expanded), [])

Expand All @@ -23,7 +27,11 @@ export function MapWithLocationsAndPath({ positions, plannedRouteStops }: MapPro
</IconButton>

<MapContainer center={position.loc} zoom={13} scrollWheelZoom={true}>
<MapContent positions={positions} plannedRouteStops={plannedRouteStops} />
<MapContent
positions={positions}
plannedRouteStops={plannedRouteStops}
showNavigationButtons={showNavigationButtons}
/>
</MapContainer>
</div>
)
Expand Down
1 change: 1 addition & 0 deletions src/pages/components/map-related/map-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ export interface Path {
export interface MapProps {
positions: Point[]
plannedRouteStops: BusStop[]
showNavigationButtons?: boolean
}
2 changes: 2 additions & 0 deletions src/pages/homepage/HomePage.scss
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
gap: 1rem;

@media (width <= 600px) {
grid-template-columns: repeat(2, 1fr);
margin-bottom: 3rem;
}
}
Expand All @@ -61,6 +62,7 @@
padding: 0 1.5rem;
border-radius: 0.5rem;
transition: 0.2s ease-in-out 0s;
margin-bottom: 0.25rem;

&:hover {
transform: scale(1.25);
Expand Down
1 change: 1 addition & 0 deletions src/pages/singleLineMap/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ const SingleLineMapPage = () => {
<MapWithLocationsAndPath
positions={filteredPositions}
plannedRouteStops={plannedRouteStops}
showNavigationButtons
/>
</PageContainer>
)
Expand Down
18 changes: 18 additions & 0 deletions tests/mainHeader.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { test, expect } from './utils'

test.beforeEach(async ({ page }) => {
await page.goto('/')
})

test("the main header doesn't show duplicate icons", async ({ page }) => {
const headerLocator = page.locator('div.header-links')
const svgLocators = headerLocator.locator('svg')
const svgCount = await svgLocators.count()
const svgInnerHTML = []
for (let i = 0; i < svgCount; i++) {
const innerHTML = await svgLocators.nth(i).innerHTML()
svgInnerHTML.push(innerHTML)
}
const svgCountWithoutDuplicates = new Set(svgInnerHTML).size
expect(svgCountWithoutDuplicates).toBe(svgCount)
})

0 comments on commit b5b72cc

Please sign in to comment.