aboutsummaryrefslogtreecommitdiffstats
path: root/sdnr/wt/odlux/apps/networkMapApp/src/components
diff options
context:
space:
mode:
Diffstat (limited to 'sdnr/wt/odlux/apps/networkMapApp/src/components')
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/src/components/customize/customizationView.tsx291
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/src/components/customize/themeElement.tsx47
-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>;