Add data-provider
[ccsdk/features.git] / sdnr / wt / odlux / apps / performanceHistoryApp / src / views / performanceHistoryApplication.tsx
1 /**
2  * ============LICENSE_START========================================================================
3  * ONAP : ccsdk feature sdnr wt odlux
4  * =================================================================================================
5  * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
6  * =================================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
8  * in compliance with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software distributed under the License
13  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
14  * or implied. See the License for the specific language governing permissions and limitations under
15  * the License.
16  * ============LICENSE_END==========================================================================
17  */
18 import * as React from 'react';
19
20 import { createStyles, Theme, withStyles, WithStyles } from '@material-ui/core/styles';
21 import FormControl from '@material-ui/core/FormControl';
22 import MenuItem from '@material-ui/core/MenuItem';
23 import Select from '@material-ui/core/Select';
24
25 import connect, { Connect, IDispatcher } from '../../../../framework/src/flux/connect';
26 import { IApplicationStoreState } from '../../../../framework/src/store/applicationStore';
27 import { Panel } from '../../../../framework/src/components/material-ui';
28 import { loadAllMountedNetworkElementsAsync } from '../../../connectApp/src/actions/mountedNetworkElementsActions';
29 import { NavigateToApplication } from '../../../../framework/src/actions/navigationActions';
30 import { Dispatch } from '../../../../framework/src/flux/store';
31
32 import { PanelId } from '../models/panelId';
33 import { PmDataInterval } from '../models/performanceDataType';
34 import PerformanceData from '../components/performanceData';
35 import ReceiveLevel from '../components/receiveLevel';
36 import TransmissionPower from '../components/transmissionPower';
37 import AdaptiveModulation from '../components/adaptiveModulation';
38 import Temperature from '../components/temperature';
39 import SignalToInterference from '../components/signalToInterference';
40 import CrossPolarDiscrimination from '../components/crossPolarDiscrimination';
41 import { loadAllConnectedNetworkElementsAsync } from '../actions/connectedNetworkElementsActions';
42 import { TimeChangeAction } from '../actions/timeChangeAction';
43 import { loadDistinctLtpsbyNetworkElementAsync } from '../actions/ltpAction';
44 import { SetPanelAction } from '../actions/panelChangeActions';
45 import { createPerformanceDataPreActions, performanceDataReloadAction, createPerformanceDataActions } from '../handlers/performanceDataHandler';
46 import { createReceiveLevelPreActions, receiveLevelReloadAction, createReceiveLevelActions } from '../handlers/receiveLevelHandler';
47 import { createTransmissionPowerPreActions, transmissionPowerReloadAction, createTransmissionPowerActions } from '../handlers/transmissionPowerHandler';
48 import { createAdaptiveModulationPreActions, adaptiveModulationReloadAction, createAdaptiveModulationActions } from '../handlers/adaptiveModulationHandler';
49 import { createTemperaturePreActions, temperatureReloadAction, createTemperatureActions } from '../handlers/temperatureHandler';
50 import { createSignalToInterferencePreActions, signalToInterferenceReloadAction, createSignalToInterferenceActions } from '../handlers/signalToInterferenceHandler';
51 import { createCrossPolarDiscriminationPreActions, crossPolarDiscriminationReloadAction, createCrossPolarDiscriminationActions } from '../handlers/crossPolarDiscriminationHandler';
52
53 import { MaterialTable, MaterialTableCtorType } from '../../../../framework/src/components/material-table';
54
55 const PerformanceHistoryComponentStyles = (theme: Theme) => createStyles({
56   root: {
57     display: "flex",
58     flexWrap: "wrap",
59   },
60   margin: {
61     margin: theme.spacing.unit,
62   },
63   display: {
64     display: "inline-block"
65   },
66   selectDropdown: {
67     borderRadius: 1,
68     position: "relative",
69     backgroundColor: theme.palette.background.paper,
70     border: "1px solid #ced4da",
71     fontSize: 16,
72     width: "auto",
73     padding: "5px 26px 5px 12px",
74     transition: theme.transitions.create(["border-color", "box-shadow"]),
75   }
76 });
77
78 const mapProps = (state: IApplicationStoreState) => ({
79   ...state.performanceHistory,
80   activePanel: state.performanceHistory.currentOpenPanel,
81   availableLtps: state.performanceHistory.ltps.distinctLtps,
82   networkElements: state.performanceHistory.networkElements.connectedNetworkElementIds
83 });
84
85 const mapDispatcher = (dispatcher: IDispatcher) => ({
86   enableFilterPerformanceData: createPerformanceDataActions(dispatcher.dispatch),
87   enableFilterReceiveLevel: createReceiveLevelActions(dispatcher.dispatch),
88   enableFilterTransmissionPower: createTransmissionPowerActions(dispatcher.dispatch),
89   enableFilterAdaptiveModulation: createAdaptiveModulationActions(dispatcher.dispatch),
90   enableFilterTemperature: createTemperatureActions(dispatcher.dispatch),
91   enableFilterSinr: createSignalToInterferenceActions(dispatcher.dispatch),
92   enableFilterCpd: createCrossPolarDiscriminationActions(dispatcher.dispatch),
93   reloadPerformanceData: () => dispatcher.dispatch(performanceDataReloadAction),
94   reloadReceiveLevel: () => dispatcher.dispatch(receiveLevelReloadAction),
95   reloadTransmissionPower: () => dispatcher.dispatch(transmissionPowerReloadAction),
96   reloadAdaptiveModulation: () => dispatcher.dispatch(adaptiveModulationReloadAction),
97   reloadTemperature: () => dispatcher.dispatch(temperatureReloadAction),
98   reloadSignalToInterference: () => dispatcher.dispatch(signalToInterferenceReloadAction),
99   reloadCrossPolarDiscrimination: () => dispatcher.dispatch(crossPolarDiscriminationReloadAction),
100   performanceDataPreActions: createPerformanceDataPreActions(dispatcher.dispatch),
101   receiveLevelPreActions: createReceiveLevelPreActions(dispatcher.dispatch),
102   transmissionPowerPreActions: createTransmissionPowerPreActions(dispatcher.dispatch),
103   adaptiveModulationPreActions: createAdaptiveModulationPreActions(dispatcher.dispatch),
104   temperaturePreActions: createTemperaturePreActions(dispatcher.dispatch),
105   signalToInterferencePreActions: createSignalToInterferencePreActions(dispatcher.dispatch),
106   crossPolarDiscriminationPreActions: createCrossPolarDiscriminationPreActions(dispatcher.dispatch),
107   getConnectedNetworkElementsIds: async () => {
108     await dispatcher.dispatch(loadAllMountedNetworkElementsAsync)
109     dispatcher.dispatch(loadAllConnectedNetworkElementsAsync);
110   },
111   getDistinctLtpsIds: (selectedNetworkElement: string, selectedTimePeriod: string, selectedLtp: string, selectFirstLtp?: Function, resetLTP?: Function) => dispatcher.dispatch(loadDistinctLtpsbyNetworkElementAsync(selectedNetworkElement, selectedTimePeriod, selectedLtp, selectFirstLtp, resetLTP)),
112   setCurrentPanel: (panelId: PanelId) => dispatcher.dispatch(new SetPanelAction(panelId)),
113   timeIntervalChange: (time: PmDataInterval) => dispatcher.dispatch(new TimeChangeAction(time)),
114   changeNode: (nodeId: string) => dispatcher.dispatch((dispatch: Dispatch) => {
115     dispatch(new NavigateToApplication("performanceHistory", nodeId));
116   })
117 });
118
119 export type NetworkElementType = {
120   mountId: string,
121 }
122 const NetworkElementTable = MaterialTable as MaterialTableCtorType<NetworkElementType>;
123
124 type PerformanceHistoryComponentProps = Connect<typeof mapProps, typeof mapDispatcher> & WithStyles<typeof PerformanceHistoryComponentStyles>;
125
126 type PerformanceHistoryComponentState = {
127   selectedNetworkElement: string,
128   selectedTimePeriod: string,
129   selectedLtp: string,
130   showNetworkElementsTable: boolean,
131   showLtps: boolean,
132   showPanels: boolean
133 };
134
135 /**
136 * Represents the component for Performance history application.
137 */
138 class PerformanceHistoryComponent extends React.Component<PerformanceHistoryComponentProps, PerformanceHistoryComponentState>{
139   /**
140   * Initialises this instance
141   */
142   constructor(props: PerformanceHistoryComponentProps) {
143     super(props);
144     this.state = {
145       selectedNetworkElement: "-1",
146       selectedTimePeriod: "15min",
147       selectedLtp: "-1",
148       showNetworkElementsTable: true,
149       showLtps: false,
150       showPanels: false
151     };
152   }
153
154   onTogglePanel = (panelId: PanelId) => {
155     const nextActivePanel = panelId === this.props.activePanel ? null : panelId;
156     this.props.setCurrentPanel(nextActivePanel);
157     switch (nextActivePanel) {
158       case "PerformanceData":
159         this.props.reloadPerformanceData();
160         break;
161       case "ReceiveLevel":
162         this.props.reloadReceiveLevel();
163         break;
164       case "TransmissionPower":
165         this.props.reloadTransmissionPower();
166         break;
167       case "AdaptiveModulation":
168         this.props.reloadAdaptiveModulation();
169         break;
170       case "Temperature":
171         this.props.reloadTemperature();
172         break;
173       case "SINR":
174         this.props.reloadSignalToInterference();
175         break;
176       case "CPD":
177         this.props.reloadCrossPolarDiscrimination();
178         break;
179       default:
180         // do nothing if all panels are closed
181         break;
182     }
183   }
184
185   render(): JSX.Element {
186     const { classes } = this.props;
187     const { activePanel, mountId } = this.props;
188     if (mountId === "") {
189       return (
190         <>
191           <h2>Please select the network element !</h2>
192           <NetworkElementTable idProperty={"mountId"}  rows={ this.props.networkElements }  asynchronus
193             onHandleClick={(event, rowData) => { this.handleNetworkElementSelect(rowData.mountId) }} columns={
194               [{ property: "mountId" }]
195             } />
196         </>
197       )
198     }
199     else {
200       this.handleURLChange(mountId);
201       return (
202         <>
203           <h2>Selected Network Element: { this.state.selectedNetworkElement } </h2>
204           { this.state.showLtps && (
205             <div>
206               <FormControl className={ classes.display }>
207                 <span>
208                   Select LTP
209                 </span>
210                 <Select className={ classes.selectDropdown } value={ this.state.selectedLtp } onChange={ this.handleLtpChange }  >
211                   <MenuItem value={ "-1" }><em>--Select--</em></MenuItem>
212                   { this.props.availableLtps.map(ltp =>
213                     (<MenuItem value={ ltp.key } key={ ltp.key }>{ ltp.key }</MenuItem>)) }
214                 </Select>
215                 <span> Time-Period </span>
216                 <Select className={ classes.selectDropdown } value={ this.state.selectedTimePeriod } onChange={ this.handleTimePeriodChange } >
217                   <MenuItem value={ "15min" }>15min</MenuItem>
218                   <MenuItem value={ "24hours" }>24hours</MenuItem>
219                 </Select>
220               </FormControl>
221               { this.state.showPanels && (
222                 <div>
223                   <Panel activePanel={ activePanel } panelId={ "PerformanceData" } onToggle={ this.onTogglePanel } title={ "Performance Data" }>
224                     <PerformanceData selectedTimePeriod={ this.state.selectedTimePeriod } />
225                   </Panel>
226                   <Panel activePanel={ activePanel } panelId={ "ReceiveLevel" } onToggle={ this.onTogglePanel } title={ "Receive Level" }>
227                     <ReceiveLevel selectedTimePeriod={ this.state.selectedTimePeriod } />
228                   </Panel>
229                   <Panel activePanel={ activePanel } panelId={ "TransmissionPower" } onToggle={ this.onTogglePanel } title={ "Transmission Power" }>
230                     <TransmissionPower selectedTimePeriod={ this.state.selectedTimePeriod } />
231                   </Panel>
232                   <Panel activePanel={ activePanel } panelId={ "AdaptiveModulation" } onToggle={ this.onTogglePanel } title={ "Adaptive Modulation" }>
233                     <AdaptiveModulation selectedTimePeriod={ this.state.selectedTimePeriod } />
234                   </Panel>
235                   <Panel activePanel={ activePanel } panelId={ "Temperature" } onToggle={ this.onTogglePanel } title={ "Temperature" }>
236                     <Temperature selectedTimePeriod={ this.state.selectedTimePeriod } />
237                   </Panel>
238                   <Panel activePanel={ activePanel } panelId={ "SINR" } onToggle={ this.onTogglePanel } title={ "Signal-to-interference-plus-noise ratio (SINR)" }>
239                     <SignalToInterference selectedTimePeriod={ this.state.selectedTimePeriod } />
240                   </Panel>
241                   <Panel activePanel={ activePanel } panelId={ "CPD" } onToggle={ this.onTogglePanel } title={ "Cross Polar Discrimination" }>
242                     <CrossPolarDiscrimination selectedTimePeriod={ this.state.selectedTimePeriod } />
243                   </Panel>
244                 </div>
245               )}
246             </div>
247           )}
248         </>
249       );
250     }
251   };
252
253   public componentDidMount() {
254     this.props.getConnectedNetworkElementsIds();
255     this.props.enableFilterPerformanceData.onToggleFilter();
256     this.props.enableFilterReceiveLevel.onToggleFilter();
257     this.props.enableFilterTransmissionPower.onToggleFilter();
258     this.props.enableFilterTemperature.onToggleFilter();
259     this.props.enableFilterAdaptiveModulation.onToggleFilter();
260     this.props.enableFilterSinr.onToggleFilter();
261     this.props.enableFilterCpd.onToggleFilter();
262   }
263
264   /**
265   * Function which selects the first ltp returned from the database on selection of network element.
266   */
267   private selectFirstLtp = (firstLtp: string) => {
268     this.setState({
269       showPanels: true,
270       selectedLtp: firstLtp
271     });
272     this.preFilterChangeAndReload(this.state.selectedNetworkElement, this.state.selectedTimePeriod, firstLtp);
273   }
274
275   /**
276   * A function which loads the tables based on prefilters defined by network element and ltp on selected time period.
277   */
278   private preFilterChangeAndReload = (networkElement: string, timePeriod: string, ltp: string) => {
279     const preFilter = {
280       "node-name": networkElement,
281       "uuid-interface": ltp
282     };
283     this.props.performanceDataPreActions.onPreFilterChanged(preFilter);
284     this.props.receiveLevelPreActions.onPreFilterChanged(preFilter);
285     this.props.transmissionPowerPreActions.onPreFilterChanged(preFilter);
286     this.props.adaptiveModulationPreActions.onPreFilterChanged(preFilter);
287     this.props.temperaturePreActions.onPreFilterChanged(preFilter);
288     this.props.signalToInterferencePreActions.onPreFilterChanged(preFilter);
289     this.props.crossPolarDiscriminationPreActions.onPreFilterChanged(preFilter);
290
291   }
292
293  /**
294   * Function which handles network element changes.
295   */
296  private handleNetworkElementSelect = (selectedNetworkElement: string) => {
297
298   this.setState({
299     showLtps: true,
300     selectedNetworkElement: selectedNetworkElement,
301     showNetworkElementsTable: false,
302     showPanels: false,
303     selectedLtp: "-1"
304   });
305   this.props.changeNode(selectedNetworkElement);
306   this.props.getDistinctLtpsIds(selectedNetworkElement, this.state.selectedTimePeriod, "-1", this.selectFirstLtp);
307 }
308
309 private handleURLChange = (selectedNetworkElement: string) => {
310   if(selectedNetworkElement !== this.state.selectedNetworkElement) {
311     this.setState({
312       showLtps: true,
313       selectedNetworkElement: selectedNetworkElement,
314       showPanels: false,
315       selectedLtp: "-1"
316     });
317     this.props.getDistinctLtpsIds(selectedNetworkElement, this.state.selectedTimePeriod, "-1", this.selectFirstLtp);
318   }
319 }
320
321 /**
322   * Function which resets the ltps to "--select--" in the state if the passed parameter @ltpNotSelected is true.
323   * @param ltpNotSelected: true, if existing selected is not available in the given time period, else false
324   */
325   private resetLtpDropdown = (ltpNotSelected: boolean) => {
326     if (ltpNotSelected) {
327       this.setState({
328         selectedLtp: "-1",
329       });
330     }
331   }
332
333   /**
334   * Function which handles the time period changes.
335   */
336   private handleTimePeriodChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
337     const selectedTimeInterval = event.target.value === "15min"
338       ? PmDataInterval.pmInterval15Min
339       : PmDataInterval.pmInterval24Hours
340
341     this.setState({
342       selectedTimePeriod: event.target.value,
343     });
344     this.props.timeIntervalChange(selectedTimeInterval);
345     this.props.reloadPerformanceData();
346     this.props.reloadReceiveLevel();
347     this.props.reloadTransmissionPower();
348     this.props.reloadAdaptiveModulation();
349     this.props.reloadTemperature();
350     this.props.reloadSignalToInterference();
351     this.props.reloadCrossPolarDiscrimination();
352     this.props.getDistinctLtpsIds(this.state.selectedNetworkElement, event.target.value, this.state.selectedLtp, undefined, this.resetLtpDropdown);
353     this.preFilterChangeAndReload(this.state.selectedNetworkElement, event.target.value, this.state.selectedLtp);
354   }
355
356   /**
357   * Function which handles the ltp changes.
358   */
359   private handleLtpChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
360     var showPanels: boolean = true;
361     if (event.target.value === "-1") {
362       showPanels = false;
363     }
364     this.setState({
365       showPanels: showPanels,
366       selectedLtp: event.target.value
367     });
368     this.preFilterChangeAndReload(this.state.selectedNetworkElement, this.state.selectedTimePeriod, event.target.value);
369   }
370 }
371
372 const PerformanceHistoryApplication = withStyles(PerformanceHistoryComponentStyles)(connect(mapProps, mapDispatcher)(PerformanceHistoryComponent));
373 export default PerformanceHistoryApplication;