aboutsummaryrefslogtreecommitdiffstats
path: root/sdnr/wt/odlux/apps/networkMapApp
diff options
context:
space:
mode:
authorAijana Schumann <aijana.schumann@highstreet-technologies.com>2021-08-04 11:59:18 +0200
committerAijana Schumann <aijana.schumann@highstreet-technologies.com>2021-08-04 16:06:05 +0200
commit437f67407aece6f7aed8e989638b0d64075f0c0a (patch)
tree53e9e336cd8544edf8a06c889e33f5b9c98fe083 /sdnr/wt/odlux/apps/networkMapApp
parent1c4995eb199437e9c86336efff9972f2049e1532 (diff)
Update ODLUX
Add various updates and bugfixes to NetworkMap, Configuration, LinkCalculation and ConnectApp Issue-ID: CCSDK-3414 Signed-off-by: Aijana Schumann <aijana.schumann@highstreet-technologies.com> Change-Id: I6ea5c3a9d6ccbe9c450da43220654a53fd2f262b Signed-off-by: Aijana Schumann <aijana.schumann@highstreet-technologies.com>
Diffstat (limited to 'sdnr/wt/odlux/apps/networkMapApp')
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/icons/README.md2
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/icons/apartment.png.d.ts18
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/icons/customize.png.d.ts18
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/icons/datacenter.png.d.ts18
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/icons/datacenterred.png.d.ts18
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/icons/factory.png.d.ts18
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/icons/factoryred.png.d.ts18
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/icons/lamp.png.d.ts18
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/icons/lampred.png.d.ts18
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/package.json4
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/pom.xml4
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/src/actions/detailsAction.ts21
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/src/components/denseTable.tsx15
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/src/components/details/linkDetails.tsx34
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/src/components/details/siteDetails.tsx77
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/src/components/details/stadokDetailsPopup.tsx274
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/src/components/map/connectionInfo.tsx2
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/src/components/map/iconSwitch.tsx4
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/src/components/map/map.tsx204
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/src/components/map/searchBar.tsx1
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/src/components/map/statistics.tsx2
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/src/config.ts1
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/src/handlers/detailsReducer.ts10
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/src/index.html5
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/src/model/link.ts10
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/src/model/site.ts3
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/src/model/stadokOrder.ts56
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/src/model/stadokSite.ts54
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/src/pluginTransport.tsx7
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/src/utils/mapLayers.ts2
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/webpack.config.js13
31 files changed, 665 insertions, 284 deletions
diff --git a/sdnr/wt/odlux/apps/networkMapApp/icons/README.md b/sdnr/wt/odlux/apps/networkMapApp/icons/README.md
index 85c75c4e9..b26fbc29b 100644
--- a/sdnr/wt/odlux/apps/networkMapApp/icons/README.md
+++ b/sdnr/wt/odlux/apps/networkMapApp/icons/README.md
@@ -19,7 +19,7 @@ Copyright of icons is as followes:
*/
-->
-datacenter.png, lamp.png and customize.png with all variations (different colors)
+datacenter.png and lamp.png
Taken from MS Word
diff --git a/sdnr/wt/odlux/apps/networkMapApp/icons/apartment.png.d.ts b/sdnr/wt/odlux/apps/networkMapApp/icons/apartment.png.d.ts
index 9f956f813..bf398f5a4 100644
--- a/sdnr/wt/odlux/apps/networkMapApp/icons/apartment.png.d.ts
+++ b/sdnr/wt/odlux/apps/networkMapApp/icons/apartment.png.d.ts
@@ -1,20 +1,2 @@
-/**
- * ============LICENSE_START========================================================================
- * ONAP : ccsdk feature sdnr wt odlux
- * =================================================================================================
- * Copyright (C) 2020 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==========================================================================
- */
-
declare const apartment: string;
export default apartment; \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/networkMapApp/icons/customize.png.d.ts b/sdnr/wt/odlux/apps/networkMapApp/icons/customize.png.d.ts
index 16327f5af..7bcffb2ca 100644
--- a/sdnr/wt/odlux/apps/networkMapApp/icons/customize.png.d.ts
+++ b/sdnr/wt/odlux/apps/networkMapApp/icons/customize.png.d.ts
@@ -1,20 +1,2 @@
-/**
- * ============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==========================================================================
- */
-
declare const customize: string;
export default customize; \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/networkMapApp/icons/datacenter.png.d.ts b/sdnr/wt/odlux/apps/networkMapApp/icons/datacenter.png.d.ts
index dc7019766..a58a9f5af 100644
--- a/sdnr/wt/odlux/apps/networkMapApp/icons/datacenter.png.d.ts
+++ b/sdnr/wt/odlux/apps/networkMapApp/icons/datacenter.png.d.ts
@@ -1,20 +1,2 @@
-/**
- * ============LICENSE_START========================================================================
- * ONAP : ccsdk feature sdnr wt odlux
- * =================================================================================================
- * Copyright (C) 2020 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==========================================================================
- */
-
declare const datacenter: string;
export default datacenter; \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/networkMapApp/icons/datacenterred.png.d.ts b/sdnr/wt/odlux/apps/networkMapApp/icons/datacenterred.png.d.ts
index 74836be8d..33f3061e2 100644
--- a/sdnr/wt/odlux/apps/networkMapApp/icons/datacenterred.png.d.ts
+++ b/sdnr/wt/odlux/apps/networkMapApp/icons/datacenterred.png.d.ts
@@ -1,20 +1,2 @@
-/**
- * ============LICENSE_START========================================================================
- * ONAP : ccsdk feature sdnr wt odlux
- * =================================================================================================
- * Copyright (C) 2020 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==========================================================================
- */
-
declare const datacenterred: string;
export default datacenterred; \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/networkMapApp/icons/factory.png.d.ts b/sdnr/wt/odlux/apps/networkMapApp/icons/factory.png.d.ts
index e341c5f95..b5c4f19d9 100644
--- a/sdnr/wt/odlux/apps/networkMapApp/icons/factory.png.d.ts
+++ b/sdnr/wt/odlux/apps/networkMapApp/icons/factory.png.d.ts
@@ -1,20 +1,2 @@
-/**
- * ============LICENSE_START========================================================================
- * ONAP : ccsdk feature sdnr wt odlux
- * =================================================================================================
- * Copyright (C) 2020 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==========================================================================
- */
-
declare const factory: string;
export default factory; \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/networkMapApp/icons/factoryred.png.d.ts b/sdnr/wt/odlux/apps/networkMapApp/icons/factoryred.png.d.ts
index 317ff7e85..1fac0a943 100644
--- a/sdnr/wt/odlux/apps/networkMapApp/icons/factoryred.png.d.ts
+++ b/sdnr/wt/odlux/apps/networkMapApp/icons/factoryred.png.d.ts
@@ -1,20 +1,2 @@
-/**
- * ============LICENSE_START========================================================================
- * ONAP : ccsdk feature sdnr wt odlux
- * =================================================================================================
- * Copyright (C) 2020 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==========================================================================
- */
-
declare const factoryRed: string;
export default factoryRed; \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/networkMapApp/icons/lamp.png.d.ts b/sdnr/wt/odlux/apps/networkMapApp/icons/lamp.png.d.ts
index eeedc7fcd..9634b1275 100644
--- a/sdnr/wt/odlux/apps/networkMapApp/icons/lamp.png.d.ts
+++ b/sdnr/wt/odlux/apps/networkMapApp/icons/lamp.png.d.ts
@@ -1,20 +1,2 @@
-/**
- * ============LICENSE_START========================================================================
- * ONAP : ccsdk feature sdnr wt odlux
- * =================================================================================================
- * Copyright (C) 2020 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==========================================================================
- */
-
declare const lamp: string;
export default lamp; \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/networkMapApp/icons/lampred.png.d.ts b/sdnr/wt/odlux/apps/networkMapApp/icons/lampred.png.d.ts
index b053df0b8..12a8f91cb 100644
--- a/sdnr/wt/odlux/apps/networkMapApp/icons/lampred.png.d.ts
+++ b/sdnr/wt/odlux/apps/networkMapApp/icons/lampred.png.d.ts
@@ -1,20 +1,2 @@
-/**
- * ============LICENSE_START========================================================================
- * ONAP : ccsdk feature sdnr wt odlux
- * =================================================================================================
- * Copyright (C) 2020 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==========================================================================
- */
-
declare const lampred: string;
export default lampred; \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/networkMapApp/package.json b/sdnr/wt/odlux/apps/networkMapApp/package.json
index cde312ce3..160537045 100644
--- a/sdnr/wt/odlux/apps/networkMapApp/package.json
+++ b/sdnr/wt/odlux/apps/networkMapApp/package.json
@@ -30,8 +30,8 @@
"@types/react": "17.0.3",
"@types/react-dom": "17.0.2",
"@types/react-router-dom": "5.1.7",
- "@material-ui/core": "4.11.0",
- "@material-ui/icons": "4.9.1",
+ "@material-ui/core": "4.11.4",
+ "@material-ui/icons": "4.11.2",
"@types/classnames": "2.2.6",
"@types/flux": "3.1.8",
"@types/jquery": "3.3.10",
diff --git a/sdnr/wt/odlux/apps/networkMapApp/pom.xml b/sdnr/wt/odlux/apps/networkMapApp/pom.xml
index 8284149e0..76da05dc1 100644
--- a/sdnr/wt/odlux/apps/networkMapApp/pom.xml
+++ b/sdnr/wt/odlux/apps/networkMapApp/pom.xml
@@ -140,8 +140,8 @@
<!-- optional: default phase is "generate-resources" -->
<phase>initialize</phase>
<configuration>
- <nodeVersion>v10.16.3</nodeVersion>
- <yarnVersion>v1.19.0</yarnVersion>
+ <nodeVersion>v12.13.0</nodeVersion>
+ <yarnVersion>v1.22.10</yarnVersion>
</configuration>
</execution>
<execution>
diff --git a/sdnr/wt/odlux/apps/networkMapApp/src/actions/detailsAction.ts b/sdnr/wt/odlux/apps/networkMapApp/src/actions/detailsAction.ts
index 34cf10915..a9bea4fc2 100644
--- a/sdnr/wt/odlux/apps/networkMapApp/src/actions/detailsAction.ts
+++ b/sdnr/wt/odlux/apps/networkMapApp/src/actions/detailsAction.ts
@@ -25,6 +25,7 @@ import { link } from '../model/link';
import { HistoryEntry } from "../model/historyEntry";
import { IApplicationStoreState } from '../../../../framework/src/store/applicationStore';
import { Dispatch } from '../../../../framework/src/flux/store';
+import { SITEDOC_URL } from '../config';
export class SelectSiteAction extends Action {
constructor(public site: Site){
@@ -80,6 +81,12 @@ export class InitializeLoadedDevicesAction extends Action{
}
}
+export class IsSitedocReachableAction extends Action{
+ constructor(public isReachable: boolean){
+ super();
+ }
+}
+
let running=false;
export const UpdateDetailsView = (nodeId: string) =>(dispatcher: Dispatch, getState: () => IApplicationStoreState) =>{
@@ -137,4 +144,18 @@ running=true;
dispatcher(new IsBusyCheckingDeviceListAction(false));
});
+}
+
+export const checkSitedockReachablity = () => async (dispatcher: Dispatch, getState: () => IApplicationStoreState) =>{
+ console.log("searching for sitedoc server...")
+ requestRest<any>(SITEDOC_URL+'/app/versioninfo').then(response =>{
+ console.log(response);
+ if(response){
+
+ dispatcher(new IsSitedocReachableAction(true));
+
+ }else{
+ dispatcher(new IsSitedocReachableAction(false));
+ }
+ })
} \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/networkMapApp/src/components/denseTable.tsx b/sdnr/wt/odlux/apps/networkMapApp/src/components/denseTable.tsx
index 7e378b81e..e04fda547 100644
--- a/sdnr/wt/odlux/apps/networkMapApp/src/components/denseTable.tsx
+++ b/sdnr/wt/odlux/apps/networkMapApp/src/components/denseTable.tsx
@@ -26,7 +26,16 @@ import TableRow from '@material-ui/core/TableRow';
import Paper from '@material-ui/core/Paper';
import { makeStyles, Button, Tooltip } from '@material-ui/core';
-type props = { headers: string[], height: number, navigate?(applicationName: string, path?: string): void, onLinkClick?(id: string): void, data: any[], hover: boolean, ariaLabelRow: string, ariaLabelColumn: string[], verticalTable?: boolean, onClick?(id: string): void, actions?: boolean };
+type props = { headers: string[],
+ height: number,
+ navigate?(applicationName: string, path?: string): void,
+ onLinkClick?(id: string): void, data: any[],
+ hover: boolean,
+ ariaLabelRow: string,
+ ariaLabelColumn?: string[],
+ verticalTable?: boolean,
+ onClick?(id: string): void,
+ actions?: boolean };
const styles = makeStyles({
@@ -81,7 +90,7 @@ const DenseTable: React.FunctionComponent<props> = (props) => {
if (data !== undefined) {
if (!props.verticalTable) {
- const ariaLabel = props.ariaLabelColumn[i];
+ const ariaLabel = props.ariaLabelColumn === undefined ? props.headers[i].toLowerCase() : props.ariaLabelColumn[i];
if (ariaLabel.length > 0) {
return <TableCell aria-label={ariaLabel}>{data}</TableCell>
} else {
@@ -93,7 +102,7 @@ const DenseTable: React.FunctionComponent<props> = (props) => {
if (i === 0) {
return <TableCell>{data}</TableCell>
} else {
- const ariaLabel = props.ariaLabelColumn[index];
+ const ariaLabel = props.ariaLabelColumn === undefined ? props.headers[index].toLowerCase() : props.ariaLabelColumn[index];
return <TableCell aria-label={ariaLabel}>{data}</TableCell>
}
}
diff --git a/sdnr/wt/odlux/apps/networkMapApp/src/components/details/linkDetails.tsx b/sdnr/wt/odlux/apps/networkMapApp/src/components/details/linkDetails.tsx
index 57091aebf..96727cc0d 100644
--- a/sdnr/wt/odlux/apps/networkMapApp/src/components/details/linkDetails.tsx
+++ b/sdnr/wt/odlux/apps/networkMapApp/src/components/details/linkDetails.tsx
@@ -37,7 +37,7 @@ const LinkDetails: React.FunctionComponent<props> = (props) => {
if(el && el2){
if(props.link.type==="microwave")
- setHeight(el!.height - el2!.y -30);
+ setHeight(el!.height - el2!.y -50);
else
setHeight(el!.height - el2!.y +20);
@@ -68,10 +68,34 @@ const LinkDetails: React.FunctionComponent<props> = (props) => {
const distance = props.link.length > 0 ? props.link.length : props.link.calculatedLength;
const azimuthA = props.link.azimuthA;
const azimuthB = props.link.azimuthB;
+ const antennaA = props.link.locationA.antenna;
+ const antennaB = props.link.locationB.antenna;
+
+
+ let antennaData = "";
+ if(antennaA!==null && antennaB!==null){
+ antennaData = `&antennaNameA=${antennaA.name}&antennaGainA=${antennaA.gain}&waveguideLossA=${antennaA.waveguideLossIndB}&antennaNameB=${antennaB.name}&antennaGainB=${antennaB.gain}&waveguideLossB=${antennaB.waveguideLossIndB}`;
+ }
+
+
const baseUrl = window.location.pathname.split('#')[0];
- window.open(`${baseUrl}#/linkCalculation?lat1=${siteA.lat}&lon1=${siteA.lon}&lat2=${siteB.lat}&lon2=${siteB.lon}&siteA=${nameA}&siteB=${nameB}&azimuthA=${azimuthA}&azimuthB=${azimuthB}&distance=${distance}&amslSiteA=${siteA.amsl}&AGLsiteA=${siteA.antennaHeight}&amslSiteB=${siteB.amsl}&AGLsiteB=${siteB.antennaHeight}`)
+ window.open(`${baseUrl}#/linkCalculation?lat1=${siteA.lat}&lon1=${siteA.lon}&lat2=${siteB.lat}&lon2=${siteB.lon}&siteA=${nameA}&siteB=${nameB}&azimuthA=${azimuthA}&azimuthB=${azimuthB}&distance=${distance}&amslSiteA=${siteA.amsl}&AGLsiteA=${siteA.antennaHeight}&amslSiteB=${siteB.amsl}&AGLsiteB=${siteB.antennaHeight}${antennaData}`)
+
+ }
+
+ const onLineofSightClick = (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) =>{
+ e.preventDefault();
+
+ const siteA= props.link.locationA;
+ const siteB =props.link.locationB;
+
+ //TODO: add check if available
+ let heightPart = `&amslA=${siteA.amsl}&antennaHeightA=${siteA.antennaHeight}&amslB=${siteB.amsl}&antennaHeightB=${siteB.antennaHeight}`;
+
+ const baseUrl = window.location.pathname.split('#')[0];
+ window.open(`${baseUrl}#/lineofsight/los?lat1=${siteA.lat}&lon1=${siteA.lon}&lat2=${siteB.lat}&lon2=${siteB.lon}${heightPart}`);
}
const data = [
@@ -94,7 +118,11 @@ const LinkDetails: React.FunctionComponent<props> = (props) => {
</AppBar>
<DenseTable ariaLabelRow="site-information-table-entry" ariaLabelColumn={["site-name", "latitude", "longitude", "azimuth"]} verticalTable height={height} hover={false} headers={["", "Site A", "Site B"]} data={data} />
{
- props.link.type==="microwave" && <Button style={{marginTop:20}} fullWidth variant="contained" color="primary" onClick={onCalculateLinkClick}>Calculate link</Button>
+ props.link.type==="microwave" &&<>
+ <Button style={{marginTop:20}} fullWidth variant="contained" color="primary" onClick={onCalculateLinkClick}>Calculate link</Button>
+ <Button style={{marginTop:20}} fullWidth variant="contained" color="primary" onClick={onLineofSightClick}>Line of Sight</Button>
+
+ </>
}
</div>)
}
diff --git a/sdnr/wt/odlux/apps/networkMapApp/src/components/details/siteDetails.tsx b/sdnr/wt/odlux/apps/networkMapApp/src/components/details/siteDetails.tsx
index 3aa35c348..7f0c1c926 100644
--- a/sdnr/wt/odlux/apps/networkMapApp/src/components/details/siteDetails.tsx
+++ b/sdnr/wt/odlux/apps/networkMapApp/src/components/details/siteDetails.tsx
@@ -30,6 +30,9 @@ import { CheckDeviceList, InitializeLoadedDevicesAction } from '../../actions/de
import { NavigateToApplication } from '../../../../../framework/src/actions/navigationActions';
import connect, { Connect, IDispatcher } from '../../../../../framework/src/flux/connect';
import { IApplicationStoreState } from '../../../../../framework/src/store/applicationStore';
+import StadokSite from '../../model/stadokSite';
+import { requestRest } from '../../../../../framework/src/services/restService';
+import StadokDetailsPopup from './stadokDetailsPopup';
type linkRow = { name: string, azimuth?: string}
type deviceRow = { id: string;type: string,name: string,manufacturer: string,owner: string,status?: string,port: number[]}
@@ -48,6 +51,8 @@ const SiteDetails: React.FunctionComponent<siteDetailProps> = (props) => {
const [value, setValue] = React.useState<panelId>("links");
const [height, setHeight] = React.useState(330);
+ const [openPopup, setOpenPopup] = React.useState(false);
+ const [staSite, setStaSite] = React.useState<StadokSite|null>(null);
const handleResize = () =>{
const el = document.getElementById('site-details-panel')?.getBoundingClientRect();
@@ -82,35 +87,55 @@ const SiteDetails: React.FunctionComponent<siteDetailProps> = (props) => {
setValue(newValue);
}
+ const getFurtherInformation = (url: string) =>{
+
+ const request = requestRest<StadokSite>(url, { method: "GET"});
+
+ request.then(result =>{
+ if(result){
+ setStaSite(result);
+ setOpenPopup(true);
+ }else{
+ console.error(result);
+ }
+
+
+ });
+ }
+
+ const closePopup = () =>{
+ setOpenPopup(false);
+ }
+
//prepare link table
let hasAzimuth = false;
- const linkRows: linkRow[] = props.site.links.map(link=>
+ const linkRows: linkRow[] = props.site.links?.map(link=>
{
if(link.azimuthB!==null){
hasAzimuth=true;
- return {name: link.name, azimuth: link.azimuthB.toFixed(2) }
+ return {name: link.name, azimuth: link.azimuthB.toFixed(2) }
- }else{
- return {name: link.name }
- }
-
- });
+ }else{
+ return {name: link.name }
+ }
+ });
const linkTableHeader = hasAzimuth ? ["Link Name", "Azimuth in °"] : ["Link Name"];
//prepare device table
- const deviceRows : deviceRow[] = props.updatedDevices.map(device=>{
- return{
- id: device.id,
- name: device.name,
- type: device.type,
- status: device.status,
- manufacturer: device.manufacturer,
- owner: device.owner,
- port: device.port
- }
- });
+ const deviceRows : deviceRow[] = props.updatedDevices?.map(device=>{
+ return{
+ id: device.id,
+ name: device.name,
+ type: device.type,
+ status: device.status,
+ manufacturer: device.manufacturer,
+ owner: device.owner,
+ port: device.port
+ }
+ });
+
const adressString = props.site.address == null ? null : buildAdress(props.site.address);
@@ -152,12 +177,12 @@ const SiteDetails: React.FunctionComponent<siteDetailProps> = (props) => {
value === "links" &&
<>
{
- props.site.links.length === 0 &&
+ props.site.links==null &&
<Typography aria-label="no-links-available" variant="body1" style={{ marginTop: '10px' }}>No links available.</Typography>
}
{
- props.site.links.length > 0 &&
+ props.site.links?.length > 0 &&
<DenseTable ariaLabelRow="available-links-table" ariaLabelColumn={["link-name", "azimuth"]} height={height} hover={true} headers={linkTableHeader} data={linkRows} onClick={props.onLinkClick} ></DenseTable>
}
@@ -178,6 +203,15 @@ const SiteDetails: React.FunctionComponent<siteDetailProps> = (props) => {
}
</>
}
+ {
+ props.isSitedocReachable && props.site.furtherInformation!==null && props.site.furtherInformation.length>0 &&
+ <Button style={{marginTop:20}} fullWidth variant="contained" color="primary" onClick={e => getFurtherInformation(props.site.furtherInformation) }>Further information available</Button>
+ }
+
+ {
+ staSite !== null && openPopup && <StadokDetailsPopup site={staSite} onClose={closePopup} open={true} />
+ }
+
</div>
)
}
@@ -200,7 +234,8 @@ const buildAdress = (adress: Address) =>{
}
const mapStateToProps = (state: IApplicationStoreState) => ({
- updatedDevices: state.network.details.checkedDevices
+ updatedDevices: state.network.details.checkedDevices,
+ isSitedocReachable: state.network.details.isSitedocReachable
});
const mapDispatchToProps = (dispatcher: IDispatcher) => ({
diff --git a/sdnr/wt/odlux/apps/networkMapApp/src/components/details/stadokDetailsPopup.tsx b/sdnr/wt/odlux/apps/networkMapApp/src/components/details/stadokDetailsPopup.tsx
new file mode 100644
index 000000000..4f3235db7
--- /dev/null
+++ b/sdnr/wt/odlux/apps/networkMapApp/src/components/details/stadokDetailsPopup.tsx
@@ -0,0 +1,274 @@
+/**
+ * ============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 * as React from 'react';
+
+import MuiDialogTitle from '@material-ui/core/DialogTitle';
+import { AppBar, Dialog, DialogContent, IconButton, Tab, Tabs, TextField, Typography } from '@material-ui/core';
+import CloseIcon from '@material-ui/icons/Close';
+import { withStyles, WithStyles, createStyles, Theme, makeStyles } from '@material-ui/core/styles';
+
+
+import StadokSite from '../../model/stadokSite';
+import { LatLonToDMS } from '../../utils/mapUtils';
+import DenseTable from '../../components/denseTable';
+import { requestRest } from '../../../../../framework/src/services/restService';
+import { OrderToDisplay, StadokOrder } from '../../model/stadokOrder';
+import { CSSProperties } from '@material-ui/core/styles/withStyles';
+import { SITEDOC_URL } from '../../config';
+
+
+type props = { site: StadokSite; onClose(): void; open:boolean };
+
+const styles = (theme: Theme) => createStyles({
+ root: {
+ margin: 0,
+ padding: theme.spacing(2),
+ },
+ closeButton: {
+ position: 'absolute',
+ right: theme.spacing(1),
+ top: theme.spacing(1),
+ color: theme.palette.grey[500],
+ },
+});
+
+const useStyles = makeStyles({
+ largeImage:{cursor:'pointer', width:300},
+ smallImage:{cursor:'pointer', width: 50, marginTop:'10px', marginLeft:'10px'}
+});
+
+const StadokDetailsPopup: React.FunctionComponent<props> = (props) => {
+ const classes = useStyles();
+
+ const [open, setOpen] = React.useState(props.open);
+ const [value, setValue] = React.useState("devices");
+ const [orders, setOrders] = React.useState<OrderToDisplay[]|null>(null);
+
+ const DialogTitle = withStyles(styles)((props: any) => {
+ const { children, classes, onClose, ...other } = props;
+ return (
+ <MuiDialogTitle disableTypography className={classes.root} {...other}>
+ <Typography variant="h6">{children}</Typography>
+ {onClose ? (
+ <IconButton aria-label="close" style={{position: 'absolute', top:0, right:0, color: 'black'}} onClick={onClose}>
+ <CloseIcon />
+ </IconButton>
+ ) : null}
+ </MuiDialogTitle>
+ );
+ });
+
+ const getContacts = (site: StadokSite) =>{
+ const contacts = [];
+
+ if(site.createdBy){
+ contacts.push({h: "Site Creator",col1: site.createdBy.firstName, col2: site.createdBy.lastName, col3: site.createdBy.email, col4: site.createdBy.telephoneNumber });
+ }
+
+ if(site.contacts.manager){
+ contacts.push({h: "Manager",col1: site.contacts.manager.firstName, col2: site.contacts.manager.lastName, col3: site.contacts.manager.email, col4: site.contacts.manager.telephoneNumber });
+ }
+
+ if(site.contacts.owner){
+ contacts.push({h: "Owner",col1: site.contacts.owner.firstName, col2: site.contacts.owner.lastName, col3: site.contacts.owner.email, col4: site.contacts.owner.telephoneNumber });
+ }
+ return contacts;
+ }
+
+ const onClose = () =>{
+ // setOpen(false);
+ props.onClose()
+ }
+
+ //todo: use a set 'panelId' -> which values are allowed
+ const onHandleTabChange = (event: React.ChangeEvent<{}>, newValue: string) => {
+ setValue(newValue);
+}
+console.log(props.site)
+ const contacts = getContacts(props.site);
+
+ const orderUrl=`${SITEDOC_URL}/site/${props.site.siteId}/orders`;
+
+ if(orders==null){
+ requestRest<StadokOrder[]>(orderUrl,{ method: "GET"}).then(result =>{
+ if(result){
+ const orderList = result.map(order =>{
+ return OrderToDisplay.parse(order);
+ });
+ setOrders(orderList);
+
+ }else{
+ setOrders([]);
+ }
+ });
+ }
+
+ const createOrderInfo = () => {
+
+ if (orders === null) {
+ return (<div style={{ height: 300 }}>
+ <Typography variant="body1" style={{ marginTop: '10px' }}>
+ Loading orders
+ </Typography>
+ </div>)
+ } else if (orders.length === 0) {
+ return (<div style={{ height: 300 }}>
+ <Typography variant="body1" style={{ marginTop: '10px' }}>
+ No orders available
+ </Typography>
+ </div>)
+ } else {
+ return <DenseTable data={orders} height={300} headers={["Person", "State", "Current Task"]} hover={false} ariaLabelRow="activity-log-table" />
+ }
+ }
+
+ const displayImages = () => {
+
+ if (props.site.images.length === 1) {
+ return stadokImage(props.site.siteId, props.site.images[0],"large")
+ } else {
+ return <>
+ {
+ stadokImage(props.site.siteId, props.site.images[0], "large")
+ }
+ <div style={{ display: 'flex', flexDirection: 'row', flexWrap:'wrap' }}>
+
+ {
+ props.site.images.length<=9 ?
+ props.site.images.slice(1, props.site.images.length).map(image =>
+ stadokImage(props.site.siteId, image, "small")
+ )
+ :
+ <>
+ {
+ props.site.images.slice(1, 9).map(image =>
+ stadokImage(props.site.siteId, image, "small")
+ )
+ }
+
+ </>
+ }
+ </div>
+ </>
+ }
+
+ }
+
+ const stadokImage = (siteId: string, imagename: string, size: 'large' | 'small') => {
+ const url = `${SITEDOC_URL}/site/${siteId}/files/${imagename}`;
+ const className = size === "small" ? classes.smallImage : classes.largeImage;
+ return <img className={className} src={url} onClick={e => window.open(url)} />
+
+ }
+
+
+ return (<Dialog onClose={onClose} fullWidth maxWidth="md" aria-labelledby="customized-dialog-title" open={open}>
+ <DialogTitle id="customized-dialog-title" onClose={onClose}>
+ {props.site.siteId}
+ </DialogTitle>
+ <DialogContent style={{minWidth:'900px'}} dividers>
+ <div style={{ display: 'flex', flexDirection: 'row', flexGrow: 1 }}>
+ <div style={{ width: '60%', display:'flex', flexDirection: 'column' }}>
+
+ <TextField inputProps={{ 'aria-label': 'type' }} disabled={true} value={props.site.updatedOn} label="Updated on" style={{ marginTop: "5px" }} />
+
+
+ {
+ props.site.type !== undefined && props.site.type.length > 0 &&
+ <TextField inputProps={{ 'aria-label': 'type' }} disabled={true} value={props.site.type} label="Type" style={{ marginTop: "5px" }} />
+ }
+
+
+ <TextField inputProps={{ 'aria-label': 'adress' }} disabled={true} value={`${props.site.address.streetAndNr}, ${props.site.address.zipCode !== null ? props.site.address.zipCode : ''} ${props.site.address.city}`} label="Address" style={{ marginTop: "5px" }} />
+
+
+ <TextField inputProps={{ 'aria-label': 'latitude' }} style={{ marginTop: "5px" }} disabled={true} value={LatLonToDMS(props.site.location.lat)} label="Latitude" />
+ <TextField inputProps={{ 'aria-label': 'longitude' }} style={{ marginTop: "5px" }} disabled={true} value={LatLonToDMS(props.site.location.lon, true)} label="Longitude" />
+ <AppBar position="static" style={{ marginTop: "5px", background: '#2E3B55' }}>
+ <Tabs id="site-tabs" variant="scrollable" scrollButtons="on" value={value} onChange={onHandleTabChange} aria-label="simple tabs example">
+ <Tab label="Devices" value="devices" />
+ <Tab label="Contacts" value="contacts" />
+ <Tab label="Saftey" value="safteyInfo" />
+ <Tab label="Logs" value="logs" />
+ <Tab label="Orders" value="orders" />
+ </Tabs>
+ </AppBar>
+ {
+ value == "devices" && (props.site.devices?.length>0 ?
+ <DenseTable data={props.site.devices} height={300} headers={["Device", "Antenna"]} hover={false} ariaLabelRow="devices-table" />
+ :
+ <div style={{height:300}}>
+ <Typography variant="body1" style={{ marginTop: '10px' }}>
+ No devices available
+ </Typography>
+ </div>)
+ }
+ {
+ value == "contacts" && (contacts.length>0 ?
+ <DenseTable data={contacts} height={300} headers={["Person", "Firstname", "Lastname", "Email", "Phone No."]} hover={false} ariaLabelRow="contacts-table" ariaLabelColumn={["person", "firstname", "lastname", "email", "phoneno"]} />
+ :
+ <div style={{height:300}}>
+ <Typography variant="body1" style={{ marginTop: '10px' }}>
+ No contacts available
+ </Typography>
+ </div>)
+ }
+ {
+ value == "safteyInfo" && (props.site.safteyNotices.length>0 ?
+ <DenseTable data={props.site.safteyNotices} height={300} headers={["Note"]} hover={false} ariaLabelRow="saftey-info-table" />
+ :
+ <div style={{height:300}}>
+ <Typography variant="body1" style={{ marginTop: '10px' }}>
+ No saftey notices applicable
+ </Typography>
+ </div>)
+ }
+ {
+ value == "logs" && (props.site.logs.length>0 ?
+ <DenseTable data={props.site.logs} height={300} headers={["Date","Person", "Activity"]} hover={false} ariaLabelRow="activity-log-table" />
+ :
+ <div style={{height:300}}>
+ <Typography variant="body1" style={{ marginTop: '10px' }}>
+ No activity log available
+ </Typography>
+ </div>)
+ }
+
+ {
+ value ==="orders" && createOrderInfo()
+ }
+
+ </div>
+ <div style={{padding: '10px', display: 'flex', alignItems:'center', flexDirection:'column', justifyContent: 'start', width:'40%'}}>
+ {
+ props.site.images.length == 0 ?
+ <Typography variant="body1" style={{ marginTop: '10px' }}>
+ No images available
+ </Typography>
+ : displayImages()
+ }
+ </div>
+ </div>
+
+ </DialogContent>
+ </Dialog>)
+
+}
+
+export default StadokDetailsPopup; \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/networkMapApp/src/components/map/connectionInfo.tsx b/sdnr/wt/odlux/apps/networkMapApp/src/components/map/connectionInfo.tsx
index c1fdccfb8..3b5a15ce5 100644
--- a/sdnr/wt/odlux/apps/networkMapApp/src/components/map/connectionInfo.tsx
+++ b/sdnr/wt/odlux/apps/networkMapApp/src/components/map/connectionInfo.tsx
@@ -29,7 +29,7 @@ type props = Connect<typeof mapStateToProps, typeof mapDispatchToProps>;
const ConnectionInfo: React.FunctionComponent<props> = (props) => {
- return ((props.isTopoServerReachable === false || props.isTileServerReachable === false )? <Paper style={{padding:5, position: 'absolute', top: 160, width: 230, left:"40%"}}>
+ return ((props.isTopoServerReachable === false || props.isTileServerReachable === false )? <Paper style={{padding:5, position: 'absolute', top: 160, width: 230, left:"40%", zIndex:1}}>
<div style={{display: 'flex', flexDirection: 'column'}}>
<div style={{'alignSelf': 'center', marginBottom:5}}> <Typography> <FontAwesomeIcon icon={faExclamationTriangle} /> Connection Error</Typography></div>
{props.isTileServerReachable === false && <Typography> Tile data can't be loaded.</Typography>}
diff --git a/sdnr/wt/odlux/apps/networkMapApp/src/components/map/iconSwitch.tsx b/sdnr/wt/odlux/apps/networkMapApp/src/components/map/iconSwitch.tsx
index bb98cb467..221e7dab8 100644
--- a/sdnr/wt/odlux/apps/networkMapApp/src/components/map/iconSwitch.tsx
+++ b/sdnr/wt/odlux/apps/networkMapApp/src/components/map/iconSwitch.tsx
@@ -32,9 +32,9 @@ const IconSwitch: React.FunctionComponent<props> = (props) =>{
return (
props.visible ?
- <FormControlLabel style={{ padding:5, position: 'absolute',top: 190}}
+ <FormControlLabel style={{ padding:5, position: 'absolute',top: 190, zIndex:1}}
value="end"
- control={<Switch color="secondary" checked={props.areIconsEnabled} onChange={toggleChecked} />}
+ control={<Switch color="secondary" style={{zIndex:1}} checked={props.areIconsEnabled} onChange={toggleChecked} />}
label="Show icons"
labelPlacement="end"
/>: null)
diff --git a/sdnr/wt/odlux/apps/networkMapApp/src/components/map/map.tsx b/sdnr/wt/odlux/apps/networkMapApp/src/components/map/map.tsx
index 9637d745e..1314edbba 100644
--- a/sdnr/wt/odlux/apps/networkMapApp/src/components/map/map.tsx
+++ b/sdnr/wt/odlux/apps/networkMapApp/src/components/map/map.tsx
@@ -54,6 +54,7 @@ let notLoadedBoundingBoxes: mapboxgl.LngLatBounds[] = [];
let lastBoundingBox: mapboxgl.LngLatBounds | null = null;
let myRef = React.createRef<HTMLDivElement>();
+import 'mapbox-gl/dist/mapbox-gl.css';
class Map extends React.Component<mapProps, { isPopupOpen: boolean }> {
@@ -158,7 +159,7 @@ class Map extends React.Component<mapProps, { isPopupOpen: boolean }> {
mapLayerService.addBaseSources(map, this.props.selectedSite, this.props.selectedLink);
addImages(map, (result: boolean)=>{
- if(map.getZoom()>11)
+ if(map.getZoom()>11 && this.props.showIcons)
{
mapLayerService.addIconLayers(map, this.props.selectedSite?.properties.id)
}else{
@@ -190,134 +191,142 @@ class Map extends React.Component<mapProps, { isPopupOpen: boolean }> {
}
})
.catch(error => this.props.handleConnectionError(error));
+
+ map.on('click', this.mapClick);
+ map.on('moveend', this.mapMoveEnd);
+ map.on('move', this.mapMove);
+
});
+ }
- map.on('click', (e: any) => {
+ mapMove = () => {
+
+ const mapZoom = map.getZoom();
- if (map.getLayer('points')) { // data is shown as points
+ const boundingBox = map.getBounds();
+
+ this.loadNetworkData(boundingBox);
+ if (mapZoom > 9) {
- var clickedLines = getUniqueFeatures(map.queryRenderedFeatures([[e.point.x - 5, e.point.y - 5],
- [e.point.x + 5, e.point.y + 5]], {
- layers: ['microwave-lines', 'fibre-lines']
- }), "id");
+ if (map.getLayer('points')) {
+ map.setLayoutProperty('selectedPoints', 'visibility', 'visible');
+ map.setPaintProperty('points', 'circle-radius', 7);
+ }
+ } else {
- const clickedPoints = getUniqueFeatures(map.queryRenderedFeatures(e.point, { layers: ['points'] }), "id");
- const alarmedSites = getUniqueFeatures(map.queryRenderedFeatures(e.point, { layers: ['alarmedPoints'] }), "id");
+ // reduce size of points / lines if zoomed out
+ map.setPaintProperty('points', 'circle-radius', 2);
+ map.setLayoutProperty('selectedPoints', 'visibility', 'none');
- if (clickedPoints.length != 0) {
+ if (mapZoom <= 4) {
+ map.setPaintProperty('fibre-lines', 'line-width', 1);
+ map.setPaintProperty('microwave-lines', 'line-width', 1);
+
+ } else {
+ map.setPaintProperty('fibre-lines', 'line-width', 2);
+ map.setPaintProperty('microwave-lines', 'line-width', 2);
+ }
+ }
+ };
+ mapClick = (e: any) => {
- if (alarmedSites.length > 0) {
- alarmedSites.forEach(alarm => {
- const index = clickedPoints.findIndex(item => item.properties!.id === alarm.properties!.id);
+
+ if (map.getLayer('points')) { // data is shown as points
- if (index !== -1) {
- clickedPoints[index].properties!.alarmed = true;
- clickedPoints[index].properties!.type = "alarmed";
- }
- });
- }
+ var clickedLines = getUniqueFeatures(map.queryRenderedFeatures([[e.point.x - 5, e.point.y - 5],
+ [e.point.x + 5, e.point.y + 5]], {
+ layers: ['microwave-lines', 'fibre-lines']
+ }), "id");
- this.showSitePopup(clickedPoints, e.point.x, e.point.y);
- } else if (clickedLines.length != 0) {
- this.showLinkPopup(clickedLines, e.point.x, e.point.y);
- }
+ const clickedPoints = getUniqueFeatures(map.queryRenderedFeatures(e.point, { layers: ['points'] }), "id");
+ const alarmedSites = getUniqueFeatures(map.queryRenderedFeatures(e.point, { layers: ['alarmedPoints'] }), "id");
+ if (clickedPoints.length != 0) {
- } else { // data is shown as icons
- const clickedSites = getUniqueFeatures(map.queryRenderedFeatures(e.point, { layers: ['point-lamps', 'point-building', 'point-data-center', 'point-factory', 'point-remaining'] }), "id");
- const clickedLines = getUniqueFeatures(map.queryRenderedFeatures([[e.point.x - 5, e.point.y - 5],
- [e.point.x + 5, e.point.y + 5]], {
- layers: ['microwave-lines', 'fibre-lines']
- }), "id");
+ if (alarmedSites.length > 0) {
+ alarmedSites.forEach(alarm => {
+ const index = clickedPoints.findIndex(item => item.properties!.id === alarm.properties!.id);
- if (clickedSites.length > 0)
- this.showSitePopup(clickedSites, e.point.x, e.point.y);
- else if (clickedLines.length != 0) {
- this.showLinkPopup(clickedLines, e.point.x, e.point.y);
+ if (index !== -1) {
+ clickedPoints[index].properties!.alarmed = true;
+ clickedPoints[index].properties!.type = "alarmed";
+ }
+ });
}
- }
- });
+ this.showSitePopup(clickedPoints, e.point.x, e.point.y);
+ } else if (clickedLines.length != 0) {
+ this.showLinkPopup(clickedLines, e.point.x, e.point.y);
+ }
- map.on('moveend', () => {
- const mapZoom = Number(map.getZoom().toFixed(2));
- const lat = Number(map.getCenter().lat.toFixed(4));
- const lon = Number(map.getCenter().lng.toFixed(4));
+ } else { // data is shown as icons
+ const clickedSites = getUniqueFeatures(map.queryRenderedFeatures(e.point, { layers: ['point-lamps', 'point-building', 'point-data-center', 'point-factory', 'point-remaining'] }), "id");
+ const clickedLines = getUniqueFeatures(map.queryRenderedFeatures([[e.point.x - 5, e.point.y - 5],
+ [e.point.x + 5, e.point.y + 5]], {
+ layers: ['microwave-lines', 'fibre-lines']
+ }), "id");
- if (this.props.lat !== lat || this.props.lon !== lon || this.props.zoom !== mapZoom) {
- this.props.updateMapPosition(lat, lon, mapZoom)
+ if (clickedSites.length > 0)
+ this.showSitePopup(clickedSites, e.point.x, e.point.y);
+ else if (clickedLines.length != 0) {
+ this.showLinkPopup(clickedLines, e.point.x, e.point.y);
}
+ }
+ };
- // update the url to current lat,lon,zoom values
+ mapMoveEnd = () => {
- const currentUrl = window.location.href;
- const parts = currentUrl.split(URL_BASEPATH);
- if(parts.length>0){
+ const mapZoom = Number(map.getZoom().toFixed(2));
+ const lat = Number(map.getCenter().lat.toFixed(4));
+ const lon = Number(map.getCenter().lng.toFixed(4));
- const detailsPath = parts[1].split("/details/");
- if (detailsPath[1] !== undefined && detailsPath[1].length > 0) {
- this.props.history.replace(`/${URL_BASEPATH}/${map.getCenter().lat.toFixed(4)},${map.getCenter().lng.toFixed(4)},${mapZoom.toFixed(2)}/details/${detailsPath[1]}`)
- }
- else {
- this.props.history.replace(`/${URL_BASEPATH}/${map.getCenter().lat.toFixed(4)},${map.getCenter().lng.toFixed(4)},${mapZoom.toFixed(2)}`)
- }
- }
-
-
- //switch icon layers if applicable
- mapLayerService.showIconLayers(map, this.props.showIcons, this.props.selectedSite?.properties.id);
+ if (this.props.lat !== lat || this.props.lon !== lon || this.props.zoom !== mapZoom) {
+ this.props.updateMapPosition(lat, lon, mapZoom)
+ }
- //update statistics
- const boundingBox = map.getBounds();
+ // update the url to current lat,lon,zoom values
- fetch(`${URL_API}/info/count/${boundingBox.getWest()},${boundingBox.getSouth()},${boundingBox.getEast()},${boundingBox.getNorth()}`)
- .then(result => verifyResponse(result))
- .then(res => res.json())
- .then(result => {
- if (result.links !== this.props.linkCount || result.sites !== this.props.siteCount) {
- this.props.setStatistics(result.links, result.sites);
- }
- })
- .catch(error => this.props.handleConnectionError(error));;
- })
+ const currentUrl = window.location.href;
+ const parts = currentUrl.split(URL_BASEPATH);
+ if (parts.length > 0) {
- map.on('move', () => {
- const mapZoom = map.getZoom();
+ const detailsPath = parts[1].split("/details/");
- const boundingBox = map.getBounds();
+ if (detailsPath[1] !== undefined && detailsPath[1].length > 0) {
+ this.props.history.replace(`/${URL_BASEPATH}/${map.getCenter().lat.toFixed(4)},${map.getCenter().lng.toFixed(4)},${mapZoom.toFixed(2)}/details/${detailsPath[1]}`)
+ }
+ else {
+ this.props.history.replace(`/${URL_BASEPATH}/${map.getCenter().lat.toFixed(4)},${map.getCenter().lng.toFixed(4)},${mapZoom.toFixed(2)}`)
+ }
+ }
- this.loadNetworkData(boundingBox);
- if (mapZoom > 9) {
- if (map.getLayer('points')) {
- map.setLayoutProperty('selectedPoints', 'visibility', 'visible');
- map.setPaintProperty('points', 'circle-radius', 7);
- }
- } else {
+ //switch icon layers if applicable
- // reduce size of points / lines if zoomed out
- map.setPaintProperty('points', 'circle-radius', 2);
- map.setLayoutProperty('selectedPoints', 'visibility', 'none');
+ mapLayerService.showIconLayers(map, this.props.showIcons, this.props.selectedSite?.properties.id);
- if (mapZoom <= 4) {
- map.setPaintProperty('fibre-lines', 'line-width', 1);
- map.setPaintProperty('microwave-lines', 'line-width', 1);
+ //update statistics
+ const boundingBox = map.getBounds();
- } else {
- map.setPaintProperty('fibre-lines', 'line-width', 2);
- map.setPaintProperty('microwave-lines', 'line-width', 2);
+ fetch(`${URL_API}/info/count/${boundingBox.getWest()},${boundingBox.getSouth()},${boundingBox.getEast()},${boundingBox.getNorth()}`)
+ .then(result => verifyResponse(result))
+ .then(res => res.json())
+ .then(result => {
+ if (result.links !== this.props.linkCount || result.sites !== this.props.siteCount) {
+ this.props.setStatistics(result.links, result.sites);
}
- }
- });
+ })
+ .catch(error => this.props.handleConnectionError(error));;
}
componentDidUpdate(prevProps: mapProps, prevState: {}) {
+ if(prevProps !== this.props){
//(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){
@@ -329,6 +338,7 @@ class Map extends React.Component<mapProps, { isPopupOpen: boolean }> {
//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();
}
@@ -443,12 +453,22 @@ class Map extends React.Component<mapProps, { isPopupOpen: boolean }> {
}
}
}
+ }
}
componentWillUnmount(){
+
+ //unregister events
window.removeEventListener("menu-resized", this.handleResize);
- lastBoundingBox=null;
+
+ if(map){
+ map.off('click', this.mapClick);
+ map.off('moveend', this.mapMoveEnd);
+ map.off('move', this.mapMove);
+ }
+ lastBoundingBox=null;
+
// will be checked again on next load
this.props.setConnectivityCheck(true);
}
@@ -624,7 +644,7 @@ class Map extends React.Component<mapProps, { isPopupOpen: boolean }> {
<ConnectionInfo />
<Button
disabled={!this.props.isTopoServerReachable}
- style={{'position': 'absolute', 'right':5, top:5, backgroundColor:'white'}}
+ style={{'position': 'absolute', 'right':5, top:5, backgroundColor:'white', zIndex:1}}
onClick={e => this.props.navigateToApplication("network", "customize")} >
<img src={customize} />
</Button>
diff --git a/sdnr/wt/odlux/apps/networkMapApp/src/components/map/searchBar.tsx b/sdnr/wt/odlux/apps/networkMapApp/src/components/map/searchBar.tsx
index 45bc6092d..307c5d203 100644
--- a/sdnr/wt/odlux/apps/networkMapApp/src/components/map/searchBar.tsx
+++ b/sdnr/wt/odlux/apps/networkMapApp/src/components/map/searchBar.tsx
@@ -46,6 +46,7 @@ const styles = makeStyles({
top: 15,
marginLeft: 5,
width: 400,
+ zIndex:1
},
input: {
flex: 1,
diff --git a/sdnr/wt/odlux/apps/networkMapApp/src/components/map/statistics.tsx b/sdnr/wt/odlux/apps/networkMapApp/src/components/map/statistics.tsx
index 116b789d7..562689198 100644
--- a/sdnr/wt/odlux/apps/networkMapApp/src/components/map/statistics.tsx
+++ b/sdnr/wt/odlux/apps/networkMapApp/src/components/map/statistics.tsx
@@ -41,7 +41,7 @@ const Statistics: React.FunctionComponent<props> = (props: props) =>{
const reachabe = props.isTopoServerReachable && props.isTileServerReachable;
- return (<Paper style={{ padding: 5, position: 'absolute', display: 'flex', flexDirection: "column", top: 70, width: 200, marginLeft: 5 }}>
+ return (<Paper style={{ padding: 5, position: 'absolute', display: 'flex', flexDirection: "column", top: 70, width: 200, marginLeft: 5, zIndex:1 }}>
<div style={{ display: 'flex', flexDirection: "row" }}>
<Typography style={{ fontWeight: "bold", flex: "1", color: reachabe ? "black" : "lightgrey" }} >Statistics</Typography>
<Tooltip style={{ alignSelf: "flex-end" }} title="Gets updated when the map stops moving.">
diff --git a/sdnr/wt/odlux/apps/networkMapApp/src/config.ts b/sdnr/wt/odlux/apps/networkMapApp/src/config.ts
index 633bd3732..bdb7d15e6 100644
--- a/sdnr/wt/odlux/apps/networkMapApp/src/config.ts
+++ b/sdnr/wt/odlux/apps/networkMapApp/src/config.ts
@@ -17,6 +17,7 @@
*/
export const URL_API="/topology/network"
+export const SITEDOC_URL="/sitedoc";
export const URL_TILE_API = '/tiles'; // http://tile.openstreetmap.org can be used for local testing, never commit with tile url changed! /tiles
diff --git a/sdnr/wt/odlux/apps/networkMapApp/src/handlers/detailsReducer.ts b/sdnr/wt/odlux/apps/networkMapApp/src/handlers/detailsReducer.ts
index 67e10e629..8a7fc6ada 100644
--- a/sdnr/wt/odlux/apps/networkMapApp/src/handlers/detailsReducer.ts
+++ b/sdnr/wt/odlux/apps/networkMapApp/src/handlers/detailsReducer.ts
@@ -20,13 +20,14 @@ import { IActionHandler } from '../../../../framework/src/flux/action';
import { link } from "../model/link";
import { Site, Device } from "../model/site";
import { HistoryEntry } from "../model/historyEntry";
-import { SelectSiteAction, SelectLinkAction, AddToHistoryAction, ClearHistoryAction, IsBusyCheckingDeviceListAction, FinishedLoadingDeviceListAction, ClearLoadedDevicesAction, ClearDetailsAction, InitializeLoadedDevicesAction } from '../actions/detailsAction';
+import { SelectSiteAction, SelectLinkAction, AddToHistoryAction, ClearHistoryAction, IsBusyCheckingDeviceListAction, FinishedLoadingDeviceListAction, ClearLoadedDevicesAction, ClearDetailsAction, InitializeLoadedDevicesAction, IsSitedocReachableAction } from '../actions/detailsAction';
export type DetailsStoreState={
data: Site | link | null,
history: HistoryEntry[],
isBusyCheckingDeviceList: boolean,
- checkedDevices: Device[]
+ checkedDevices: Device[],
+ isSitedocReachable: boolean
}
@@ -34,7 +35,8 @@ const initialState: DetailsStoreState = {
data: null,
history:[],
isBusyCheckingDeviceList: false,
- checkedDevices: []
+ checkedDevices: [],
+ isSitedocReachable: false
}
export const DetailsReducer:IActionHandler<DetailsStoreState>=(state = initialState, action)=>{
@@ -63,6 +65,8 @@ export const DetailsReducer:IActionHandler<DetailsStoreState>=(state = initialSt
}else if(action instanceof InitializeLoadedDevicesAction){
state = Object.assign({}, state, {checkedDevices: action.devices});
+ }else if(action instanceof IsSitedocReachableAction){
+ state = Object.assign({}, state, {isSitedocReachable: action.isReachable});
}
diff --git a/sdnr/wt/odlux/apps/networkMapApp/src/index.html b/sdnr/wt/odlux/apps/networkMapApp/src/index.html
index e64c08c1e..f70571152 100644
--- a/sdnr/wt/odlux/apps/networkMapApp/src/index.html
+++ b/sdnr/wt/odlux/apps/networkMapApp/src/index.html
@@ -13,15 +13,14 @@
<div id="app"></div>
<script type="text/javascript" src="./require.js"></script>
<script type="text/javascript" src="./config.js"></script>
- <link href='https://api.tiles.mapbox.com/mapbox-gl-js/v1.8.1/mapbox-gl.css' rel='stylesheet' />
<script>
// run the application
require(["app","connectApp","faultApp", "networkMapApp", "configurationApp", "linkCalculationApp"], function (app, connectApp, faultApp, networkMapApp, configurationApp, linkCalculationApp) {
connectApp.register();
- //faultApp.register();
+ faultApp.register();
//configurationApp.register();
- //linkCalculationApp.register();
+ linkCalculationApp.register();
networkMapApp.register();
app("./app.tsx").runApplication();
});
diff --git a/sdnr/wt/odlux/apps/networkMapApp/src/model/link.ts b/sdnr/wt/odlux/apps/networkMapApp/src/model/link.ts
index d992c66db..c1612098d 100644
--- a/sdnr/wt/odlux/apps/networkMapApp/src/model/link.ts
+++ b/sdnr/wt/odlux/apps/networkMapApp/src/model/link.ts
@@ -16,6 +16,12 @@
* ============LICENSE_END==========================================================================
*/
+type Antenna = {
+ name:string,
+ waveguideLossIndB: number,
+ gain: number
+}
+
export type link = {id: string,
name: string,
length: number,
@@ -25,6 +31,6 @@ export type link = {id: string,
siteB: string,
azimuthA: number | null,
azimuthB: number | null,
- locationA: { lon: number, lat: number, amsl:number | null, antennaHeight: number | null },
- locationB: { lon: number, lat: number, amsl:number | null, antennaHeight: number | null },
+ locationA: { lon: number, lat: number, amsl:number | null, antennaHeight: number | null, antenna: Antenna |null },
+ locationB: { lon: number, lat: number, amsl:number | null, antennaHeight: number | null, antenna: Antenna |null },
}; \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/networkMapApp/src/model/site.ts b/sdnr/wt/odlux/apps/networkMapApp/src/model/site.ts
index b9102e871..13a7361f6 100644
--- a/sdnr/wt/odlux/apps/networkMapApp/src/model/site.ts
+++ b/sdnr/wt/odlux/apps/networkMapApp/src/model/site.ts
@@ -28,7 +28,8 @@ export type Site = {
operator: string,
location:{lon: number, lat: number},
devices: Device[],
- links: link[]
+ links: link[],
+ furtherInformation:string
}
export type Address={
diff --git a/sdnr/wt/odlux/apps/networkMapApp/src/model/stadokOrder.ts b/sdnr/wt/odlux/apps/networkMapApp/src/model/stadokOrder.ts
new file mode 100644
index 000000000..1aad3aa97
--- /dev/null
+++ b/sdnr/wt/odlux/apps/networkMapApp/src/model/stadokOrder.ts
@@ -0,0 +1,56 @@
+/**
+ * ============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==========================================================================
+ */
+
+export type StadokOrder = {
+ date: Date,
+ assignedUser: string,
+ state: string, //todo: type restrict
+ tasks: Task[],
+
+
+};
+
+export class OrderToDisplay {
+
+ static parse = (stadokOrder: StadokOrder) =>{
+ let order = new OrderToDisplay();
+ order.assignedUser=stadokOrder.assignedUser;
+ order.state=stadokOrder.state;
+
+ const firstOpenTask = stadokOrder.tasks.find(task => !task.status);
+
+ if(firstOpenTask){
+ order.currentTask=firstOpenTask.description;
+ }else{
+ order.currentTask="No task description available";
+ }
+
+ return order;
+ }
+
+ state: string;
+ assignedUser: string;
+ currentTask: string;
+
+};
+
+type Task = {
+ type: string,
+ description: string,
+ status: boolean
+} \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/networkMapApp/src/model/stadokSite.ts b/sdnr/wt/odlux/apps/networkMapApp/src/model/stadokSite.ts
new file mode 100644
index 000000000..ed0ca397f
--- /dev/null
+++ b/sdnr/wt/odlux/apps/networkMapApp/src/model/stadokSite.ts
@@ -0,0 +1,54 @@
+/**
+ * ============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 { Address } from "./site";
+
+type StadokSite = {
+
+ siteId: string;
+ createdBy: Contact;
+ updatedOn: Date;
+ location: { lat: number, lon: number },
+ address: Address;
+ contacts: { manager: Contact, owner: Contact };
+ safteyNotices: string[];
+ images: string[];
+ type: string;
+ devices: Device[];
+ logs: Log[];
+
+};
+
+type Contact = {
+ firstName: string;
+ lastName: string;
+ email: string;
+ telephoneNumber: string;
+};
+type Log = {
+ date: Date, //string?
+ person: string;
+ entry: string;
+};
+
+type Device = {
+ "device": string,
+ "antenna": string
+};
+
+export default StadokSite; \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/networkMapApp/src/pluginTransport.tsx b/sdnr/wt/odlux/apps/networkMapApp/src/pluginTransport.tsx
index e93368524..24a46994a 100644
--- a/sdnr/wt/odlux/apps/networkMapApp/src/pluginTransport.tsx
+++ b/sdnr/wt/odlux/apps/networkMapApp/src/pluginTransport.tsx
@@ -27,7 +27,7 @@ import { networkmapRootHandler } from './handlers/rootReducer';
import MainView from "./App";
import { subscribe, IFormatedMessage } from "../../../framework/src/services/notificationService";
import applicationApi from "../../../framework/src/services/applicationApi";
-import { UpdateDetailsView } from "./actions/detailsAction";
+import { checkSitedockReachablity, IsSitedocReachableAction, UpdateDetailsView } from "./actions/detailsAction";
import { findSiteToAlarm } from "./actions/mapActions";
import { URL_BASEPATH } from "./config";
import { Redirect, Route, RouteComponentProps, Switch, withRouter } from "react-router-dom";
@@ -40,7 +40,8 @@ const mapProps = (state: IApplicationStoreState) => ({
});
const mapDisp = (dispatcher: IDispatcher) => ({
- getSettings: () => dispatcher.dispatch(getSettings())
+ getSettings: () => dispatcher.dispatch(getSettings()),
+ tryReachSitedoc: () => dispatcher.dispatch(checkSitedockReachablity())
});
@@ -51,6 +52,8 @@ const NetworkRouterApp = withRouter(connect(mapProps, mapDisp)((props: RouteComp
(async function waitFor() {
await props.getSettings();
})();
+
+ props.tryReachSitedoc();
}, []);
diff --git a/sdnr/wt/odlux/apps/networkMapApp/src/utils/mapLayers.ts b/sdnr/wt/odlux/apps/networkMapApp/src/utils/mapLayers.ts
index 6dfd7983a..7ce4bfa92 100644
--- a/sdnr/wt/odlux/apps/networkMapApp/src/utils/mapLayers.ts
+++ b/sdnr/wt/odlux/apps/networkMapApp/src/utils/mapLayers.ts
@@ -141,6 +141,8 @@ class MapLayerService {
public addBaseLayers = (map: mapboxgl.Map, themesettings?: ThemeElement) => {
const theme = !themesettings ? this.pickTheme() : themesettings;
+ console.log("user selected theme: " + this.selectedTheme)
+ console.log("found theme:" + theme);
this.addCommonLayers(map);
diff --git a/sdnr/wt/odlux/apps/networkMapApp/webpack.config.js b/sdnr/wt/odlux/apps/networkMapApp/webpack.config.js
index 3e80514f5..5684040b7 100644
--- a/sdnr/wt/odlux/apps/networkMapApp/webpack.config.js
+++ b/sdnr/wt/odlux/apps/networkMapApp/webpack.config.js
@@ -67,6 +67,10 @@ module.exports = (env) => {
name: './icons/[hash].[ext]'
}
}]
+ },
+ {
+ test: /\.css$/i,
+ use: ["style-loader", "css-loader"],
}]
},
@@ -168,8 +172,15 @@ module.exports = (env) => {
target: "http://localhost:3002",
secure: false
},
+ "/sitedoc/": {
+ target: "http://localhost:3002",
+ secure: false,
+ pathRewrite(pathname) {
+ return pathname.replace(/^\/sitedoc/, '/topology/stadok')
+ }
+ },
"/tiles/": {
- target: "http://www.openstreetmap.org",
+ target: "http://tile.openstreetmap.org",
secure: false
},
"/help/": {