Project UI updates and bug fixes
[osm/UI.git] / skyquake / framework / widgets / skyquake_container / skyquakeContainerStore.js
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 //This will reach out to the global routes endpoint
19
20 import Alt from './skyquakeAltInstance.js';
21 import SkyquakeContainerSource from './skyquakeContainerSource.js';
22 import SkyquakeContainerActions from './skyquakeContainerActions';
23 let Utils = require('utils/utils.js');
24 import _ from 'lodash';
25 //Temporary, until api server is on same port as webserver
26 var rw = require('utils/rw.js');
27 var API_SERVER = rw.getSearchParams(window.location).api_server;
28 var UPLOAD_SERVER = rw.getSearchParams(window.location).upload_server;
29
30 class SkyquakeContainerStore {
31 constructor() {
32 this.currentPlugin = getCurrentPlugin();
33 this.nav = {};
34 this.notifications = [];
35 this.socket = null;
36 this.projects = [];
37 this.user = {};
38 //Notification defaults
39 this.notificationMessage = '';
40 this.displayNotification = false;
41 this.notificationType = 'error';
42 //Screen Loader default
43 this.displayScreenLoader = false;
44 this.bindActions(SkyquakeContainerActions);
45 this.exportAsync(SkyquakeContainerSource);
46
47
48 this.exportPublicMethods({
49 // getNav: this.getNav
50 });
51
52 }
53 getSkyquakeNavSuccess = (data) => {
54 var self = this;
55 this.setState({
56 nav: decorateAndTransformNav(data, self.currentPlugin)
57 })
58 }
59
60 closeSocket = () => {
61 if (this.socket) {
62 window.multiplexer.channel(this.channelId).close();
63 }
64 this.setState({
65 socket: null
66 });
67 }
68 //Remove once logging plugin is implemented
69 getSysLogViewerURLSuccess(data){
70 window.open(data.url);
71 }
72 getSysLogViewerURLError(data){
73 console.log('failed', data)
74 }
75
76 openNotificationsSocketLoading = () => {
77 this.setState({
78 isLoading: true
79 })
80 }
81
82 openNotificationsSocketSuccess = (data) => {
83 var self = this;
84
85 let connection = data.connection;
86 let streamSource = data.streamSource;
87 console.log('Success opening notification socket for stream ', streamSource);
88
89 let ws = window.multiplexer.channel(connection);
90
91 if (!connection) return;
92 self.setState({
93 socket: ws.ws,
94 isLoading: false,
95 channelId: connection
96 });
97
98 ws.onmessage = (socket) => {
99 try {
100 var data = JSON.parse(socket.data);
101 if (!data.notification) {
102 console.warn('No notification in the received payload: ', data);
103 } else {
104 // Temp to test before adding multi-sources
105 data.notification.source = streamSource;
106 if (_.indexOf(self.notifications, data.notification) == -1) {
107 // newly appreared event.
108 // Add to the notifications list and setState
109 self.notifications.unshift(data.notification);
110 self.setState({
111 newNotificationEvent: true,
112 newNotificationMsg: data.notification,
113 notifications: self.notifications,
114 isLoading: false
115 });
116 }
117 }
118 } catch(e) {
119 console.log('Error in parsing data on notification socket');
120 }
121 };
122
123 ws.onclose = () => {
124 self.closeSocket();
125 };
126 }
127
128 openNotificationsSocketError = (data) => {
129 console.log('Error opening notification socket', data);
130 }
131
132 getEventStreamsLoading = () => {
133 this.setState({
134 isLoading: true
135 });
136 }
137
138 getEventStreamsSuccess = (streams) => {
139 console.log('Found streams: ', streams);
140 let self = this;
141
142 streams['ietf-restconf-monitoring:streams'] &&
143 streams['ietf-restconf-monitoring:streams']['stream'] &&
144 streams['ietf-restconf-monitoring:streams']['stream'].map((stream) => {
145 stream['access'] && stream['access'].map((streamLocation) => {
146 if (streamLocation['encoding'] == 'ws_json') {
147 setTimeout(() => {
148 self.getInstance().openNotificationsSocket(streamLocation['location'], stream['name']);
149 }, 0);
150 }
151 })
152 })
153
154 this.setState({
155 isLoading: true,
156 streams: streams
157 })
158 }
159
160 getEventStreamsError = (error) => {
161 console.log('Failed to get streams object');
162 this.setState({
163 isLoading: false
164 })
165 }
166
167 openProjectSocketSuccess = (connection) => {
168 var self = this;
169 var ws = window.multiplexer.channel(connection);
170 if (!connection) return;
171 self.setState({
172 socket: ws.ws,
173 channelId: connection
174 });
175 ws.onmessage = function(socket) {
176 try {
177 var data = JSON.parse(socket.data);
178 Utils.checkAuthentication(data.statusCode, function() {
179 self.closeSocket();
180 });
181
182 self.setState({
183 projects: data.project
184 });
185 } catch(e) {
186 console.log('HIT an exception in openProjectSocketSuccess', e);
187 }
188 };
189 }
190 getUserProfileSuccess = (user) => {
191 this.setState({user})
192 }
193 //Notifications
194 showNotification = (data) => {
195 let state = {
196 displayNotification: true,
197 notificationMessage: data,
198 notificationType: 'error',
199 displayScreenLoader: false
200 }
201 if(typeof(data) == 'string') {
202
203 } else {
204 state.notificationMessage = data.msg;
205 if(data.type) {
206 state.notificationType = data.type;
207 }
208 }
209 this.setState(state);
210 }
211 hideNotification = () => {
212 this.setState({
213 displayNotification: false
214 })
215 }
216 //ScreenLoader
217 showScreenLoader = () => {
218 this.setState({
219 displayScreenLoader: true
220 });
221 }
222 hideScreenLoader = () => {
223 this.setState({
224 displayScreenLoader: false
225 })
226 }
227
228 }
229
230 /**
231 * Receives nav data from routes rest endpoint and decorates the data with internal/external linking information
232 * @param {object} nav Nav item from /nav endoingpoint
233 * @param {string} currentPlugin Current plugin name taken from url path.
234 * @return {array} Returns list of constructed nav items.
235 */
236 function decorateAndTransformNav(nav, currentPlugin) {
237 for ( let k in nav) {
238 nav[k].pluginName = k;
239 if (k != currentPlugin) {
240 nav[k].routes.map(function(route, i) {
241 if (API_SERVER) {
242 route.route = '/' + k + '/index.html?api_server=' + API_SERVER + '&upload_server=' + UPLOAD_SERVER + '#' + route.route;
243 } else {
244 route.route = '/' + k + '/#' + route.route;
245 }
246 route.isExternal = true;
247 })
248 }
249 }
250 return nav;
251 }
252
253 function getCurrentPlugin() {
254 var paths = window.location.pathname.split('/');
255 var currentPath = null;
256 if (paths[0] != "") {
257 currentPath = paths[0]
258 } else {
259 currentPath = paths[1];
260 }
261 if (currentPath != null) {
262 return currentPath;
263 } else {
264 console.error('Well, something went horribly wrong with discovering the current plugin name - perhaps you should consider moving this logic to the server?')
265 }
266 }
267
268 export default Alt.createStore(SkyquakeContainerStore);