1- import React , { useState , useEffect } from 'react' ;
1+ import React , { useState , useEffect , useMemo } from 'react' ;
22import {
33 Box ,
44 ToggleButtonGroup ,
@@ -25,17 +25,18 @@ import { Map } from './Map';
2525import { useTranslation } from 'react-i18next' ;
2626import type { LatLngExpression } from 'leaflet' ;
2727import { useTheme } from '@mui/material/styles' ;
28- import { type GBFSFeedType , type AllFeedType } from '../services/feeds/utils' ;
28+ import { type AllFeedType } from '../services/feeds/utils' ;
2929import { OpenInNew } from '@mui/icons-material' ;
3030import { computeBoundingBox } from '../screens/Feed/Feed.functions' ;
3131import { displayFormattedDate } from '../utils/date' ;
3232import { useSelector } from 'react-redux' ;
33- import { selectAutodiscoveryGbfsVersion } from '../store/feed-selectors' ;
3433import ModeOfTravelIcon from '@mui/icons-material/ModeOfTravel' ;
3534import { GtfsVisualizationMap } from './GtfsVisualizationMap' ;
3635import ZoomOutMapIcon from '@mui/icons-material/ZoomOutMap' ;
3736import { useRemoteConfig } from '../context/RemoteConfigProvider' ;
3837import ReactGA from 'react-ga4' ;
38+ import { selectLatestGbfsVersion } from '../store/feed-selectors' ;
39+ import { selectGtfsDatasetRoutesLoadingStatus } from '../store/supporting-files-selectors' ;
3940
4041interface CoveredAreaMapProps {
4142 boundingBox ?: LatLngExpression [ ] ;
@@ -77,20 +78,26 @@ const CoveredAreaMap: React.FC<CoveredAreaMapProps> = ({
7778 > ( null ) ;
7879 const [ geoJsonError , setGeoJsonError ] = useState ( false ) ;
7980 const [ geoJsonLoading , setGeoJsonLoading ] = useState ( false ) ;
80- const [ view , setView ] = useState < MapViews > ( 'detailedCoveredAreaView' ) ;
81- const latestGbfsVersion = useSelector ( selectAutodiscoveryGbfsVersion ) ;
81+ const [ view , setView ] = useState < MapViews > (
82+ feed ?. data_type === 'gtfs'
83+ ? 'gtfsVisualizationView'
84+ : 'detailedCoveredAreaView' ,
85+ ) ;
86+
87+ const latestGbfsVersion = useSelector ( selectLatestGbfsVersion ) ;
88+ const routesJsonLoadingStatus = useSelector (
89+ selectGtfsDatasetRoutesLoadingStatus ,
90+ ) ;
8291
8392 const getAndSetGeoJsonData = ( urlToExtract : string ) : void => {
8493 setGeoJsonLoading ( true ) ;
8594 fetchGeoJson ( urlToExtract )
8695 . then ( ( data ) => {
8796 setGeoJsonData ( data ) ;
8897 setGeoJsonError ( false ) ;
89- setView ( 'detailedCoveredAreaView' ) ;
9098 } )
9199 . catch ( ( ) => {
92100 setGeoJsonError ( true ) ;
93- setView ( 'boundingBoxView' ) ;
94101 } )
95102 . finally ( ( ) => {
96103 setGeoJsonLoading ( false ) ;
@@ -119,9 +126,23 @@ const CoveredAreaMap: React.FC<CoveredAreaMapProps> = ({
119126 }
120127 setGeoJsonData ( null ) ;
121128 setGeoJsonError ( true ) ;
122- setView ( 'boundingBoxView' ) ;
123129 } , [ latestDataset , feed ] ) ;
124130
131+ // effect to determine which view to display
132+ useEffect ( ( ) => {
133+ if ( feed == undefined ) return ;
134+ if ( feed ?. data_type === 'gbfs' ) return ;
135+ if ( routesJsonLoadingStatus != 'failed' && boundingBox != undefined ) {
136+ setView ( 'gtfsVisualizationView' ) ;
137+ return ;
138+ }
139+ if ( geoJsonData != null && boundingBox != undefined ) {
140+ setView ( 'detailedCoveredAreaView' ) ;
141+ return ;
142+ }
143+ setView ( 'boundingBoxView' ) ;
144+ } , [ feed , routesJsonLoadingStatus , boundingBox , geoJsonData ] ) ;
145+
125146 const handleViewChange = (
126147 _ : React . MouseEvent < HTMLElement > ,
127148 newView : MapViews | null ,
@@ -137,9 +158,7 @@ const CoveredAreaMap: React.FC<CoveredAreaMapProps> = ({
137158 } ) ;
138159 } ;
139160
140- const getGbfsLatestVersionVisualizationUrl = (
141- feed : GBFSFeedType ,
142- ) : string | undefined => {
161+ const getGbfsLatestVersionVisualizationUrl = ( ) : string | undefined => {
143162 const latestAutodiscoveryUrl = latestGbfsVersion ?. endpoints ?. find (
144163 ( endpoint ) => endpoint . name === 'gbfs' ,
145164 ) ?. url ;
@@ -154,11 +173,13 @@ const CoveredAreaMap: React.FC<CoveredAreaMapProps> = ({
154173 view === 'boundingBoxView' && feed ?. data_type === 'gtfs' ;
155174
156175 const displayGtfsVisualizationView =
157- view === 'gtfsVisualizationView' &&
158- feed ?. data_type === 'gtfs' &&
159- config . enableGtfsVisualizationMap ;
176+ view === 'gtfsVisualizationView' && feed ?. data_type === 'gtfs' ;
177+
160178 let gbfsBoundingBox : LatLngExpression [ ] = [ ] ;
161179 if ( feed ?. data_type === 'gbfs' ) {
180+ if ( geoJsonData == null ) {
181+ return < > </ > ;
182+ }
162183 gbfsBoundingBox = computeBoundingBox ( geoJsonData ) ?? [ ] ;
163184 if ( gbfsBoundingBox . length === 0 ) {
164185 setGeoJsonError ( true ) ;
@@ -187,19 +208,33 @@ const CoveredAreaMap: React.FC<CoveredAreaMapProps> = ({
187208 </ >
188209 ) ;
189210 }
211+ if ( geoJsonData != null ) {
212+ return (
213+ < MapGeoJSON
214+ geoJSONData = { geoJsonData }
215+ polygon = { boundingBox ?? gbfsBoundingBox }
216+ displayMapDetails = { feed ?. data_type === 'gtfs' }
217+ />
218+ ) ;
219+ }
220+ return < > </ > ;
221+ } ;
190222
223+ const latestAutodiscoveryUrl = getGbfsLatestVersionVisualizationUrl ( ) ;
224+ const enableGtfsVisualizationView = useMemo ( ( ) => {
191225 return (
192- < MapGeoJSON
193- geoJSONData = { geoJsonData }
194- polygon = { boundingBox ?? gbfsBoundingBox }
195- displayMapDetails = { feed ?. data_type === 'gtfs' }
196- />
226+ config . enableGtfsVisualizationMap &&
227+ feed ?. data_type === 'gtfs' &&
228+ routesJsonLoadingStatus != 'failed' &&
229+ boundingBox != undefined
197230 ) ;
198- } ;
231+ } , [
232+ feed ?. data_type ,
233+ config . enableGtfsVisualizationMap ,
234+ routesJsonLoadingStatus ,
235+ boundingBox ,
236+ ] ) ;
199237
200- const latestAutodiscoveryUrl = getGbfsLatestVersionVisualizationUrl (
201- feed as GBFSFeedType ,
202- ) ;
203238 return (
204239 < ContentBox
205240 sx = { {
@@ -271,6 +306,17 @@ const CoveredAreaMap: React.FC<CoveredAreaMapProps> = ({
271306 aria-label = 'map view selection'
272307 onChange = { handleViewChange }
273308 >
309+ { config . enableGtfsVisualizationMap && (
310+ < Tooltip title = { t ( 'gtfsVisualizationTooltip' ) } >
311+ < ToggleButton
312+ value = 'gtfsVisualizationView'
313+ disabled = { ! enableGtfsVisualizationView }
314+ aria-label = { t ( 'gtfsVisualizationViewLabel' ) }
315+ >
316+ < ModeOfTravelIcon />
317+ </ ToggleButton >
318+ </ Tooltip >
319+ ) }
274320 < Tooltip title = { t ( 'detailedCoveredAreaViewTooltip' ) } >
275321 < ToggleButton
276322 value = 'detailedCoveredAreaView'
@@ -290,19 +336,6 @@ const CoveredAreaMap: React.FC<CoveredAreaMapProps> = ({
290336 < MapIcon />
291337 </ ToggleButton >
292338 </ Tooltip >
293- { config . enableGtfsVisualizationMap && (
294- < Tooltip title = { t ( 'gtfsVisualizationTooltip' ) } >
295- < span >
296- < ToggleButton
297- value = 'gtfsVisualizationView'
298- disabled = { ! config . enableGtfsVisualizationMap }
299- aria-label = 'Bounding Box View'
300- >
301- < ModeOfTravelIcon />
302- </ ToggleButton >
303- </ span >
304- </ Tooltip >
305- ) }
306339 </ ToggleButtonGroup >
307340 ) }
308341 </ Box >
@@ -320,15 +353,15 @@ const CoveredAreaMap: React.FC<CoveredAreaMapProps> = ({
320353
321354 { ( boundingBox != undefined || ! geoJsonError ) && (
322355 < Box sx = { mapBoxPositionStyle } >
323- { geoJsonLoading ? (
356+ { geoJsonLoading || routesJsonLoadingStatus === 'loading' ? (
324357 < Skeleton
325358 variant = 'rectangular'
326359 width = '100%'
327360 height = '100%'
328361 animation = 'wave'
329362 />
330363 ) : (
331- < > { geoJsonData !== null && < > { renderMap ( ) } </ > } </ >
364+ < > { renderMap ( ) } </ >
332365 ) }
333366 </ Box >
334367 ) }
0 commit comments