From 889c7fbc0f78eadc302e8849ea7e6cad795e0d6e Mon Sep 17 00:00:00 2001 From: Aijana Schumann Date: Fri, 28 Feb 2020 15:15:26 +0100 Subject: update odlux stage 3 PerformanceApp: Add filter to chart view add scrolling header to tables, add basic validation to editNetworkElementDialog bugfixes Issue-ID: SDNC-1087 Signed-off-by: Aijana Schumann Change-Id: I585bd6cfeb11b867cd630e96e6479170d2f92fe8 --- .../performanceHistoryApp/src/actions/ltpAction.ts | 16 +++++ .../src/actions/toggleActions.ts | 24 ++++++++ .../src/components/adaptiveModulation.tsx | 22 ++++--- .../src/components/chartFilter.tsx | 50 ++++++++++++++++ .../src/components/crossPolarDiscrimination.tsx | 20 ++++--- .../src/components/ltpSelection.tsx | 22 +++++-- .../src/components/performanceData.tsx | 20 +++---- .../src/components/receiveLevel.tsx | 23 +++---- .../src/components/signalToInterference.tsx | 20 ++++--- .../src/components/temperature.tsx | 22 ++++--- .../src/components/toggleContainer.tsx | 70 +++++++++++++++++----- .../src/components/transmissionPower.tsx | 22 ++++--- .../src/handlers/availableLtpsActionHandler.ts | 34 ++++++++++- .../src/handlers/performanceHistoryRootHandler.ts | 48 +++++++++++---- .../src/services/performanceHistoryService.ts | 2 +- .../src/views/performanceHistoryApplication.tsx | 21 +++---- 16 files changed, 330 insertions(+), 106 deletions(-) create mode 100644 sdnr/wt/odlux/apps/performanceHistoryApp/src/components/chartFilter.tsx (limited to 'sdnr/wt/odlux/apps/performanceHistoryApp') diff --git a/sdnr/wt/odlux/apps/performanceHistoryApp/src/actions/ltpAction.ts b/sdnr/wt/odlux/apps/performanceHistoryApp/src/actions/ltpAction.ts index 375617593..a678ed78c 100644 --- a/sdnr/wt/odlux/apps/performanceHistoryApp/src/actions/ltpAction.ts +++ b/sdnr/wt/odlux/apps/performanceHistoryApp/src/actions/ltpAction.ts @@ -50,6 +50,18 @@ export class SetInitialLoadedAction extends BaseAction { } } +export class NoLtpsFoundAction extends BaseAction { + constructor() { + super(); + } +} + +export class ResetLtpsAction extends BaseAction { + constructor() { + super(); + } +} + /** * Represents an asynchronous thunk action to load available distinctLtps by networkElement from the database and set the returned first Ltp as default. @@ -65,6 +77,10 @@ export const loadDistinctLtpsbyNetworkElementAsync = (networkElement: string, se if (distinctLtps) { const ltps = getDistinctLtps(distinctLtps, selectedLtp, selectFirstLtp, resetLtp); dispatch(new AllAvailableLtpsLoadedAction(ltps)); + } else { + if (resetLtp) + resetLtp(); + dispatch(new NoLtpsFoundAction()); } }).catch(error => { dispatch(new AllAvailableLtpsLoadedAction(null, error)); diff --git a/sdnr/wt/odlux/apps/performanceHistoryApp/src/actions/toggleActions.ts b/sdnr/wt/odlux/apps/performanceHistoryApp/src/actions/toggleActions.ts index 1f53a5806..0efaaae92 100644 --- a/sdnr/wt/odlux/apps/performanceHistoryApp/src/actions/toggleActions.ts +++ b/sdnr/wt/odlux/apps/performanceHistoryApp/src/actions/toggleActions.ts @@ -1,3 +1,21 @@ +/** + * ============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 { currentViewType } from "../models/toggleDataType"; @@ -12,4 +30,10 @@ export class ResetAllSubViewsAction extends Action { constructor() { super(); } +} + +export class SetFilterVisibility extends Action { + constructor(public currentView: currentViewType, public isVisible: boolean) { + super(); + } } \ No newline at end of file diff --git a/sdnr/wt/odlux/apps/performanceHistoryApp/src/components/adaptiveModulation.tsx b/sdnr/wt/odlux/apps/performanceHistoryApp/src/components/adaptiveModulation.tsx index c62698630..ca00d8214 100644 --- a/sdnr/wt/odlux/apps/performanceHistoryApp/src/components/adaptiveModulation.tsx +++ b/sdnr/wt/odlux/apps/performanceHistoryApp/src/components/adaptiveModulation.tsx @@ -29,17 +29,19 @@ import { createAdaptiveModulationProperties, createAdaptiveModulationActions } f import { lineChart, sortDataByTimeStamp } from '../utils/chartUtils'; import { addColumnLabels } from '../utils/tableUtils'; import ToggleContainer from './toggleContainer'; -import { SetSubViewAction } from '../actions/toggleActions'; +import { SetSubViewAction, SetFilterVisibility } from '../actions/toggleActions'; const mapProps = (state: IApplicationStoreState) => ({ adaptiveModulationProperties: createAdaptiveModulationProperties(state), - currentView: state.performanceHistory.subViews.adaptiveModulation, - + currentView: state.performanceHistory.subViews.adaptiveModulation.subView, + isFilterVisible: state.performanceHistory.subViews.adaptiveModulation.isFilterVisible, + existingFilter: state.performanceHistory.adaptiveModulation.filter }); const mapDisp = (dispatcher: IDispatcher) => ({ adaptiveModulationActions: createAdaptiveModulationActions(dispatcher.dispatch), setSubView: (value: "chart" | "table") => dispatcher.dispatch(new SetSubViewAction("adaptiveModulation", value)), + toggleFilterButton: (value: boolean) => { dispatcher.dispatch(new SetFilterVisibility("adaptiveModulation", value)) }, }); type AdaptiveModulationComponentProps = RouteComponentProps & Connect & { @@ -52,6 +54,11 @@ const AdaptiveModulationTable = MaterialTable as MaterialTableCtorType{ + + onToggleFilterButton = () => { + this.props.toggleFilterButton(!this.props.isFilterVisible); + } + onChange = (value: "chart" | "table") => { this.props.setSubView(value); } @@ -66,10 +73,7 @@ class AdaptiveModulationComponent extends React.Component { - const suspectIntervalFlag = rowData["suspectIntervalFlag"].toString(); - return
{suspectIntervalFlag}
- } + property: "suspectIntervalFlag", title: "Suspect Interval", type: ColumnType.boolean }]; chartPagedData.datasets.forEach(ds => { @@ -78,9 +82,9 @@ class AdaptiveModulationComponent extends React.Component - + {lineChart(chartPagedData)} - + ); diff --git a/sdnr/wt/odlux/apps/performanceHistoryApp/src/components/chartFilter.tsx b/sdnr/wt/odlux/apps/performanceHistoryApp/src/components/chartFilter.tsx new file mode 100644 index 000000000..280a1dac8 --- /dev/null +++ b/sdnr/wt/odlux/apps/performanceHistoryApp/src/components/chartFilter.tsx @@ -0,0 +1,50 @@ +import * as React from 'react'; +import { makeStyles, TextField, Typography, Select, MenuItem, FormControl, InputLabel } from '@material-ui/core'; + +const styles = makeStyles({ + filterInput: { + marginRight: "15px" + }, + filterContainer: { + marginLeft: "90px" + } +}); + +type filterProps = { isVisible: boolean, onFilterChanged: (property: string, filterTerm: string) => void, filters: any }; +//put chart visibility into redux +const ChartFilter: React.FunctionComponent = (props) => { + + //get filter from redux state (just pass da object?), onfilterchange + const classes = styles(); + + return ( + <> + { + props.isVisible && +
+ props.onFilterChanged("radioSignalId", event.target.value)} InputLabelProps={{ + shrink: true, + }} /> + props.onFilterChanged("scannerId", event.target.value)} InputLabelProps={{ + shrink: true, + }} /> + props.onFilterChanged("timeStamp", event.target.value)} InputLabelProps={{ + shrink: true, + }} /> + + Suspect Interval + + + + + } + + ) + +} + +export default ChartFilter; \ No newline at end of file diff --git a/sdnr/wt/odlux/apps/performanceHistoryApp/src/components/crossPolarDiscrimination.tsx b/sdnr/wt/odlux/apps/performanceHistoryApp/src/components/crossPolarDiscrimination.tsx index 7489757f5..a8c6ed78d 100644 --- a/sdnr/wt/odlux/apps/performanceHistoryApp/src/components/crossPolarDiscrimination.tsx +++ b/sdnr/wt/odlux/apps/performanceHistoryApp/src/components/crossPolarDiscrimination.tsx @@ -28,19 +28,22 @@ import { IDataSet, IDataSetsObject } from '../models/chartTypes'; import { createCrossPolarDiscriminationProperties, createCrossPolarDiscriminationActions } from '../handlers/crossPolarDiscriminationHandler'; import { lineChart, sortDataByTimeStamp } from '../utils/chartUtils'; import { addColumnLabels } from '../utils/tableUtils'; -import { SetSubViewAction } from '../actions/toggleActions'; +import { SetSubViewAction, SetFilterVisibility } from '../actions/toggleActions'; import ToggleContainer from './toggleContainer'; const mapProps = (state: IApplicationStoreState) => ({ crossPolarDiscriminationProperties: createCrossPolarDiscriminationProperties(state), - currentView: state.performanceHistory.subViews.CPD, + currentView: state.performanceHistory.subViews.CPD.subView, + isFilterVisible: state.performanceHistory.subViews.CPD.isFilterVisible, + existingFilter: state.performanceHistory.crossPolarDiscrimination.filter }); const mapDisp = (dispatcher: IDispatcher) => ({ crossPolarDiscriminationActions: createCrossPolarDiscriminationActions(dispatcher.dispatch), setSubView: (value: "chart" | "table") => dispatcher.dispatch(new SetSubViewAction("CPD", value)), + toggleFilterButton: (value: boolean) => { dispatcher.dispatch(new SetFilterVisibility("CPD", value)) }, }); type CrossPolarDiscriminationComponentProps = RouteComponentProps & Connect & { @@ -54,6 +57,10 @@ const CrossPolarDiscriminationTable = MaterialTable as MaterialTableCtorType{ + onToggleFilterButton = () => { + this.props.toggleFilterButton(!this.props.isFilterVisible); + } + onChange = (value: "chart" | "table") => { this.props.setSubView(value); } @@ -69,10 +76,7 @@ class CrossPolarDiscriminationComponent extends React.Component { - const suspectIntervalFlag = rowData["suspectIntervalFlag"].toString(); - return
{suspectIntervalFlag}
- } + property: "suspectIntervalFlag", title: "Suspect Interval", type: ColumnType.boolean } ]; @@ -81,9 +85,9 @@ class CrossPolarDiscriminationComponent extends React.Component - + {lineChart(chartPagedData)} - + ); diff --git a/sdnr/wt/odlux/apps/performanceHistoryApp/src/components/ltpSelection.tsx b/sdnr/wt/odlux/apps/performanceHistoryApp/src/components/ltpSelection.tsx index 8327ec4ed..b0aebd208 100644 --- a/sdnr/wt/odlux/apps/performanceHistoryApp/src/components/ltpSelection.tsx +++ b/sdnr/wt/odlux/apps/performanceHistoryApp/src/components/ltpSelection.tsx @@ -17,7 +17,7 @@ */ import * as React from 'react'; -import { MenuItem, Select, FormControl } from '@material-ui/core'; +import { MenuItem, Select, FormControl, Typography } from '@material-ui/core'; import { makeStyles } from '@material-ui/core/styles'; import { LtpIds } from 'models/availableLtps'; import { Loader } from '../../../../framework/src/components/material-ui'; @@ -43,10 +43,11 @@ const useStyles = makeStyles(theme => ({ "display": "flex", "alignItems": "center", "justifyContent": "center", + flexDirection: "column" } })); -type LtpSelectionProps = { selectedNE: string, finishedLoading: boolean, selectedLtp: string, availableLtps: LtpIds[], onChangeLtp(event: React.ChangeEvent): void, selectedTimePeriod: string, onChangeTimePeriod(event: React.ChangeEvent): void }; +type LtpSelectionProps = { selectedNE: string, error?: string, finishedLoading: boolean, selectedLtp: string, availableLtps: LtpIds[], onChangeLtp(event: React.ChangeEvent): void, selectedTimePeriod: string, onChangeTimePeriod(event: React.ChangeEvent): void }; export const LtpSelection = (props: LtpSelectionProps) => { const classes = useStyles(); @@ -69,18 +70,29 @@ export const LtpSelection = (props: LtpSelectionProps) => { { - !props.finishedLoading && + !props.finishedLoading && !props.error &&

Collecting Data ...

} { - props.selectedLtp === "-1" && props.finishedLoading && + props.finishedLoading && props.error &&
-

Please select a LTP

+

Data couldn't be loaded

+ {props.error}
} + { + props.selectedLtp === "-1" && props.finishedLoading && !props.error && (props.availableLtps.length > 0 ? +
+

Please select a LTP

+
+ : +
+

No performance data found

+
) + } ) } diff --git a/sdnr/wt/odlux/apps/performanceHistoryApp/src/components/performanceData.tsx b/sdnr/wt/odlux/apps/performanceHistoryApp/src/components/performanceData.tsx index d0caa6fd6..0a4f03273 100644 --- a/sdnr/wt/odlux/apps/performanceHistoryApp/src/components/performanceData.tsx +++ b/sdnr/wt/odlux/apps/performanceHistoryApp/src/components/performanceData.tsx @@ -28,16 +28,19 @@ import { createPerformanceDataProperties, createPerformanceDataActions } from '. import { lineChart, sortDataByTimeStamp } from '../utils/chartUtils'; import { addColumnLabels } from '../utils/tableUtils'; import ToggleContainer from './toggleContainer'; -import { SetSubViewAction } from '../actions/toggleActions'; +import { SetSubViewAction, SetFilterVisibility } from '../actions/toggleActions'; const mapProps = (state: IApplicationStoreState) => ({ performanceDataProperties: createPerformanceDataProperties(state), - currentView: state.performanceHistory.subViews.performanceDataSelection, + currentView: state.performanceHistory.subViews.performanceData.subView, + isFilterVisible: state.performanceHistory.subViews.performanceData.isFilterVisible, + existingFilter: state.performanceHistory.performanceData.filter }); const mapDisp = (dispatcher: IDispatcher) => ({ performanceDataActions: createPerformanceDataActions(dispatcher.dispatch), setSubView: (value: "chart" | "table") => dispatcher.dispatch(new SetSubViewAction("performanceData", value)), + toggleFilterButton: (value: boolean) => { dispatcher.dispatch(new SetFilterVisibility("performanceData", value)) } }); type PerformanceDataComponentProps = RouteComponentProps & Connect & { @@ -51,8 +54,8 @@ const PerformanceDataTable = MaterialTable as MaterialTableCtorType{ - onChange = (value: "chart" | "table") => { - this.props.setSubView(value); + onToggleFilterButton = () => { + this.props.toggleFilterButton(!this.props.isFilterVisible); } render(): JSX.Element { @@ -65,10 +68,7 @@ class PerformanceDataComponent extends React.Component { - const suspectIntervalFlag = rowData["suspectIntervalFlag"].toString(); - return
{suspectIntervalFlag}
- } + property: "suspectIntervalFlag", title: "Suspect Interval", type: ColumnType.boolean } ]; @@ -77,9 +77,9 @@ class PerformanceDataComponent extends React.Component - + this.props.toggleFilterButton(!this.props.isFilterVisible)} existingFilter={this.props.existingFilter} onFilterChanged={this.props.performanceDataActions.onFilterChanged} selectedValue={this.props.currentView} showFilter={this.props.isFilterVisible} onChange={this.props.setSubView}> {lineChart(chartPagedData)} - + ); diff --git a/sdnr/wt/odlux/apps/performanceHistoryApp/src/components/receiveLevel.tsx b/sdnr/wt/odlux/apps/performanceHistoryApp/src/components/receiveLevel.tsx index 4b0a835d4..ae729306b 100644 --- a/sdnr/wt/odlux/apps/performanceHistoryApp/src/components/receiveLevel.tsx +++ b/sdnr/wt/odlux/apps/performanceHistoryApp/src/components/receiveLevel.tsx @@ -28,19 +28,20 @@ import { IDataSet, IDataSetsObject } from '../models/chartTypes'; import { createReceiveLevelProperties, createReceiveLevelActions } from '../handlers/receiveLevelHandler'; import { lineChart, sortDataByTimeStamp } from '../utils/chartUtils'; import { addColumnLabels } from '../utils/tableUtils'; -import { SetSubViewAction } from '../actions/toggleActions'; +import { SetSubViewAction, SetFilterVisibility } from '../actions/toggleActions'; import ToggleContainer from './toggleContainer'; const mapProps = (state: IApplicationStoreState) => ({ receiveLevelProperties: createReceiveLevelProperties(state), - currentView: state.performanceHistory.subViews.receiveLevelDataSelection, - + currentView: state.performanceHistory.subViews.receiveLevel.subView, + isFilterVisible: state.performanceHistory.subViews.receiveLevel.isFilterVisible, + existingFilter: state.performanceHistory.receiveLevel.filter }); const mapDisp = (dispatcher: IDispatcher) => ({ receiveLevelActions: createReceiveLevelActions(dispatcher.dispatch), setSubView: (value: "chart" | "table") => dispatcher.dispatch(new SetSubViewAction("receiveLevel", value)), - + toggleFilterButton: (value: boolean) => { dispatcher.dispatch(new SetFilterVisibility("receiveLevel", value)) }, }); type ReceiveLevelComponentProps = RouteComponentProps & Connect & { @@ -54,6 +55,11 @@ const ReceiveLevelTable = MaterialTable as MaterialTableCtorType{ + onToggleFilterButton = () => { + this.props.toggleFilterButton(!this.props.isFilterVisible); + } + + onChange = (value: "chart" | "table") => { this.props.setSubView(value); } @@ -68,10 +74,7 @@ class ReceiveLevelComponent extends React.Component{ { property: "scannerId", title: "Scanner ID", type: ColumnType.text }, { property: "timeStamp", title: "End Time", type: ColumnType.text }, { - property: "suspectIntervalFlag", title: "Suspect Interval", customControl: ({ rowData }) => { - const suspectIntervalFlag = rowData["suspectIntervalFlag"].toString(); - return
{suspectIntervalFlag}
- } + property: "suspectIntervalFlag", title: "Suspect Interval", type: ColumnType.boolean } ]; @@ -81,9 +84,9 @@ class ReceiveLevelComponent extends React.Component{ return ( <> - + {lineChart(chartPagedData)} - + ); diff --git a/sdnr/wt/odlux/apps/performanceHistoryApp/src/components/signalToInterference.tsx b/sdnr/wt/odlux/apps/performanceHistoryApp/src/components/signalToInterference.tsx index ba480d57d..00eba5fe3 100644 --- a/sdnr/wt/odlux/apps/performanceHistoryApp/src/components/signalToInterference.tsx +++ b/sdnr/wt/odlux/apps/performanceHistoryApp/src/components/signalToInterference.tsx @@ -28,17 +28,20 @@ import { IDataSet, IDataSetsObject } from '../models/chartTypes'; import { createSignalToInterferenceProperties, createSignalToInterferenceActions } from '../handlers/signalToInterferenceHandler'; import { lineChart, sortDataByTimeStamp } from '../utils/chartUtils'; import { addColumnLabels } from '../utils/tableUtils'; -import { SetSubViewAction } from '../actions/toggleActions'; +import { SetSubViewAction, SetFilterVisibility } from '../actions/toggleActions'; import ToggleContainer from './toggleContainer'; const mapProps = (state: IApplicationStoreState) => ({ signalToInterferenceProperties: createSignalToInterferenceProperties(state), - currentView: state.performanceHistory.subViews.SINR, + currentView: state.performanceHistory.subViews.SINR.subView, + isFilterVisible: state.performanceHistory.subViews.SINR.isFilterVisible, + existingFilter: state.performanceHistory.signalToInterference.filter }); const mapDisp = (dispatcher: IDispatcher) => ({ signalToInterferenceActions: createSignalToInterferenceActions(dispatcher.dispatch), setSubView: (value: "chart" | "table") => dispatcher.dispatch(new SetSubViewAction("SINR", value)), + toggleFilterButton: (value: boolean) => { dispatcher.dispatch(new SetFilterVisibility("SINR", value)) }, }); type SignalToInterferenceComponentProps = RouteComponentProps & Connect & { @@ -52,6 +55,10 @@ const SignalToInterferenceTable = MaterialTable as MaterialTableCtorType{ + onToggleFilterButton = () => { + this.props.toggleFilterButton(!this.props.isFilterVisible); + } + onChange = (value: "chart" | "table") => { this.props.setSubView(value); } @@ -67,10 +74,7 @@ class SignalToInterferenceComponent extends React.Component { - const suspectIntervalFlag = rowData["suspectIntervalFlag"].toString(); - return
{suspectIntervalFlag}
- } + property: "suspectIntervalFlag", title: "Suspect Interval", type: ColumnType.boolean } ]; @@ -79,9 +83,9 @@ class SignalToInterferenceComponent extends React.Component - + {lineChart(chartPagedData)} - diff --git a/sdnr/wt/odlux/apps/performanceHistoryApp/src/components/temperature.tsx b/sdnr/wt/odlux/apps/performanceHistoryApp/src/components/temperature.tsx index 28f75d84c..c0d12ee47 100644 --- a/sdnr/wt/odlux/apps/performanceHistoryApp/src/components/temperature.tsx +++ b/sdnr/wt/odlux/apps/performanceHistoryApp/src/components/temperature.tsx @@ -29,16 +29,20 @@ import { createTemperatureProperties, createTemperatureActions } from '../handle import { lineChart, sortDataByTimeStamp } from '../utils/chartUtils'; import { addColumnLabels } from '../utils/tableUtils'; import ToggleContainer from './toggleContainer'; -import { SetSubViewAction } from '../actions/toggleActions'; +import { SetSubViewAction, SetFilterVisibility } from '../actions/toggleActions'; const mapProps = (state: IApplicationStoreState) => ({ temperatureProperties: createTemperatureProperties(state), - currentView: state.performanceHistory.subViews.temperatur, + currentView: state.performanceHistory.subViews.temperatur.subView, + isFilterVisible: state.performanceHistory.subViews.temperatur.isFilterVisible, + existingFilter: state.performanceHistory.temperature.filter }); const mapDisp = (dispatcher: IDispatcher) => ({ temperatureActions: createTemperatureActions(dispatcher.dispatch), setSubView: (value: "chart" | "table") => dispatcher.dispatch(new SetSubViewAction("Temp", value)), + toggleFilterButton: (value: boolean) => { dispatcher.dispatch(new SetFilterVisibility("Temp", value)) }, + }); type TemperatureComponentProps = RouteComponentProps & Connect & { @@ -52,6 +56,11 @@ const TemperatureTable = MaterialTable as MaterialTableCtorType{ + onToggleFilterButton = () => { + this.props.toggleFilterButton(!this.props.isFilterVisible); + } + + onChange = (value: "chart" | "table") => { this.props.setSubView(value); } @@ -66,10 +75,7 @@ class TemperatureComponent extends React.Component{ { property: "scannerId", title: "Scanner ID", type: ColumnType.text }, { property: "timeStamp", title: "End Time", type: ColumnType.text }, { - property: "suspectIntervalFlag", title: "Suspect Interval", customControl: ({ rowData }) => { - const suspectIntervalFlag = rowData["suspectIntervalFlag"].toString(); - return
{suspectIntervalFlag}
- } + property: "suspectIntervalFlag", title: "Suspect Interval", type: ColumnType.boolean } ]; @@ -79,9 +85,9 @@ class TemperatureComponent extends React.Component{ return ( <> - + {lineChart(chartPagedData)} - + ); diff --git a/sdnr/wt/odlux/apps/performanceHistoryApp/src/components/toggleContainer.tsx b/sdnr/wt/odlux/apps/performanceHistoryApp/src/components/toggleContainer.tsx index 97a2006f7..618dddfc8 100644 --- a/sdnr/wt/odlux/apps/performanceHistoryApp/src/components/toggleContainer.tsx +++ b/sdnr/wt/odlux/apps/performanceHistoryApp/src/components/toggleContainer.tsx @@ -23,16 +23,34 @@ import BarChartIcon from '@material-ui/icons/BarChart'; import TableChartIcon from '@material-ui/icons/TableChart'; import { makeStyles } from '@material-ui/core'; import Tooltip from '@material-ui/core/Tooltip'; +import ChartFilter from './chartFilter' +import FilterListIcon from '@material-ui/icons/FilterList'; const styles = makeStyles({ - toggleButton: { + toggleButtonContainer: { + display: "flex", alignItems: "center", justifyContent: "center", padding: "10px", + }, + subViewGroup: { + padding: "10px" + }, + filterGroup: { + marginLeft: "10px" } }); -type toggleProps = { selectedValue: string, onChange(value: string): void }; +type filterType = { + onRefresh: () => void; + onHandleRequestSort: (orderBy: string) => void; + onToggleFilter: () => void; + onFilterChanged: (property: string, filterTerm: string) => void; + onHandleChangePage: (page: number) => void; + onHandleChangeRowsPerPage: (rowsPerPage: number | null) => void; +}; + +type toggleProps = { selectedValue: string, onChange(value: string): void, showFilter: boolean, onToggleFilterButton(): void, onFilterChanged: (property: string, filterTerm: string) => void, existingFilter: any }; const ToggleContainer: React.FunctionComponent = (props) => { @@ -44,22 +62,46 @@ const ToggleContainer: React.FunctionComponent = (props) => { } }; + const handleFilterChange = (event: React.MouseEvent, newView: string) => { + props.onToggleFilterButton(); + }; + const children = React.Children.toArray(props.children); + //hide filter if visible + table + //put current name into state, let container handle stuff itelf, register for togglestate, get right via set name + return ( <> - - - - - - - - - - - - +
+ + + + + + + + + + + + + + + + + + + + + + +
+ { + props.selectedValue === "chart" && + + + } {props.selectedValue === "chart" ? children[0] : props.selectedValue === "table" && children[1]} ); diff --git a/sdnr/wt/odlux/apps/performanceHistoryApp/src/components/transmissionPower.tsx b/sdnr/wt/odlux/apps/performanceHistoryApp/src/components/transmissionPower.tsx index 6fe66d2b5..d89aca052 100644 --- a/sdnr/wt/odlux/apps/performanceHistoryApp/src/components/transmissionPower.tsx +++ b/sdnr/wt/odlux/apps/performanceHistoryApp/src/components/transmissionPower.tsx @@ -28,17 +28,22 @@ import { IDataSet, IDataSetsObject } from '../models/chartTypes'; import { createTransmissionPowerProperties, createTransmissionPowerActions } from '../handlers/transmissionPowerHandler'; import { lineChart, sortDataByTimeStamp } from '../utils/chartUtils'; import { addColumnLabels } from '../utils/tableUtils'; -import { SetSubViewAction } from '../actions/toggleActions'; +import { SetSubViewAction, SetFilterVisibility } from '../actions/toggleActions'; import ToggleContainer from './toggleContainer'; const mapProps = (state: IApplicationStoreState) => ({ transmissionPowerProperties: createTransmissionPowerProperties(state), - currentView: state.performanceHistory.subViews.transmissionPower, + currentView: state.performanceHistory.subViews.transmissionPower.subView, + isFilterVisible: state.performanceHistory.subViews.transmissionPower.isFilterVisible, + existingFilter: state.performanceHistory.transmissionPower.filter }); const mapDisp = (dispatcher: IDispatcher) => ({ transmissionPowerActions: createTransmissionPowerActions(dispatcher.dispatch), setSubView: (value: "chart" | "table") => dispatcher.dispatch(new SetSubViewAction("transmissionPower", value)), + toggleFilterButton: (value: boolean) => { dispatcher.dispatch(new SetFilterVisibility("transmissionPower", value)) }, + + }); type TransmissionPowerComponentProps = RouteComponentProps & Connect & { @@ -52,6 +57,10 @@ const TransmissionPowerTable = MaterialTable as MaterialTableCtorType{ + onToggleFilterButton = () => { + this.props.toggleFilterButton(!this.props.isFilterVisible); + } + onChange = (value: "chart" | "table") => { this.props.setSubView(value); } @@ -67,10 +76,7 @@ class TransmissionPowerComponent extends React.Component { - const suspectIntervalFlag = rowData["suspectIntervalFlag"].toString(); - return
{suspectIntervalFlag}
- } + property: "suspectIntervalFlag", title: "Suspect Interval", type: ColumnType.boolean } ]; @@ -80,9 +86,9 @@ class TransmissionPowerComponent extends React.Component - + {lineChart(chartPagedData)} - + ); diff --git a/sdnr/wt/odlux/apps/performanceHistoryApp/src/handlers/availableLtpsActionHandler.ts b/sdnr/wt/odlux/apps/performanceHistoryApp/src/handlers/availableLtpsActionHandler.ts index fd137fe37..4605efdb0 100644 --- a/sdnr/wt/odlux/apps/performanceHistoryApp/src/handlers/availableLtpsActionHandler.ts +++ b/sdnr/wt/odlux/apps/performanceHistoryApp/src/handlers/availableLtpsActionHandler.ts @@ -21,6 +21,8 @@ import { AllAvailableLtpsLoadedAction, LoadAllAvailableLtpsAction, SetInitialLoadedAction, + NoLtpsFoundAction, + ResetLtpsAction, } from '../actions/ltpAction'; import { LtpIds } from '../models/availableLtps'; @@ -29,12 +31,14 @@ export interface IAvailableLtpsState { distinctLtps: LtpIds[]; busy: boolean; loadedOnce: boolean; + error: string | undefined; } const ltpListStateInit: IAvailableLtpsState = { distinctLtps: [], busy: false, - loadedOnce: false + loadedOnce: false, + error: undefined }; export const availableLtpsActionHandler: IActionHandler = (state = ltpListStateInit, action) => { @@ -51,8 +55,16 @@ export const availableLtpsActionHandler: IActionHandler = ( ...state, distinctLtps: action.availableLtps, busy: false, + error: undefined, loadedOnce: true }; + } else if (action.error) { + state = { + ...state, + busy: false, + loadedOnce: true, + error: action.error + } } } else if (action instanceof SetInitialLoadedAction) { @@ -60,7 +72,25 @@ export const availableLtpsActionHandler: IActionHandler = ( ...state, loadedOnce: action.initialLoaded }; - } else { + } else if (action instanceof NoLtpsFoundAction) { + state = { + ...state, + busy: false, + error: undefined, + loadedOnce: true, + distinctLtps: [] + } + } else if (action instanceof ResetLtpsAction) { + state = { + ...state, + busy: false, + error: undefined, + loadedOnce: false, + distinctLtps: [] + } + } + + else { state = { ...state, busy: false diff --git a/sdnr/wt/odlux/apps/performanceHistoryApp/src/handlers/performanceHistoryRootHandler.ts b/sdnr/wt/odlux/apps/performanceHistoryApp/src/handlers/performanceHistoryRootHandler.ts index e57f3860c..6b9081502 100644 --- a/sdnr/wt/odlux/apps/performanceHistoryApp/src/handlers/performanceHistoryRootHandler.ts +++ b/sdnr/wt/odlux/apps/performanceHistoryApp/src/handlers/performanceHistoryRootHandler.ts @@ -37,8 +37,8 @@ import { IAvailableLtpsState, availableLtpsActionHandler } from './availableLtps import { PmDataInterval } from '../models/performanceDataType'; import { TimeChangeAction } from '../actions/timeChangeAction'; import { UpdateMountId } from '../actions/deviceListActions'; -import { SetSubViewAction, ResetAllSubViewsAction } from '../actions/toggleActions'; -import { SubTabType } from '../models/toggleDataType'; +import { SetSubViewAction, ResetAllSubViewsAction, SetFilterVisibility } from '../actions/toggleActions'; +import { SubTabType, currentViewType } from '../models/toggleDataType'; export interface IPerformanceHistoryStoreState { nodeId: string; @@ -81,24 +81,46 @@ const currentPMDataIntervalHandler: IActionHandler = (state = Pm return state; } +type filterableSubview = { subView: SubTabType, isFilterVisible: boolean }; +type toggleViewDataType = { currentSubView: currentViewType, performanceData: filterableSubview, receiveLevel: filterableSubview, transmissionPower: filterableSubview, adaptiveModulation: filterableSubview, temperatur: filterableSubview, SINR: filterableSubview, CPD: filterableSubview }; -type toggleViewDataType = { performanceDataSelection: SubTabType, receiveLevelDataSelection: SubTabType, transmissionPower: SubTabType, adaptiveModulation: SubTabType, temperatur: SubTabType, SINR: SubTabType, CPD: SubTabType }; - -const toogleViewDataHandler: IActionHandler = (state = { performanceDataSelection: "chart", receiveLevelDataSelection: "chart", adaptiveModulation: "chart", transmissionPower: "chart", temperatur: "chart", SINR: "chart", CPD: "chart" }, action) => { +const toogleViewDataHandler: IActionHandler = (state = { currentSubView: "performanceData", performanceData: { subView: "chart", isFilterVisible: true }, receiveLevel: { subView: "chart", isFilterVisible: true }, adaptiveModulation: { subView: "chart", isFilterVisible: true }, transmissionPower: { subView: "chart", isFilterVisible: true }, temperatur: { subView: "chart", isFilterVisible: true }, SINR: { subView: "chart", isFilterVisible: true }, CPD: { subView: "chart", isFilterVisible: true } }, action) => { if (action instanceof SetSubViewAction) { switch (action.currentView) { - case "performanceData": state = { ...state, performanceDataSelection: action.selectedTab }; break; - case "adaptiveModulation": state = { ...state, adaptiveModulation: action.selectedTab }; break; - case "receiveLevel": state = { ...state, receiveLevelDataSelection: action.selectedTab }; break; - case "transmissionPower": state = { ...state, transmissionPower: action.selectedTab }; break; - case "Temp": state = { ...state, temperatur: action.selectedTab }; break; - case "SINR": state = { ...state, SINR: action.selectedTab }; break; - case "CPD": state = { ...state, CPD: action.selectedTab }; break; + case "performanceData": state = { ...state, performanceData: { ...state.performanceData, subView: action.selectedTab } }; break; + case "adaptiveModulation": state = { ...state, adaptiveModulation: { ...state.adaptiveModulation, subView: action.selectedTab } }; break; + case "receiveLevel": state = { ...state, receiveLevel: { ...state.receiveLevel, subView: action.selectedTab } }; break; + case "transmissionPower": state = { ...state, transmissionPower: { ...state.transmissionPower, subView: action.selectedTab } }; break; + case "Temp": state = { ...state, temperatur: { ...state.temperatur, subView: action.selectedTab } }; break; + case "SINR": state = { ...state, SINR: { ...state.SINR, subView: action.selectedTab } }; break; + case "CPD": state = { ...state, CPD: { ...state.CPD, subView: action.selectedTab } }; break; + } + } + else if (action instanceof SetFilterVisibility) { + switch (action.currentView) { + case "performanceData": state = { + ...state, performanceData: { ...state.performanceData, isFilterVisible: action.isVisible } + }; break; + case "adaptiveModulation": state = { ...state, adaptiveModulation: { ...state.performanceData, isFilterVisible: action.isVisible } }; break; + case "receiveLevel": state = { ...state, receiveLevel: { ...state.receiveLevel, isFilterVisible: action.isVisible } }; break; + case "transmissionPower": state = { ...state, transmissionPower: { ...state.transmissionPower, isFilterVisible: action.isVisible } }; break; + case "Temp": state = { ...state, temperatur: { ...state.temperatur, isFilterVisible: action.isVisible } }; break; + case "SINR": state = { ...state, SINR: { ...state.SINR, isFilterVisible: action.isVisible } }; break; + case "CPD": state = { ...state, CPD: { ...state.CPD, isFilterVisible: action.isVisible } }; break; } + } else if (action instanceof ResetAllSubViewsAction) { - state = { performanceDataSelection: "chart", adaptiveModulation: "chart", receiveLevelDataSelection: "chart", transmissionPower: "chart", temperatur: "chart", SINR: "chart", CPD: "chart" } + state = { + ...state, performanceData: { ...state.performanceData, subView: "chart" }, + adaptiveModulation: { ...state.adaptiveModulation, subView: "chart" }, + receiveLevel: { ...state.receiveLevel, subView: "chart" }, + transmissionPower: { ...state.transmissionPower, subView: "chart" }, + temperatur: { ...state.temperatur, subView: "chart" }, + SINR: { ...state.SINR, subView: "chart" }, + CPD: { ...state.CPD, subView: "chart" } + } } return state; diff --git a/sdnr/wt/odlux/apps/performanceHistoryApp/src/services/performanceHistoryService.ts b/sdnr/wt/odlux/apps/performanceHistoryApp/src/services/performanceHistoryService.ts index 2b03d1c2e..685859850 100644 --- a/sdnr/wt/odlux/apps/performanceHistoryApp/src/services/performanceHistoryService.ts +++ b/sdnr/wt/odlux/apps/performanceHistoryApp/src/services/performanceHistoryService.ts @@ -53,7 +53,7 @@ class PerformanceService { } const result = await requestRest>(path, { method: "POST", body: JSON.stringify(convertPropertyNames({ input: query }, replaceUpperCase)) }); - return result && result.output && result.output.data.map(ne => ({ key: ne })) || null; + return result && result.output && result.output.data && result.output.data.map(ne => ({ key: ne })) || null; } diff --git a/sdnr/wt/odlux/apps/performanceHistoryApp/src/views/performanceHistoryApplication.tsx b/sdnr/wt/odlux/apps/performanceHistoryApp/src/views/performanceHistoryApplication.tsx index 4984e80c3..4a1c654fb 100644 --- a/sdnr/wt/odlux/apps/performanceHistoryApp/src/views/performanceHistoryApplication.tsx +++ b/sdnr/wt/odlux/apps/performanceHistoryApp/src/views/performanceHistoryApplication.tsx @@ -39,7 +39,7 @@ import SignalToInterference from '../components/signalToInterference'; import CrossPolarDiscrimination from '../components/crossPolarDiscrimination'; import { loadAllDeviceListAsync } from '../actions/deviceListActions'; import { TimeChangeAction } from '../actions/timeChangeAction'; -import { loadDistinctLtpsbyNetworkElementAsync, SetInitialLoadedAction } from '../actions/ltpAction'; +import { loadDistinctLtpsbyNetworkElementAsync, ResetLtpsAction } from '../actions/ltpAction'; import { SetPanelAction } from '../actions/panelChangeActions'; import { createPerformanceDataPreActions, performanceDataReloadAction, createPerformanceDataActions } from '../handlers/performanceDataHandler'; import { createReceiveLevelPreActions, receiveLevelReloadAction, createReceiveLevelActions } from '../handlers/receiveLevelHandler'; @@ -69,7 +69,8 @@ const mapProps = (state: IApplicationStoreState) => ({ activePanel: state.performanceHistory.currentOpenPanel, availableLtps: state.performanceHistory.ltps.distinctLtps, networkElements: state.performanceHistory.networkElements.deviceList, - initialLoaded: state.performanceHistory.ltps.loadedOnce + initialLoaded: state.performanceHistory.ltps.loadedOnce, + error: state.performanceHistory.ltps.error }); const mapDispatcher = (dispatcher: IDispatcher) => ({ @@ -103,7 +104,7 @@ const mapDispatcher = (dispatcher: IDispatcher) => ({ changeNode: (nodeId: string) => dispatcher.dispatch((dispatch: Dispatch) => { dispatch(new NavigateToApplication("performanceHistory", nodeId)); }), - setInitialLoaded: (isLoaded: boolean) => dispatcher.dispatch((dispatch: Dispatch) => { dispatch(new SetInitialLoadedAction(isLoaded)); }), + resetLtps: () => dispatcher.dispatch((dispatch: Dispatch) => { dispatch(new ResetLtpsAction()); }), resetSubViews: () => dispatcher.dispatch(new ResetAllSubViewsAction()) }); @@ -138,7 +139,7 @@ class PerformanceHistoryComponent extends React.Component - { this.handleNetworkElementSelect(rowData.nodeId) }} columns={ [{ property: "nodeId", title: "Node Name" }] } /> @@ -232,7 +233,7 @@ class PerformanceHistoryComponent extends React.Component {this.state.showLtps && - @@ -293,6 +294,9 @@ class PerformanceHistoryComponent extends React.Component