cb731c73c6d808e61d31718809a2de4e22bfabbd
[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 if (!_.isEqual(data.project, self.projects)) {
182 let user = self.user;
183 user.projects = data.project;
184 self.setState({
185 user: user,
186 projects: data.project
187 });
188 }
189 } catch(e) {
190 console.log('HIT an exception in openProjectSocketSuccess', e);
191 }
192 };
193 }
194 getUserProfileSuccess = (user) => {
195 this.alt.actions.global.hideScreenLoader.defer();
196 this.setState({user})
197 }
198 selectActiveProjectSuccess = (projectId) => {
199 let user = this.user;
200 user.projectId = projectId;
201 this.setState({user});
202 }
203 //Notifications
204 showNotification = (data) => {
205 let state = {
206 displayNotification: true,
207 notificationMessage: data,
208 notificationType: 'error',
209 displayScreenLoader: false
210 }
211 if(typeof(data) == 'string') {
212
213 } else {
214 if(!data) data = {};
215 state.notificationMessage = data.msg || 'Something wrong occurred. Check the network tab and console logs for more information.';
216 if(data.type) {
217 state.notificationType = data.type;
218 }
219 }
220 this.setState(state);
221 }
222 hideNotification = () => {
223 this.setState({
224 displayNotification: false
225 })
226 }
227 //ScreenLoader
228 showScreenLoader = () => {
229 this.setState({
230 displayScreenLoader: true
231 });
232 }
233 hideScreenLoader = () => {
234 this.setState({
235 displayScreenLoader: false
236 })
237 }
238
239 }
240
241 /**
242 * Receives nav data from routes rest endpoint and decorates the data with internal/external linking information
243 * @param {object} nav Nav item from /nav endoingpoint
244 * @param {string} currentPlugin Current plugin name taken from url path.
245 * @return {array} Returns list of constructed nav items.
246 */
247 function decorateAndTransformNav(nav, currentPlugin) {
248 for ( let k in nav) {
249 nav[k].pluginName = k;
250 if (k != currentPlugin) {
251 nav[k].routes.map(function(route, i) {
252 if (API_SERVER) {
253 route.route = '/' + k + '/index.html?api_server=' + API_SERVER + '&upload_server=' + UPLOAD_SERVER + '#' + route.route;
254 } else {
255 route.route = '/' + k + '/#' + route.route;
256 }
257 route.isExternal = true;
258 })
259 }
260 }
261 return nav;
262 }
263
264 function getCurrentPlugin() {
265 var paths = window.location.pathname.split('/');
266 var currentPath = null;
267 if (paths[0] != "") {
268 currentPath = paths[0]
269 } else {
270 currentPath = paths[1];
271 }
272 if (currentPath != null) {
273 return currentPath;
274 } else {
275 console.error('Well, something went horribly wrong with discovering the current plugin name - perhaps you should consider moving this logic to the server?')
276 }
277 }
278
279 export default Alt.createStore(SkyquakeContainerStore);