Merge "YANG Model update for A1 Adapter"
[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 } 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   activePanel: 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   setCurrentPanel: (panelId: PanelId) => dispatcher.dispatch(new SetPanelAction(panelId)),
54 });
55
56 type FaultApplicationComponentProps = RouteComponentProps & Connect<typeof mapProps, typeof mapDisp>;
57
58 type FaultApplicationState = {
59   clearAlarmDialogMode: ClearStuckAlarmsDialogMode,
60   stuckAlarms: string[]
61 }
62
63
64 const FaultTable = MaterialTable as MaterialTableCtorType<Fault>;
65 const FaultAlarmNotificationTable = MaterialTable as MaterialTableCtorType<FaultAlarmNotification>;
66
67
68 class FaultApplicationComponent extends React.Component<FaultApplicationComponentProps, FaultApplicationState>{
69
70   /**
71    *
72    */
73   constructor(props: FaultApplicationComponentProps) {
74     super(props);
75     this.state = { clearAlarmDialogMode: ClearStuckAlarmsDialogMode.None, stuckAlarms: [] }
76   }
77
78   onDialogClose = () => {
79     this.setState({ clearAlarmDialogMode: ClearStuckAlarmsDialogMode.None, stuckAlarms: [] })
80   }
81
82   onDialogOpen = () => {
83     const stuckAlarms = [...new Set(this.props.currentProblemsProperties.rows.map(item => item.nodeId))];
84     this.setState({ clearAlarmDialogMode: ClearStuckAlarmsDialogMode.Show, stuckAlarms: stuckAlarms })
85   }
86
87
88
89   render(): JSX.Element {
90
91     const refreshButton = {
92       icon: RefreshIcon, tooltip: 'Clear stuck alarms', onClick: this.onDialogOpen
93     };
94     const areFaultsAvailable = this.props.currentProblemsProperties.rows && this.props.currentProblemsProperties.rows.length > 0
95     const customAction = areFaultsAvailable ? [refreshButton] : [];
96
97     const { activePanel } = this.props;
98
99     const onTogglePanel = (panelId: PanelId) => {
100       const nextActivePanel = panelId === this.props.activePanel ? null : panelId;
101       this.props.setCurrentPanel(nextActivePanel);
102
103       switch (nextActivePanel) {
104         case 'CurrentProblem':
105           this.props.reloadCurrentProblems();
106           break;
107         case 'AlarmLog':
108           this.props.reloadAlarmLogEntries();
109           break;
110         case 'AlarmNotifications':
111         case null:
112         default:
113           // nothing to do
114           break;
115       }
116     };
117
118     return (
119       <>
120         <Panel activePanel={activePanel} panelId={'CurrentProblem'} onToggle={onTogglePanel} title={'Current Problem List'}>
121           <FaultTable idProperty={'id'} customActionButtons={customAction} columns={[
122             { property: "icon", title: "", type: ColumnType.custom, customControl: this.renderIcon },
123             { property: "timestamp", type: ColumnType.text, title: "Time Stamp" },
124             { property: "nodeId", title: "Node Name", type: ColumnType.text },
125             { property: "counter", title: "Count", type: ColumnType.numeric, width: "100px" },
126             { property: "objectId", title: "Object Id", type: ColumnType.text },
127             { property: "problem", title: "Alarm Type", type: ColumnType.text },
128             { property: "severity", title: "Severity", type: ColumnType.text, width: "140px" },
129           ]} {...this.props.currentProblemsProperties} {...this.props.currentProblemsActions} />
130         </Panel>
131         <Panel activePanel={activePanel} panelId={'AlarmNotifications'} onToggle={onTogglePanel} title={`Alarm Notifications ${this.props.faultNotifications.faults.length} since ${this.props.faultNotifications.since}`}>
132           <FaultAlarmNotificationTable rows={this.props.faultNotifications.faults} asynchronus columns={[
133             { property: "icon", title: "", type: ColumnType.custom, customControl: this.renderIcon },
134             { property: "timeStamp", title: "Time Stamp" },
135             { property: "nodeName", title: "Node Name" },
136             { property: "counter", title: "Count", width: "100px" },
137             { property: "objectId", title: "Object Id" },
138             { property: "problem", title: "Alarm Type" },
139             { property: "severity", title: "Severity", width: "140px" },
140           ]} idProperty={'id'} />
141         </Panel>
142         <Panel activePanel={activePanel} panelId={'AlarmLog'} onToggle={onTogglePanel} title={'Alarm Log'}>
143           <FaultTable idProperty={'id'} columns={[
144             { property: "icon", title: "", type: ColumnType.custom, customControl: this.renderIcon },
145             { property: "timestamp", title: "Time Stamp" },
146             { property: "nodeId", title: "Node Name" },
147             { property: "counter", title: "Count", type: ColumnType.numeric, width: "100px" },
148             { property: "objectId", title: "Object Id" },
149             { property: "problem", title: "Alarm Type" },
150             { property: "severity", title: "Severity", width: "140px" },
151             { property: "sourceType", title: "Source", width: "140px" },
152           ]} {...this.props.alarmLogEntriesProperties} {...this.props.alarmLogEntriesActions} />
153         </Panel>
154         {
155           this.state.clearAlarmDialogMode !== ClearStuckAlarmsDialogMode.None && <ClearStuckAlarmsDialog mode={this.state.clearAlarmDialogMode} numberDevices={this.state.stuckAlarms.length} stuckAlarms={this.state.stuckAlarms} onClose={this.onDialogClose} />
156
157         }
158
159       </>
160     );
161   };
162
163   public componentDidMount() {
164     this.props.alarmLogEntriesActions.onToggleFilter();
165     this.props.currentProblemsActions.onToggleFilter();
166   }
167   private renderIcon = (props: { rowData: Fault | FaultAlarmNotification }) => {
168     return (
169       <FontAwesomeIcon icon={faExclamationTriangle} />
170     );
171   };
172
173 }
174
175 export const FaultApplication = withRouter(connect(mapProps, mapDisp)(FaultApplicationComponent));
176 export default FaultApplication;