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

🚲 Bike station migration 🚲 : Moving to mobility API (v2) #470

Merged
merged 17 commits into from
Sep 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
"@entur/loader": "^0.4.1",
"@entur/menu": "^4.0.0",
"@entur/modal": "^1.5.4",
"@entur/sdk": "^4.0.0",
"@entur/sdk": "^4.2.0",
"@entur/tab": "^0.4.24",
"@entur/table": "^4.3.15",
"@entur/tokens": "^3.1.0",
Expand Down
16 changes: 6 additions & 10 deletions src/components/Map/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { BikeRentalStation } from '@entur/sdk'
import React, { useState, memo, useRef } from 'react'

import { InteractiveMap, Marker } from 'react-map-gl'
Expand All @@ -7,7 +6,7 @@ import useSupercluster from 'use-supercluster'

import type { ClusterProperties } from 'supercluster'

import { Vehicle } from '@entur/sdk/lib/mobility/types'
import { Station, Vehicle } from '@entur/sdk/lib/mobility/types'

import PositionPin from '../../assets/icons/positionPin'

Expand Down Expand Up @@ -51,20 +50,17 @@ const Map = ({
},
}))
const bikeRentalStationPoints = bikeRentalStations?.map(
(bikeRentalStation: BikeRentalStation) => ({
(bikeRentalStation: Station) => ({
type: 'Feature' as const,
properties: {
cluster: false,
stationId: bikeRentalStation.id,
bikesAvailable: bikeRentalStation.bikesAvailable,
spacesAvailable: bikeRentalStation.spacesAvailable,
bikesAvailable: bikeRentalStation.numBikesAvailable,
spacesAvailable: bikeRentalStation.numDocksAvailable,
},
geometry: {
type: 'Point' as const,
coordinates: [
bikeRentalStation.longitude,
bikeRentalStation.latitude,
],
coordinates: [bikeRentalStation.lon, bikeRentalStation.lat],
},
}),
)
Expand Down Expand Up @@ -224,7 +220,7 @@ const Map = ({

interface Props {
stopPlaces?: StopPlaceWithDepartures[] | null
bikeRentalStations?: BikeRentalStation[] | null
bikeRentalStations?: Station[] | null
scooters?: Vehicle[] | null
walkTimes?: Array<{ stopId: string; walkTime: number }> | null
interactive: boolean
Expand Down
12 changes: 7 additions & 5 deletions src/containers/Admin/EditTab/BikePanel/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React, { useCallback } from 'react'

import { BikeRentalStation } from '@entur/sdk'
import { Station } from '@entur/sdk/lib/mobility/types'
import { Checkbox, Fieldset } from '@entur/form'
import { Paragraph } from '@entur/typography'

import { toggleValueInList } from '../../../../utils'
import { getTranslation, toggleValueInList } from '../../../../utils'
import { useSettingsContext } from '../../../../settings'

import './styles.scss'
Expand Down Expand Up @@ -59,19 +59,21 @@ function BikePanel(props: Props): JSX.Element {
<Checkbox
key={id}
id={id}
name={name}
name={getTranslation(name) || ''}
checked={!hiddenStations.includes(id)}
onChange={onToggleStation}
>
<span className="bike-panel__eds-paragraph">{name}</span>
<span className="bike-panel__eds-paragraph">
{getTranslation(name) || ''}
</span>
</Checkbox>
))}
</Fieldset>
)
}

interface Props {
stations: BikeRentalStation[]
stations: Station[]
}

export default BikePanel
40 changes: 29 additions & 11 deletions src/containers/Admin/EditTab/BikeSearch/index.tsx
Original file line number Diff line number Diff line change
@@ -1,40 +1,56 @@
import React, { useState, useEffect } from 'react'

import { Coordinates, BikeRentalStation } from '@entur/sdk'
import { Coordinates } from '@entur/sdk'
import { Dropdown } from '@entur/dropdown'
import { Station } from '@entur/sdk/lib/mobility/types'

import service from '../../../../service'

import './styles.scss'
import { getTranslation } from '../../../../utils'

const MAX_SEARCH_RANGE = 100_000

interface Item {
value: string
label: string
}

function mapFeaturesToItems(features: BikeRentalStation[]): Item[] {
function mapFeaturesToItems(features: Station[]): Item[] {
return features.map(({ id, name }) => ({
value: id,
label: name,
label: getTranslation(name) || '',
}))
}

const BikePanelSearch = ({ onSelected, position }: Props): JSX.Element => {
const [stations, setStations] = useState<BikeRentalStation[]>([])
const [stations, setStations] = useState<Station[]>([])

useEffect(() => {
let isMounted = true
const controller = new AbortController()
if (position) {
service
.getBikeRentalStationsByPosition(position, 100000)
service.mobility
.getStations(
{
lat: position.latitude,
lon: position.longitude,
range: MAX_SEARCH_RANGE,
},
{
signal: controller.signal,
},
)
.then((data) => {
if (isMounted) {
setStations(data)
setStations(data)
})
bendiksk marked this conversation as resolved.
Show resolved Hide resolved
.catch((err) => {
if (!controller.signal.aborted) {
throw err
}
})
}
return () => {
isMounted = false
controller.abort()
}
}, [position])

Expand All @@ -45,7 +61,9 @@ const BikePanelSearch = ({ onSelected, position }: Props): JSX.Element => {

return mapFeaturesToItems(
stations.filter((station) =>
station.name.toLowerCase().match(new RegExp(inputValue)),
getTranslation(station.name)
?.toLowerCase()
.match(new RegExp(inputValue)),
),
)
}
Expand Down
4 changes: 2 additions & 2 deletions src/containers/Admin/EditTab/StopPlaceSearch/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ async function getItems(query: string): Promise<Item[]> {
return mapFeaturesToItems(featuresData)
}

const SelectionPanelSearch = ({ handleAddNewStop }: Props): JSX.Element => {
const StopPlaceSearch = ({ handleAddNewStop }: Props): JSX.Element => {
const onItemSelected = (item: Item | null): void => {
if (item) {
handleAddNewStop(item.value)
Expand All @@ -59,4 +59,4 @@ interface Props {
handleAddNewStop: (stopId: string) => void
}

export default SelectionPanelSearch
export default StopPlaceSearch
67 changes: 36 additions & 31 deletions src/containers/Admin/EditTab/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import React, {
useCallback,
SyntheticEvent,
} from 'react'
import { BikeRentalStation } from '@entur/sdk'
import {
Heading2,
Heading3,
Expand All @@ -17,7 +16,7 @@ import { Switch, TextField } from '@entur/form'
import { Tooltip } from '@entur/tooltip'
import { WidthProvider, Responsive } from 'react-grid-layout'

import { FormFactor } from '@entur/sdk/lib/mobility/types'
import { FormFactor, Station } from '@entur/sdk/lib/mobility/types'

import { useSettingsContext, Mode } from '../../../settings'

Expand All @@ -26,12 +25,17 @@ import {
toggleValueInList,
isNotNullOrUndefined,
isMobileWeb,
getTranslation,
} from '../../../utils'

import { DEFAULT_DISTANCE, DEFAULT_ZOOM } from '../../../constants'
import { StopPlaceWithLines } from '../../../types'
import { useNearestPlaces, useMobility } from '../../../logic'
import service, { getStopPlacesWithLines } from '../../../service'
import {
useNearestPlaces,
useMobility,
useBikeRentalStations,
} from '../../../logic'
import { getStopPlacesWithLines } from '../../../service'
import {
saveToLocalStorage,
getFromLocalStorage,
Expand Down Expand Up @@ -95,7 +99,10 @@ const EditTab = (): JSX.Element => {
}, [debouncedDistance, setSettings, settings])

const [stopPlaces, setStopPlaces] = useState<StopPlaceWithLines[]>([])
const [stations, setStations] = useState<BikeRentalStation[]>([])
const bikeRentalStations: Station[] | null = useBikeRentalStations(false)
const [sortedBikeRentalStations, setSortedBikeRentalStations] = useState<
Station[]
>([])

const nearestPlaces = useNearestPlaces(
settings?.coordinates,
Expand All @@ -114,13 +121,13 @@ const EditTab = (): JSX.Element => {
const scooters = useMobility(FormFactor.SCOOTER)

useEffect(() => {
let ignoreResponse = false
const controller = new AbortController()
const ids = [...newStops, ...nearestStopPlaceIds]

getStopPlacesWithLines(
ids.map((id: string) => id.replace(/-\d+$/, '')),
).then((resultingStopPlaces) => {
if (ignoreResponse) return
if (controller.signal.aborted) return

setStopPlaces(
resultingStopPlaces.map((s, index) => ({
Expand All @@ -131,34 +138,31 @@ const EditTab = (): JSX.Element => {
})

return (): void => {
ignoreResponse = true
controller.abort()
}
}, [nearestPlaces, nearestStopPlaceIds, newStops])

useEffect(() => {
let ignoreResponse = false

const nearestBikeRentalStationIds = nearestPlaces
.filter(({ type }) => type === 'BikeRentalStation')
.map(({ id }) => id)

const ids = [...newStations, ...nearestBikeRentalStationIds]
const controller = new AbortController()

service.getBikeRentalStations(ids).then((freshStations) => {
if (ignoreResponse) return

const sortedStations = freshStations
if (bikeRentalStations) {
const sortedStations = bikeRentalStations
.filter(isNotNullOrUndefined)
.sort((a: BikeRentalStation, b: BikeRentalStation) =>
a.name.localeCompare(b.name, 'no'),
)
setStations(sortedStations)
})
.sort((a: Station, b: Station) => {
const aName = getTranslation(a.name)
const bName = getTranslation(b.name)
if (!aName) return 1
if (!bName) return -1
return aName.localeCompare(bName, 'no')
})
if (controller.signal.aborted) return
setSortedBikeRentalStations(sortedStations)
}

return (): void => {
ignoreResponse = true
controller.abort()
}
}, [nearestPlaces, newStations])
}, [bikeRentalStations])

const addNewStop = useCallback(
(stopId: string) => {
Expand All @@ -179,6 +183,7 @@ const EditTab = (): JSX.Element => {

const addNewStation = useCallback(
(stationId: string) => {
if (newStations.includes(stationId)) return
setSettings({
newStations: [...newStations, stationId],
})
Expand Down Expand Up @@ -239,7 +244,7 @@ const EditTab = (): JSX.Element => {
x: 1.5,
y: 0,
w: 1.5,
h: 1.55 + tileHeight(stations.length, 0.24, 0),
h: 1.55 + tileHeight(sortedBikeRentalStations.length, 0.24, 0),
},
{ i: 'scooterPanel', x: 1.5, y: 3.2, w: 1.5, h: 1.4 },
{ i: 'mapPanel', x: 3, y: 5, w: 1.5, h: 3.2 },
Expand All @@ -258,7 +263,7 @@ const EditTab = (): JSX.Element => {
x: 2,
y: 0,
w: 1,
h: 1.55 + tileHeight(stations.length, 0.24, 0),
h: 1.55 + tileHeight(sortedBikeRentalStations.length, 0.24, 0),
},
{ i: 'scooterPanel', x: 2, y: 3, w: 1, h: 1.75 },
{ i: 'mapPanel', x: 0, y: 7, w: 2, h: 3 },
Expand All @@ -277,7 +282,7 @@ const EditTab = (): JSX.Element => {
x: 0,
y: 3,
w: 1,
h: 1.4 + tileHeight(stations.length, 0.24, 0),
h: 1.4 + tileHeight(sortedBikeRentalStations.length, 0.24, 0),
},
{ i: 'scooterPanel', x: 0, y: 5, w: 1, h: 1.2 },
{ i: 'mapPanel', x: 0, y: 9.5, w: 1, h: 3 },
Expand All @@ -296,7 +301,7 @@ const EditTab = (): JSX.Element => {
x: 0,
y: 3,
w: 1,
h: 1.4 + tileHeight(stations.length, 0.265, 0),
h: 1.4 + tileHeight(sortedBikeRentalStations.length, 0.265, 0),
},
{ i: 'scooterPanel', x: 0, y: 5, w: 1, h: 1.6 },
{ i: 'mapPanel', x: 0, y: 9.5, w: 1, h: 3 },
Expand Down Expand Up @@ -395,7 +400,7 @@ const EditTab = (): JSX.Element => {
position={settings?.coordinates}
onSelected={addNewStation}
/>
<BikePanel stations={stations} />
<BikePanel stations={sortedBikeRentalStations} />
</div>
<div key="scooterPanel" className="edit-tab__tile">
<div className="edit-tab__header">
Expand Down
Loading