Bug 209
[osm/UI.git] / skyquake / framework / widgets / skyquake_container / eventCenter.jsx
1 /*
2  * 
3  *   Copyright 2016 RIFT.IO Inc
4  *
5  *   Licensed under the Apache License, Version 2.0 (the "License");
6  *   you may not use this file except in compliance with the License.
7  *   You may obtain a copy of the License at
8  *
9  *       http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *   Unless required by applicable law or agreed to in writing, software
12  *   distributed under the License is distributed on an "AS IS" BASIS,
13  *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *   See the License for the specific language governing permissions and
15  *   limitations under the License.
16  *
17  */
18
19  /**
20   * EventCenter module to display a list of events from the system
21   * @module framework/widgets/skyquake_container/EventCenter
22   * @author Kiran Kashalkar <kiran.kashalkar@riftio.com>
23   *
24   */
25
26 import React from 'react';
27 import { Link } from 'react-router';
28 import Utils from 'utils/utils.js';
29 import Crouton from 'react-crouton';
30 import TreeView from 'react-treeview';
31 import _ from 'lodash';
32 import '../../../node_modules/react-treeview/react-treeview.css';
33 import './eventCenter.scss';
34
35 export default class EventCenter extends React.Component {
36         constructor(props) {
37                 super(props);
38                 this.state = {};
39                 this.state.isOpen = false;
40         }
41
42         componentWillReceiveProps(props) {
43                 let stateObject = {};
44
45                 let notificationList = sessionStorage.getItem('notificationList');
46                 let latestNotification = sessionStorage.getItem('latestNotification');
47
48                 if (props.newNotificationEvent && props.newNotificationMsg) {
49                         if (latestNotification) {
50                                 latestNotification = JSON.parse(latestNotification);
51                                 if (!_.isEqual(props.newNotificationMsg, latestNotification)) {
52                                         stateObject.newNotificationEvent = props.newNotificationEvent;
53                                         stateObject.newNotificationMsg = props.newNotificationMsg;
54                                         sessionStorage.setItem('latestNotification', JSON.stringify(stateObject.newNotificationMsg));
55                                 } else {
56                                         stateObject.newNotificationEvent = false;
57                                         stateObject.newNotificationMsg = null;
58                                 }
59                         } else {
60                                 stateObject.newNotificationEvent = true;
61                                 stateObject.newNotificationMsg = props.newNotificationMsg;
62                                 sessionStorage.setItem('latestNotification', JSON.stringify(stateObject.newNotificationMsg));
63                         }
64                 } else {
65                         stateObject.newNotificationEvent = false;
66                         stateObject.newNotificationMsg = null;
67                 }
68
69                 if (notificationList) {
70                         stateObject.notifications = _.merge(notificationList, props.notifications);
71                 } else {
72                         stateObject.notifications = props.notifications;
73                 }
74                 sessionStorage.setItem('notifications', JSON.stringify(stateObject.notifications));
75                 this.setState(stateObject);
76         }
77
78         newNotificationReset = () => {
79         this.setState({
80             newNotificationEvent: false
81         });
82     }
83
84         onClickToggleOpenClose(event) {
85                 this.props.onToggle();
86                 this.setState({
87                         isOpen: !this.state.isOpen
88                 });
89         }
90         constructTree(details) {
91                 let markup = [];
92                 for (let key in details) {
93                         if (typeof(details[key]) == "object") {
94                             let html = (
95                                 <TreeView key={key} nodeLabel={key}>
96                                   {this.constructTree(details[key])}
97                                 </TreeView>
98                             );
99                             markup.push(html);
100                         } else {
101                                 markup.push((<div key={key} className="info">{key} = {details[key].toString()}</div>));
102                         }
103                 }
104                 return markup;
105         }
106
107         getNotificationFields(notification) {
108                 let notificationFields = {};
109                 if (notification) {
110
111                         notificationFields.source = notification.source;
112                         notificationFields.eventTime = notification.eventTime;
113
114                         Object.keys(notification).map((notificationKey) => {
115                                 if (_.indexOf(['source', 'eventTime'], notificationKey) == -1) {
116                                         notificationFields.eventKey = notificationKey;
117                                         notificationFields.details = notification[notificationFields.eventKey];
118                                 }
119                         });
120
121                 }
122                 return notificationFields;
123         }
124
125         render() {
126                 let html;
127                 let displayNotifications = [];
128                 let displayNotificationsTableHead = null;
129
130                 if (this.state.notifications && this.state.notifications.length > 0) {
131                         displayNotificationsTableHead = (
132                                 <thead>
133                                         <tr key='header' className='header'>
134                                                 <th className='source column'> Source Event Stream </th>
135                                                 <th className='timestamp column'> Timestamp </th>
136                                                 <th className='event column'> Event </th>
137                                                 <th className='details column'> Details </th>
138                                         </tr>
139                                 </thead>
140                         );
141                 }
142
143                 this.state.notifications && this.state.notifications.map((notification, notifIndex) => {
144                         let notificationFields = {};
145
146                         notificationFields = this.getNotificationFields(notification);
147
148                         displayNotifications.push(
149                                 <tr key={notifIndex} className='notificationItem'>
150                                         <td className='source column'> {notificationFields.source} </td>
151                                         <td className='timestamp column'> {notificationFields.eventTime} </td>
152                                         <td className='event column'> {notificationFields.eventKey} </td>
153                                         <td className='details column'>
154                                                 <TreeView key={notifIndex + '-detail'} nodeLabel='Event Details'>
155                                                         {this.constructTree(notificationFields.details)}
156                                                 </TreeView>
157                                         </td>
158                                 </tr>
159                         );
160                 });
161
162                 let openedClassName = this.state.isOpen ? 'open' : 'closed';
163                 html = (
164                         <div className={'eventCenter ' + openedClassName}>
165
166                         <div className='notification'>
167                             <Crouton
168                                 id={Date.now()}
169                                 message={this.getNotificationFields(this.state.newNotificationMsg).eventKey +
170                                         ' notification received. Check Event Center for more details.'}
171                                 type={'info'}
172                                 hidden={!(this.state.newNotificationEvent && this.state.newNotificationMsg)}
173                                 onDismiss={this.newNotificationReset}
174                                 timeout={this.props.dismissTimeout}
175                             />
176                         </div>
177                                 <h1 className='title' data-open-close-icon={this.state.isOpen ? 'open' : 'closed'}
178                                         onClick={this.onClickToggleOpenClose.bind(this)}>
179                                         EVENT CENTER
180                                 </h1>
181                                 <div className='notificationListBody'>
182                                         <table className='notificationList'>
183                                                 {displayNotificationsTableHead}
184                                                 <tbody>
185                                                         {displayNotifications}
186                                                 </tbody>
187                                         </table>
188                                 </div>
189                         </div>
190                 );
191
192                 return html;
193         }
194 }
195
196 EventCenter.defaultProps = {
197         dismissTimeout: 3000
198 }