From 4bd84bebdaa0c2d82050fbedd1fa8260eb62146d Mon Sep 17 00:00:00 2001 From: Aijana Schumann Date: Thu, 27 Aug 2020 09:01:53 +0200 Subject: Add link calculation app Add link calculation app to odlux Issue-ID: CCSDK-2562 Signed-off-by: Aijana Schumann Change-Id: Ifc0a5b2a8bb974dfd85d70a9f05990b1f11925a3 Signed-off-by: Aijana Schumann --- sdnr/wt/odlux/apps/linkCalculationApp/.babelrc | 17 ++ sdnr/wt/odlux/apps/linkCalculationApp/package.json | 40 ++++ sdnr/wt/odlux/apps/linkCalculationApp/pom.xml | 176 +++++++++++++++ .../src/actions/commonLinkCalculationActions.ts | 104 +++++++++ .../src/components/connectionInfo.tsx | 55 +++++ .../src/components/denseTable.tsx | 121 ++++++++++ .../src/handlers/linkCalculationAppRootHandler.ts | 115 ++++++++++ .../odlux/apps/linkCalculationApp/src/index.html | 27 +++ .../src/pluginLinkCalculation.tsx | 148 +++++++++++++ .../src/views/linkCalculationComponent.tsx | 246 +++++++++++++++++++++ .../sdnr/wt/odlux/bundles/MyOdluxBundle.java | 68 ++++++ .../resources/OSGI-INF/blueprint/blueprint.xml | 9 + .../sdnr/wt/odlux/bundles/test/TestBundleRes.java | 46 ++++ .../linkCalculationApp/src2/test/resources/test.js | 5 + .../wt/odlux/apps/linkCalculationApp/tsconfig.json | 37 ++++ .../apps/linkCalculationApp/webpack.config.js | 159 +++++++++++++ 16 files changed, 1373 insertions(+) create mode 100644 sdnr/wt/odlux/apps/linkCalculationApp/.babelrc create mode 100644 sdnr/wt/odlux/apps/linkCalculationApp/package.json create mode 100644 sdnr/wt/odlux/apps/linkCalculationApp/pom.xml create mode 100644 sdnr/wt/odlux/apps/linkCalculationApp/src/actions/commonLinkCalculationActions.ts create mode 100644 sdnr/wt/odlux/apps/linkCalculationApp/src/components/connectionInfo.tsx create mode 100644 sdnr/wt/odlux/apps/linkCalculationApp/src/components/denseTable.tsx create mode 100644 sdnr/wt/odlux/apps/linkCalculationApp/src/handlers/linkCalculationAppRootHandler.ts create mode 100644 sdnr/wt/odlux/apps/linkCalculationApp/src/index.html create mode 100644 sdnr/wt/odlux/apps/linkCalculationApp/src/pluginLinkCalculation.tsx create mode 100644 sdnr/wt/odlux/apps/linkCalculationApp/src/views/linkCalculationComponent.tsx create mode 100644 sdnr/wt/odlux/apps/linkCalculationApp/src2/main/java/org/onap/ccsdk/features/sdnr/wt/odlux/bundles/MyOdluxBundle.java create mode 100644 sdnr/wt/odlux/apps/linkCalculationApp/src2/main/resources/OSGI-INF/blueprint/blueprint.xml create mode 100644 sdnr/wt/odlux/apps/linkCalculationApp/src2/test/java/org/onap/ccsdk/features/sdnr/wt/odlux/bundles/test/TestBundleRes.java create mode 100644 sdnr/wt/odlux/apps/linkCalculationApp/src2/test/resources/test.js create mode 100644 sdnr/wt/odlux/apps/linkCalculationApp/tsconfig.json create mode 100644 sdnr/wt/odlux/apps/linkCalculationApp/webpack.config.js (limited to 'sdnr/wt/odlux/apps/linkCalculationApp') diff --git a/sdnr/wt/odlux/apps/linkCalculationApp/.babelrc b/sdnr/wt/odlux/apps/linkCalculationApp/.babelrc new file mode 100644 index 000000000..3d8cd1260 --- /dev/null +++ b/sdnr/wt/odlux/apps/linkCalculationApp/.babelrc @@ -0,0 +1,17 @@ +{ + "presets": [ + ["@babel/preset-react"], + ["@babel/preset-env", { + "targets": { + "chrome": "66" + }, + "spec": true, + "loose": false, + "modules": false, + "debug": false, + "useBuiltIns": "usage", + "forceAllTransforms": true + }] + ], + "plugins": [] +} diff --git a/sdnr/wt/odlux/apps/linkCalculationApp/package.json b/sdnr/wt/odlux/apps/linkCalculationApp/package.json new file mode 100644 index 000000000..40e1be913 --- /dev/null +++ b/sdnr/wt/odlux/apps/linkCalculationApp/package.json @@ -0,0 +1,40 @@ +{ + "name": "@odlux/linkcalculation-app", + "version": "0.1.0", + "description": "A react based modular UI to do link analysis.", + "main": "index.js", + "scripts": { + "start": "webpack-dev-server --env debug", + "build": "webpack --env release --config webpack.config.js", + "build:dev": "webpack --env debug --config webpack.config.js" + }, + "repository": { + "type": "git", + "url": "https://git.mfico.de/highstreet-technologies/odlux.git" + }, + "keywords": [ + "reactjs", + "redux", + "ui", + "framework" + ], + "author": "Mohammad Boroon", + "license": "Apache-2.0", + "dependencies": { + "@odlux/framework": "*" + }, + "peerDependencies": { + "@types/react": "16.9.19", + "@types/react-dom": "16.9.5", + "@types/react-router-dom": "4.3.1", + "@material-ui/core": "4.9.0", + "@material-ui/icons": "4.5.1", + "@types/classnames": "2.2.6", + "@types/flux": "3.1.8", + "@types/jquery": "3.3.10", + "jquery": "3.3.1", + "react": "16.12.0", + "react-dom": "16.12.0", + "react-router-dom": "4.3.1" + } +} \ No newline at end of file diff --git a/sdnr/wt/odlux/apps/linkCalculationApp/pom.xml b/sdnr/wt/odlux/apps/linkCalculationApp/pom.xml new file mode 100644 index 000000000..8f057bd56 --- /dev/null +++ b/sdnr/wt/odlux/apps/linkCalculationApp/pom.xml @@ -0,0 +1,176 @@ + + + + + 4.0.0 + + + org.onap.ccsdk.parent + odlparent + 2.0.1-SNAPSHOT + + + + org.onap.ccsdk.features.sdnr.wt + sdnr-wt-odlux-app-linkCalculationApp + 1.0.1-SNAPSHOT + bundle + + ccsdk-features :: ${project.artifactId} + + + Apache License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0 + + + + + true + true + + + + + ${project.groupId} + sdnr-wt-odlux-core-model + ${project.version} + + + ${project.groupId} + sdnr-wt-odlux-core-provider + ${project.version} + test + + + junit + junit + test + + + + + src2/main/java + + + dist + odlux + + + src2/main/resources + + + src2/test/resources + + + + + maven-clean-plugin + + + + dist + false + + + node + false + + + node_modules + false + + + ../node_modules + false + + + + bin + false + + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + add-test-source + generate-test-sources + + add-test-source + + + + src2/test/java + + + + + + + de.jacks-it-lab + frontend-maven-plugin + 1.7.2 + + + install node and yarn + + install-node-and-yarn + + + initialize + + v10.16.3 + v1.19.0 + + + + yarn build + + yarn + + + run build + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + org.apache.felix + maven-bundle-plugin + true + + + org.onap.ccsdk.features.sdnr.wt.odlux.model.*,com.opensymphony.* + + + + + + + diff --git a/sdnr/wt/odlux/apps/linkCalculationApp/src/actions/commonLinkCalculationActions.ts b/sdnr/wt/odlux/apps/linkCalculationApp/src/actions/commonLinkCalculationActions.ts new file mode 100644 index 000000000..555954d15 --- /dev/null +++ b/sdnr/wt/odlux/apps/linkCalculationApp/src/actions/commonLinkCalculationActions.ts @@ -0,0 +1,104 @@ +/** + * ============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========================================================================== + */ + +import { Action } from "../../../../framework/src/flux/action"; +import { Dispatch } from "../../../../framework/src/flux/store"; +import { IApplicationStoreState } from "../../../../framework/src/store/applicationStore"; + + +export class UpdateLinkIdAction extends Action{ + constructor(public linkId: string){ + super(); + } +} + +export class UpdateFrequencyAction extends Action{ + constructor(public frequency: number){ + super(); + } +} +export class UpdateSiteAction extends Action{ + constructor( + public siteA?: any, + public siteB?: any + ){ + super(); + } +} +export class UpdateRainAttAction extends Action{ + + constructor(public rainAtt: number){ + super(); + } +} +export class UpdateRainValAction extends Action{ + constructor(public rainVal: number){ + super(); + } +} + +export class updateHideForm extends Action{ + constructor(public formView: boolean){ + super(); + } +} +export class UpdateDistanceAction extends Action{ + constructor(public distance: number){ + super(); + } +} + +export class UpdateFslCalculation extends Action{ + constructor(public fsl: number){ + super(); + } +} + + +export class UpdateLatLonAction extends Action{ + constructor( + public Lat1: number, + public Lon1:number, + public Lat2: number, + public Lon2: number + ){ + super(); + + } +} +export class isCalculationServerReachableAction extends Action{ + constructor(public reachable: boolean){ + super(); + } +} + +// export const checkCalculationsServerConnectivityAction = (callback: Promise) => (dispatcher: Dispatch, getState: () => IApplicationStoreState)=>{ +// callback +// .then(res =>{ +// const {linkCalculation:{calculations: {isCalculationServerAvailable}}} = getState(); +// if(!isToplogyServerAvailable){ +// dispatcher(new IsTopologyServerReachableAction(true)) +// } +// }) +// .catch(error=>{ +// const {network:{connectivity: {isToplogyServerAvailable}}} = getState(); +// if(isToplogyServerAvailable){ +// dispatcher(new IsTopologyServerReachableAction(false)) +// } +// }) +// } diff --git a/sdnr/wt/odlux/apps/linkCalculationApp/src/components/connectionInfo.tsx b/sdnr/wt/odlux/apps/linkCalculationApp/src/components/connectionInfo.tsx new file mode 100644 index 000000000..c798e481f --- /dev/null +++ b/sdnr/wt/odlux/apps/linkCalculationApp/src/components/connectionInfo.tsx @@ -0,0 +1,55 @@ +/** + * ============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========================================================================== + */ + +import * as React from 'react' + +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'; + + +type props = Connect; + +const ConnectionInfo: React.FunctionComponent = (props) => { + + return ( + (props.isCalculationServerReachable === false)? +
+
Connection Error
+ {props.isCalculationServerReachable === false && Calculation data can't be loaded.} +
+
: null +)} + +const mapStateToProps = (state: IApplicationStoreState) => ({ + isCalculationServerReachable: state.linkCalculation.calculations.reachable +}); + + + +const mapDispatchToProps = (dispatcher: IDispatcher) => ({ + + //zoomToSearchResult: (lat: number, lon: number) => dispatcher.dispatch(new ZoomToSearchResultAction(lat, lon)) + +});; + + +export default connect(mapStateToProps,mapDispatchToProps)(ConnectionInfo) + diff --git a/sdnr/wt/odlux/apps/linkCalculationApp/src/components/denseTable.tsx b/sdnr/wt/odlux/apps/linkCalculationApp/src/components/denseTable.tsx new file mode 100644 index 000000000..96d6f4ed1 --- /dev/null +++ b/sdnr/wt/odlux/apps/linkCalculationApp/src/components/denseTable.tsx @@ -0,0 +1,121 @@ +/** + * ============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========================================================================== + */ + +import * as React from 'react'; +import Table from '@material-ui/core/Table'; +import TableBody from '@material-ui/core/TableBody'; +import TableCell from '@material-ui/core/TableCell'; +import TableContainer from '@material-ui/core/TableContainer'; +import TableHead from '@material-ui/core/TableHead'; +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[], width: number, height:number, navigate?(applicationName: string, path?: string):void, onLinkClick?(id: string): void, data: any[], hover: boolean, onClick?(id: string): void, actions?:boolean }; + + +const styles = makeStyles({ + container: { + overflow:"auto" + }, + button: { + margin: 0, + padding: "6px 6px", + minWidth: 'unset' + } + + }); + + +const DenseTable: React.FunctionComponent = (props) => { + + const classes = styles(); + + const handleClick = (event: any, id: string) =>{ + event.preventDefault(); + props.onClick !== undefined && props.onClick(id); + + } + + const handleHover = (event: any, id: string) =>{ + event.preventDefault(); + + } + + return ( + + + + + + { + props.headers.map((data) => { + return {data} + }) + } + + + + {props.data.map((row, index) => { + + + var filteredRows = Object.keys(row).filter(function(e) { if(e!=="simulatorId") return row }); + + //var filteredRows = Object.keys(row).filter(function(e) { if(e!=="simulatorId") return row[e] }); + var values = Object.keys(row).map(function(e) { if(e!=="simulatorId"){ return row[e];} else return undefined }); + + + return ( + handleHover(e,row.name)} onClick={ e => handleClick(e, row.name)}> + + { + values.map((data:any) => { + + if(data!== undefined) + return {data} + else + return null; + }) + } + { + + props.actions && +
+ + + + + + +
+
+ + } +
) + }) + } + +
+
+ +
+ ); + +} + +export default DenseTable; \ No newline at end of file diff --git a/sdnr/wt/odlux/apps/linkCalculationApp/src/handlers/linkCalculationAppRootHandler.ts b/sdnr/wt/odlux/apps/linkCalculationApp/src/handlers/linkCalculationAppRootHandler.ts new file mode 100644 index 000000000..00dd48d45 --- /dev/null +++ b/sdnr/wt/odlux/apps/linkCalculationApp/src/handlers/linkCalculationAppRootHandler.ts @@ -0,0 +1,115 @@ +/** +* ============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========================================================================== +*/ +// main state handler + +import { combineActionHandler } from '../../../../framework/src/flux/middleware'; + +// ** do not remove ** +import { IApplicationStoreState } from '../../../../framework/src/store/applicationStore'; +import { IActionHandler } from '../../../../framework/src/flux/action';; +import { UpdateLinkIdAction, UpdateFrequencyAction , UpdateLatLonAction, UpdateRainAttAction, UpdateRainValAction, updateHideForm, UpdateFslCalculation, UpdateSiteAction, UpdateDistanceAction, isCalculationServerReachableAction} from '../actions/commonLinkCalculationActions'; + +declare module '../../../../framework/src/store/applicationStore' { + interface IApplicationStoreState { + linkCalculation: ICalculationsState; + } +} + +type ICalculationsState = { + calculations:ILinkCalculationAppStateState +} + +export type ILinkCalculationAppStateState= { + linkId: string | null, + frequency: number, + formView:boolean, + fsl:number, + distance:number, + Lat1: number, + Lon1: number, + Lat2: number, + Lon2: number, + rainVal : number, + rainAtt : number, + siteA: any, + siteB: any, + reachable: boolean +} + +const initialState: ILinkCalculationAppStateState ={ + linkId: null, + frequency: 0, + Lat1: 0, + Lon1: 0, + Lat2: 0, + Lon2: 0, + formView : false, + fsl:0, + distance:0, + siteA : '', + siteB: '', + rainVal : 0, + rainAtt: 0, + reachable : true +} + + + +export const LinkCalculationHandler: IActionHandler = (state=initialState, action) => { + + if(action instanceof UpdateLinkIdAction){ + state = Object.assign({}, state, {linkId:action.linkId}) + } + else if(action instanceof updateHideForm){ + + state = Object.assign({}, state, {formView:action.formView}) + } + else if (action instanceof UpdateDistanceAction){ + state = Object.assign({}, state, {distance:action.distance}) + } + else if (action instanceof UpdateFrequencyAction){ + state = Object.assign({}, state, {frequency:action.frequency}) +} + else if (action instanceof UpdateFslCalculation){ + state = Object.assign({}, state, {fsl:action.fsl}) + } + else if (action instanceof UpdateLatLonAction){ + state = Object.assign({}, state, {Lat1:action.Lat1, Lon1:action.Lon1, Lat2:action.Lat2, Lon2:action.Lon2}) + } + else if (action instanceof UpdateRainAttAction){ + state = Object.assign({}, state, {rainAtt:action.rainAtt}) + } + else if (action instanceof UpdateRainValAction){ + state = Object.assign({}, state, {rainVal:action.rainVal}) + } + else if (action instanceof UpdateSiteAction){ + state = Object.assign({}, state, {siteA:action.siteA, siteB:action.siteB}) + } + else if(action instanceof isCalculationServerReachableAction){ + state = Object.assign({}, state, { reachable: action.reachable }); +} + return state +} + +const actionHandlers = { + calculations: LinkCalculationHandler +} + +export const LinkCalculationAppRootHandler = combineActionHandler(actionHandlers); +export default LinkCalculationAppRootHandler; + diff --git a/sdnr/wt/odlux/apps/linkCalculationApp/src/index.html b/sdnr/wt/odlux/apps/linkCalculationApp/src/index.html new file mode 100644 index 000000000..c1cb3f9f3 --- /dev/null +++ b/sdnr/wt/odlux/apps/linkCalculationApp/src/index.html @@ -0,0 +1,27 @@ + + + + + + + + + Link Calculation App + + + +
+ + + + + + \ No newline at end of file diff --git a/sdnr/wt/odlux/apps/linkCalculationApp/src/pluginLinkCalculation.tsx b/sdnr/wt/odlux/apps/linkCalculationApp/src/pluginLinkCalculation.tsx new file mode 100644 index 000000000..fc72f5ab3 --- /dev/null +++ b/sdnr/wt/odlux/apps/linkCalculationApp/src/pluginLinkCalculation.tsx @@ -0,0 +1,148 @@ +/** +* ============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========================================================================== +*/ +// app configuration and main entry point for the app + +import * as React from "react"; +import { withRouter, RouteComponentProps, Route, Switch, Redirect } from 'react-router-dom'; + +import { faBookOpen } from '@fortawesome/free-solid-svg-icons'; // select app icon +import applicationManager from '../../../framework/src/services/applicationManager'; + +import LinkCalculation from './views/linkCalculationComponent'; +import LinkCalculationAppRootHandler from './handlers/linkCalculationAppRootHandler'; +import connect, { Connect, IDispatcher } from '../../../framework/src/flux/connect'; +import { IApplicationStoreState } from "../../../framework/src/store/applicationStore"; +import { UpdateLinkIdAction, UpdateLatLonAction, updateHideForm, UpdateSiteAction, UpdateDistanceAction } from "./actions/commonLinkCalculationActions"; + + +let currentLinkId: string | null = null; +let lastUrl: string = "/linkCalculation"; + +const mapProps = (state: IApplicationStoreState) => ({ +}); + +const mapDisp = (dispatcher: IDispatcher) => ({ + updateLinkId: (mountId: string) => dispatcher.dispatch(new UpdateLinkIdAction(mountId)), + + updateSiteName: (siteNameA?:any, siteNameB?:any)=>{ + dispatcher.dispatch(new UpdateSiteAction(siteNameA, siteNameB)) + }, + updateDistance :(distance:number) =>{ + dispatcher.dispatch(new UpdateDistanceAction(distance)) + }, + updateLatLon : (Lat1:number, Lon1:number, Lat2:number, Lon2:number)=> { + + dispatcher.dispatch(new UpdateLatLonAction(Lat1, Lon1, Lat2, Lon2)) + dispatcher.dispatch(new updateHideForm (true)) + }, +}); + + +const LinkCalculationRouteAdapter = connect(mapProps, mapDisp)((props: RouteComponentProps<{ mountId?: string }> & Connect) => { + let linkId: string = ""; + + // called when component finshed mounting + React.useEffect(() => { + + lastUrl = props.location.pathname; + linkId = getLinkId(lastUrl); + + const data= props.location.search + + + + if (data !== undefined && data.length>0){ + + + + const lat1 = data.split('&')[0].split('=')[1] + const lon1 = data.split('&')[1].split('=')[1] + const lat2 = data.split('&')[2].split('=')[1] + const lon2 = data.split('&')[3].split('=')[1] + + const siteNameA = data.split('&')[4].split('=')[1] + const siteNameB = data.split('&')[5].split('=')[1] + + const distance = data.split('&')[8].split('=')[1] + + + props.updateSiteName(String(siteNameA), String(siteNameB)) + props.updateDistance(Number(distance)) + + + props.updateLatLon(Number(lat1),Number(lon1),Number(lat2),Number(lon2)) + + } + + + if (currentLinkId !== linkId) { // new element is loaded + currentLinkId = linkId; + props.updateLinkId(currentLinkId); + } + }, []); + + // called when component gets updated + React.useEffect(() => { + + lastUrl = props.location.pathname; + linkId = getLinkId(lastUrl); + + if (currentLinkId !== linkId) { + currentLinkId = linkId; + props.updateLinkId(currentLinkId); + } + }); + + const getLinkId = (lastUrl: string) => { + let index = lastUrl.lastIndexOf("linkCalculation/"); + if (index >= 0) { + linkId = lastUrl.substr(index+16); + } else { + linkId = ""; + } + + return linkId; + } + + + return ( + + ); +}); + +const App = withRouter((props: RouteComponentProps) => { + props.history.action = "POP"; + return ( + + + + + + ) +}); + +export function register() { + applicationManager.registerApplication({ + name: "linkCalculation", + icon: faBookOpen, + rootActionHandler: LinkCalculationAppRootHandler, + rootComponent: App, + menuEntry: "Link Calculation" + }); +} + diff --git a/sdnr/wt/odlux/apps/linkCalculationApp/src/views/linkCalculationComponent.tsx b/sdnr/wt/odlux/apps/linkCalculationApp/src/views/linkCalculationComponent.tsx new file mode 100644 index 000000000..97219b6d8 --- /dev/null +++ b/sdnr/wt/odlux/apps/linkCalculationApp/src/views/linkCalculationComponent.tsx @@ -0,0 +1,246 @@ +/** + * ============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========================================================================== + */ +import * as React from "react"; + +import { Connect, connect, IDispatcher } from '../../../../framework/src/flux/connect'; +import { MaterialTable, MaterialTableCtorType } from '../../../../framework/src/components/material-table'; +import { TextField, Tabs, Tab, Typography, AppBar, Button, Tooltip } from '@material-ui/core'; +import DenseTable from '../components/denseTable' + +import { IApplicationStoreState } from "../../../../framework/src/store/applicationStore"; +import { UpdateFrequencyAction, UpdateLatLonAction, UpdateRainAttAction, UpdateRainValAction, UpdateFslCalculation, isCalculationServerReachableAction } from "../actions/commonLinkCalculationActions"; +import { faPlaneArrival } from "@fortawesome/free-solid-svg-icons"; + +const mapProps = (state: IApplicationStoreState) => ({ + linkId: state.linkCalculation.calculations.linkId, + frequency: state.linkCalculation.calculations.frequency, + lat1: state.linkCalculation.calculations.Lat1, + lon1: state.linkCalculation.calculations.Lon1, + lat2: state.linkCalculation.calculations.Lat2, + lon2: state.linkCalculation.calculations.Lon2, + rainAtt: state.linkCalculation.calculations.rainAtt, + rainVal: state.linkCalculation.calculations.rainVal, + formView: state.linkCalculation.calculations.formView, + fsl:state.linkCalculation.calculations.fsl, + siteA: state.linkCalculation.calculations.siteA, + siteB: state.linkCalculation.calculations.siteB, + distance: state.linkCalculation.calculations.distance, + reachable :state.linkCalculation.calculations.reachable +}); + +const BASE_URL="/topology/services" + +const mapDispatch = (dispatcher: IDispatcher) => ({ + + updateFrequency: (frequency: number) => { + dispatcher.dispatch(new UpdateFrequencyAction(frequency)) + + }, + updateLatLon: (Lat1: number, Lon1: number, Lat2: number, Lon2: number) => { + + dispatcher.dispatch(new UpdateLatLonAction(Lat1, Lon1, Lat2, Lon2)) + + }, + + updateRainValue: (rainVal: number) => { + dispatcher.dispatch(new UpdateRainValAction(rainVal)) + }, + + UpdateRainAtt: (rainAtt: number) => { + dispatcher.dispatch(new UpdateRainAttAction(rainAtt)) + }, + + specificRain: (rainAtt: number) => { + dispatcher.dispatch(new UpdateRainAttAction(rainAtt)) + + }, + + FSL :(free:number)=> { + dispatcher.dispatch(new UpdateFslCalculation (free)) + }, + + UpdateConectivity : (reachable:boolean) => { + dispatcher.dispatch (new isCalculationServerReachableAction (reachable)) + } +}); + +class LinkCalculation extends React.Component, { rainMethodDisplay: boolean }> { + constructor(props: any) { + super(props) + this.state = { rainMethodDisplay: true } + } + + handleChange = (e: number) => { + this.props.updateFrequency(e) + } + + updateLatLon = (e: any) => { + + if (e.target.id == 'Lat1') this.props.updateLatLon(e.target.value, this.props.lon1, this.props.lat2, this.props.lon2) + if (e.target.id == 'Lon1') this.props.updateLatLon(this.props.lat1, e.target.value, this.props.lat2, this.props.lon2) + if (e.target.id == 'Lat2') this.props.updateLatLon(this.props.lat1, this.props.lon1, e.target.value, this.props.lon2) + if (e.target.id == 'Lon2') this.props.updateLatLon(this.props.lat1, this.props.lon1, this.props.lat2, e.target.value) + + } + + LatLonToDMS = (value: number, isLon: boolean = false) => { + const absoluteValue = Math.abs(value); + const d = Math.floor(absoluteValue); + const m = Math.floor((absoluteValue - d) * 60); + const s = (absoluteValue - d - m / 60) * 3600; + const dms = `${d}° ${m}' ${s.toFixed(2)}"` + + const sign = Math.sign(value); + + if (isLon) { + return (sign === -1 || sign === -0) ? dms + " W" : dms + " E"; + } else { + return (sign === -1 || sign === -0) ? dms + " S" : dms + " N"; + } + } + + calRain = (lat1: any, lon1: any, lat2: any, lon2: any, frequency: any) => { + fetch(BASE_URL+'/calculations/rain/' + lat1 + '/' + lon1 + '/' + lat2 + '/' + lon2 + '/' + frequency) + .then(res => res.json()) + .then(result => { this.props.UpdateRainAtt(result.RainAtt) }) + } + + + updateRainValue = (lat1: any, lon1: any, lat2: any, lon2: any) => { + fetch(BASE_URL+'/calculations/rain/' + lat1 + '/' + lon1 + '/' + lat2 + '/' + lon2) + .then(res => res.json()) + .then(result => { this.props.updateRainValue(result.RainAtt) }) + } + + + specificRain = (rainfall: number, frequency: number) => { + fetch(BASE_URL+'/calculations/rain/' + rainfall + '/' + frequency) + .then(res => res.json()) + .then(result => { this.props.specificRain(result.RainAtt) }) + } + + FSL = (distance:number, frequency:number) => { + fetch(BASE_URL+'/calculations/FSL/' + distance + '/' + frequency) + .then(res=>res.json()) + .then (result => {this.props.FSL(result.free)}) + } + + buttonHandler =() => { + this.FSL(this.props.distance, this.props.frequency) + + if (this.state.rainMethodDisplay === true){ + + this.specificRain(this.props.rainVal, this.props.frequency); + } + else { + this.calRain(this.props.lat1, this.props.lon1, this.props.lat2, this.props.lon2, this.props.frequency); + this.updateRainValue(this.props.lat1, this.props.lon1, this.props.lat2, this.props.lon2) + } + } + + componentDidMount = () => { + fetch (BASE_URL+'/calculations/fsl/0/0') + .then(res => {if (res.ok) {this.props.reachable===false && this.props.UpdateConectivity(true)}else {this.props.reachable===true && this.props.UpdateConectivity(false)} }) + .catch (res => {this.props.reachable===true && this.props.UpdateConectivity(false)} ) + } + + render() { + console.log(this.props); + const data = [ + + { name: "Site Name", val1: this.props.siteA, val2: '', val3: this.props.siteB}, + { name: "Latitude", val1: this.props.lat1 && this.LatLonToDMS(this.props.lat1), val2:'', val3: this.props.lat2 && this.LatLonToDMS(this.props.lat2) }, + { name: "Longitude", val1: this.props.lon1 && this.LatLonToDMS(this.props.lon1, true), val2:'', val3: this.props.lon2 && this.LatLonToDMS(this.props.lon2, true) }, + { name: "Azimuth in °", val1: '', val2: '' , val3:''}, + { name: "", val1: '', val2: '' , val3:''}, + { name: "Distance (km)", val1: '', val2: (this.props.distance).toFixed(3) ,val3:'' }, + {name: 'Polarization', val1:'', val2:
Horizontal
+ Vertical +
, val3:''}, + {name : 'Frequency (GHz)', val1: '', val2:
+
,val3: ''}, + {name: 'Free Space Loss (dB)' ,val1: '', val2: this.props.fsl,val3: ''}, + {name:'Rain Model', val1:'', val2:
+
, val3:''}, + {name: 'Rainfall Rate (mm/h)', val1: '', val2:, val3:''}, + {name: 'Rain Loss (dB/km)', val1: '', val2: this.props.rainAtt, val3: ''}, + {name: '', val1:'', val2:, val3:'' } + + ]; + + + return
+ Link Calculation app. LinkId: {this.props.linkId}
+ + {!this.props.formView &&
+
+ +
Site A +
Site Id: + +

+ +
+

Site B
Site Id: + + +
+
+
+ } + + + + + + +
+ + } + + +} + +export default connect(mapProps, mapDispatch)(LinkCalculation); diff --git a/sdnr/wt/odlux/apps/linkCalculationApp/src2/main/java/org/onap/ccsdk/features/sdnr/wt/odlux/bundles/MyOdluxBundle.java b/sdnr/wt/odlux/apps/linkCalculationApp/src2/main/java/org/onap/ccsdk/features/sdnr/wt/odlux/bundles/MyOdluxBundle.java new file mode 100644 index 000000000..43b072c4b --- /dev/null +++ b/sdnr/wt/odlux/apps/linkCalculationApp/src2/main/java/org/onap/ccsdk/features/sdnr/wt/odlux/bundles/MyOdluxBundle.java @@ -0,0 +1,68 @@ +/* + * ============LICENSE_START======================================================================== + * ONAP : ccsdk feature sdnr wt + * ================================================================================================= + * Copyright (C) 2019 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========================================================================== + */ +package org.onap.ccsdk.features.sdnr.wt.odlux.bundles; + +import org.onap.ccsdk.features.sdnr.wt.odlux.model.bundles.OdluxBundle; +import org.onap.ccsdk.features.sdnr.wt.odlux.model.bundles.OdluxBundleLoader; + +public class MyOdluxBundle extends OdluxBundle { + + @Override + public void initialize() { + super.initialize(); + } + + @Override + public void clean() { + super.clean(); + } + + @Override + public String getResourceFileContent(String filename) { + return super.getResourceFileContent(filename); + } + + @Override + public boolean hasResource(String filename) { + return super.hasResource(filename); + } + + @Override + public void setBundleName(String bundleName) { + super.setBundleName(bundleName); + } + + @Override + public void setLoader(OdluxBundleLoader loader) { + super.setLoader(loader); + } + + @Override + public String getBundleName() { + return super.getBundleName(); + } + + @Override + public OdluxBundleLoader getLoader() { + return super.getLoader(); + } + + public MyOdluxBundle() { + super(); + } +} diff --git a/sdnr/wt/odlux/apps/linkCalculationApp/src2/main/resources/OSGI-INF/blueprint/blueprint.xml b/sdnr/wt/odlux/apps/linkCalculationApp/src2/main/resources/OSGI-INF/blueprint/blueprint.xml new file mode 100644 index 000000000..8eb652e2d --- /dev/null +++ b/sdnr/wt/odlux/apps/linkCalculationApp/src2/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/sdnr/wt/odlux/apps/linkCalculationApp/src2/test/java/org/onap/ccsdk/features/sdnr/wt/odlux/bundles/test/TestBundleRes.java b/sdnr/wt/odlux/apps/linkCalculationApp/src2/test/java/org/onap/ccsdk/features/sdnr/wt/odlux/bundles/test/TestBundleRes.java new file mode 100644 index 000000000..c319bb189 --- /dev/null +++ b/sdnr/wt/odlux/apps/linkCalculationApp/src2/test/java/org/onap/ccsdk/features/sdnr/wt/odlux/bundles/test/TestBundleRes.java @@ -0,0 +1,46 @@ +/* + * ============LICENSE_START======================================================================== + * ONAP : ccsdk feature sdnr wt + * ================================================================================================= + * Copyright (C) 2019 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========================================================================== + */ +package org.onap.ccsdk.features.sdnr.wt.odlux.bundles.test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import org.junit.Test; +import org.onap.ccsdk.features.sdnr.wt.odlux.OdluxBundleLoaderImpl; +import org.onap.ccsdk.features.sdnr.wt.odlux.bundles.MyOdluxBundle; + +public class TestBundleRes { + + @Test + public void test() { + OdluxBundleLoaderImpl loader = OdluxBundleLoaderImpl.getInstance(); + MyOdluxBundle b = new MyOdluxBundle(); + b.setLoader(loader); + b.setIndex(0); + b.setBundleName("abc"); + b.initialize(); + assertTrue(loader.getNumberOfBundles()==1); + assertNotNull(b.getLoader()); + assertEquals("abc",b.getBundleName()); + assertTrue(b.hasResource("test.js")); + assertNotNull(b.getResourceFileContent("test.js")); + b.clean(); + assertTrue(loader.getNumberOfBundles()==0); + } + +} diff --git a/sdnr/wt/odlux/apps/linkCalculationApp/src2/test/resources/test.js b/sdnr/wt/odlux/apps/linkCalculationApp/src2/test/resources/test.js new file mode 100644 index 000000000..b47fdc39f --- /dev/null +++ b/sdnr/wt/odlux/apps/linkCalculationApp/src2/test/resources/test.js @@ -0,0 +1,5 @@ +asdac sad +as +d +sad + sadfa \ No newline at end of file diff --git a/sdnr/wt/odlux/apps/linkCalculationApp/tsconfig.json b/sdnr/wt/odlux/apps/linkCalculationApp/tsconfig.json new file mode 100644 index 000000000..a66b5d828 --- /dev/null +++ b/sdnr/wt/odlux/apps/linkCalculationApp/tsconfig.json @@ -0,0 +1,37 @@ +{ + "compilerOptions": { + "baseUrl": "./src", + "outDir": "./dist", + "sourceMap": true, + "forceConsistentCasingInFileNames": true, + "allowSyntheticDefaultImports": false, + "allowUnreachableCode": false, + "allowUnusedLabels": false, + "noFallthroughCasesInSwitch": true, + "noImplicitAny": true, + "noImplicitReturns": true, + "noImplicitThis": true, + "strictNullChecks": true, + "pretty": true, + "newLine": "LF", + "module": "es2015", + "target": "es2016", + "moduleResolution": "node", + "experimentalDecorators": true, + "jsx": "preserve", + "lib": [ + "dom", + "es2015", + "es2016" + ], + "types": [ + "prop-types", + "react", + "react-dom" + ] + }, + "exclude": [ + "dist", + "node_modules" + ] +} diff --git a/sdnr/wt/odlux/apps/linkCalculationApp/webpack.config.js b/sdnr/wt/odlux/apps/linkCalculationApp/webpack.config.js new file mode 100644 index 000000000..4f2bd2ec9 --- /dev/null +++ b/sdnr/wt/odlux/apps/linkCalculationApp/webpack.config.js @@ -0,0 +1,159 @@ +/** + * Webpack 4 configuration file + * see https://webpack.js.org/configuration/ + * see https://webpack.js.org/configuration/dev-server/ + */ + +"use strict"; + +const path = require("path"); +const webpack = require("webpack"); +const CopyWebpackPlugin = require("copy-webpack-plugin"); +const TerserPlugin = require('terser-webpack-plugin'); + +// const __dirname = (path => path.replace(/^([a-z]\:)/, c => c.toUpperCase()))(process.__dirname()); + +module.exports = (env) => { + const distPath = path.resolve(__dirname, env === "release" ? "." : "../..", "dist"); + const frameworkPath = path.resolve(__dirname, env === "release" ? "../../framework" : "../..", "dist"); + return [{ + name: "App", + + mode: "none", //disable default behavior + + target: "web", + + context: path.resolve(__dirname, "src"), + + entry: { + linkCalculationApp: ["./pluginLinkCalculation.tsx"] + }, + + devtool: env === "release" ? false : "source-map", + + resolve: { + extensions: [".ts", ".tsx", ".js", ".jsx"] + }, + + output: { + path: distPath, + filename: "[name].js", + library: "[name]", + libraryTarget: "umd2", + chunkFilename: "[name].js" + }, + module: { + rules: [{ + test: /\.tsx?$/, + exclude: /node_modules/, + use: [{ + loader: "babel-loader" + }, { + loader: "ts-loader" + }] + }, { + test: /\.jsx?$/, + exclude: /node_modules/, + use: [{ + loader: "babel-loader" + }] + }] + }, + + optimization: { + noEmitOnErrors: true, + namedModules: env !== "release", + minimize: env === "release", + minimizer: env !== "release" ? [] : [new TerserPlugin({ + terserOptions: { + warnings: false, // false, true, "verbose" + compress: { + drop_console: true, + drop_debugger: true, + } + } + })], + }, + + plugins: [ + new webpack.DllReferencePlugin({ + context: path.resolve(__dirname, "../../framework/src"), + manifest: require(path.resolve(frameworkPath, "vendor-manifest.json")), + sourceType: "umd2" + }), + new webpack.DllReferencePlugin({ + context: path.resolve(__dirname, "../../framework/src"), + manifest: require(path.resolve(frameworkPath, "app-manifest.json")), + sourceType: "umd2" + }), + ...(env === "release") ? [ + new webpack.DefinePlugin({ + "process.env": { + NODE_ENV: "'production'", + VERSION: JSON.stringify(require("./package.json").version) + } + }), + ] : [ + new webpack.DefinePlugin({ + "process.env": { + NODE_ENV: "'development'", + VERSION: JSON.stringify(require("./package.json").version) + } + }), + new CopyWebpackPlugin([{ + from: 'index.html', + to: distPath + }]), + ] + ], + + devServer: { + public: "http://localhost:3100", + contentBase: frameworkPath, + + compress: true, + headers: { + "Access-Control-Allow-Origin": "*" + }, + host: "0.0.0.0", + port: 3100, + disableHostCheck: true, + historyApiFallback: true, + inline: true, + hot: false, + quiet: false, + stats: { + colors: true + }, + proxy: { + "/oauth2/": { + target: "http://10.20.6.29:8181", + secure: false + }, + "/database/": { + target: "http://10.20.6.29:8181", + secure: false + }, + "/restconf/": { + target: "http://10.20.6.29:8181", + secure: false + }, + "/topology/": { + target: "http://localhost:3001", + secure: false + }, + "/help/": { + target: "http://10.20.6.29:8181", + secure: false + }, + "/websocket/": { + target: "http://10.20.6.29:8181", + ws: true, + changeOrigin: true, + secure: false + } + } + + } + }]; +} -- cgit 1.2.3-korg