You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spot.apache.org by na...@apache.org on 2017/09/26 21:37:09 UTC

[03/18] incubator-spot git commit: syncing with master

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/fbcfa683/spot-oa/ui/js/stores/GraphQLStore.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/js/stores/GraphQLStore.js b/spot-oa/ui/js/stores/GraphQLStore.js
new file mode 100644
index 0000000..ad0989e
--- /dev/null
+++ b/spot-oa/ui/js/stores/GraphQLStore.js
@@ -0,0 +1,89 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You 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.
+//
+const $ = require('jquery');
+const SpotConstants = require('../constants/SpotConstants');
+
+class GraphQLStore {
+    constructor() {
+        this.variables = {};
+        this.data = {};
+    }
+
+    getQuery() {
+        return null;
+    }
+
+    setVariable(name, value) {
+        this.variables[name] = value;
+    }
+
+    getVariable(name) {
+        return this.variables[name];
+    }
+
+    unsetVariable(name) {
+        delete this.variables[name];
+    }
+
+    setData(data) {
+        this.data = data;
+    }
+
+    getData() {
+        if (Object.keys(this.data).length==0 || this.data.loading || this.data.error) return this.data;
+
+        return {loading: false, data: this.unboxData(this.data)};
+    }
+
+    resetData() {
+        this.setData({});
+    }
+
+    sendQuery() {
+        const query = this.getQuery();
+        const variables = this.variables;
+
+        this.setData({loading: true});
+        $.post({
+            accept: 'application/json',
+            contentType: 'application/json',
+            dataType: 'json',
+            data: JSON.stringify({
+                query,
+                variables
+            }),
+            url: SpotConstants.GRAPHQL_ENDPOINT
+        })
+        .done((response) => {
+            if (response.errors) {
+                console.error('Unexpected GraphQL error', response)
+                this.setData({error: 'Oops... something went wrong'});
+            }
+            else {
+                this.setData(response.data);
+                if(response.data !== undefined && JSON.stringify(response.data).indexOf('"success":true') !== -1)
+                  this.reloadElements();
+            }
+        })
+        .fail((jqxhr, textStatus, error) => {
+            console.error('Unexpected GraphQL error', jqxhr.responseJSON)
+            this.setData({error: `${textStatus}: ${error}`})
+        });
+    }
+}
+
+module.exports = GraphQLStore;

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/fbcfa683/spot-oa/ui/js/stores/IngestSummaryStore.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/js/stores/IngestSummaryStore.js b/spot-oa/ui/js/stores/IngestSummaryStore.js
index 0f3d4a9..ac2a6a2 100755
--- a/spot-oa/ui/js/stores/IngestSummaryStore.js
+++ b/spot-oa/ui/js/stores/IngestSummaryStore.js
@@ -1,178 +1,116 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements; and to You under the Apache License, Version 2.0.
-
-const assign = require('object-assign');
-const d3 = require('d3');
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You 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.
+//
 
 const SpotDispatcher = require('../dispatchers/SpotDispatcher');
 const SpotConstants = require('../constants/SpotConstants');
-const DateUtils = require('../utils/DateUtils');
-const RestStore = require('../stores/RestStore');
-
-const PIPELINE_FILTER = 'pipeline';
-const CURRENT_YEAR_FILTER = 'year';
-const CURRENT_MONTH_FILTER = 'month';
-
-const requestQueue = [];
-const requestErrors = [];
-
-const IngestSummaryStore = assign(new RestStore(SpotConstants.API_INGEST_SUMMARY), {
-    PIPELINES: {
-        [SpotConstants.PIPELINE_NETFLOW]: 'Netflow',
-        [SpotConstants.PIPELINE_DNS]: 'Dns',
-        [SpotConstants.PIPELINE_PROXY]: 'Proxy'
-    },
-    errorMessages: {
-        404: 'No details available'
-    },
-    setStartDate(date) {
-        this._startDate = date;
-    },
-    getStartDate() {
-        return this._startDate;
-    },
-    setEndDate(date) {
-        this._endDate = date;
-    },
-    getEndDate() {
-        return this._endDate;
-    },
-    setPipeline(pipeline) {
-        this.setRestFilter(PIPELINE_FILTER, pipeline);
-    },
-    getPipeline() {
-        return this.getRestFilter(PIPELINE_FILTER);
-    },
-    setCurrentDate(date) {
-        this.setRestFilter(CURRENT_YEAR_FILTER, date.getFullYear())
-
-        const month = date.getMonth() + 1 + "";
-        this.setRestFilter(CURRENT_MONTH_FILTER, month.length==1 ? `0${month}`:month);
-
-        this._currentDate = date;
-    },
-    getCurrentDate() {
-        return this._currentDate;
-    },
-    /**
-     *  Start asking the server for CSV data to create the chart
-     **/
-    requestSummary: function () {
-        var startDate, endDate, date, delta, startRequests, i, month;
-
-        startDate = DateUtils.parseDate(this.getStartDate());
-        endDate = DateUtils.parseDate(this.getEndDate());
-
-        // Find out how many request need to be made
-        delta = (endDate.getFullYear() - startDate.getFullYear()) * 12 + (endDate.getMonth() - startDate.getMonth());
-
-        startRequests = requestQueue.length == 0;
-
-        // Go to first day in month
-        date = new Date(startDate);
-        date.setDate(1);
-
-        // Queue date requests
-        requestQueue.push(date);
-        for (i = 1; i <= delta; i++) {
-            requestQueue.push(DateUtils.calcDate(date, i, 'month'));
-        }
-
-        // dequeue is no request is running
-        startRequests && this.dequeue();
-    },
-    dequeue: function () {
-        if (requestQueue.length == 0) return;
-
-        const date = requestQueue.shift();
-        this.setCurrentDate(date);
-
-        this.reload();
-    },
-    setData: function (data) {
-        var startDate, endDate, date, dayFilter, parse;
-
-        // Does the loading indicator needs to be displayed?
-        if (data.loading) {
-            if (!this._data.loading) {
-                this._data = data;
-                this.emitChangeData();
-            }
 
-            // Do nothing when loading is in progress
-            return;
-        }
-
-        // Store errors for later usage
-        if (data.error) {
-            requestErrors.push(data);
-        }
-        else if (data.data) {
-            parse = d3.time.format("%Y-%m-%d %H:%M:%S%Z").parse; // Date formatting parser
-            startDate = DateUtils.parseDate(this.getStartDate());
-            endDate = DateUtils.parseDate(this.getEndDate());
-            date = DateUtils.parseDate(this.getCurrentDate());
-
-            if (date.getFullYear() == startDate.getFullYear() && date.getMonth() == startDate.getMonth()) {
-                dayFilter = startDate.getDate();
-                data.data = data.data.filter(function (row) {
-                    return DateUtils.parseDate(row.date, true).getDate() >= dayFilter
-                });
-            }
+const ObservableGraphQLStore = require('./ObservableGraphQLStore');
 
-            if (date.getFullYear() == endDate.getFullYear() && date.getMonth() == endDate.getMonth()) {
-                dayFilter = endDate.getDate();
-                data.data = data.data.filter(function (row) {
-                    return DateUtils.parseDate(row.date, true).getDate() <= dayFilter
-                });
+const START_DATE_VAR = 'startDate';
+const END_DATE_VAR = 'endDate';
+
+class IngestSummaryStore extends ObservableGraphQLStore {
+    constructor() {
+        super();
+
+        this.pipeline = null;
+        this.PIPELINES = {};
+        this.PIPELINES[SpotConstants.PIPELINE_NETFLOW] = 'Netflow';
+        this.PIPELINES[SpotConstants.PIPELINE_DNS] = 'Dns';
+        this.PIPELINES[SpotConstants.PIPELINE_PROXY] = 'Proxy';
+    }
+
+    getQuery() {
+        let pipeline = this.getPipeline() || '';
+
+        return `
+            query($startDate:SpotDateType!,$endDate:SpotDateType!) {
+                ${pipeline} {
+                    ingestSummary(startDate:$startDate, endDate:$endDate) {
+                        date: datetime
+                        total
+                    }
+                }
             }
+        `;
+    }
 
-            // Parse dates and numbers.
-            data.data.forEach(function (d) {
-                d.date = parse(`${d.date}:00-0000`);
-                d.total = +d.total;
-            });
+    unboxData(data) {
+        let pipeline = this.getPipeline();
+        let parser = parser = d3.time.format("%Y-%m-%d %H:%M:%S%Z").parse;
 
-            // Sort the data by date ASC
-            data.data.sort(function (a, b) {
-                return a.date - b.date;
-            });
+        let dataByMonth = {};
+        data[pipeline].ingestSummary.forEach(record => {
+            record = {total: record.total, date: parser(`${record.date}-0000`)};
+            let month = record.date.toISOString().substr(0,7);
 
-            if (!this._data.data) this._data.data = [];
+            if (!(month in dataByMonth)) dataByMonth[month] = [];
+            dataByMonth[month].push(record);
+        });
 
-            this._data.data.push(data.data);
-        }
+        return Object.keys(dataByMonth).map(month => dataByMonth[month].sort((a, b) => a.date - b.date));
+    }
 
-        this._data.loading = requestQueue.length > 0;
+    setStartDate(date) {
+        this.setVariable(START_DATE_VAR, date);
+    }
 
-        if (!this._data.loading) {
-            if (this._data.data && this._data.data.length==0) {
-                // Broadcast first found error
-                this._data = requestErrors[0];
-            }
-            this.emitChangeData();
-        }
-        else {
-            setTimeout(this.dequeue.bind(this), 1);
-        }
+    getStartDate() {
+        return this.getVariable(START_DATE_VAR);
     }
-});
+
+    setEndDate(date) {
+        this.setVariable(END_DATE_VAR, date);
+    }
+
+    getEndDate() {
+        return this.getVariable(END_DATE_VAR);
+    }
+
+    setPipeline(pipeline) {
+        this.pipeline = pipeline;
+    }
+
+    getPipeline() {
+        return this.pipeline;
+    }
+}
+
+const iss = new IngestSummaryStore();
 
 SpotDispatcher.register(function (action) {
     switch (action.actionType) {
         case SpotConstants.UPDATE_DATE:
             switch (action.name) {
                 case SpotConstants.START_DATE:
-                    IngestSummaryStore.setStartDate(action.date);
+                    iss.setStartDate(action.date);
                     break;
                 case SpotConstants.END_DATE:
-                    IngestSummaryStore.setEndDate(action.date);
+                    iss.setEndDate(action.date);
                     break;
             }
             break;
         case SpotConstants.RELOAD_INGEST_SUMMARY:
-            IngestSummaryStore.requestSummary();
+            iss.sendQuery();
             break;
+        case SpotConstants.UPDATE_PIPELINE:
+            iss.setPipeline(action.pipeline)
+        break;
     }
 });
 
-module.exports = IngestSummaryStore;
+module.exports = iss;

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/fbcfa683/spot-oa/ui/js/stores/JsonStore.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/js/stores/JsonStore.js b/spot-oa/ui/js/stores/JsonStore.js
index 2c7fa74..324c727 100755
--- a/spot-oa/ui/js/stores/JsonStore.js
+++ b/spot-oa/ui/js/stores/JsonStore.js
@@ -1,4 +1,19 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements; and to You under the Apache License, Version 2.0.
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You 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.
+//
 
 const $ = require('jquery');
 

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/fbcfa683/spot-oa/ui/js/stores/ObservableGraphQLStore.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/js/stores/ObservableGraphQLStore.js b/spot-oa/ui/js/stores/ObservableGraphQLStore.js
new file mode 100644
index 0000000..7d9ef1c
--- /dev/null
+++ b/spot-oa/ui/js/stores/ObservableGraphQLStore.js
@@ -0,0 +1,55 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You 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.
+//
+const EventEmitter = require('events').EventEmitter;
+
+const GraphQLStore = require('./GraphQLStore');
+
+const DATA_CHANGE_EVENT = 'data-change';
+
+class ObervableGraphQLStore extends GraphQLStore {
+    constructor() {
+        super();
+        this.eventEmitter = new EventEmitter();
+    }
+
+    addChangeDataListener(callback) {
+        this.addListener(DATA_CHANGE_EVENT, callback);
+    }
+
+    removeChangeDataListener(callback) {
+        this.removeListener(DATA_CHANGE_EVENT, callback);
+    }
+
+    addListener(eventName, callback) {
+        this.eventEmitter.on(eventName, callback);
+    }
+
+    removeListener(eventName, callback) {
+        this.eventEmitter.removeListener(eventName, callback);
+    }
+
+    notifyListeners(eventName) {
+        this.eventEmitter.emit(eventName);
+    }
+
+    setData(data) {
+        super.setData(data);
+        this.notifyListeners(DATA_CHANGE_EVENT);
+    }
+}
+
+module.exports = ObervableGraphQLStore;

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/fbcfa683/spot-oa/ui/js/stores/ObservableWithHeadersGraphQLStore.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/js/stores/ObservableWithHeadersGraphQLStore.js b/spot-oa/ui/js/stores/ObservableWithHeadersGraphQLStore.js
new file mode 100644
index 0000000..679b46d
--- /dev/null
+++ b/spot-oa/ui/js/stores/ObservableWithHeadersGraphQLStore.js
@@ -0,0 +1,31 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You 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.
+//
+const ObservableGraphQLStore = require('./ObservableGraphQLStore');
+
+class ObservableWithHeadersGraphQLStore extends ObservableGraphQLStore {
+    getData() {
+        const data = super.getData();
+
+        if (data.loading || data.error) return data;
+
+        data.headers = this.headers;
+
+        return data;
+    }
+}
+
+module.exports = ObservableWithHeadersGraphQLStore

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/fbcfa683/spot-oa/ui/js/stores/RestStore.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/js/stores/RestStore.js b/spot-oa/ui/js/stores/RestStore.js
index 16e8203..6c9b797 100755
--- a/spot-oa/ui/js/stores/RestStore.js
+++ b/spot-oa/ui/js/stores/RestStore.js
@@ -1,4 +1,19 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements; and to You under the Apache License, Version 2.0.
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You 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.
+//
 
 var $ = require('jquery');
 var assign = require('object-assign');

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/fbcfa683/spot-oa/ui/js/stores/SpotStore.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/js/stores/SpotStore.js b/spot-oa/ui/js/stores/SpotStore.js
index 488f4dc..7912ebb 100755
--- a/spot-oa/ui/js/stores/SpotStore.js
+++ b/spot-oa/ui/js/stores/SpotStore.js
@@ -1,4 +1,19 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements; and to You under the Apache License, Version 2.0.
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You 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.
+//
 
 var EventEmitter = require('events').EventEmitter;
 var assign = require('object-assign');

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/fbcfa683/spot-oa/ui/js/stores/__tests__/JsonStore.test.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/js/stores/__tests__/JsonStore.test.js b/spot-oa/ui/js/stores/__tests__/JsonStore.test.js
index 1a0eb81..19695e6 100644
--- a/spot-oa/ui/js/stores/__tests__/JsonStore.test.js
+++ b/spot-oa/ui/js/stores/__tests__/JsonStore.test.js
@@ -1,4 +1,18 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements; and to You under the Apache License, Version 2.0.
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You 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
+
 
 jest.mock('jquery');
 const $ = require('jquery');

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/fbcfa683/spot-oa/ui/js/stores/__tests__/RestStore.test.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/js/stores/__tests__/RestStore.test.js b/spot-oa/ui/js/stores/__tests__/RestStore.test.js
index 8a2e4cd..63b8145 100644
--- a/spot-oa/ui/js/stores/__tests__/RestStore.test.js
+++ b/spot-oa/ui/js/stores/__tests__/RestStore.test.js
@@ -1,4 +1,18 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements; and to You under the Apache License, Version 2.0.
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You 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
+
 
 jest.mock('jquery');
 const $ = require('jquery');

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/fbcfa683/spot-oa/ui/js/stores/__tests__/SpotStore.test.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/js/stores/__tests__/SpotStore.test.js b/spot-oa/ui/js/stores/__tests__/SpotStore.test.js
index 67ec57a..5788284 100644
--- a/spot-oa/ui/js/stores/__tests__/SpotStore.test.js
+++ b/spot-oa/ui/js/stores/__tests__/SpotStore.test.js
@@ -1,4 +1,18 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements; and to You under the Apache License, Version 2.0.
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You 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
+
 
 const SpotStore = require('../SpotStore');
 

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/fbcfa683/spot-oa/ui/js/tooltip.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/js/tooltip.js b/spot-oa/ui/js/tooltip.js
index edc4b6f..dc53183 100755
--- a/spot-oa/ui/js/tooltip.js
+++ b/spot-oa/ui/js/tooltip.js
@@ -1,4 +1,19 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements; and to You under the Apache License, Version 2.0.
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You 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.
+//
 
 $(function () {
     $('body').tooltip({

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/fbcfa683/spot-oa/ui/js/utils/CategoryLayout.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/js/utils/CategoryLayout.js b/spot-oa/ui/js/utils/CategoryLayout.js
index 7ac0d5c..28b9829 100755
--- a/spot-oa/ui/js/utils/CategoryLayout.js
+++ b/spot-oa/ui/js/utils/CategoryLayout.js
@@ -1,4 +1,19 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements; and to You under the Apache License, Version 2.0.
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You 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.
+//
 
 class CategoryLayout {
     constructor() {

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/fbcfa683/spot-oa/ui/js/utils/DateUtils.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/js/utils/DateUtils.js b/spot-oa/ui/js/utils/DateUtils.js
index 82be435..a0978cc 100644
--- a/spot-oa/ui/js/utils/DateUtils.js
+++ b/spot-oa/ui/js/utils/DateUtils.js
@@ -1,4 +1,19 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements; and to You under the Apache License, Version 2.0.
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You 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.
+//
 
 var DateUtils = {
   /**

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/fbcfa683/spot-oa/ui/js/utils/SpotUtils.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/js/utils/SpotUtils.js b/spot-oa/ui/js/utils/SpotUtils.js
index 0549c74..953f5e1 100755
--- a/spot-oa/ui/js/utils/SpotUtils.js
+++ b/spot-oa/ui/js/utils/SpotUtils.js
@@ -1,4 +1,19 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements; and to You under the Apache License, Version 2.0.
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You 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.
+//
 
 const Base64 = require('js-base64').Base64;
 
@@ -114,6 +129,41 @@ var SpotUtils = {
   },
   decodeId(id) {
       return Base64.decode(id.replace(ID_REPLACEMENT_REGEX, ID_REPLACE));
+  },
+  filterTextOnSelect(selectionEl, str, isCaseSensitive) {
+    if (isCaseSensitive)
+    str = str.toLowerCase();
+    // cache the jQuery object of the <select> element
+    var $el = $(selectionEl);
+    if (!$el.data("options")) {
+      // cache all the options inside the <select> element for easy recover
+      $el.data("options", $el.find("option").clone());
+    }
+    var newOptions = $el.data("options").filter(function () {
+      var text = $(this).text();
+      if (isCaseSensitive)
+      text = text.toLowerCase();
+      //select the first element of all results
+      if ($el.children().length > 0)
+      $el.children().get(0).selected = true;
+      return text.match(str);
+    });
+    $el.empty().append(newOptions);
+  },
+  switchDivs(elOne, elTwo) {
+    let elOneVal = $(`#${elOne}`).attr('style').split(';')[0].split(' ')[1] || '';
+    let elTwoVal = $(`#${elTwo}`).attr('style').split(';')[0].split(' ')[1] || '';
+
+    if (elOneVal === elTwoVal) {
+      $(`#${elOne}`).css({'order': '1'});
+      $(`#${elTwo}`).css({'order': '2'});
+    } else if(elOneVal === '1') {
+      $(`#${elOne}`).css({'order': '2'});
+      $(`#${elTwo}`).css({'order': '1'});
+    } else {
+      $(`#${elOne}`).css({'order': '1'});
+      $(`#${elTwo}`).css({'order': '2'});
+    }
   }
 };
 

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/fbcfa683/spot-oa/ui/js/utils/__tests__/CategoryLayout.test.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/js/utils/__tests__/CategoryLayout.test.js b/spot-oa/ui/js/utils/__tests__/CategoryLayout.test.js
index 16dbc68..168926f 100644
--- a/spot-oa/ui/js/utils/__tests__/CategoryLayout.test.js
+++ b/spot-oa/ui/js/utils/__tests__/CategoryLayout.test.js
@@ -1,4 +1,18 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements; and to You under the Apache License, Version 2.0.
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You 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
+
 
 const CategoryLayout = require('../CategoryLayout');
 

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/fbcfa683/spot-oa/ui/js/utils/__tests__/DateUtils.test.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/js/utils/__tests__/DateUtils.test.js b/spot-oa/ui/js/utils/__tests__/DateUtils.test.js
index a622f0c..2fc255b 100644
--- a/spot-oa/ui/js/utils/__tests__/DateUtils.test.js
+++ b/spot-oa/ui/js/utils/__tests__/DateUtils.test.js
@@ -1,4 +1,18 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements; and to You under the Apache License, Version 2.0.
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You 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
+
 
 const DateUtils = require('../DateUtils');
 

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/fbcfa683/spot-oa/ui/js/utils/__tests__/SpotUtils.test.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/js/utils/__tests__/SpotUtils.test.js b/spot-oa/ui/js/utils/__tests__/SpotUtils.test.js
index 9ccd8cd..30bea82 100644
--- a/spot-oa/ui/js/utils/__tests__/SpotUtils.test.js
+++ b/spot-oa/ui/js/utils/__tests__/SpotUtils.test.js
@@ -1,4 +1,18 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements; and to You under the Apache License, Version 2.0.
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You 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
+
 
 const DateUtils = require('../DateUtils');
 const SpotUtils = require('../SpotUtils');

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/fbcfa683/spot-oa/ui/package.json
----------------------------------------------------------------------
diff --git a/spot-oa/ui/package.json b/spot-oa/ui/package.json
index 3863c64..3a61cf6 100644
--- a/spot-oa/ui/package.json
+++ b/spot-oa/ui/package.json
@@ -2,7 +2,7 @@
   "name": "spot_ui",
   "version": "1.1.0",
   "description": "Apache Spot :: UI",
-  "repository": "https://github.com/Open-Network-Insight/open-network-insight",
+  "repository": "https://github.com/apache/incubator-spot",
   "license": "Apache License, Version 2.0",
   "dependencies": {
     "bootstrap": "3.3.5",
@@ -19,6 +19,7 @@
     "object-assign": "^1.0.0",
     "react": "^15.3.2",
     "react-dom": "^15.3.2",
+    "sweetalert2": "^6.6.0",
     "underscore": "^1.8.3"
   },
   "devDependencies": {
@@ -36,7 +37,7 @@
   "scripts": {
     "test": "jest",
     "postinstall": "npm run build-all",
-    "watch-ingest-summary": "NODE_ENV=development watchify js/ingest-summary.js -o js/ingest-summary.bundle.min.js -v -d",
+    "watch-ingest-summary": "watchify js/ingest-summary.js -o js/ingest-summary.bundle.min.js -v",
     "build-all": "npm run build-flow && npm run build-dns && npm run build-proxy && npm run build-ingest-summary",
     "build-flow": "cd flow/ && npm run build-all && cd ../",
     "build-dns": "cd dns/ && npm run build-all && cd ../",

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/fbcfa683/spot-oa/ui/proxy/ipython_notebook.html
----------------------------------------------------------------------
diff --git a/spot-oa/ui/proxy/ipython_notebook.html b/spot-oa/ui/proxy/ipython_notebook.html
new file mode 100644
index 0000000..01dde73
--- /dev/null
+++ b/spot-oa/ui/proxy/ipython_notebook.html
@@ -0,0 +1,108 @@
+<!DOCTYPE html>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You 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.
+  -->
+
+<html>
+<head>
+    <title>Proxy :: Advanced mode</title>
+
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
+
+    <!--Bootstrap styles-->
+    <link rel="stylesheet" type="text/css" href="../css/bootstrap-spot.min.css" />
+    <!--Font awesome ICONS-->
+    <link rel="stylesheet" href="../node_modules/font-awesome/css/font-awesome.min.css">
+    <!--Bootstrap Date picker styles-->
+    <link rel="stylesheet" type="text/css" href="../node_modules/bootstrap-datepicker/dist/css/bootstrap-datepicker3.min.css" />
+    <!-- Spot styles -->
+    <link rel="stylesheet" type="text/css" href="../css/main.css" />
+    <!-- Sweetalert2 -->
+    <link rel="stylesheet" type="text/css" href="../node_modules/sweetalert2/dist/sweetalert2.min.css">
+
+    <!-- Favicon -->
+    <link rel="apple-touch-icon" sizes="57x57" href="../images/favicon/apple-icon-57x57.png">
+    <link rel="apple-touch-icon" sizes="60x60" href="../images/favicon/apple-icon-60x60.png"
+    <link rel="apple-touch-icon" sizes="72x72" href="../images/favicon/apple-icon-72x72.png">
+    <link rel="apple-touch-icon" sizes="76x76" href="../images/favicon/apple-icon-76x76.png">
+    <link rel="apple-touch-icon" sizes="114x114" href="../images/favicon/apple-icon-114x114.png">
+    <link rel="apple-touch-icon" sizes="120x120" href="../images/favicon/apple-icon-120x120.png">
+    <link rel="apple-touch-icon" sizes="144x144" href="../images/favicon/apple-icon-144x144.png">
+    <link rel="apple-touch-icon" sizes="152x152" href="../images/favicon/apple-icon-152x152.png">
+    <link rel="apple-touch-icon" sizes="180x180" href="../images/favicon/apple-icon-180x180.png">
+    <link rel="icon" type="image/png" sizes="192x192"  href="../images/favicon/android-icon-192x192.png">
+    <link rel="icon" type="image/png" sizes="32x32" href="../images/favicon/favicon-32x32.png">
+    <link rel="icon" type="image/png" sizes="96x96" href="../images/favicon/favicon-96x96.png">
+    <link rel="icon" type="image/png" sizes="16x16" href="../images/favicon/favicon-16x16.png">
+    <link rel="manifest" href="../images/favicon/manifest.json">
+    <meta name="msapplication-TileColor" content="#ffffff">
+    <meta name="msapplication-TileImage" content="../images/favicon/ms-icon-144x144.png">
+    <meta name="theme-color" content="#ffffff">
+
+    <style>
+        .spot-row {
+            height: 100%;
+        }
+
+        td.srcIP_rep, td.dstIP_rep {
+            white-space: nowrap;
+        }
+    </style>
+</head>
+<body>
+    <nav id="spot-nav" class="navbar navbar-default">
+        <div class="container-fluid">
+            <!-- App name and toggle get grouped for better mobile display -->
+            <div class="navbar-header">
+                <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#main-menu">
+                    <span class="sr-only">Toggle navigation</span>
+                    <span class="icon-bar"></span>
+                    <span class="icon-bar"></span>
+                    <span class="icon-bar"></span>
+                </button>
+                <span class="navbar-brand">Apache Spot :: Proxy :: Advanced mode</span>
+            </div>
+            <!-- Collect the nav links, forms, and other content for toggling -->
+            <div class="collapse navbar-collapse" id="main-menu">
+              <!-- Main Menu -->
+            </div>
+            <div id="search-box" class="row text-right">
+                <!--Tools Buttons-->
+                <div id="nav_form" class="col-md-12">
+                  <!-- Search form placeholder -->
+                </div>
+            </div> <!-- /Tools Buttons-->
+        </div>
+    </nav>
+    <div id="spot-content-wrapper" class="container-fluid">
+        <!-- Main Content Placeholder -->
+    </div>
+
+    <!-- SCRIPTS -->
+    <script type="application/javascript" src="../node_modules/jquery/dist/jquery.min.js"></script>
+    <script type="application/javascript" src="../node_modules/d3/d3.min.js"></script>
+    <script type="application/javascript" src="../node_modules/d3-tip/index.js"></script>
+    <script type="application/javascript" src="../node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
+    <script type="application/javascript" src="../node_modules/bootstrap-datepicker/dist/js/bootstrap-datepicker.min.js"></script>
+    <script type="application/javascript" src="../node_modules/underscore/underscore-min.js"></script>
+    <script type="application/javascript" src="../node_modules/react/dist/react.min.js"></script>
+    <script type="application/javascript" src="../node_modules/react-dom/dist/react-dom.min.js"></script>
+    <script type="application/javascript" src="../node_modules/react-dom/dist/react-dom-server.min.js"></script>
+    <script type="application/javascript" src="../node_modules/sweetalert2/dist/sweetalert2.min.js"></script>
+    <script type="application/javascript" src="js/notebooks.bundle.min.js"></script>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/fbcfa683/spot-oa/ui/proxy/js/components/DetailsPanel.react.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/proxy/js/components/DetailsPanel.react.js b/spot-oa/ui/proxy/js/components/DetailsPanel.react.js
index 6e5a93e..0fc9e76 100755
--- a/spot-oa/ui/proxy/js/components/DetailsPanel.react.js
+++ b/spot-oa/ui/proxy/js/components/DetailsPanel.react.js
@@ -1,4 +1,19 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements; and to You under the Apache License, Version 2.0.
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You 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.
+//
 
 var React = require('react');
 
@@ -10,9 +25,6 @@ var DetailsPanel = React.createClass({
     mixins: [GridPanelMixin, DetailsGridMixin],
     store: DetailsStore,
     // Custom cells
-    _render_p_date_cell: function (date, item) {
-        return date + ' ' + item.p_time;
-    },
     _render_host_cell(host) {
         return (
             <p className="spot-text-wrapper" data-toggle="tooltip">

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/fbcfa683/spot-oa/ui/proxy/js/components/FilterInput.react.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/proxy/js/components/FilterInput.react.js b/spot-oa/ui/proxy/js/components/FilterInput.react.js
index 666fc3e..3599603 100755
--- a/spot-oa/ui/proxy/js/components/FilterInput.react.js
+++ b/spot-oa/ui/proxy/js/components/FilterInput.react.js
@@ -1,4 +1,19 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements; and to You under the Apache License, Version 2.0.
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You 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.
+//
 
 var React = require('react');
 

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/fbcfa683/spot-oa/ui/proxy/js/components/IncidentProgressionPanel.react.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/proxy/js/components/IncidentProgressionPanel.react.js b/spot-oa/ui/proxy/js/components/IncidentProgressionPanel.react.js
index 67adb5e..3dc4ffb 100755
--- a/spot-oa/ui/proxy/js/components/IncidentProgressionPanel.react.js
+++ b/spot-oa/ui/proxy/js/components/IncidentProgressionPanel.react.js
@@ -1,4 +1,19 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements; and to You under the Apache License, Version 2.0.
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You 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.
+//
 
 const $ = require('jquery');
 const d3 = require('d3');

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/fbcfa683/spot-oa/ui/proxy/js/components/NetworkViewPanel.react.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/proxy/js/components/NetworkViewPanel.react.js b/spot-oa/ui/proxy/js/components/NetworkViewPanel.react.js
index 7862c63..7bc4035 100755
--- a/spot-oa/ui/proxy/js/components/NetworkViewPanel.react.js
+++ b/spot-oa/ui/proxy/js/components/NetworkViewPanel.react.js
@@ -1,4 +1,19 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements; and to You under the Apache License, Version 2.0.
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You 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.
+//
 
 const $ = require('jquery');
 const assign = require('object-assign');
@@ -102,7 +117,7 @@ var NetworkViewPanel = React.createClass({
         // Delete old links
         this.link.exit().remove();
 
-        // Update nodes
+        // Update nodesw
         this.node = this.canvas.selectAll('.node, .proxy_node')
             .data(nodes.filter((node) => node.visible), function(d) { return d.id; });
 
@@ -261,7 +276,7 @@ var NetworkViewPanel = React.createClass({
                 type: 'Root',
                 tooltip: 'Double click to toggle child nodes',
                 rep: -1,
-                visible: true,
+                visible: state.data.length > 0 ? true : false,
                 expanded: false,
                 root: true
             };
@@ -375,7 +390,7 @@ var NetworkViewPanel = React.createClass({
                     0
                 );
             } else {
-                node.size = node.hits.length;
+                node.size = node.hits === undefined ? 0 : node.hits.length;
             }
 
             nodes.push(node);

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/fbcfa683/spot-oa/ui/proxy/js/components/ScoreNotebook.react.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/proxy/js/components/ScoreNotebook.react.js b/spot-oa/ui/proxy/js/components/ScoreNotebook.react.js
new file mode 100644
index 0000000..80dc3bd
--- /dev/null
+++ b/spot-oa/ui/proxy/js/components/ScoreNotebook.react.js
@@ -0,0 +1,199 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You 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.
+//
+
+var React = require('react');
+
+var SuspiciousStore = require('../stores/SuspiciousStore');
+var NotebookStore = require('../stores/NotebookStore');
+var EdInActions = require('../../../js/actions/EdInActions');
+var SelectInput = require('../../../js/components/scoring/SelectInput.react');
+var FilterSelectInput = require('../../../js/components/scoring/FilterSelectInput.react');
+var ButtonsScoring = require('../../../js/components/scoring/ButtonsScoring.react');
+var RatingInput = require('../../../js/components/scoring/RatingInput.react');
+var SearchGlobalInput = require('../../../js/components/scoring/SearchGlobalInput.react');
+var ScoreMessage = require('../../../js/components/scoring/ScoreMessage.react');
+
+var SpotUtils = require('../../../js/utils/SpotUtils');
+
+var ScoreNotebook = React.createClass({
+  // mixins: [GridPanelMixin],
+  emptySetMessage: 'There is no data available for selected date.',
+  propTypes: {
+    date: React.PropTypes.string.isRequired,
+  },
+  getInitialState: function () {
+    return {
+      scoredEmelents: []
+    };
+  },
+  componentDidMount: function() {
+    SuspiciousStore.addChangeDataListener(this._onChange);
+    NotebookStore.addChangeDataListener(this._onChange);
+    this.setState({size: NotebookStore.completeClass})
+  },
+  componentWillUnmount: function () {
+    SuspiciousStore.removeChangeDataListener(this._onChange);
+    NotebookStore.addChangeDataListener(this._onChange);
+  },
+  render: function () {
+    var content, state, data, cssCls, uriArr = [];
+    state = this.state || {};
+
+    if (state.error)
+    {
+      content = (
+        <div className="text-center text-danger">
+          {state.error}
+        </div>
+      );
+    }
+    else if (state.loading)
+    {
+      content = (
+        <div className="spot-loader">
+          Loading <span className="spinner"></span>
+        </div>
+      );
+    }
+    else if (!state.data || state.data.length === 0)
+    {
+      content = (
+        <div className="text-center">
+          {this.emptySetMessage || ''}
+        </div>
+      );
+    }
+    else
+    {
+      state.data.map((obj) => {
+        if(uriArr.indexOf(obj.fulluri) === -1) {
+          uriArr.push(obj.fulluri);
+        }
+      });
+
+      data = [
+              {value: 1, name: 'High', radioName: 'optradio', selected: true},
+              {value: 2, name: 'Medium', radioName: 'optradio', selected: false},
+              {value: 3, name: 'Low', radioName: 'optradio', selected: false}
+            ];
+
+      content = (
+        <div>
+            <div className="margin-up-down">
+              <SearchGlobalInput col="6" maxlength="255"/>
+              <RatingInput data={data} col="6"/>
+            </div>
+            <div className="margin-up-down">
+              <ButtonsScoring name="Score" action="score" onChange={this.score.bind(this)} col="3"/>
+              <ButtonsScoring name="Save" action="save" onChange={this.save.bind(this)} col="3"/>
+              <ButtonsScoring name="Reset Scoring" action="reset" onChange={this.reset.bind(this)} col="3"/>
+            </div>
+            <div className="margin-up-down">
+              <FilterSelectInput nameBox="URI..." idSelect="#fullUri" idInput="fullUriIn" col="9"/>
+            </div>
+            <div className="margin-up-down">
+              <SelectInput title="Source IP" who="fullUri" options={uriArr} col="9"/>
+            </div>
+            <div className="margin-up-down">
+              <ScoreMessage who="scoreMsg"/>
+            </div>
+          </div>
+        );
+    }
+    cssCls = this.state.size ? 'col-md-6 col-lg-6 col-xs-12' : 'col-md-offset-3 col-lg-offset-3 col-md-6 col-lg-6 col-xs-12';
+
+    return(
+      <div className={cssCls + ' spot-frame'}>
+        {content}
+      </div>
+    )
+  },
+  _onChange: function() {
+    const data = SuspiciousStore.getData();
+    this.setState(data);
+  },
+  reset: function() {
+    swal({
+      title: 'Are you sure?',
+      text: "You won't be able to revert this!",
+      type: 'warning',
+      showCancelButton: true,
+      confirmButtonColor: '#3085d6',
+      cancelButtonColor: '#d33',
+      confirmButtonText: 'Yes, reset all!'
+    }).then(() => {
+      EdInActions.resetScoring(SpotUtils.getCurrentDate());
+      swal({
+        title: 'Done!',
+        text: "All scores have been reset.",
+        type: 'success',
+        showCancelButton: false,
+        confirmButtonColor: '#3085d6',
+        cancelButtonColor: '#d33',
+        confirmButtonText: 'Ok!'
+      }).then(() => {
+        this.setState({loading: true});
+      });
+    });
+  },
+  save: function() {
+    let variables = [];
+
+    if (this.state.scoredEmelents.length === 0) {
+      swal('Warning.','You should score at least 1 threat.','warning');
+    } else {
+      this.state.scoredEmelents.map((row) => {
+        variables.push({
+          'date': SpotUtils.getCurrentDate(),
+          'uri':  row[0] || "None",
+          'score': row[1],
+        });
+      });
+
+      EdInActions.saveScoring(variables);
+      $('#scoreMsg').addClass("hidden");
+      this.setState({scoredEmelents: [], loading: true});
+    }
+  },
+  score: function() {
+    //this should be changed to take all data at the time, time needed.
+    let dataScored = this.state.scoredEmelents || [];
+    let quickIpScoring = document.getElementById('globalTxt').value;
+    let fullUri = document.getElementById('fullUri').value;
+    let rating  = $('input[name="optradio"]:checked').val();
+
+    //callback from the father
+    if(quickIpScoring !== '') {
+      dataScored.push([quickIpScoring, rating]);
+    } else {
+      dataScored.push([fullUri, rating]);
+    }
+
+    this.removeSelected([fullUri, quickIpScoring]);
+    $('#scoreMsg').removeClass("hidden");
+    this.setState({scoredEmelents: dataScored});
+  },
+  removeSelected: function(data) {
+    //when an user score, all elements selected need to be removed.
+    data.map((element) => data.map((e) => e !== '' ? $(`option[value="${e}"]`).remove() : ''));
+    $(".select-picker, #globalTxt").val('');
+  }
+
+});
+
+
+module.exports = ScoreNotebook;

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/fbcfa683/spot-oa/ui/proxy/js/components/SuspiciousPanel.react.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/proxy/js/components/SuspiciousPanel.react.js b/spot-oa/ui/proxy/js/components/SuspiciousPanel.react.js
index 95a9024..cdc6197 100755
--- a/spot-oa/ui/proxy/js/components/SuspiciousPanel.react.js
+++ b/spot-oa/ui/proxy/js/components/SuspiciousPanel.react.js
@@ -1,4 +1,19 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements; and to You under the Apache License, Version 2.0.
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You 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.
+//
 
 var React = require('react');
 const ReactDOMServer = require('react-dom/server');
@@ -61,9 +76,6 @@ var SuspiciousPanel = React.createClass({
             </span>
         );
     },
-    _render_p_date_cell: function (date, item) {
-        return date + ' ' + item['p_time'];
-    },
     _render_host_cell: function (host, item, idx) {
         var reps, highestRep;
 

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/fbcfa683/spot-oa/ui/proxy/js/components/TimelinePanel.react.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/proxy/js/components/TimelinePanel.react.js b/spot-oa/ui/proxy/js/components/TimelinePanel.react.js
index 01dcb41..33bc725 100755
--- a/spot-oa/ui/proxy/js/components/TimelinePanel.react.js
+++ b/spot-oa/ui/proxy/js/components/TimelinePanel.react.js
@@ -1,5 +1,19 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements; and to You under the Apache License, Version 2.0.
-
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You 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.
+//
 const React = require('react') ;
 
 const TimelineStore = require('../stores/TimelineStore');

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/fbcfa683/spot-oa/ui/proxy/js/constants/ProxyConstants.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/proxy/js/constants/ProxyConstants.js b/spot-oa/ui/proxy/js/constants/ProxyConstants.js
deleted file mode 100755
index ed19357..0000000
--- a/spot-oa/ui/proxy/js/constants/ProxyConstants.js
+++ /dev/null
@@ -1,12 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements; and to You under the Apache License, Version 2.0.
-
-var ProxyConstants = {
-    // API URLS
-    API_SUSPICIOUS: '../../data/proxy/${date}/proxy_scores.tsv',
-    API_DETAILS: '../../data/proxy/${date}/edge-${clientip}-${hash}.tsv',
-    API_COMMENTS: '../../data/proxy/${date}/threats.csv',
-    API_INCIDENT_PROGRESSION: '../../data/proxy/${date}/incident-progression-${hash}.json',
-    API_TIMELINE: '../../data/proxy/${date}/timeline-${hash}.tsv'
-};
-
-module.exports = ProxyConstants;

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/fbcfa683/spot-oa/ui/proxy/js/notebooks.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/proxy/js/notebooks.js b/spot-oa/ui/proxy/js/notebooks.js
new file mode 100644
index 0000000..1ee6e66
--- /dev/null
+++ b/spot-oa/ui/proxy/js/notebooks.js
@@ -0,0 +1,72 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You 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.
+//
+
+const React = require('react');
+const ReactDOM = require('react-dom');
+
+const SpotActions = require('../../js/actions/SpotActions');
+const SpotUtils = require('../../js/utils/SpotUtils');
+
+const DateInput = require('../../js/components/DateInput.react');
+const MainMenu = require('../../js/menu/components/MainMenu.react');
+
+ReactDOM.render(
+  <MainMenu />,
+  document.getElementById('main-menu')
+);
+
+ReactDOM.render(
+    (
+      <form className="form-inline">
+        <div className="form-group">
+          <label htmlFor="dataDatePicker">Data Date:</label>
+          <div className="input-group input-group-xs">
+            <DateInput id="dataDatePicker" />
+            <div className="input-group-addon">
+              <span className="glyphicon glyphicon-calendar" aria-hidden="true"></span>
+            </div>
+          </div>
+        </div>
+      </form>
+    ),
+    document.getElementById('nav_form')
+);
+
+// Build and Render Edge Investigation's panels
+const PanelRow = require('../../js/components/PanelRow.react');
+const Panel = require('../../js/components/Panel.react');
+const IPythonNotebookPanel = require('../../js/components/IPythonNotebookPanel.react');
+
+const ipynbClosure = IPythonNotebookPanel.createIPythonNotebookClosure('',false);
+
+ReactDOM.render(
+  <div id="spot-content">
+    <PanelRow maximized>
+      <Panel title={ipynbClosure.getTitle()} container className="col-md-12">
+        <IPythonNotebookPanel title={ipynbClosure.getTitle()} date={SpotUtils.getCurrentDate()} ipynb="proxy/${date}/Advanced_Mode.ipynb" ipython="NoIpythonNotebooks"/>
+      </Panel>
+    </PanelRow>
+  </div>,
+  document.getElementById('spot-content-wrapper')
+);
+
+// Set search criteria
+var date;
+
+date = SpotUtils.getCurrentDate();
+
+SpotActions.setDate(date);

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/fbcfa683/spot-oa/ui/proxy/js/stores/CommentsStore.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/proxy/js/stores/CommentsStore.js b/spot-oa/ui/proxy/js/stores/CommentsStore.js
index a31456c..eefc400 100755
--- a/spot-oa/ui/proxy/js/stores/CommentsStore.js
+++ b/spot-oa/ui/proxy/js/stores/CommentsStore.js
@@ -1,33 +1,64 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements; and to You under the Apache License, Version 2.0.
-
-var assign = require('object-assign');
-var d3 = require('d3');
-
-var SpotDispatcher = require('../../../js/dispatchers/SpotDispatcher');
-var SpotConstants = require('../../../js/constants/SpotConstants');
-var ProxyConstants = require('../constants/ProxyConstants');
-var RestStore = require('../../../js/stores/RestStore');
-
-var CommentsStore = assign(new RestStore(ProxyConstants.API_COMMENTS), {
-  _parser: d3.dsv('|', 'text/plain'),
-  errorMessages: {
-    404: 'Please choose a different date, no comments have been found'
-  },
-  setDate: function (date)
-  {
-    this.setEndpoint(ProxyConstants.API_COMMENTS.replace('${date}', date.replace(/-/g, '')));
-  }
-});
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You 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.
+//
+
+const SpotDispatcher = require('../../../js/dispatchers/SpotDispatcher');
+const SpotConstants = require('../../../js/constants/SpotConstants');
+
+const ObservableGraphQLStore = require('../../../js/stores/ObservableGraphQLStore');
+
+const DATE_VAR = 'date';
+
+class CommentsStore extends ObservableGraphQLStore {
+    getQuery() {
+        return `
+            query($date:SpotDateType!) {
+                proxy {
+                    threats {
+                        comments(date:$date) {
+                            uri
+                            title
+                            summary: text
+                        }
+                    }
+                }
+            }
+        `;
+    }
+
+    unboxData(data) {
+        return data.proxy.threats.comments;
+    }
+
+    setDate(date) {
+        this.setVariable(DATE_VAR, date);
+    }
+}
+
+const cs = new CommentsStore();
 
 SpotDispatcher.register(function (action) {
   switch (action.actionType) {
     case SpotConstants.UPDATE_DATE:
-      CommentsStore.setDate(action.date);
+      cs.setDate(action.date);
       break;
     case SpotConstants.RELOAD_COMMENTS:
-      CommentsStore.reload();
+      cs.sendQuery();
       break;
   }
 });
 
-module.exports = CommentsStore;
+module.exports = cs;

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/fbcfa683/spot-oa/ui/proxy/js/stores/DetailsStore.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/proxy/js/stores/DetailsStore.js b/spot-oa/ui/proxy/js/stores/DetailsStore.js
index a3c2a4d..33d38b4 100755
--- a/spot-oa/ui/proxy/js/stores/DetailsStore.js
+++ b/spot-oa/ui/proxy/js/stores/DetailsStore.js
@@ -1,64 +1,114 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements; and to You under the Apache License, Version 2.0.
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You 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.
+//
 
-var assign = require('object-assign');
-var d3 = require('d3');
+const SpotDispatcher = require('../../../js/dispatchers/SpotDispatcher');
+const SpotConstants = require('../../../js/constants/SpotConstants');
 
-var SpotDispatcher = require('../../../js/dispatchers/SpotDispatcher');
-var SpotConstants = require('../../../js/constants/SpotConstants');
-var ProxyConstants = require('../constants/ProxyConstants');
-var RestStore = require('../../../js/stores/RestStore');
+const ObservableWithHeadersGraphQLStore = require('../../../js/stores/ObservableWithHeadersGraphQLStore');
 
-var CLIENT_IP_FILTER = 'clientip';
-var HASH_FILTER = 'hash';
+const DATE_VAR = 'date';
+const URI_VAR = 'uri';
+const CLIENT_IP_VAR = 'clientIp';
 
-var DetailsStore = assign(new RestStore(ProxyConstants.API_DETAILS), {
-    _parser: d3.dsv('\t', 'text/plain'),
-    errorMessages: {
-        404: 'No details available'
-    },
-    headers: {
-        p_date: 'Time',
-        clientip: 'Client IP',
-        host: 'Host',
-        webcat: 'Web Category',
-        respcode_name: 'Response Code',
-        reqmethod: 'Request Method',
-        useragent: 'User Agent',
-        resconttype: 'MIME Type',
-        referer: 'Referer',
-        uriport: 'URI Port',
-        serverip: 'Proxy IP',
-        scbytes: 'Server Bytes',
-        csbytes: 'Client Bytes',
-        fulluri: 'Full URI'
-    },
-    setDate: function (date) {
-        this.setEndpoint(ProxyConstants.API_DETAILS.replace('${date}', date.replace(/-/g, '')));
-    },
-    setClientIp: function (clientIp) {
-        this.setRestFilter(CLIENT_IP_FILTER, clientIp);
-    },
-    setHash: function (hash) {
-        this.setRestFilter(HASH_FILTER, hash);
+class DetailsStore extends ObservableWithHeadersGraphQLStore {
+    constructor() {
+        super();
+
+        this.headers = {
+            datetime: 'Time',
+            clientip: 'Client IP',
+            host: 'Host',
+            webcat: 'Web Category',
+            respcode_name: 'Response Code',
+            reqmethod: 'Request Method',
+            useragent: 'User Agent',
+            resconttype: 'MIME Type',
+            referer: 'Referer',
+            uriport: 'URI Port',
+            serverip: 'Proxy IP',
+            scbytes: 'Server Bytes',
+            csbytes: 'Client Bytes',
+            fulluri: 'Full URI'
+        };
+
+        this.ITERATOR = ['datetime', 'clientip', 'host', 'webcat', 'respcode_name', 'reqmethod', 'useragent', 'resconttype', 'referer', 'uriport', 'serverip', 'scbytes', 'csbytes', 'fulluri'];
     }
-});
+
+    getQuery() {
+        return `
+            query($date:SpotDateType!,$uri:String!,$clientIp:SpotIpType!) {
+                proxy {
+                    edgeDetails(date:$date,uri:$uri,clientIp:$clientIp) {
+                        uriport: uriPort
+                        webcat: webCategory
+                        resconttype: responseContentType
+                        datetime
+                        host
+                        referer
+                        csbytes: clientToServerBytes
+                        useragent: userAgent
+                        fulluri: uri
+                        serverip: serverIp
+                        reqmethod: requestMethod
+                        respcode: responseCode
+                        respcode_name: responseCodeLabel
+                        clientip: clientIp
+                        scbytes: serverToClientBytes
+                    }
+                }
+            }
+        `;
+    }
+
+    unboxData(data) {
+        return data.proxy.edgeDetails;
+    }
+
+    setDate(date) {
+        this.setVariable(DATE_VAR, date);
+    }
+
+    setClientIp(clientIp) {
+        this.setVariable(CLIENT_IP_VAR, clientIp);
+    }
+
+    setUri(uri) {
+        this.setVariable(URI_VAR, uri);
+    }
+}
+
+const ds = new DetailsStore();
 
 SpotDispatcher.register(function (action) {
     switch (action.actionType) {
         case SpotConstants.UPDATE_DATE:
-            DetailsStore.setDate(action.date);
+            ds.setDate(action.date);
             break;
         case SpotConstants.SELECT_THREAT:
-            DetailsStore.setClientIp(action.threat[CLIENT_IP_FILTER]);
-            DetailsStore.setHash(action.threat[HASH_FILTER].replace(/\//g, '-'));
+            ds.setClientIp(action.threat.clientip);
+            ds.setUri(action.threat.fulluri);
             break;
         case SpotConstants.RELOAD_SUSPICIOUS:
-            DetailsStore.resetData();
+            ds.resetData();
             break;
         case SpotConstants.RELOAD_DETAILS:
-            DetailsStore.reload();
+            ds.sendQuery();
             break;
     }
 });
 
-module.exports = DetailsStore;
+module.exports = ds;

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/fbcfa683/spot-oa/ui/proxy/js/stores/IncidentProgressionStore.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/proxy/js/stores/IncidentProgressionStore.js b/spot-oa/ui/proxy/js/stores/IncidentProgressionStore.js
index a35bb70..961e00f 100755
--- a/spot-oa/ui/proxy/js/stores/IncidentProgressionStore.js
+++ b/spot-oa/ui/proxy/js/stores/IncidentProgressionStore.js
@@ -1,41 +1,80 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements; and to You under the Apache License, Version 2.0.
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You 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.
+//
 
-var assign = require('object-assign');
+const SpotDispatcher = require('../../../js/dispatchers/SpotDispatcher');
+const SpotConstants = require('../../../js/constants/SpotConstants');
 
-var SpotDispatcher = require('../../../js/dispatchers/SpotDispatcher');
-var SpotConstants = require('../../../js/constants/SpotConstants');
-var JsonStore = require('../../../js/stores/JsonStore');
+const ObservableGraphQLStore = require('../../../js/stores/ObservableGraphQLStore');
 
-var ProxyConstants = require('../constants/ProxyConstants');
+const DATE_VAR = 'date';
+const URI_VAR = 'uri';
 
-var IncidentProgressionStore = assign(new JsonStore(ProxyConstants.API_INCIDENT_PROGRESSION), {
-    errorMessages: {
-        404: 'Please choose a different date, no data has been found'
-    },
-    setDate: function (date) {
-        this.setEndpoint(ProxyConstants.API_INCIDENT_PROGRESSION.replace('${date}', date.replace(/-/g, '')));
-    },
-    setHash: function (hash) {
-        this.setRestFilter('hash', hash);
+class IncidentProgressionStore extends ObservableGraphQLStore {
+    getQuery() {
+        return `
+            query($date:SpotDateType!,$uri:String!) {
+                proxy {
+                    threat {
+                        incidentProgression(date:$date,uri:$uri) {
+                            requests {
+                                reqmethod: requestMethod
+                                clientip: clientIp
+                                resconttype: responseContentType
+                                referer
+                            }
+                            fulluri: uri
+                            referer_for: refererFor
+                        }
+                    }
+                }
+            }
+        `;
     }
-});
+
+    unboxData(data) {
+        return data.proxy.threat.incidentProgression;
+    }
+
+    setDate(date) {
+        this.setVariable(DATE_VAR, date);
+    }
+
+    setUri(uri) {
+        this.setVariable(URI_VAR, uri);
+    }
+}
+
+const ips = new IncidentProgressionStore();
 
 SpotDispatcher.register(function (action) {
     switch (action.actionType) {
         case SpotConstants.UPDATE_DATE:
-            IncidentProgressionStore.setDate(action.date);
+            ips.setDate(action.date);
 
             break;
         case SpotConstants.RELOAD_COMMENTS:
-            IncidentProgressionStore.removeRestFilter('hash');
-            IncidentProgressionStore.resetData();
+            ips.resetData();
             break;
         case SpotConstants.SELECT_COMMENT:
-            IncidentProgressionStore.setHash(action.comment.hash);
-            IncidentProgressionStore.reload();
+            ips.setUri(action.comment.uri);
+            ips.sendQuery();
 
             break;
     }
 });
 
-module.exports = IncidentProgressionStore;
+module.exports = ips;

http://git-wip-us.apache.org/repos/asf/incubator-spot/blob/fbcfa683/spot-oa/ui/proxy/js/stores/NotebookStore.js
----------------------------------------------------------------------
diff --git a/spot-oa/ui/proxy/js/stores/NotebookStore.js b/spot-oa/ui/proxy/js/stores/NotebookStore.js
new file mode 100644
index 0000000..31cffc6
--- /dev/null
+++ b/spot-oa/ui/proxy/js/stores/NotebookStore.js
@@ -0,0 +1,107 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You 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.
+//
+
+const SpotDispatcher = require('../../../js/dispatchers/SpotDispatcher');
+const SpotConstants = require('../../../js/constants/SpotConstants');
+const SuspiciousStore = require('./SuspiciousStore');
+
+const ObservableWithHeadersGraphQLStore = require('../../../js/stores/ObservableWithHeadersGraphQLStore');
+
+const SCORED_ELEMENTS = 'input';
+const RESET_SCORED_ELEMENTS = 'date';
+
+class NotebookStore extends ObservableWithHeadersGraphQLStore {
+    constructor() {
+        super();
+        this.selectedQuery = 'scoreQuery';
+        this.query = {
+          scoreQuery: `
+          mutation($input:[ProxyScoreInputType!]!) {
+            proxy{
+              score(input:$input)
+                  {success}
+            }
+          }`,
+          resetQuery: `
+          mutation($date:SpotDateType!) {
+                  proxy{
+                      resetScoredConnections(date:$date){
+                      success
+                  }
+              }
+          }`
+        };
+        this.completeClass = false;
+    }
+
+    getQuery() {
+        return this.query[this.selectedQuery];
+    }
+
+    unboxData(data) {
+        return data.flow.suspicious;
+    }
+
+    setScoredElements(scoredElements) {
+        this.selectedQuery = 'scoreQuery';
+        this.setVariable(SCORED_ELEMENTS, scoredElements);
+        this.unsetVariables(RESET_SCORED_ELEMENTS);
+    }
+
+    resetScoredElements(date) {
+        this.selectedQuery = 'resetQuery';
+        this.setVariable(RESET_SCORED_ELEMENTS, date);
+        this.unsetVariables(SCORED_ELEMENTS);
+    }
+
+    unsetVariables(variable) {
+        this.unsetVariable(variable);
+    }
+
+    reloadElements() {
+      SuspiciousStore.sendQuery();
+    }
+
+    changeCssCls() {
+      this.completeClass = !this.completeClass;
+    }
+
+
+}
+
+const ns = new NotebookStore();
+
+SpotDispatcher.register(function (action) {
+    switch (action.actionType) {
+        case SpotConstants.SAVE_SCORED_ELEMENTS:
+            ns.setScoredElements(action.scoredElems);
+            ns.sendQuery();
+            break;
+        case SpotConstants.RESET_SCORED_ELEMENTS:
+            ns.resetScoredElements(action.date);
+            ns.sendQuery();
+            break;
+        case SpotConstants.RELOAD_SUSPICIOUS:
+            ns.resetData();
+            break;
+        case SpotConstants.CHANGE_CSS_CLS:
+            ns.changeCssCls();
+            break;
+    }
+});
+
+module.exports = ns;