diff options
Diffstat (limited to 'sdnr/wt/odlux/apps/networkMapApp/src/components')
-rw-r--r-- | sdnr/wt/odlux/apps/networkMapApp/src/components/customize/customizationView.tsx | 291 | ||||
-rw-r--r-- | sdnr/wt/odlux/apps/networkMapApp/src/components/customize/themeElement.tsx | 47 | ||||
-rw-r--r-- | sdnr/wt/odlux/apps/networkMapApp/src/components/map/connectionInfo.tsx (renamed from sdnr/wt/odlux/apps/networkMapApp/src/components/connectionInfo.tsx) | 4 | ||||
-rw-r--r-- | sdnr/wt/odlux/apps/networkMapApp/src/components/map/iconSwitch.tsx (renamed from sdnr/wt/odlux/apps/networkMapApp/src/components/iconSwitch.tsx) | 6 | ||||
-rw-r--r-- | sdnr/wt/odlux/apps/networkMapApp/src/components/map/map.tsx (renamed from sdnr/wt/odlux/apps/networkMapApp/src/components/map.tsx) | 164 | ||||
-rw-r--r-- | sdnr/wt/odlux/apps/networkMapApp/src/components/map/mapPopup.tsx (renamed from sdnr/wt/odlux/apps/networkMapApp/src/components/mapPopup.tsx) | 16 | ||||
-rw-r--r-- | sdnr/wt/odlux/apps/networkMapApp/src/components/map/searchBar.tsx (renamed from sdnr/wt/odlux/apps/networkMapApp/src/components/searchBar.tsx) | 20 | ||||
-rw-r--r-- | sdnr/wt/odlux/apps/networkMapApp/src/components/map/statistics.tsx (renamed from sdnr/wt/odlux/apps/networkMapApp/src/components/statistics.tsx) | 4 |
8 files changed, 487 insertions, 65 deletions
diff --git a/sdnr/wt/odlux/apps/networkMapApp/src/components/customize/customizationView.tsx b/sdnr/wt/odlux/apps/networkMapApp/src/components/customize/customizationView.tsx new file mode 100644 index 000000000..82e7b795b --- /dev/null +++ b/sdnr/wt/odlux/apps/networkMapApp/src/components/customize/customizationView.tsx @@ -0,0 +1,291 @@ +/** + * ============LICENSE_START======================================================================== + * ONAP : ccsdk feature sdnr wt odlux + * ================================================================================================= + * Copyright (C) 2021 highstreet technologies GmbH Intellectual Property. All rights reserved. + * ================================================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * ============LICENSE_END========================================================================== + */ + +import { Button, Grid, InputLabel, makeStyles, MenuItem, Select, Slider, TextField, Typography } from '@material-ui/core'; +import { NetworkMapSettings, ThemeElement } from '../../model/settings'; +import * as React from 'react' +import connect, { Connect, IDispatcher } from '../../../../../framework/src/flux/connect'; +import { IApplicationStoreState } from '../../../../../framework/src/store/applicationStore'; +import { updateSettings } from '../../actions/settingsAction'; +import ThemeEntry from './themeElement' +import * as mapboxgl from 'mapbox-gl'; +import { OSM_STYLE } from '../../config'; +import mapLayerService from '../../utils/mapLayers'; +import { requestRest } from '../../../../../framework/src/services/restService'; +import { NavigateToApplication } from '../../../../../framework/src/actions/navigationActions'; + +type props = Connect<typeof mapProps, typeof mapDispatch>; +let map: mapboxgl.Map; +let myMapRef = React.createRef<HTMLDivElement>(); +const default_boundingbox = "12.882544785787754,52.21421979821472,13.775455214211949,52.80406241672602"; + + +const mapProps = (state: IApplicationStoreState) => ({ + settings: state.network.settings, +}); + +const mapDispatch = (dispatcher: IDispatcher) => ({ + updateSettings: (mapSettings: NetworkMapSettings) => dispatcher.dispatch(updateSettings(mapSettings)), + navigateToApplication: (applicationName: string) => dispatcher.dispatch(new NavigateToApplication(applicationName)), + + +}); + +const styles = makeStyles({ + sectionMargin: { + marginTop: "30px", + marginBottom: "15px" + }, + elementMargin: { + + marginLeft: "10px" + } +}); + +const CustomizationView: React.FunctionComponent<props> = (props) => { + + const [opacity, setOpacity] = React.useState(Number(props.settings.mapSettings?.networkMap.tileOpacity) || 100); + const [theme, setTheme] = React.useState(props.settings.mapSettings?.networkMap.styling.theme || ''); + const [latitude, setLatitude] = React.useState<number>(Number(props.settings.mapSettings?.networkMap.startupPosition.latitude)|| 52.5); + const [longitude, setLongitude] = React.useState<number>(Number(props.settings.mapSettings?.networkMap.startupPosition.longitude)|| 13.35); + const [zoom, setZoom] = React.useState<number>(Number(props.settings.mapSettings?.networkMap.startupPosition.zoom) || 10); + + + //used to make opacity available within the map event-listeners + //(hook state values are snapshotted at initalization and not updated afterwards, thus use a ref here) + const myOpacityRef = React.useRef(opacity); + const setOpacityState = (data:any) => { + myOpacityRef.current = data; + setOpacity(data); + }; + + const classes = styles(); + const currentTheme = props.settings.themes.networkMapThemes.themes.find(el => el.key === theme); + + + React.useEffect(() => { + mapLayerService.settings = props.settings.themes; + + map = new mapboxgl.Map({ + container: myMapRef.current!, + style: OSM_STYLE as any, + center: [longitude, latitude], + zoom: zoom, + accessToken: '' + }); + + map.on('load', (ev) => { + + mapLayerService.addBaseSources(map, null, null); + if(props.settings.mapSettings?.networkMap.styling.theme !== theme){ + mapLayerService.addBaseLayers(map, currentTheme); + + }else{ + mapLayerService.addBaseLayers(map); + } + + mapLayerService.changeMapOpacity(map, myOpacityRef.current); + + getData(); + }); + + map.on('moveend', () => { + const center = map.getCenter(); + setZoom(Number(map.getZoom().toFixed(4))); + setLatitude(Number(center.lat.toFixed(4))); + setLongitude(Number(center.lng.toFixed(4))); + }); + + }, []); + + React.useEffect(() => { + recenterMap(); + }, [latitude, longitude, zoom]); + + const setState = () => { + if (props.settings.mapSettings?.networkMap.styling) { + setTheme(props.settings.mapSettings.networkMap.styling.theme); + mapLayerService.changeTheme(map, props.settings.mapSettings.networkMap.styling.theme); + } + + const propOpacity = props.settings.mapSettings?.networkMap.tileOpacity; + if (propOpacity) { + setOpacityState(propOpacity); + } + } + + React.useEffect(() => { + setState(); + }, [props.settings.mapSettings]); + + const onOpacityChange = (event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>, newValue: number) => { + setOpacity(newValue); + mapLayerService.changeMapOpacity(map, newValue); + + }; + + const onChangeTheme = (e: any) => { + + const newTheme = e.target.value; + setTheme(newTheme); + mapLayerService.changeTheme(map, newTheme); + } + + const onCancel = (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => { + e.preventDefault(); + props.navigateToApplication("network"); + } + + const onSaveSettings = async (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => { + e.preventDefault(); + + const updatedSettings: NetworkMapSettings = { + networkMap: { + tileOpacity: opacity.toString(), + styling: { theme: theme }, + startupPosition: { + latitude: latitude.toString(), + longitude: longitude.toString(), + zoom: zoom.toString() + } + } + }; + + console.log(updatedSettings); + + await props.updateSettings(updatedSettings) + props.navigateToApplication("network"); + + } + + const recenterMap = () => { + + if (!isNaN(latitude) && !isNaN(longitude) && !isNaN(zoom)) + + map.flyTo({ + center: [ + longitude, + latitude + ], zoom: zoom, + essential: false + }); + } + + + + const getData = () => { + + //get data of boundingbox from networkmap + + const links = requestRest<any>("/topology/network/links/geojson/" + default_boundingbox); + const sites = requestRest<any>("/topology/network/sites/geojson/" + default_boundingbox); + + Promise.all([links, sites]).then(results => { + if (map.getSource('lines')) { + (map.getSource('lines') as mapboxgl.GeoJSONSource).setData(results[0]); + } + + if (map.getSource('points')) { + (map.getSource('points') as mapboxgl.GeoJSONSource).setData(results[1]); + } + + if (map.getSource('selectedPoints')) { + (map.getSource('selectedPoints') as mapboxgl.GeoJSONSource).setData(results[1].features[0]); + } + }); + } + + /** + * Style property names to readable text + * @param text propretyName + * @returns readable text + */ + const styleText = (text: string) => { + const textParts = text.split(/(?=[A-Z])/); //split on uppercase character + const newText = textParts.join(" "); + return newText.charAt(0).toUpperCase() + newText.slice(1); + } + + + return (<> + <h3>Settings</h3> + <div style={{ display: 'flex', flexDirection: 'row', flexGrow: 1, height: "100%", position: 'relative' }}> + <div style={{ width: "60%", flexDirection: 'column', position:'relative' }}> + <Typography variant="body1" style={{ fontWeight: "bold" }} gutterBottom>Startup Position</Typography> + <div style={{ display: 'flex', flexDirection: 'row' }}> + <TextField type="number" value={latitude} onChange={(e) => setLatitude(e.target.value as any)} style={{ marginLeft: 10 }} label="Latitude" /> + <TextField type="number" value={longitude} onChange={(e) => setLongitude(e.target.value as any)} style={{ marginLeft: 5 }} label="Longitude" /> + <TextField type="number" value={zoom} onChange={(e) => setZoom(e.target.value as any)} style={{ marginLeft: 5 }} label="Zoom" /> + </div> + + <Typography className={classes.sectionMargin} variant="body1" style={{ fontWeight: "bold" }} gutterBottom> + Tile Opacity + </Typography> + <Grid className={classes.elementMargin} container spacing={2} style={{ width: '50%' }}> + <Grid item>0</Grid> + <Grid item xs> + <Slider color="secondary" min={0} max={100} value={opacity} onChange={onOpacityChange} aria-labelledby="continuous-slider" /> + </Grid> + <Grid item>100</Grid> + </Grid> + + <Typography className={classes.sectionMargin} variant="body1" style={{ fontWeight: "bold" }} gutterBottom> + Style of properties + </Typography> + <InputLabel id="theme-select-label">Theme</InputLabel> + <Select + className={classes.elementMargin} + value={theme} + onChange={onChangeTheme} + labelId="theme-select-label" + style={{ marginLeft: 10 }}> + { + props.settings.themes.networkMapThemes.themes.map(el => <MenuItem value={el.key}>{el.key}</MenuItem>) + } + + </Select> + + { + currentTheme && <div style={{ marginLeft: 60 }}> + { //skip the 'key' (theme name) entry + Object.keys(currentTheme).slice(1).map(el => <ThemeEntry text={styleText(el)} color={(currentTheme as any)[el]} />) + } + </div> + } + + + <div className={classes.sectionMargin} style={{ position: 'absolute', right: 0, top: '60%' }}> + <Button className={classes.elementMargin} variant="contained" + color="primary" onClick={onCancel}>Cancel</Button> + + <Button className={classes.elementMargin} variant="contained" + color="secondary" onClick={onSaveSettings}>Save</Button> + </div> + </div> + <div id="map" ref={myMapRef} style={{ width: "35%", height: "50%" }}> + + </div> + </div> + + </>) + +} + +export default connect(mapProps, mapDispatch)(CustomizationView); + + diff --git a/sdnr/wt/odlux/apps/networkMapApp/src/components/customize/themeElement.tsx b/sdnr/wt/odlux/apps/networkMapApp/src/components/customize/themeElement.tsx new file mode 100644 index 000000000..c991aaf63 --- /dev/null +++ b/sdnr/wt/odlux/apps/networkMapApp/src/components/customize/themeElement.tsx @@ -0,0 +1,47 @@ +/** + * ============LICENSE_START======================================================================== + * ONAP : ccsdk feature sdnr wt odlux + * ================================================================================================= + * Copyright (C) 2021 highstreet technologies GmbH Intellectual Property. All rights reserved. + * ================================================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * ============LICENSE_END========================================================================== + */ + +import { Typography } from '@material-ui/core'; +import * as React from 'react' + + +type props={ + color: string, + text: string +}; + +const ThemeEntry = (props: props) =>{ + + var circleStyle = { + padding:10, + margin:20, + backgroundColor: props.color, + borderRadius: "50%", + width:10, + height:10, + left:0, + top:0}; + + return <div style={{display: 'flex', flexDirection:'row'}}> + <div style={circleStyle} /> + <Typography variant="body1" style={{marginTop:24}}>{props.text}</Typography> + </div> + +} + +export default ThemeEntry;
\ No newline at end of file diff --git a/sdnr/wt/odlux/apps/networkMapApp/src/components/connectionInfo.tsx b/sdnr/wt/odlux/apps/networkMapApp/src/components/map/connectionInfo.tsx index d1e2d978f..c1fdccfb8 100644 --- a/sdnr/wt/odlux/apps/networkMapApp/src/components/connectionInfo.tsx +++ b/sdnr/wt/odlux/apps/networkMapApp/src/components/map/connectionInfo.tsx @@ -18,8 +18,8 @@ import * as React from 'react' -import { IApplicationStoreState } from "../../../../framework/src/store/applicationStore"; -import connect, { IDispatcher, Connect } from "../../../../framework/src/flux/connect"; +import { IApplicationStoreState } from "../../../../../framework/src/store/applicationStore"; +import connect, { IDispatcher, Connect } from "../../../../../framework/src/flux/connect"; import { Paper, Typography } from "@material-ui/core"; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faExclamationTriangle } from '@fortawesome/free-solid-svg-icons'; diff --git a/sdnr/wt/odlux/apps/networkMapApp/src/components/iconSwitch.tsx b/sdnr/wt/odlux/apps/networkMapApp/src/components/map/iconSwitch.tsx index 8df1385d0..bb98cb467 100644 --- a/sdnr/wt/odlux/apps/networkMapApp/src/components/iconSwitch.tsx +++ b/sdnr/wt/odlux/apps/networkMapApp/src/components/map/iconSwitch.tsx @@ -18,9 +18,9 @@ import * as React from 'react'; import { FormControlLabel, Switch, Paper } from "@material-ui/core"; -import connect, { Connect, IDispatcher } from '../../../../framework/src/flux/connect'; -import { IApplicationStoreState } from '../../../../framework/src/store/applicationStore'; -import { SetIconSwitchAction } from '../actions/mapActions'; +import connect, { Connect, IDispatcher } from '../../../../../framework/src/flux/connect'; +import { IApplicationStoreState } from '../../../../../framework/src/store/applicationStore'; +import { SetIconSwitchAction } from '../../actions/mapActions'; type props = Connect<typeof mapStateToProps, typeof mapDispatchToProps> & {visible: boolean} diff --git a/sdnr/wt/odlux/apps/networkMapApp/src/components/map.tsx b/sdnr/wt/odlux/apps/networkMapApp/src/components/map/map.tsx index 855e5cedf..9637d745e 100644 --- a/sdnr/wt/odlux/apps/networkMapApp/src/components/map.tsx +++ b/sdnr/wt/odlux/apps/networkMapApp/src/components/map/map.tsx @@ -21,25 +21,28 @@ import * as mapboxgl from 'mapbox-gl'; import { RouteComponentProps, withRouter } from 'react-router-dom'; -import { Site } from '../model/site'; -import { SelectSiteAction, ClearHistoryAction, SelectLinkAction } from '../actions/detailsAction'; -import { OSM_STYLE, URL_API, URL_BASEPATH, URL_TILE_API } from '../config'; -import { link } from '../model/link'; +import { Site } from '../../model/site'; +import { SelectSiteAction, ClearHistoryAction, SelectLinkAction } from '../../actions/detailsAction'; +import { OSM_STYLE, URL_API, URL_BASEPATH, URL_TILE_API } from '../../config'; +import { link } from '../../model/link'; import MapPopup from './mapPopup'; -import { SetPopupPositionAction, SelectMultipleLinksAction, SelectMultipleSitesAction } from '../actions/popupActions'; -import { Feature } from '../model/Feature'; -import { HighlightLinkAction, HighlightSiteAction, SetCoordinatesAction, SetStatistics } from '../actions/mapActions'; -import { addDistance, getUniqueFeatures, increaseBoundingBox } from '../utils/mapUtils'; -import { IApplicationStoreState } from '../../../../framework/src/store/applicationStore'; -import connect, { IDispatcher, Connect } from '../../../../framework/src/flux/connect'; +import { SetPopupPositionAction, SelectMultipleLinksAction, SelectMultipleSitesAction } from '../../actions/popupActions'; +import { Feature } from '../../model/Feature'; +import { HighlightLinkAction, HighlightSiteAction, SetCoordinatesAction, SetStatistics } from '../../actions/mapActions'; +import { addDistance, getUniqueFeatures, increaseBoundingBox } from '../../utils/mapUtils'; +import { IApplicationStoreState } from '../../../../../framework/src/store/applicationStore'; +import connect, { IDispatcher, Connect } from '../../../../../framework/src/flux/connect'; import SearchBar from './searchBar'; -import { verifyResponse, IsTileServerReachableAction, handleConnectionError, setTileServerReachableAction } from '../actions/connectivityAction'; +import { verifyResponse, IsTileServerReachableAction, handleConnectionError, setTileServerReachableAction, IsBusycheckingConnectivityAction } from '../../actions/connectivityAction'; import ConnectionInfo from './connectionInfo' -import { showIconLayers, addBaseLayers, addBaseSources, addIconLayers } from '../utils/mapLayers'; +import mapLayerService from '../../utils/mapLayers'; import Statistics from './statistics'; import IconSwitch from './iconSwitch'; -import { addImages } from '../services/mapImagesService'; -import { PopupElement } from '../model/popupElements'; +import { addImages } from '../../services/mapImagesService'; +import { PopupElement } from '../../model/popupElements'; +import { Button } from '@material-ui/core'; +import { NavigateToApplication } from '../../../../../framework/src/actions/navigationActions'; +import customize from '../../../icons/customize.png'; type coordinates = { lat: number, lon: number, zoom: number } @@ -61,31 +64,52 @@ class Map extends React.Component<mapProps, { isPopupOpen: boolean }> { } - componentDidMount() { + updateTheme(){ + mapLayerService.settings=this.props.settings.themes; + if(this.props.settings.mapSettings?.networkMap.styling.theme){ + mapLayerService.selectedTheme = this.props.settings.mapSettings?.networkMap.styling.theme; + } + } + + updateOpacity(){ + if(this.props.settings.mapSettings && this.props.settings.mapSettings.networkMap.tileOpacity){ + mapLayerService.changeMapOpacity(map, Number(this.props.settings.mapSettings.networkMap.tileOpacity)); + } + } + + async componentDidMount() { // resize the map, if menu gets collapsed window.addEventListener("menu-resized", this.handleResize); - // try if connection to tile + topologyserver is available + //pass themes to mapLayerService + this.updateTheme(); - fetch(URL_TILE_API + '/10/0/0.png') - .then(res => { - if (res.ok) { - this.setupMap(); - this.props.setTileServerLoaded(true); - } else { - this.props.setTileServerLoaded(false); - console.error("tileserver " + URL_TILE_API + " can't be reached."); - } - }) - .catch(err => { + // try if connection to tile + topologyserver are available + + try { + const tiles = await fetch(URL_TILE_API + '/10/0/0.png'); + if (tiles.ok) { + this.props.setTileServerLoaded(true); + }else{ this.props.setTileServerLoaded(false); - console.error("tileserver " + URL_TILE_API + " can't be reached."); - }); + } - fetch(URL_API + "/info/count/all") - .then(result => verifyResponse(result)) - .catch(error => this.props.handleConnectionError(error)); + } catch (error) { + this.props.setTileServerLoaded(false); + console.error("tileserver " + URL_TILE_API + " can't be reached."); + } + + try { + const topology = await fetch(URL_API + "/info/count/all"); + verifyResponse(topology); + } catch (error) { + this.props.handleConnectionError(error) + } + + //both done + this.props.setConnectivityCheck(false); + //map loaded in componentDidUpdate } setupMap = () => { @@ -94,6 +118,21 @@ class Map extends React.Component<mapProps, { isPopupOpen: boolean }> { let lon = this.props.lon; let zoom = this.props.zoom; + if(this.props.settings.mapSettings){ + if(this.props.settings.mapSettings.networkMap.startupPosition.latitude){ + lat = Number(this.props.settings.mapSettings.networkMap.startupPosition.latitude) + } + + if(this.props.settings.mapSettings.networkMap.startupPosition.longitude){ + lon = Number(this.props.settings.mapSettings.networkMap.startupPosition.longitude) + } + + if(this.props.settings.mapSettings.networkMap.startupPosition.zoom){ + zoom = Number(this.props.settings.mapSettings.networkMap.startupPosition.zoom) + } + + } + const coordinates = this.extractCoordinatesFromUrl(); // override lat/lon/zoom with coordinates from url, if available if (this.areCoordinatesValid(coordinates)) { @@ -116,15 +155,17 @@ class Map extends React.Component<mapProps, { isPopupOpen: boolean }> { const bbox = map.getBounds(); this.props.updateMapPosition(bbox.getCenter().lat, bbox.getCenter().lng, map.getZoom()) - addBaseSources(map, this.props.selectedSite, this.props.selectedLink); - + mapLayerService.addBaseSources(map, this.props.selectedSite, this.props.selectedLink); + addImages(map, (result: boolean)=>{ if(map.getZoom()>11) { - addIconLayers(map, this.props.selectedSite?.properties.id) + mapLayerService.addIconLayers(map, this.props.selectedSite?.properties.id) }else{ - addBaseLayers(map, this.props.selectedSite, this.props.selectedLink); + mapLayerService.addBaseLayers(map); } + this.updateOpacity(); + }); const boundingBox = increaseBoundingBox(map); @@ -229,7 +270,7 @@ class Map extends React.Component<mapProps, { isPopupOpen: boolean }> { //switch icon layers if applicable - showIconLayers(map, this.props.showIcons, this.props.selectedSite?.properties.id); + mapLayerService.showIconLayers(map, this.props.showIcons, this.props.selectedSite?.properties.id); //update statistics const boundingBox = map.getBounds(); @@ -277,6 +318,29 @@ class Map extends React.Component<mapProps, { isPopupOpen: boolean }> { componentDidUpdate(prevProps: mapProps, prevState: {}) { + //(load map) + //triggered if either settings were done loading or tile/topology server connectivity checked + if(prevProps.settings !== this.props.settings || this.props.isConnectivityCheckBusy !== prevProps.isConnectivityCheckBusy){ + + //update theme if settings changed + if(prevProps.settings !== this.props.settings){ + this.updateTheme(); + } + + //if everything done loading/reachable, load map + if(!this.props.isConnectivityCheckBusy && this.props.isTileServerReachable && !this.props.settings.isLoadingData && (prevProps.settings.isLoadingData !==this.props.settings.isLoadingData || prevProps.isConnectivityCheckBusy !== this.props.isConnectivityCheckBusy)){ + if(map == undefined){ + this.setupMap(); + } + else + if(map.getContainer() !== myRef.current){ + // reload map, because the current container (fresh div) doesn't hold the map and changing containers isn't supported + map.remove(); + this.setupMap(); + } + } + } + if (map !== undefined) { if (prevProps.selectedSite?.properties.id !== this.props.selectedSite?.properties.id) { @@ -361,7 +425,7 @@ class Map extends React.Component<mapProps, { isPopupOpen: boolean }> { if (prevProps.showIcons !== this.props.showIcons) { if (map && map.getZoom() > 11) { - showIconLayers(map, this.props.showIcons, this.props.selectedSite?.properties.id); + mapLayerService.showIconLayers(map, this.props.showIcons, this.props.selectedSite?.properties.id); } } @@ -384,6 +448,9 @@ class Map extends React.Component<mapProps, { isPopupOpen: boolean }> { componentWillUnmount(){ window.removeEventListener("menu-resized", this.handleResize); lastBoundingBox=null; + + // will be checked again on next load + this.props.setConnectivityCheck(true); } handleResize = () => { @@ -543,6 +610,9 @@ class Map extends React.Component<mapProps, { isPopupOpen: boolean }> { return <> +{ + !this.props.settings.isLoadingData ? + <div id="map" style={{ width: "70%", position: 'relative' }} ref={myRef} > { this.state.isPopupOpen && @@ -552,7 +622,16 @@ class Map extends React.Component<mapProps, { isPopupOpen: boolean }> { <Statistics /> <IconSwitch visible={this.props.zoom>11} /> <ConnectionInfo /> + <Button + disabled={!this.props.isTopoServerReachable} + style={{'position': 'absolute', 'right':5, top:5, backgroundColor:'white'}} + onClick={e => this.props.navigateToApplication("network", "customize")} > + <img src={customize} /> + </Button> </div> + :<div style={{ width: "70%", position: 'relative' }} /> + + } </> } @@ -572,7 +651,9 @@ const mapStateToProps = (state: IApplicationStoreState) => ({ siteCount: state.network.map.statistics.sites, isTopoServerReachable: state.network.connectivity.isToplogyServerAvailable, isTileServerReachable: state.network.connectivity.isTileServerAvailable, - showIcons: state.network.map.allowIconSwitch + isConnectivityCheckBusy: state.network.connectivity.isBusy, + showIcons: state.network.map.allowIconSwitch, + settings: state.network.settings, }); const mapDispatchToProps = (dispatcher: IDispatcher) => ({ @@ -587,7 +668,10 @@ const mapDispatchToProps = (dispatcher: IDispatcher) => ({ updateMapPosition: (lat: number, lon: number, zoom: number) => dispatcher.dispatch(new SetCoordinatesAction(lat, lon, zoom)), setStatistics: (linkCount: string, siteCount: string) => dispatcher.dispatch(new SetStatistics(siteCount, linkCount)), setTileServerLoaded: (reachable: boolean) => dispatcher.dispatch(setTileServerReachableAction(reachable)), - handleConnectionError: (error: Error) => dispatcher.dispatch(handleConnectionError(error)) + handleConnectionError: (error: Error) => dispatcher.dispatch(handleConnectionError(error)), + navigateToApplication: (applicationName: string, path?: string) => dispatcher.dispatch(new NavigateToApplication(applicationName, path, "test3")), + setConnectivityCheck: (done: boolean) => dispatcher.dispatch(new IsBusycheckingConnectivityAction(done)), + }) export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Map));
\ No newline at end of file diff --git a/sdnr/wt/odlux/apps/networkMapApp/src/components/mapPopup.tsx b/sdnr/wt/odlux/apps/networkMapApp/src/components/map/mapPopup.tsx index 7435a0a3f..7a64f5a58 100644 --- a/sdnr/wt/odlux/apps/networkMapApp/src/components/mapPopup.tsx +++ b/sdnr/wt/odlux/apps/networkMapApp/src/components/map/mapPopup.tsx @@ -18,14 +18,14 @@ import * as React from 'react'; import { Typography, Select, MenuItem, ClickAwayListener, Popper, Paper, FormGroup, Portal, Popover } from '@material-ui/core'; -import { SelectSiteAction, ClearHistoryAction, ClearDetailsAction } from '../actions/detailsAction'; -import { Site } from '../model/site'; -import { link } from '../model/link'; -import { URL_API } from '../config'; -import { HighlightLinkAction, HighlightSiteAction } from '../actions/mapActions'; -import { IApplicationStoreState } from '../../../../framework/src/store/applicationStore'; -import connect, { IDispatcher, Connect } from '../../../../framework/src/flux/connect'; -import { verifyResponse, handleConnectionError } from '../actions/connectivityAction'; +import { SelectSiteAction, ClearHistoryAction, ClearDetailsAction } from '../../actions/detailsAction'; +import { Site } from '../../model/site'; +import { link } from '../../model/link'; +import { URL_API } from '../../config'; +import { HighlightLinkAction, HighlightSiteAction } from '../../actions/mapActions'; +import { IApplicationStoreState } from '../../../../../framework/src/store/applicationStore'; +import connect, { IDispatcher, Connect } from '../../../../../framework/src/flux/connect'; +import { verifyResponse, handleConnectionError } from '../../actions/connectivityAction'; diff --git a/sdnr/wt/odlux/apps/networkMapApp/src/components/searchBar.tsx b/sdnr/wt/odlux/apps/networkMapApp/src/components/map/searchBar.tsx index 2e698158d..45bc6092d 100644 --- a/sdnr/wt/odlux/apps/networkMapApp/src/components/searchBar.tsx +++ b/sdnr/wt/odlux/apps/networkMapApp/src/components/map/searchBar.tsx @@ -20,16 +20,16 @@ import * as React from 'react'; import { makeStyles, Paper, InputBase, IconButton, Divider, Popover, Typography } from '@material-ui/core'; import SearchIcon from '@material-ui/icons/Search'; -import { URL_API } from '../config'; -import { isSite } from '../utils/utils'; -import { Site } from '../model/site'; -import { link } from '../model/link'; -import { SelectSiteAction, SelectLinkAction } from '../actions/detailsAction'; -import { HighlightLinkAction, HighlightSiteAction, ZoomToSearchResultAction } from '../actions/mapActions'; -import { calculateMidPoint } from '../utils/mapUtils'; -import { SetSearchValueAction } from '../actions/searchAction'; -import connect,{ Connect, IDispatcher } from '../../../../framework/src/flux/connect'; -import { IApplicationStoreState } from '../../../../framework/src/store/applicationStore'; +import { URL_API } from '../../config'; +import { isSite } from '../../utils/utils'; +import { Site } from '../../model/site'; +import { link } from '../../model/link'; +import { SelectSiteAction, SelectLinkAction } from '../../actions/detailsAction'; +import { HighlightLinkAction, HighlightSiteAction, ZoomToSearchResultAction } from '../../actions/mapActions'; +import { calculateMidPoint } from '../../utils/mapUtils'; +import { SetSearchValueAction } from '../../actions/searchAction'; +import connect,{ Connect, IDispatcher } from '../../../../../framework/src/flux/connect'; +import { IApplicationStoreState } from '../../../../../framework/src/store/applicationStore'; diff --git a/sdnr/wt/odlux/apps/networkMapApp/src/components/statistics.tsx b/sdnr/wt/odlux/apps/networkMapApp/src/components/map/statistics.tsx index 4103d64f1..116b789d7 100644 --- a/sdnr/wt/odlux/apps/networkMapApp/src/components/statistics.tsx +++ b/sdnr/wt/odlux/apps/networkMapApp/src/components/map/statistics.tsx @@ -20,8 +20,8 @@ import * as React from 'react'; import { Paper, Typography, Tooltip } from '@material-ui/core'; import InfoIcon from '@material-ui/icons/Info'; -import { IApplicationStoreState } from '../../../../framework/src/store/applicationStore'; -import connect, { IDispatcher, Connect } from '../../../../framework/src/flux/connect'; +import { IApplicationStoreState } from '../../../../../framework/src/store/applicationStore'; +import connect, { IDispatcher, Connect } from '../../../../../framework/src/flux/connect'; type props = Connect<typeof mapStateToProps, typeof mapDispatchToProps>; |