Update odlux
[ccsdk/features.git] / sdnr / wt / odlux / apps / faultApp / src / views / faultApplication.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 { withRouter, RouteComponentProps } from 'react-router-dom';
21
22 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
23 import { faExclamationTriangle } from '@fortawesome/free-solid-svg-icons';
24
25 import { MaterialTable, ColumnType, MaterialTableCtorType } from '../../../../framework/src/components/material-table';
26 import { Panel } from '../../../../framework/src/components/material-ui';
27
28 import { IApplicationStoreState } from '../../../../framework/src/store/applicationStore';
29 import connect, { Connect, IDispatcher } from '../../../../framework/src/flux/connect';
30
31 import { Fault, FaultAlarmNotification } from '../models/fault';
32 import { PanelId } from '../models/panelId';
33
34 import { createCurrentProblemsProperties, createCurrentProblemsActions, currentProblemsReloadAction } from '../handlers/currentProblemsHandler';
35 import { createAlarmLogEntriesProperties, createAlarmLogEntriesActions, alarmLogEntriesReloadAction } from '../handlers/alarmLogEntriesHandler';
36 import { setPanelAction } from '../actions/panelChangeActions';
37 import { Tooltip, IconButton, AppBar, Tabs, Tab } from '@material-ui/core';
38 import RefreshIcon from '@material-ui/icons/Refresh';
39 import ClearStuckAlarmsDialog, { ClearStuckAlarmsDialogMode } from '../components/clearStuckAlarmsDialog';
40
41 const mapProps = (state: IApplicationStoreState) => ({
42   panelId: state.fault.currentOpenPanel,
43   currentProblemsProperties: createCurrentProblemsProperties(state),
44   faultNotifications: state.fault.faultNotifications,
45   alarmLogEntriesProperties: createAlarmLogEntriesProperties(state)
46 });
47
48 const mapDisp = (dispatcher: IDispatcher) => ({
49   currentProblemsActions: createCurrentProblemsActions(dispatcher.dispatch),
50   alarmLogEntriesActions: createAlarmLogEntriesActions(dispatcher.dispatch),
51   reloadCurrentProblems: () => dispatcher.dispatch(currentProblemsReloadAction),
52   reloadAlarmLogEntries: () => dispatcher.dispatch(alarmLogEntriesReloadAction),
53   switchActivePanel: (panelId: PanelId) => {
54     dispatcher.dispatch(setPanelAction(panelId));
55   }
56 });
57
58 type FaultApplicationComponentProps = RouteComponentProps & Connect<typeof mapProps, typeof mapDisp>;
59
60 type FaultApplicationState = {
61   clearAlarmDialogMode: ClearStuckAlarmsDialogMode,
62   stuckAlarms: string[]
63 }
64
65
66 const FaultTable = MaterialTable as MaterialTableCtorType<Fault>;
67 const FaultAlarmNotificationTable = MaterialTable as MaterialTableCtorType<FaultAlarmNotification>;
68
69
70 class FaultApplicationComponent extends React.Component<FaultApplicationComponentProps, FaultApplicationState>{
71
72   /**
73    *
74    */
75   constructor(props: FaultApplicationComponentProps) {
76     super(props);
77     this.state = { clearAlarmDialogMode: ClearStuckAlarmsDialogMode.None, stuckAlarms: [] }
78   }
79
80   onDialogClose = () => {
81     this.setState({ clearAlarmDialogMode: ClearStuckAlarmsDialogMode.None, stuckAlarms: [] })
82   }
83
84   onDialogOpen = () => {
85     const stuckAlarms = [...new Set(this.props.currentProblemsProperties.rows.map(item => item.nodeId))];
86     this.setState({ clearAlarmDialogMode: ClearStuckAlarmsDialogMode.Show, stuckAlarms: stuckAlarms })
87   }
88
89   private onHandleTabChange = (event: React.ChangeEvent<{}>, newValue: PanelId) => {
90     this.props.switchActivePanel(newValue);
91     //this.onToggleTabs(newValue);
92   }
93
94   private onToggleTabs = (panelId: PanelId) => {
95     const nextActivePanel = panelId;
96     this.props.switchActivePanel(nextActivePanel);
97     switch (nextActivePanel) {
98       case 'CurrentProblem':
99         this.props.reloadCurrentProblems();
100         break;
101       case 'AlarmLog':
102         this.props.reloadAlarmLogEntries();
103         break;
104       case 'AlarmNotifications':
105       case null:
106       default:
107         // nothing to do
108         break;
109     }
110   };
111
112
113
114   render(): JSX.Element {
115
116     const refreshButton = {
117       icon: RefreshIcon, tooltip: 'Clear stuck alarms', onClick: this.onDialogOpen
118     };
119     const areFaultsAvailable = this.props.currentProblemsProperties.rows && this.props.currentProblemsProperties.rows.length > 0
120     const customAction = areFaultsAvailable ? [refreshButton] : [];
121
122     const { panelId: activePanelId } = this.props;
123
124     return (
125       <>
126         <AppBar position="static" >
127           <Tabs value={activePanelId} onChange={this.onHandleTabChange} aria-label="fault tabs">
128             <Tab label="Current Problem List" value="CurrentProblem" />
129             <Tab label={`Alarm Notifications (${this.props.faultNotifications.faults.length})`} value="AlarmNotifications" />
130             <Tab label="Alarm Log" value="AlarmLog" />
131           </Tabs>
132         </AppBar>
133         {
134           activePanelId === 'CurrentProblem' && <FaultTable stickyHeader idProperty={'id'} customActionButtons={customAction} columns={[
135             { property: "icon", title: "", type: ColumnType.custom, customControl: this.renderIcon },
136             { property: "timestamp", type: ColumnType.text, title: "Time Stamp" },
137             { property: "nodeId", title: "Node Name", type: ColumnType.text },
138             { property: "counter", title: "Count", type: ColumnType.numeric, width: "100px" },
139             { property: "objectId", title: "Object Id", type: ColumnType.text },
140             { property: "problem", title: "Alarm Type", type: ColumnType.text },
141             { property: "severity", title: "Severity", type: ColumnType.text, width: "140px" },
142           ]} {...this.props.currentProblemsProperties} {...this.props.currentProblemsActions} />
143         }
144         {activePanelId === 'AlarmNotifications' &&
145
146           <FaultAlarmNotificationTable stickyHeader rows={this.props.faultNotifications.faults} asynchronus columns={[
147             { property: "icon", title: "", type: ColumnType.custom, customControl: this.renderIcon },
148             { property: "timeStamp", title: "Time Stamp" },
149             { property: "nodeName", title: "Node Name" },
150             { property: "counter", title: "Count", width: "100px" },
151             { property: "objectId", title: "Object Id" },
152             { property: "problem", title: "Alarm Type" },
153             { property: "severity", title: "Severity", width: "140px" },
154           ]} idProperty={'id'} />
155
156         }
157
158         {activePanelId === 'AlarmLog' && <FaultTable stickyHeader idProperty={'id'} columns={[
159           { property: "icon", title: "", type: ColumnType.custom, customControl: this.renderIcon },
160           { property: "timestamp", title: "Time Stamp" },
161           { property: "nodeId", title: "Node Name" },
162           { property: "counter", title: "Count", type: ColumnType.numeric, width: "100px" },
163           { property: "objectId", title: "Object Id" },
164           { property: "problem", title: "Alarm Type" },
165           { property: "severity", title: "Severity", width: "140px" },
166           { property: "sourceType", title: "Source", width: "140px" },
167         ]} {...this.props.alarmLogEntriesProperties} {...this.props.alarmLogEntriesActions} />
168
169         }
170         {
171           this.state.clearAlarmDialogMode !== ClearStuckAlarmsDialogMode.None && <ClearStuckAlarmsDialog mode={this.state.clearAlarmDialogMode} numberDevices={this.state.stuckAlarms.length} stuckAlarms={this.state.stuckAlarms} onClose={this.onDialogClose} />
172         }
173       </>
174     )
175
176   };
177
178   public componentDidMount() {
179
180     if (this.props.panelId === null) { //don't change tabs, if one is selected already
181       this.onToggleTabs("CurrentProblem");
182     }
183
184     this.props.alarmLogEntriesActions.onToggleFilter();
185     this.props.currentProblemsActions.onToggleFilter();
186   }
187   private renderIcon = (props: { rowData: Fault | FaultAlarmNotification }) => {
188     return (
189       <FontAwesomeIcon icon={faExclamationTriangle} />
190     );
191   };
192
193 }
194
195 export const FaultApplication = withRouter(connect(mapProps, mapDisp)(FaultApplicationComponent));
196 export default FaultApplication;