summaryrefslogtreecommitdiffstats
path: root/sdnr/wt/odlux/apps
diff options
context:
space:
mode:
authorMohammad <mohammad.boroon@highstreet-technologies.com>2020-11-09 15:59:34 +0100
committerMohammad <mohammad.boroon@highstreet-technologies.com>2020-11-09 15:59:48 +0100
commitda4768fe4d28822a91ee7384cbb597cd24435ee6 (patch)
tree01c7411b250bf36e26458e25f98a7589d9f3edfd /sdnr/wt/odlux/apps
parent5bfc361adaf9bb8f71a6de08883c4a2143103ec0 (diff)
Update Link Calculator
Add Worst Month analysis to rain loss, update gui Issue-ID: CCSDK-2888 Signed-off-by: Mohammad <mohammad.boroon@highstreet-technologies.com> Change-Id: Ibac53720f252840bcfd41daa8d5edc7ddde78b0f
Diffstat (limited to 'sdnr/wt/odlux/apps')
-rw-r--r--sdnr/wt/odlux/apps/linkCalculationApp/package.json13
-rw-r--r--sdnr/wt/odlux/apps/linkCalculationApp/src/actions/commonLinkCalculationActions.ts14
-rw-r--r--sdnr/wt/odlux/apps/linkCalculationApp/src/components/connectionInfo.tsx1
-rw-r--r--sdnr/wt/odlux/apps/linkCalculationApp/src/handlers/linkCalculationAppRootHandler.ts23
-rw-r--r--sdnr/wt/odlux/apps/linkCalculationApp/src/index.html2
-rw-r--r--sdnr/wt/odlux/apps/linkCalculationApp/src/views/Style.scss73
-rw-r--r--sdnr/wt/odlux/apps/linkCalculationApp/src/views/linkCalculationComponent.tsx457
-rw-r--r--sdnr/wt/odlux/apps/linkCalculationApp/webpack.config.js16
8 files changed, 400 insertions, 199 deletions
diff --git a/sdnr/wt/odlux/apps/linkCalculationApp/package.json b/sdnr/wt/odlux/apps/linkCalculationApp/package.json
index f4fac3b07..22b2a6c0a 100644
--- a/sdnr/wt/odlux/apps/linkCalculationApp/package.json
+++ b/sdnr/wt/odlux/apps/linkCalculationApp/package.json
@@ -21,7 +21,9 @@
"author": "Mohammad Boroon",
"license": "Apache-2.0",
"dependencies": {
- "@odlux/framework": "*"
+ "@odlux/framework": "*",
+ "formik": "^2.1.5",
+ "yup": "^0.29.3"
},
"peerDependencies": {
"@types/react": "16.9.19",
@@ -36,5 +38,12 @@
"react": "16.12.0",
"react-dom": "16.12.0",
"react-router-dom": "4.3.1"
+ },
+ "devDependencies": {
+ "@types/yup": "^0.29.7",
+ "node-sass": "^4.14.1",
+ "sass": "^1.26.11",
+ "sass-loader": "^10.0.2",
+ "webpack": "^4.44.2"
}
-} \ No newline at end of file
+}
diff --git a/sdnr/wt/odlux/apps/linkCalculationApp/src/actions/commonLinkCalculationActions.ts b/sdnr/wt/odlux/apps/linkCalculationApp/src/actions/commonLinkCalculationActions.ts
index 09887f27f..e7427e4cc 100644
--- a/sdnr/wt/odlux/apps/linkCalculationApp/src/actions/commonLinkCalculationActions.ts
+++ b/sdnr/wt/odlux/apps/linkCalculationApp/src/actions/commonLinkCalculationActions.ts
@@ -101,4 +101,18 @@ export class updateAltitudeAction extends Action{
super();
}
}
+export class UpdateAbsorptionLossAction extends Action{
+ constructor(
+ public absorptionOxygen:number,
+ public absorptionWater:number,
+
+ ){
+ super();
+ }
+}
+export class UpdateWorstMonthRainAction extends Action{
+ constructor(public month: string){
+ super();
+ }
+}
diff --git a/sdnr/wt/odlux/apps/linkCalculationApp/src/components/connectionInfo.tsx b/sdnr/wt/odlux/apps/linkCalculationApp/src/components/connectionInfo.tsx
index cae6fbd9e..e6d82e236 100644
--- a/sdnr/wt/odlux/apps/linkCalculationApp/src/components/connectionInfo.tsx
+++ b/sdnr/wt/odlux/apps/linkCalculationApp/src/components/connectionInfo.tsx
@@ -36,6 +36,7 @@ const ConnectionInfo: React.FunctionComponent<props> = (props) => {
{props.isCalculationServerReachable === false && <Typography> Calculation data can't be loaded.</Typography>}
</div>
</Paper> : null
+
)}
const mapStateToProps = (state: IApplicationStoreState) => ({
diff --git a/sdnr/wt/odlux/apps/linkCalculationApp/src/handlers/linkCalculationAppRootHandler.ts b/sdnr/wt/odlux/apps/linkCalculationApp/src/handlers/linkCalculationAppRootHandler.ts
index 85c013572..012e457e0 100644
--- a/sdnr/wt/odlux/apps/linkCalculationApp/src/handlers/linkCalculationAppRootHandler.ts
+++ b/sdnr/wt/odlux/apps/linkCalculationApp/src/handlers/linkCalculationAppRootHandler.ts
@@ -21,7 +21,7 @@ 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, UpdatePolAction, updateAltitudeAction} from '../actions/commonLinkCalculationActions';
+import { UpdateLinkIdAction, UpdateFrequencyAction , UpdateLatLonAction, UpdateRainAttAction, UpdateRainValAction, updateHideForm, UpdateFslCalculation, UpdateSiteAction, UpdateDistanceAction, isCalculationServerReachableAction, UpdatePolAction, updateAltitudeAction, UpdateAbsorptionLossAction, UpdateWorstMonthRainAction} from '../actions/commonLinkCalculationActions';
declare module '../../../../framework/src/store/applicationStore' {
interface IApplicationStoreState {
@@ -52,7 +52,10 @@ export type ILinkCalculationAppStateState= {
amslA: number,
amslB:number,
aglA: number,
- aglB:number
+ aglB:number,
+ absorptionWater:number,
+ absorptionOxygen: number,
+ month: string
}
const initialState: ILinkCalculationAppStateState ={
@@ -74,7 +77,10 @@ const initialState: ILinkCalculationAppStateState ={
amslA: 0,
amslB:0,
aglA: 0,
- aglB:0
+ aglB:0,
+ absorptionWater:0,
+ absorptionOxygen: 0,
+ month: ''
}
@@ -93,7 +99,7 @@ export const LinkCalculationHandler: IActionHandler<ILinkCalculationAppStateStat
}
else if (action instanceof UpdateFrequencyAction){
state = Object.assign({}, state, {frequency:action.frequency})
-}
+ }
else if (action instanceof UpdateFslCalculation){
state = Object.assign({}, state, {fsl:action.fsl})
}
@@ -114,9 +120,16 @@ export const LinkCalculationHandler: IActionHandler<ILinkCalculationAppStateStat
}
else if (action instanceof UpdatePolAction){
state = Object.assign({}, state, {polarization: action.polarization})
- }else if (action instanceof updateAltitudeAction){
+ }
+ else if (action instanceof updateAltitudeAction){
state = Object.assign({}, state, {amslA:action.amslA, amslB:action.amslA, aglA:action.aglA, aglB:action.aglB})
}
+ else if (action instanceof UpdateAbsorptionLossAction){
+ state = Object.assign({}, state, {absorptionOxygen:action.absorptionOxygen, absorptionWater:action.absorptionWater})
+ }
+ else if (action instanceof UpdateWorstMonthRainAction){
+ state = Object.assign({}, state, {month:action.month})
+ }
return state
}
diff --git a/sdnr/wt/odlux/apps/linkCalculationApp/src/index.html b/sdnr/wt/odlux/apps/linkCalculationApp/src/index.html
index c1cb3f9f3..2023ae365 100644
--- a/sdnr/wt/odlux/apps/linkCalculationApp/src/index.html
+++ b/sdnr/wt/odlux/apps/linkCalculationApp/src/index.html
@@ -15,7 +15,7 @@
<script type="text/javascript" src="./config.js"></script>
<script>
// run the application
- require(["app","connectApp", "networkMapApp", "linkCalculationApp"], function (app, connectApp, networkMapApp, linkCalculationApp) {
+ require(["app","connectApp", "linkCalculationApp", "networkMapApp"], function (app, connectApp, linkCalculationApp,networkMapApp) {
connectApp.register();
linkCalculationApp.register();
networkMapApp.register();
diff --git a/sdnr/wt/odlux/apps/linkCalculationApp/src/views/Style.scss b/sdnr/wt/odlux/apps/linkCalculationApp/src/views/Style.scss
new file mode 100644
index 000000000..35a9b9702
--- /dev/null
+++ b/sdnr/wt/odlux/apps/linkCalculationApp/src/views/Style.scss
@@ -0,0 +1,73 @@
+.parent{
+
+ display: flex;
+ justify-content: space-evenly;
+ margin: auto;
+
+
+}
+.input {
+ width: 150px;
+ box-sizing: border-box;
+ // margin-bottom: 5px;
+
+}
+.error {
+ border: 1px solid red;
+ width: 150px;
+ box-sizing: border-box;
+}
+
+
+.container-1 {
+ height: 50vh;
+ width: 80%;
+ justify-content: center;
+ align-items: baseline;;
+ display: flex;
+ flex-direction: row;
+ align-content: space-between;
+ padding: 20px 40px;
+ border-radius: 10px;
+ // box-shadow: 0px 10px 50px #555;
+ background-color: #ffffff;
+ // padding-top: 10px;
+
+}
+
+ .column1 {
+ flex-direction: column;
+ width: 30%;
+ align-items: flex-end;;
+ // padding: 2em;
+
+ }
+ .column1 div {
+ margin-top: 10px;
+ // align-items: space-between;
+ // flex-wrap: wrap;
+ border-bottom-style: solid;
+ border-bottom-width: thin;
+ border-color: silver;
+ }
+ .middlecolumn{
+
+ flex-direction: column;
+ flex-grow: 1;
+ // padding: 10px 10px;
+ }
+
+ .middlecolumn div{
+ margin-top: 10px;
+ border-bottom-style: solid;
+ border-bottom-width: thin;
+ border-color: silver;
+ }
+
+ .column2 {
+ margin-left: 200px;
+ }
+ .column2 div{
+ margin-top: 10px;
+
+ } \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/linkCalculationApp/src/views/linkCalculationComponent.tsx b/sdnr/wt/odlux/apps/linkCalculationApp/src/views/linkCalculationComponent.tsx
index 9cbc771f4..7c54ed185 100644
--- a/sdnr/wt/odlux/apps/linkCalculationApp/src/views/linkCalculationComponent.tsx
+++ b/sdnr/wt/odlux/apps/linkCalculationApp/src/views/linkCalculationComponent.tsx
@@ -21,12 +21,15 @@ 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, Checkbox, Table, TableCell, TableHead, TableRow, TableBody, Paper } from '@material-ui/core';
-import DenseTable from '../components/denseTable'
+import './Style.scss'
import { IApplicationStoreState } from "../../../../framework/src/store/applicationStore";
-import { UpdateFrequencyAction, UpdateLatLonAction, UpdateRainAttAction, UpdateRainValAction, UpdateFslCalculation, isCalculationServerReachableAction, UpdatePolAction, UpdateDistanceAction, updateAltitudeAction } from "../actions/commonLinkCalculationActions";
-import { faPlaneArrival } from "@fortawesome/free-solid-svg-icons";
+import { UpdateFrequencyAction, UpdateLatLonAction, UpdateRainAttAction, UpdateRainValAction, UpdateFslCalculation, isCalculationServerReachableAction, UpdatePolAction, UpdateDistanceAction, updateAltitudeAction, UpdateAbsorptionLossAction, UpdateWorstMonthRainAction } from "../actions/commonLinkCalculationActions";
+import { faPlaneArrival, faAlignCenter } from "@fortawesome/free-solid-svg-icons";
import ConnectionInfo from '../components/connectionInfo'
+import { red } from "@material-ui/core/colors";
+
+
const mapProps = (state: IApplicationStoreState) => ({
linkId: state.linkCalculation.calculations.linkId,
@@ -47,7 +50,10 @@ const mapProps = (state: IApplicationStoreState) => ({
amslA:state.linkCalculation.calculations.amslA,
amslB:state.linkCalculation.calculations.amslB,
aglA:state.linkCalculation.calculations.aglA,
- aglB:state.linkCalculation.calculations.aglB
+ aglB:state.linkCalculation.calculations.aglB,
+ absorptionOxygen : state.linkCalculation.calculations.absorptionOxygen,
+ absorptionWater : state.linkCalculation.calculations.absorptionWater,
+ month : state.linkCalculation.calculations.month
});
const BASE_URL="/topology/services"
@@ -89,38 +95,80 @@ const mapDispatch = (dispatcher: IDispatcher) => ({
updateAutoDistance : (distance:number)=>{
dispatcher.dispatch (new UpdateDistanceAction(distance))
- }
+ },
+
+ UpdateAbsorption : (OxLoss:number , WaterLoss:number) => {
+ dispatcher.dispatch (new UpdateAbsorptionLossAction (OxLoss, WaterLoss))
+ },
+ // UpdateWorstMonth : (worstmonth:boolean) => {
+ // dispatcher.dispatch (new UpdateWorstMonthAction(worstmonth))
+ // },
+
+ UpdateWorstMonthRain : (month:string) => {
+ dispatcher.dispatch (new UpdateWorstMonthRainAction(month))
+ }
+
+
});
+
+
+
type linkCalculationProps = Connect<typeof mapProps, typeof mapDispatch>;
-class LinkCalculation extends React.Component<linkCalculationProps, {rainMethodDisplay: boolean, horizontalBoxChecked: boolean}> {
+interface initialState {
+ rainMethodDisplay: boolean,
+ horizontalBoxChecked: boolean,
+ latitude1Error: string,
+ longitude1Error:string
+ latitude2Error: string,
+ longitude2Error:string,
+ frequencyError: string,
+ rainMethodError: string,
+ worstmonth : boolean,
+ showWM : string
+
+
+}
+
+class LinkCalculation extends React.Component<linkCalculationProps, initialState> {
constructor(props: any) {
- super(props)
- this.state = { rainMethodDisplay: false,
- horizontalBoxChecked: true
- }
- }
+ super(props);
+ this.state = {
+ rainMethodDisplay: false,
+ horizontalBoxChecked: true,
+ latitude1Error: '',
+ longitude1Error:'',
+ latitude2Error: '',
+ longitude2Error:'',
+ frequencyError: '',
+ rainMethodError: '',
+ worstmonth : false,
+ showWM: ''
+ };
+ }
+
updateAutoDistance = async (lat1: number, lon1: number, lat2: number, lon2: number)=>{
const result = await fetch(BASE_URL+'/calculations/distance/' + lat1 + '/' + lon1 + '/' + lat2 + '/' + lon2)
const json = await result.json()
return json.distanceInKm
}
- updateLatLon = (e: any) => {
+ 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)
+ e.target.id== 'Lat1'? this.props.updateLatLon(e.target.value, this.props.lon1, this.props.lat2, this.props.lon2) : null
+ e.target.id== 'Lon1'? this.props.updateLatLon(this.props.lat1, e.target.value, this.props.lat2, this.props.lon2) : null
+ e.target.id== 'Lat2'? this.props.updateLatLon(this.props.lat1, this.props.lon1, e.target.value, this.props.lon2) : null
+ e.target.id== 'Lon2'? this.props.updateLatLon(this.props.lat1, e.target.value, this.props.lat2, e.target.value) : null
+
}
updatePoli = (val: string) =>{
this.setState({horizontalBoxChecked: !this.state.horizontalBoxChecked});
this.props.updatePolarization(val);
- //this.forceUpdate();
+
}
LatLonToDMS = (value: number, isLon: boolean = false) => {
@@ -139,10 +187,17 @@ class LinkCalculation extends React.Component<linkCalculationProps, {rainMethodD
}
}
- rainAttCal = (lat1: any, lon1: any, lat2: any, lon2: any, frequency: any, distance: number, polarization : any) => {
- fetch(BASE_URL+'/calculations/rain/' + lat1 + '/' + lon1 + '/' + lat2 + '/' + lon2 + '/' + frequency+ '/'+ distance + '/' + polarization)
+ rainAttCal = (lat1: any, lon1: any, lat2: any, lon2: any, frequency: any, distance: number, polarization : any, worstmonth:boolean) => {
+ if(!worstmonth){
+ fetch(BASE_URL+'/calculations/rain/Annual/' + lat1 + '/' + lon1 + '/' + lat2 + '/' + lon2 + '/' + frequency+ '/'+ distance + '/' + polarization)
.then(res => res.json())
- .then(result => { this.props.UpdateRainAtt(result.RainAtt) })
+ .then(result => { this.props.UpdateRainAtt(result.RainAtt) ; this.props.updateRainValue(result.rainfall) })
+ }
+ else {
+ fetch(BASE_URL+'/calculations/rain/WM/' + lat1 + '/' + lon1 + '/' + lat2 + '/' + lon2 + '/' + frequency+ '/'+ distance + '/' + polarization)
+ .then(res => res.json())
+ .then(result => { this.props.UpdateRainAtt(result.RainAtt) ; this.props.updateRainValue(result.rainfallWM); this.props.UpdateWorstMonthRain (result.month); this.setState({showWM: '- Wm is : '})})
+ }
}
@@ -152,33 +207,75 @@ class LinkCalculation extends React.Component<linkCalculationProps, {rainMethodD
.then(result => { this.props.specificRain(result.RainAtt) })
}
- updateRainValue = (lat1: any, lon1: any, lat2: any, lon2: any) => {
- fetch(BASE_URL+'/calculations/rainval/' + lat1 + '/' + lon1 + '/' + lat2 + '/' + lon2)
- .then(res => res.json())
- .then(result => {this.props.updateRainValue(result.rainFall) })
- }
FSL = (distance:number, frequency:number) => {
fetch(BASE_URL+'/calculations/FSL/' + distance + '/' + frequency)
.then(res=>res.json())
.then (result => {this.props.FSL(result.free)})
}
+
+ AbsorptionAtt =(lat1: number, lon1: number, lat2: number, lon2: number, distance:number, frequency:number, worstmonth:boolean) => {
+ if(!worstmonth)
+ {
+ fetch(BASE_URL+'/calculations/absorption/Annual/' +lat1 + '/' + lon1 + '/' + lat2 + '/' + lon2 + '/' + distance + '/' + frequency)
+ .then(res=>res.json())
+ .then (result => {this.props.UpdateAbsorption(result.OxLoss, result.WaterLoss)})
+ }
+ else {
+ fetch(BASE_URL+'/calculations/absorption/WM/' +lat1 + '/' + lon1 + '/' + lat2 + '/' + lon2 + '/' + distance + '/' + frequency)
+ .then(res=>res.json())
+ .then (result => {this.props.UpdateAbsorption(result.OxLoss, result.WaterLoss)})
+ }
+ }
-
+ formValid = () => {
+
+ this.props.lat1 === 0 ? this.setState({latitude1Error: 'Enter a number between -90 to 90'}) : null
+ this.props.lat2 === 0 ? this.setState({latitude2Error: 'Enter a number between -90 to 90'}) : null
+ this.props.lon1 === 0 ? this.setState({longitude1Error: 'Enter a number between -180 to 180' }) : null
+ this.props.lon2 === 0 ? this.setState({longitude2Error: 'Enter a number between -180 to 180' }) : null
+ this.props.frequency === 0 ? this.setState({frequencyError: 'Select a frequency' }) : this.setState({frequencyError: ''})
+
+ this.state.rainMethodError === null && this.props.rainVal === 0 ? this.setState({rainMethodError: 'Select the rain method'}) : this.setState({rainMethodError: ''})
+
+ console.log(this.props.lat1 !== 0 && this.props.lat2 !== 0 && this.props.lon1 !== 0 && this.props.lon2 !==0 && this.props.frequency!==0);
+
+ return this.props.lat1 !== 0 && this.props.lat2 !== 0 && this.props.lon1 !== 0 && this.props.lon2 !==0 && this.props.frequency!==0
+
+ }
+
+
buttonHandler = async () => {
- this.props.updateAutoDistance(await this.updateAutoDistance(this.props.lat1, this.props.lon1, this.props.lat2, this.props.lon2))
+
+ if (this.formValid()) {
+ this.props.updateAutoDistance(await this.updateAutoDistance(this.props.lat1, this.props.lon1, this.props.lat2, this.props.lon2))
this.FSL(this.props.distance, this.props.frequency)
- if (this.state.rainMethodDisplay === true){
+ if (this.state.worstmonth===false) {
+ this.setState({showWM : ' '})
+ this.props.UpdateWorstMonthRain('')
+ this.AbsorptionAtt (this.props.lat1, this.props.lon1, this.props.lat2, this.props.lon2, this.props.distance, this.props.frequency, this.state.worstmonth)
- this.manualRain(this.props.rainVal, this.props.frequency, this.props.distance, this.props.polarization);
- }
- else {
- this.updateRainValue(this.props.lat1, this.props.lon1, this.props.lat2, this.props.lon2)
- this.rainAttCal(this.props.lat1, this.props.lon1, this.props.lat2, this.props.lon2, this.props.frequency, this.props.distance, this.props.polarization);
+ if (this.state.rainMethodDisplay === true){
+
+ this.manualRain(this.props.rainVal, this.props.frequency, this.props.distance, this.props.polarization);
+ }
+ else {
+ // this.updateRainValue(this.props.lat1, this.props.lon1, this.props.lat2, this.props.lon2, this.state.worstmonth)
+ this.rainAttCal(this.props.lat1, this.props.lon1, this.props.lat2, this.props.lon2, this.props.frequency, this.props.distance, this.props.polarization, this.state.worstmonth);
+ }
+ }
+ else {
+ this.AbsorptionAtt (this.props.lat1, this.props.lon1, this.props.lat2, this.props.lon2, this.props.distance, this.props.frequency, this.state.worstmonth)
+
+ // this.updateRainValue(this.props.lat1, this.props.lon1, this.props.lat2, this.props.lon2, this.state.worstmonth)
+
+ this.rainAttCal(this.props.lat1, this.props.lon1, this.props.lat2, this.props.lon2, this.props.frequency, this.props.distance, this.props.polarization, this.state.worstmonth);
}
+ }
+ else null
}
@@ -189,177 +286,157 @@ class LinkCalculation extends React.Component<linkCalculationProps, {rainMethodD
}
handleChange =(e:any) => {
- this.props.updatePolarization(e.target.value)
+
+ switch (e.target.id){
+ case 'Lat1' : if ( e.target.value >90 || e.target.value<-90 )
+ { this.setState({latitude1Error: 'Enter a number between -90 to 90'})}
+ else {this.updateLatLon(e)
+ this.setState({latitude1Error: ''}) }
+ break;
+ case 'Lat2' : if ( e.target.value >90 || e.target.value<-90 )
+ { this.setState({latitude2Error: 'Enter a number between -90 to 90'})}
+ else {this.updateLatLon(e)
+ this.setState({latitude2Error: ''}) }
+ break;
+ case 'Lon1' : if ( e.target.value >180 || e.target.value<-180 )
+ { this.setState({longitude1Error: 'Enter a number between -180 to 180'})}
+ else {this.updateLatLon(e)
+ this.setState({longitude1Error: ''}) }
+ break;
+ case 'Lon2' : if ( e.target.value >180 || e.target.value<-180 )
+ { this.setState({longitude2Error: 'Enter a number between -180 to 180'})}
+ else {this.updateLatLon(e)
+ this.setState({longitude2Error: ''}) }
+ break;
+
+ }
}
- // AbsorptionAttW = () => {
- // fetch(BASE_URL+'/calculations/FSL/' + distance + '/' + frequency)
- // .then(res=>res.json())
- // .then (result => {this.props.FSL(result.free)})
- // }
+ render() {
+ return (
+
+ <div >
+
+ {!this.props.formView &&
+
+ <div className = 'parent'>
+
+ <div >Site A
+ <form >
+ <label>Latitude: <input className={this.state.latitude1Error.length>0 ? 'error' : 'input'} id='Lat1' type='number' onChange={(e: any) => {this.handleChange(e)} }/></label>
+ <div style={{fontSize:12, color:'red'}}> {this.state.latitude1Error} </div></form>
+ <form><label>Longitude: <input className={this.state.longitude1Error.length>0 ? 'error' : 'input'} id='Lon1' type='number' onChange={(e: any) => this.handleChange(e) } /></label><div style={{fontSize:12, color:'red'}}> {this.state.longitude1Error} </div>
+ </form>
+ </div>
+
+ <div>Site B
+ <form>
+ <label>Latitude: <input className={this.state.latitude2Error.length>0 ? 'error' : 'input'} id='Lat2' type='number' onChange={(e: any) => {this.handleChange(e) }} /></label><div style={{fontSize:12, color:'red'}}> {this.state.latitude2Error} </div></form>
+ <form><label>Longitude: <input className={this.state.longitude2Error.length>0 ? 'error' : 'input'} id='Lon2' type='number' onChange={(e: any) => {this.handleChange(e) } }/></label><div style={{fontSize:12, color:'red'}}> {this.state.longitude2Error} </div></form>
+ </div>
+
+ </div>
+ }
- // AbsorptionAttOx =() => {
- // fetch(BASE_URL+'/calculations/FSL/' + distance + '/' + frequency)
- // .then(res=>res.json())
- // .then (result => {this.props.FSL(result.free)})
- // }
+ <div className='container-1'>
+ <div>{<form><input type='checkbox' id='Annual' value ="Annual" checked= {this.state.worstmonth===false} onClick= {(e: any) => this.setState ({worstmonth: false})}></input>Annual
+ <input style={{marginLeft:10}} type='checkbox' id='Worst Month' value ="Worst" checked= {this.state.worstmonth===true} onClick= {(e:any)=>this.setState ({worstmonth: true})}></input>WM</form>}</div>
+
+
+ <div className='column1'>
+ <div>&nbsp;</div>
+ <div >Site Name</div>
+ <div>Latitude</div>
+ <div>Longitude</div>
+ <div>Azimuth</div>
+ <div>Average Mean Sea Level</div>
+ <div>Antenna Height Above Ground</div>
+ <div>Distance</div>
+ <div style={{marginTop:20}}>Polarization</div>
+ <div style={{marginTop:20}}>Frequency</div>
+ <div>Free Space Loss</div>
+ <div style={{marginTop:10}}>Rain Model</div>
+ <div style={{marginTop:20}}>Rainfall Rate</div>
+ <div>Rain Loss</div>
+ <div>Oxygen Specific Attenuation</div>
+ <div>Water Vapor Specific Attenuation</div>
+ </div>
+
- render() {
-
- return <div style={{position: 'relative'}}>
+ <div className='middlecolumn'>
+ <div >Site A</div>
+ <div> {this.props.siteA }</div>
+ <div> {this.props.lat1 && this.LatLonToDMS(this.props.lat1)}</div>
+ <div>{this.props.lon1 && this.LatLonToDMS(this.props.lon1)}</div>
+ <div>0</div>
+ <div>{this.props.amslA.toFixed(2)} m</div>
+ <div>{this.props.aglA.toFixed(2)} m</div>
+
- {!this.props.formView && <form>
- <div>
+ <div className='column2'>
+ <div>{this.props.distance.toFixed(3)} km</div>
+ <div>{<form><input type='checkbox' id='Horizontal' value ="Horizontal" checked= {this.props.polarization==='Horizontal'} onClick= {(e: any) => this.props.updatePolarization(e.target.value)}></input>Horizontal
+ <input style={{marginLeft:10}} type='checkbox' id='Vertical' value ="Vertical" checked= {this.props.polarization==='Vertical'} onClick= {(e:any)=>{this.props.updatePolarization(e.target.value)}}></input>Vertical</form>}</div>
- <br />Site A
- <br /> Site Id:
- <label style={{ marginInlineStart: 20 }}> latitude
- <input id='Lat1' type='number' onChange={(e: any) => this.updateLatLon(e)} />
- </label>
- <label style={{ marginInlineStart: 20 }}>longitude
- <input id='Lon1' type='number' onChange={(e: any) => this.updateLatLon(e)} />
- </label><br /><br />
+ <div> {<select className={this.state.frequencyError.length>0 ? 'error' : 'input'} onChange={(e) => {this.props.updateFrequency(Number(e.target.value)); e.target.value==='0'? this.setState({frequencyError: 'select a frequency'}): this.setState({frequencyError:''})}}>
+
+ <option value='0' >Select Freq</option>
+ <option value='7' >7 GHz</option>
+ <option value='11' >11 GHz</option>
+ <option value='15' >15 GHz</option>
+ <option value='23' >23 GHz</option>
+ <option value='26' >26 GHz</option>
+ <option value='28' >28 GHz</option>
+ <option value='38' >38 GHz</option>
+ <option value='42' >42 GHz</option>
+ <option value='80' >80 GHz</option>
+ </select>} <div style={{fontSize:12, color:'red'}}> {this.state.frequencyError} </div> </div>
+
+ <div>{this.props.fsl.toFixed(3)} dB</div>
+
+ <div> {<select className={this.state.rainMethodError.length>0 ? 'error' : 'input'} onChange = {(e) => {e.target.value === 'itu' ? this.setState({ rainMethodDisplay: false}):this.setState({ rainMethodDisplay: true}); e.target.value===''? this.setState({rainMethodError: 'select a Rain model'}): this.setState({rainMethodError:''}) }}>
+ <option value='' >Select Rain Method</option>
+ <option value='itu' >ITU-R P.837-7</option>
+ <option value='manual' >Specific Rain</option>
+ </select>} <div style={{fontSize:12,color:'red'}}>{this.state.rainMethodError}</div>
+ </div>
+ <div> {<form><input type="number" style={{ width: 70, height: 15, fontSize: 14 }} onChange={(e) => { this.props.updateRainValue(Number(e.target.value)) }}
+ value={this.props.rainVal} disabled={this.state.rainMethodDisplay === false ? true : false}>
+ </input> mm/hr {this.state.showWM} {this.props.month}</form> } </div>
+ <div>{this.props.rainAtt.toFixed(3)} dB</div>
+ <div>{this.props.absorptionOxygen.toFixed(3)} dB</div>
+ <div>{this.props.absorptionWater.toFixed(3)} dB</div>
+ <div>{<button style={{color: '#222', fontFamily:'Arial', boxAlign: 'center', display:'inline-block', insetInlineStart: '20' , alignSelf:'center' }}
+ onClick = {(e) => this.buttonHandler()} >Calculate</button>} </div>
+
</div>
- <div> <br />Site B<br /> Site Id:
- <label style={{ marginInlineStart: 20 }}> latitude
- <input id='Lat2' type='number' onChange={(e: any) => this.updateLatLon(e)} />
- </label>
- <label style={{ marginInlineStart: 20 }}>longitude
- <input id='Lon2' type='number' onChange={(e: any) => this.updateLatLon(e)} />
- </label>
- <br />
</div>
- </form>
- }
+ <div className= 'middlecolumn'>
+ <div >Site B</div>
+ <div> {this.props.siteB}</div>
+ <div> {this.props.lat2 && this.LatLonToDMS(this.props.lat2)}</div>
+ <div>{this.props.lon2 && this.LatLonToDMS(this.props.lon2)}</div>
+ <div>0</div>
+ <div>{this.props.amslB.toFixed(2)} m</div>
+ <div>{this.props.aglB.toFixed(2)} m</div>
-<Paper style={{borderRadius:"0px"}}>
- <div style={{ height:600, overflow:"auto"}}>
- <Table stickyHeader size="small" aria-label="a dense table" >
- <TableHead>
- <TableRow>
- <TableCell >{""} </TableCell>
- <TableCell >{"Site A"}</TableCell>
- <TableCell > {""} </TableCell>
- <TableCell >{"Site B"} </TableCell>
- </TableRow>
- </TableHead>
- <TableBody>
- <TableRow>
- <TableCell >{"Site Name"} </TableCell>
- <TableCell >{this.props.siteA}</TableCell>
- <TableCell > {""} </TableCell>
- <TableCell >{this.props.siteB} </TableCell>
- </TableRow>
- <TableRow>
- <TableCell >{"Latitude"} </TableCell>
- <TableCell >{this.props.lat1 && this.LatLonToDMS(this.props.lat1)} </TableCell>
- <TableCell > {""} </TableCell>
- <TableCell >{this.props.lat2 && this.LatLonToDMS(this.props.lat2)} </TableCell>
- </TableRow>
- <TableRow>
- <TableCell >{"Longitude"} </TableCell>
- <TableCell >{this.props.lon1 && this.LatLonToDMS(this.props.lon1)}</TableCell>
- <TableCell > {""} </TableCell>
- <TableCell >{this.props.lon2 && this.LatLonToDMS(this.props.lon2)} </TableCell>
- </TableRow>
- <TableRow>
- <TableCell >{"Azimuth"} </TableCell>
- <TableCell >{""}</TableCell>
- <TableCell > {""} </TableCell>
- <TableCell >{""} </TableCell>
- </TableRow>
- <TableRow>
- <TableCell >{"Average Mean Sea Level"} </TableCell>
- <TableCell >{this.props.amslA + ' m'}</TableCell>
- <TableCell > {""} </TableCell>
- <TableCell >{this.props.amslB+ ' m'} </TableCell>
- </TableRow>
- <TableRow>
- <TableCell >{"Antenna Height Above Ground"} </TableCell>
- <TableCell >{this.props.aglA+ ' m'}</TableCell>
- <TableCell > {""} </TableCell>
- <TableCell >{this.props.aglB+ ' m'} </TableCell>
- </TableRow>
- <TableRow>
- <TableCell >{"Distance"} </TableCell>
- <TableCell >{""}</TableCell>
- <TableCell > {this.props.distance.toFixed(3)+ ' km'} </TableCell>
- <TableCell >{""} </TableCell>
- </TableRow>
- <TableRow>
- <TableCell >{"Polarization"} </TableCell>
- <TableCell >{""}</TableCell>
- <TableCell > {<form><input type='checkbox' id='Horizontal' value ="Horizontal" checked= {this.props.polarization==='Horizontal'} onClick= {(e: any) => this.props.updatePolarization(e.target.value)}></input>Horizontal<br />
- <input type='checkbox' id='Vertical' value ="Vertical" checked= {this.props.polarization==='Vertical'} onClick= {(e:any)=>{this.props.updatePolarization(e.target.value)}}></input>Vertical</form>} </TableCell>
- <TableCell >{""} </TableCell>
- </TableRow>
- <TableRow>
- <TableCell >{"Frequency"} </TableCell>
- <TableCell >{""}</TableCell>
- <TableCell > {<select onChange={(e) => this.props.updateFrequency(Number(e.target.value))}>
- <option value='' >Select Freq</option>
- <option value='7' >7 GHz</option>
- <option value='11' >11 GHz</option>
- <option value='15' >15 GHz</option>
- <option value='23' >23 GHz</option>
- <option value='26' >26 GHz</option>
- <option value='28' >28 GHz</option>
- <option value='38' >38 GHz</option>
- <option value='42' >42 GHz</option>
- <option value='80' >80 GHz</option>
- </select>}
- </TableCell>
- <TableCell >{""} </TableCell>
- </TableRow>
- <TableRow>
- <TableCell >{"Free Space Loss"} </TableCell>
- <TableCell >{""}</TableCell>
- <TableCell > {this.props.fsl + ' dB'} </TableCell>
- <TableCell >{""} </TableCell>
- </TableRow>
- <TableRow>
- <TableCell >{"Rain Model"} </TableCell>
- <TableCell >{""}</TableCell>
- <TableCell > {<select onChange = {(e) => {e.target.value === 'itu' ? this.setState({ rainMethodDisplay: false}):this.setState({ rainMethodDisplay: true}) }}>
- <option >Select Rain Method</option>
- <option value='itu' >ITU-R P.837-7</option>
- <option value='manual' >Specific Rain</option>
- </select>} </TableCell>
- <TableCell >{""} </TableCell>
- </TableRow>
- <TableRow>
- <TableCell >{"Rainfall Rate"} </TableCell>
- <TableCell >{""}</TableCell>
- <TableCell > {<form><input type="number" style={{ width: 70, height: 15, fontSize: 14 }} onChange={(e) => { this.props.updateRainValue(Number(e.target.value)) }}
- value={this.props.rainVal} disabled={this.state.rainMethodDisplay === false ? true : false}>
- </input> mm/hr</form> } </TableCell>
- <TableCell >{""} </TableCell>
- </TableRow>
- <TableRow>
- <TableCell >{"Rain Loss"} </TableCell>
- <TableCell >{""}</TableCell>
- <TableCell > {this.props.rainAtt + ' dB'} </TableCell>
- <TableCell >{""} </TableCell>
- </TableRow>
- <TableRow>
- <TableCell >{""} </TableCell>
- <TableCell >{""}</TableCell>
- <TableCell > {<button style={{color: '#222', fontFamily:'Arial', boxAlign: 'center', display:'inline-block', insetInlineStart: '20' }}
- onClick = {(e) => this.buttonHandler()} >Calculate</button>} </TableCell>
- <TableCell >{""} </TableCell>
- </TableRow>
-
- </TableBody>
- </Table>
- </div>
- </Paper>
- <ConnectionInfo />
+
+ </div>
+
+
+ </div>
+
+
+ <ConnectionInfo />
+
</div>
+ )
}
-}
+
+ }
export default connect(mapProps, mapDispatch)(LinkCalculation);
diff --git a/sdnr/wt/odlux/apps/linkCalculationApp/webpack.config.js b/sdnr/wt/odlux/apps/linkCalculationApp/webpack.config.js
index 4f2bd2ec9..3c9093c4b 100644
--- a/sdnr/wt/odlux/apps/linkCalculationApp/webpack.config.js
+++ b/sdnr/wt/odlux/apps/linkCalculationApp/webpack.config.js
@@ -49,7 +49,7 @@ module.exports = (env) => {
use: [{
loader: "babel-loader"
}, {
- loader: "ts-loader"
+ loader: "ts-loader"
}]
}, {
test: /\.jsx?$/,
@@ -57,6 +57,20 @@ module.exports = (env) => {
use: [{
loader: "babel-loader"
}]
+ },{
+ test: /\.scss$/,
+ include: /node_modules/,
+ use: ['style-loader', 'css-loader', 'sass-loader'],
+ },{
+ test: /\.s[ac]ss$/i,
+ use: [
+ // Creates `style` nodes from JS strings
+ 'style-loader',
+ // Translates CSS into CommonJS
+ 'css-loader',
+ // Compiles Sass to CSS
+ 'sass-loader',
+ ],
}]
},