update from RIFT as of 696b75d2fe9fb046261b08c616f1bcf6c0b54a9b third try
[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 _isEqual from 'lodash/isEqual';
32 import _merge from 'lodash/merge';
33 import _indexOf from 'lodash/indexOf';
34 import _isArray from 'lodash/isArray';
35 import _sortBy from 'lodash/sortBy';
36 import '../../../node_modules/react-treeview/react-treeview.css';
37 import './eventCenter.scss';
38
39 export default class EventCenter extends React.Component {
40         constructor(props) {
41                 super(props);
42                 this.state = {};
43                 this.state.isOpen = false;
44         }
45
46         componentWillReceiveProps(props) {
47                 let stateObject = {};
48
49                 let latestNotification = sessionStorage.getItem('latestNotification');
50
51                 if (props.newNotificationEvent && props.newNotificationMsg) {
52                         if (latestNotification) {
53                                 latestNotification = JSON.parse(latestNotification);
54                                 if (!_isEqual(props.newNotificationMsg, latestNotification)) {
55                                         stateObject.newNotificationEvent = props.newNotificationEvent;
56                                         stateObject.newNotificationMsg = props.newNotificationMsg;
57                                         sessionStorage.setItem('latestNotification', JSON.stringify(stateObject.newNotificationMsg));
58                                 } else {
59                                         stateObject.newNotificationEvent = false;
60                                         stateObject.newNotificationMsg = null;
61                                 }
62                         } else {
63                                 stateObject.newNotificationEvent = true;
64                                 stateObject.newNotificationMsg = props.newNotificationMsg;
65                                 sessionStorage.setItem('latestNotification', JSON.stringify(stateObject.newNotificationMsg));
66                         }
67                 } else {
68                         stateObject.newNotificationEvent = false;
69                         stateObject.newNotificationMsg = null;
70                 }
71                 stateObject.notifications = props.notifications;
72
73                 this.setState(stateObject);
74         }
75
76         newNotificationReset = () => {
77                 this.setState({
78                         newNotificationEvent: false
79                 });
80         }
81
82         onClickToggleOpenClose(event) {
83                 this.props.onToggle();
84                 this.setState({
85                         isOpen: !this.state.isOpen
86                 });
87         }
88         constructTree(details) {
89                 let markup = [];
90                 for (let key in details) {
91                         if (typeof (details[key]) == "object") {
92                                 let html = (
93                                         <TreeView key={key} nodeLabel={key}>
94                                                 {this.constructTree(details[key])}
95                                         </TreeView>
96                                 );
97                                 markup.push(html);
98                         } else {
99                                 markup.push((<div key={key} className="info">{key} = {details[key].toString()}</div>));
100                         }
101                 }
102                 return markup;
103         }
104
105         getNotificationFields(notification) {
106                 let notificationFields = {};
107                 if (notification) {
108
109                         notificationFields.source = notification.source;
110                         notificationFields.eventTime = notification.eventTime;
111
112                         Object.keys(notification).map((notificationKey) => {
113                                 if (_indexOf(['source', 'eventTime'], notificationKey) == -1) {
114                                         notificationFields.eventKey = notificationKey;
115                                         notificationFields.details = notification[notificationFields.eventKey];
116                                 }
117                         });
118
119                 }
120                 return notificationFields;
121         }
122
123         render() {
124                 let html;
125                 let displayNotifications = [];
126                 let displayNotificationsTableHead = null;
127
128                 if (this.state.notifications && this.state.notifications.length > 0) {
129                         displayNotificationsTableHead = (
130                                 <thead>
131                                         <tr key='header' className='header'>
132                                                 <th className='source column'> Source Event Stream </th>
133                                                 <th className='timestamp column'> Timestamp </th>
134                                                 <th className='event column'> Event </th>
135                                                 <th className='details column'> Details </th>
136                                         </tr>
137                                 </thead>
138                         );
139                 }
140
141                 this.state.notifications &&
142                         _isArray(this.state.notifications) &&
143                         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 }