Rift.IO OSM R1 Initial Submission
[osm/UI.git] / skyquake / framework / widgets / skyquake_container / skyquakeContainerStore.js
diff --git a/skyquake/framework/widgets/skyquake_container/skyquakeContainerStore.js b/skyquake/framework/widgets/skyquake_container/skyquakeContainerStore.js
new file mode 100644 (file)
index 0000000..fe4a7b0
--- /dev/null
@@ -0,0 +1,237 @@
+/*
+ * 
+ *   Copyright 2016 RIFT.IO Inc
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+//This will reach out to the global routes endpoint
+
+import Alt from './skyquakeAltInstance.js';
+import SkyquakeContainerSource from './skyquakeContainerSource.js';
+import SkyquakeContainerActions from './skyquakeContainerActions';
+import _ from 'lodash';
+//Temporary, until api server is on same port as webserver
+var rw = require('utils/rw.js');
+var API_SERVER = rw.getSearchParams(window.location).api_server;
+var UPLOAD_SERVER = rw.getSearchParams(window.location).upload_server;
+
+class SkyquakeContainerStore {
+    constructor() {
+        this.currentPlugin = getCurrentPlugin();
+        this.nav = {};
+        this.notifications = [];
+        this.socket = null;
+        //Notification defaults
+        this.notificationMessage = '';
+        this.displayNotification = false;
+        //Screen Loader default
+        this.displayScreenLoader = false;
+        this.bindActions(SkyquakeContainerActions);
+        this.exportAsync(SkyquakeContainerSource);
+
+
+        this.exportPublicMethods({
+            // getNav: this.getNav
+        });
+
+    }
+    getSkyquakeNavSuccess = (data) => {
+        var self = this;
+        this.setState({
+            nav: decorateAndTransformNav(data, self.currentPlugin)
+        })
+    }
+
+    closeSocket = () => {
+        if (this.socket) {
+            window.multiplexer.channel(this.channelId).close();
+        }
+        this.setState({
+            socket: null
+        });
+    }
+    //Remove once logging plugin is implemented
+    getSysLogViewerURLSuccess(data){
+        window.open(data.url);
+    }
+    getSysLogViewerURLError(data){
+        console.log('failed', data)
+    }
+
+    openNotificationsSocketLoading = () => {
+        this.setState({
+            isLoading: true
+        })
+    }
+
+    openNotificationsSocketSuccess = (data) => {
+        var self = this;
+
+        let connection = data.connection;
+        let streamSource = data.streamSource;
+        console.log('Success opening notification socket for stream ', streamSource);
+        
+        let ws = window.multiplexer.channel(connection);
+        
+        if (!connection) return;
+        self.setState({
+            socket: ws.ws,
+            isLoading: false,
+            channelId: connection
+        });
+
+        ws.onmessage = (socket) => {
+            try {
+                var data = JSON.parse(socket.data);
+                if (!data.notification) {
+                    console.warn('No notification in the received payload: ', data);
+                } else {
+                    // Temp to test before adding multi-sources
+                    data.notification.source = streamSource;
+                    if (_.indexOf(self.notifications, data.notification) == -1) {
+                        // newly appreared event.
+                        // Add to the notifications list and setState
+                        self.notifications.unshift(data.notification);
+                        self.setState({
+                            newNotificationEvent: true,
+                            newNotificationMsg: data.notification,
+                            notifications: self.notifications,
+                            isLoading: false
+                        });
+                    }
+                }
+            } catch(e) {
+                console.log('Error in parsing data on notification socket');
+            }
+        };
+
+        ws.onclose = () => {
+            self.closeSocket();
+        };
+    }
+
+    openNotificationsSocketError = (data) => {
+        console.log('Error opening notification socket', data);
+    }
+
+    getEventStreamsLoading = () => {
+        this.setState({
+            isLoading: true
+        });
+    }
+
+    getEventStreamsSuccess = (streams) => {
+        console.log('Found streams: ', streams);
+        let self = this;
+
+        streams['ietf-restconf-monitoring:streams'] &&
+        streams['ietf-restconf-monitoring:streams']['stream'] &&
+        streams['ietf-restconf-monitoring:streams']['stream'].map((stream) => {
+            stream['access'] && stream['access'].map((streamLocation) => {
+                if (streamLocation['encoding'] == 'ws_json') {
+                    setTimeout(() => {
+                        self.getInstance().openNotificationsSocket(streamLocation['location'], stream['name']);
+                    }, 0);
+                }
+            })
+        })
+
+        this.setState({
+            isLoading: true,
+            streams: streams
+        })
+    }
+
+    getEventStreamsError = (error) => {
+        console.log('Failed to get streams object');
+        this.setState({
+            isLoading: false
+        })
+    }
+
+    //Notifications
+    showNotification = (data) => {
+        if(typeof(data) == 'string') {
+            this.setState({
+                displayNotification: true,
+                notificationMessage: data
+            });
+        } else {
+            if(data.type == 'error') {
+                this.setState({
+                    displayNotification: true,
+                    notificationMessage: data.msg,
+                    displayScreenLoader: false
+                });
+            }
+        }
+    }
+    hideNotification = () => {
+        this.setState({
+            displayNotification: false
+        })
+    }
+    //ScreenLoader
+    showScreenLoader = () => {
+        this.setState({
+            displayScreenLoader: true
+        });
+    }
+    hideScreenLoader = () => {
+        this.setState({
+            displayScreenLoader: false
+        })
+    }
+
+}
+
+/**
+ * Receives nav data from routes rest endpoint and decorates the data with internal/external linking information
+ * @param  {object} nav           Nav item from /nav endoingpoint
+ * @param  {string} currentPlugin Current plugin name taken from url path.
+ * @return {array}               Returns list of constructed nav items.
+ */
+function decorateAndTransformNav(nav, currentPlugin) {
+    for ( let k in nav) {
+        nav[k].pluginName = k;
+            if (k != currentPlugin)  {
+                nav[k].routes.map(function(route, i) {
+                    if (API_SERVER) {
+                        route.route = '/' + k + '/index.html?api_server=' + API_SERVER + '&upload_server=' + UPLOAD_SERVER + '#' + route.route;
+                    } else {
+                        route.route = '/' + k + '/#' + route.route;
+                    }
+                    route.isExternal = true;
+                })
+            }
+        }
+        return nav;
+}
+
+function getCurrentPlugin() {
+    var paths = window.location.pathname.split('/');
+    var currentPath = null;
+    if (paths[0] != "") {
+        currentPath = paths[0]
+    } else {
+        currentPath = paths[1];
+    }
+    if (currentPath != null) {
+        return currentPath;
+    } else {
+        console.error('Well, something went horribly wrong with discovering the current plugin name - perhaps you should consider moving this logic to the server?')
+    }
+}
+
+export default Alt.createStore(SkyquakeContainerStore);