incubator-blur-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cr...@apache.org
Subject [50/58] [partial] Initial setup of new console
Date Tue, 08 Oct 2013 17:59:58 GMT
http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/688e9d08/contrib/blur-console-old/blur-admin/app/assets/javascripts/audits.js
----------------------------------------------------------------------
diff --git a/contrib/blur-console-old/blur-admin/app/assets/javascripts/audits.js b/contrib/blur-console-old/blur-admin/app/assets/javascripts/audits.js
new file mode 100644
index 0000000..d5b799b
--- /dev/null
+++ b/contrib/blur-console-old/blur-admin/app/assets/javascripts/audits.js
@@ -0,0 +1,128 @@
+/**
+ * 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.
+ */
+//= require jquery.dataTables
+//= require jquery.timepicker
+//= require datatables.fnReloadAjax
+//= require_self
+
+$.extend( $.fn.dataTableExt.oStdClasses, {
+  "sSortAsc": "header headerSortDown",
+  "sSortDesc": "header headerSortUp",
+  "sSortable": "header"
+});
+
+$(document).ready(function() {
+  //Sets max time to one hour after page load to fix button with Now button not going to current time
+  var adjust_time = function(date){
+    date.setHours(date.getHours()+1);
+    return date;
+  };
+  var setup_datepickers = function(){
+    var default_timepicker_options = {
+      showMinute: false,
+      maxDate: adjust_time(new Date),
+      hourGrid: 6,
+      ampm: true,
+    };
+
+    var from_now = new Date();
+    var from_hours = urlVars['from']
+    from_now.setMinutes(0);
+
+
+
+    var to_now = new Date();
+    var to_hours = urlVars['to']
+    to_now.setMinutes(0);
+
+    var from_input = $('<input class="from-cal" placeholder="from"/>').datetimepicker(default_timepicker_options);
+    var to_input = $('<input class="to-cal" placeholder="to"/>').datetimepicker(default_timepicker_options);
+
+    if (from_hours){
+      from_now.setHours(from_now.getHours() - from_hours);
+      from_input.datepicker('setDate', from_now);
+    }
+
+    if (to_hours){
+      to_now.setHours(to_now.getHours() - to_hours);
+      to_input.datepicker('setDate', to_now);
+    }
+
+    $('.row > .span2').prepend('<label>Audit range:</label>', from_input, to_input ,'<button class="btn refresh-button">Refresh</button>');
+  };
+  //Grabs the current time from the page elements (long number string in element id's) 
+  var urlVars = function() {
+    var vars = {};
+    var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m, key, value) {
+      vars[key] = value;
+    });
+    return vars;
+  }();
+
+  var columnDefinitions = [
+    {mData: 'action', bSortable : false},
+    {mData: 'zookeeper_affected'},
+    {mData: 'username', bVisible : false, bSortable : false},
+    {mData: 'user'},
+    {mData: 'model'},
+    {mData: 'mutation'},
+    {mData: 'date_audited', asSorting: ['desc', 'asc']}
+  ];
+
+  var audit_data_table = $('#audits_table > table').dataTable({
+      sDom: "<'row'<'span4'i><'span8'><'span3'f><'span2'r>>t",
+      bPaginate: false,
+      bProcessing: true,
+      bAutoWidth: false,
+      bDeferRender: true,
+      aoColumns: columnDefinitions,
+      oLanguage: {
+        sInfoEmpty: "",
+        sInfo: "Displaying _TOTAL_ audits",
+        sSearch: "Filter audits:",
+        sZeroRecords: "No audits to display",
+        sInfoFiltered: "(filtered from _MAX_ total audits)"
+      }
+  });
+  //On Page Load
+  audit_data_table.fnSort([[6, 'desc']]);
+
+  setup_datepickers();
+  //Page Listeners
+  $('.refresh-button').on('click', function(){
+    var now = new Date();
+    var from = Math.floor((now - $('.from-cal').datetimepicker('getDate')) / 3600 / 1000);
+    var to = Math.floor((now - $('.to-cal').datetimepicker('getDate')) / 3600 / 1000);
+    var params = '?from=' + from + '&to=' + to;
+    var full_url = window.location.protocol + '//' + window.location.host + window.location.pathname + params;
+
+    if (!Modernizr.history) {
+      window.location(full_url);
+    } else {
+      audit_data_table.fnReloadAjax(Routes.audits_path({format: 'json'}) + params);
+
+      if(location.search.length === 0){
+        history.replaceState(null, "Audits | Blur Console", full_url);
+      } else if(location.search !== full_url){
+        history.pushState(null, "Search | Blur Console", full_url);
+      }
+    }
+  });
+});
+
+
+

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/688e9d08/contrib/blur-console-old/blur-admin/app/assets/javascripts/blur_queries.js
----------------------------------------------------------------------
diff --git a/contrib/blur-console-old/blur-admin/app/assets/javascripts/blur_queries.js b/contrib/blur-console-old/blur-admin/app/assets/javascripts/blur_queries.js
new file mode 100644
index 0000000..eafe438
--- /dev/null
+++ b/contrib/blur-console-old/blur-admin/app/assets/javascripts/blur_queries.js
@@ -0,0 +1,213 @@
+/**
+ * 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.
+ */
+//= require jquery.dataTables
+//= require datatables.fnReloadAjax
+//= require_self
+
+$.extend($.fn.dataTableExt.oStdClasses, {
+  "sSortAsc": "header headerSortDown",
+  "sSortDesc": "header headerSortUp",
+  "sSortable": "header"
+});
+
+$(document).ready(function() {
+  var visible_column_count = $('#queries-table thead th').length;
+  var refresh_rate = -1;
+  var refresh_timeout = null;
+  var data_table = null;
+  var load_queries = function() {
+    data_table = $('#queries-table').dataTable({
+      "sDom": "<'row'<'span4'i><'span2'r><'span3'f>>t",
+      bPaginate: false,
+      bProcessing: true,
+      bAutoWidth: false,
+      bDeferRender: true,
+      "oLanguage": {
+        "sInfoEmpty": "",
+        "sInfo": "Displaying _TOTAL_ queries",
+        "sSearch": "Filter queries:",
+        "sZeroRecords": "No queries to display",
+        "sInfoFiltered": "(filtered from _MAX_ total queries)"
+      },
+
+      sAjaxSource: Routes.refresh_zookeeper_blur_queries_path(CurrentZookeeper, 1, {format: 'json'}),
+      aoColumns: table_cols(),
+      fnRowCallback: process_row
+    });
+    data_table.fnSort([[4, 'desc']]);
+    add_refresh_rates(data_table);
+    $('#queries-table').ajaxComplete(function(e, xhr, settings) {
+      if (settings.url.indexOf('/blur_queries/refresh') >= 0) {
+        if (refresh_rate > -1) {
+          refresh_timeout = setTimeout(function() {
+            var range_time_limit = $('.time_range').find('option:selected').val();
+            data_table.fnReloadAjax(Routes.refresh_zookeeper_blur_queries_path(CurrentZookeeper, range_time_limit, {format: 'json'}));
+          }, refresh_rate * 1000);
+        }
+      }
+    });
+    $('.time_range').live('change', function() {
+      var range_time_limit = $(this).find('option:selected').val();
+      data_table.fnReloadAjax(Routes.refresh_zookeeper_blur_queries_path(CurrentZookeeper, range_time_limit, {format: 'json'}));
+    });
+    $('.filter_option').on('click', function(){
+      var container = $(this);
+      var index = visible_column_count - 2;
+      var filter_string = container.attr("data-filter");
+      $('#queries-table').dataTable().fnFilter(filter_string, index);
+    })
+  };
+
+  var table_cols = function() {
+    if (visible_column_count === 8) {
+      return [
+        {
+          "mDataProp": "userid",
+					"sWidth": "85px"
+        }, {
+          "mDataProp": "query",
+          "sWidth": "500px"
+        }, {
+          "mDataProp": "tablename",
+					"sWidth": "75px"
+        }, {
+          "mDataProp": "start",
+					"sWidth": "85px"
+        }, {
+          "mDataProp": "time",
+					"sWidth": "95px"
+        }, {
+          "mDataProp": "status",
+          "sWidth": "100px"
+        }, {
+          "mDataProp": "state",
+          "bVisible": false
+        }, {
+          "mDataProp": "action",
+					"sWidth": "100px"
+        }
+      ];
+    }
+    return [
+      {
+        "mDataProp": "userid"
+      }, {
+        "mDataProp": "tablename"
+      }, {
+        "mDataProp": "start"
+      }, {
+        "mDataProp": "time"
+      }, {
+        "mDataProp": "status",
+        "sWidth": "150px"
+      }, {
+        "mDataProp": "state",
+        "bVisible": false
+      }, {
+        "mDataProp": "action"
+      }
+    ];
+  };
+  var process_row = function(row, data, rowIdx, dataIdx) {
+    var action_td = $('td:last-child', row);
+    if (action_td.html() === '') {
+      action_td.append("<a href='" + (Routes.blur_query_path(data['id'])) + "' class='more_info' style='margin-right: 3px'>More Info</a>");
+      if (data['state'] === 'Running' && data['can_update']) {
+        action_td.append("<form accept-charset='UTF-8' action='" + (Routes.cancel_blur_query_path(data['id'])) + "' class='cancel' data-remote='true' method='put'><div style='margin:0;padding:0;display:inline'><input name='_method' type='hidden' value='put'></div><input class='cancel_query_button btn btn-small' type='submit' value='Cancel'><img src='/assets/loading.gif' style='display:none'></form>");
+      }
+    }
+    var time = data.time.substring(0, data.time.indexOf(' ')).split(':');
+    var timeModifier = data.time.substring(data.time.indexOf(' ') + 1) === 'PM';
+    var timeInSecs = (timeModifier ? parseInt(time[0], 10) + 12 : parseInt(time[0], 10)) * 3600 + parseInt(time[1], 10) * 60 + parseInt(time[2], 10);
+    var dateNow = new Date();
+    var timeNowSecs = dateNow.getHours() * 3600 + dateNow.getMinutes() * 60 + dateNow.getSeconds();
+    if (data.state === 'Running' && Math.abs(timeNowSecs - timeInSecs) > 60) {
+      $(row).addClass('oldRunning');
+    }
+    return row;
+  };
+  var add_refresh_rates = function(data_table) {
+    var refresh_content = '<div class="span3">Auto Refresh: <div class="btn-group">';
+    var options = [
+      {
+        'key': 'Off',
+        'value': -1
+      }, {
+        'key': '10s',
+        'value': 10
+      }, {
+        'key': '1m',
+        'value': 60
+      }, {
+        'key': '10m',
+        'value': 600
+      }
+    ];
+    $.each(options, function(idx, val) {
+      var link_class = idx === 0 ? 'btn-primary' : '';
+      refresh_content += "<a href='javascript:void(0)' class='refresh_option " + link_class + " btn' data-refresh_val='" + val.value + "'>" + val.key + "</a>";
+    });
+    refresh_content += '</div></div>';
+    $('#queries-table_wrapper > .row:first-child').prepend(refresh_content);
+    $('.dataTables_wrapper .row .span3:first-child .btn-group').append('<a id="refresh-queries" class="btn"><i class="icon-refresh"/></a>');
+    $('#refresh-queries').click(function() {
+        clearTimeout(refresh_timeout);
+        data_table.fnReloadAjax();
+    });
+    $('a.refresh_option').click(function() {
+      $('a.refresh_option').removeClass('btn-primary');
+      $(this).addClass('btn-primary');
+      var prev_refresh_rate = refresh_rate;
+      refresh_rate = $(this).data('refresh_val');
+      if (prev_refresh_rate === -1) {
+        data_table.fnReloadAjax();
+      }
+      else if (refresh_rate === -1 && refresh_timeout)
+      {
+        clearTimeout(refresh_timeout);
+      }
+    });
+  };
+  var truncate = function(value, length, ommission) {
+    if (!value) return null;
+    if (!(value.length > length)) return value;
+    return "" + (value.substring(0, length)) + (ommission != null ? ommission : {
+      ommission: ''
+    });
+  };
+  $('.more_info').live('click', function(e) {
+    var self = $(this);
+    self.after(Spinner.clone());
+    e.preventDefault();
+    $.ajax({
+      url: self.attr('href'),
+      type: 'GET',
+      success: function(data) {
+        self.siblings('#loading-spinner').remove();
+        $().popup({
+          title: "Additional Info",
+          titleClass: 'title',
+          body: data
+        });
+      }
+    });
+  });
+  $('.cancel_query_button').live('click', function() {
+    $(this).siblings('img').show();
+  });
+  load_queries();
+});

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/688e9d08/contrib/blur-console-old/blur-admin/app/assets/javascripts/blur_table/blur_tables.js
----------------------------------------------------------------------
diff --git a/contrib/blur-console-old/blur-admin/app/assets/javascripts/blur_table/blur_tables.js b/contrib/blur-console-old/blur-admin/app/assets/javascripts/blur_table/blur_tables.js
new file mode 100644
index 0000000..06e7c80
--- /dev/null
+++ b/contrib/blur-console-old/blur-admin/app/assets/javascripts/blur_table/blur_tables.js
@@ -0,0 +1,29 @@
+/**
+ * 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.
+ */
+//= require jquery.dynatree
+//= require bootstrap-tooltip
+//= require bootstrap-popover
+//= require sorttable
+//= require_tree .
+
+$(document).ready(function() {
+  // Dynatree Setup
+  $.ui.dynatree.nodedatadefaults["icon"] = false;
+
+  // Create the cluster collection and start the stream
+  new ClusterCollection().stream({interval: 10000, update: true});
+});

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/688e9d08/contrib/blur-console-old/blur-admin/app/assets/javascripts/blur_table/cluster.js
----------------------------------------------------------------------
diff --git a/contrib/blur-console-old/blur-admin/app/assets/javascripts/blur_table/cluster.js b/contrib/blur-console-old/blur-admin/app/assets/javascripts/blur_table/cluster.js
new file mode 100644
index 0000000..4c99e00
--- /dev/null
+++ b/contrib/blur-console-old/blur-admin/app/assets/javascripts/blur_table/cluster.js
@@ -0,0 +1,295 @@
+/**
+ * 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 Cluster = Backbone.Model.extend({
+  defaults: {},
+  initialize: function(){
+    this.view = new ClusterView({model: this, id: 'cluster_' + this.id});
+    this.build_child_tables();
+    this.set_running_query_header_state();
+    this.on('change:blur_tables', function(){
+      this.update_child_tables();
+    });
+    this.on('change:safe_mode', function(){
+      $('li#cluster_tab_' + this.get('id') + ' .safemode-icon').toggle();
+    });
+    this.on('table_has_been_queried', function(){
+      this.set_running_query_header_state();
+    });
+  },
+  build_child_tables: function(){
+    this.set({tables: new TableCollection(this.get('blur_tables'), {cluster: this})}, {silent: true});
+  },
+  update_child_tables: function(){
+    this.get('tables').update(this.get('blur_tables'));
+    this.view.set_table_values();
+  },
+  set_running_query_header_state: function(){
+    var tables_queried = this.get('tables').where({queried_recently: true}).length;
+    if (tables_queried > 0) {
+      $('li#cluster_tab_' + this.get('id') + ' .queries-running-icon').show();
+    } else {
+      $('li#cluster_tab_' + this.get('id') + ' .queries-running-icon').hide();
+    }
+  },
+  enable_tables: function(){
+    var selected_tables = this.get('tables').where({state: 'disabled', checked: true});
+    var table_ids = _.map(selected_tables, function(table){ return table.get('id'); });
+    this.send_action_request(selected_tables, _.bind(function(){
+      $().popup({
+        title: "Enable Tables",
+        titleClass: 'title',
+        body: "Are you sure you want to enable these tables?",
+        btns: {
+          "Enable": {
+            "class": "primary",
+            func: _.bind(function() {
+              $.ajax({
+                type: 'PUT',
+                url: Routes.enable_zookeeper_blur_tables_path(CurrentZookeeper, {format: 'json'}),
+                data: {tables: table_ids}
+              });
+              $().closePopup();
+              _.each(selected_tables, function(table){
+                table.set({table_status: 5});
+              });
+              this.view.set_table_state();
+            }, this)
+          },
+          "Cancel": {
+            func: function() {
+              $().closePopup();
+            }
+          }
+        }
+      });
+    }, this));
+  },
+  disable_tables: function(){
+    var selected_tables = this.get('tables').where({state: 'active', checked: true});
+    var table_ids = _.map(selected_tables, function(table){ return table.get('id'); });
+    this.send_action_request(selected_tables, _.bind(function(){
+      $().popup({
+        title: "Disable Tables",
+        titleClass: 'title',
+        body: "Are you sure you want to disable these tables?",
+        btns: {
+          "Disable": {
+            "class": "primary",
+            func: _.bind(function() {
+              $.ajax({
+                type: 'PUT',
+                url: Routes.disable_zookeeper_blur_tables_path(CurrentZookeeper, {format: 'json'}),
+                data: {tables: table_ids}
+              });
+              $().closePopup();
+              _.each(selected_tables, function(table){
+                table.set({table_status: 3});
+              });
+              this.view.set_table_state();
+            }, this)
+          },
+          "Cancel": {
+            func: function() {
+              $().closePopup();
+            }
+          }
+        }
+      });
+    }, this));
+  },
+  delete_tables: function(){
+    var selected_tables = this.get('tables').where({state: 'disabled', checked: true});
+    var table_ids = _.map(selected_tables, function(table){ return table.get('id'); });
+    this.send_action_request(selected_tables, _.bind(function(){
+      var delete_tables_send = function(delete_index) {
+        $.ajax({
+          type: 'DELETE',
+          url: Routes.zookeeper_blur_tables_path(CurrentZookeeper, {format: 'json'}),
+          data: {
+            tables: table_ids,
+            delete_index: delete_index
+          }
+        });
+        $().closePopup();
+        _.each(selected_tables, function(table){
+          table.set({table_status: 1});
+        });
+        this.view.set_table_state();
+      };
+      $().popup({
+        title: "Delete Tables",
+        titleClass: 'title',
+        body: "Do you want to delete all of the underlying table indicies?",
+        btns: {
+          "Delete tables and indicies": {
+            "class": "danger",
+            func: _.bind(delete_tables_send, this, true)
+          },
+          "Delete tables only": {
+            "class": "warning",
+            func: _.bind(delete_tables_send, this, false)
+          },
+          "Cancel": {
+            func: function() {
+              $().closePopup();
+            }
+          }
+        }
+      });
+    }, this));
+  },
+  send_action_request: function(selected_tables, confirm_function){
+    if (_.find(selected_tables, function(table){
+        return table.get('queried_recently') && table.get('state') == 'active';
+    })){
+      $().popup({
+        title: 'Warning! You are attempting to change an active table!',
+        titleClass: 'title',
+        body: 'You are attempting to perform an action on a recently queried table, Do you wish to continue?',
+        btns: {
+          "Continue": { class: 'danger', func: confirm_function },
+          "Cancel": { func: function() { $().closePopup(); } }
+        }
+      });
+    } else {
+      confirm_function();
+    }
+  },
+  perform_action: function(state, action){
+    var selected_tables = this.get('tables').where({state: state, checked: true});
+    if (_.find(selected_tables, function(table){ return table.get('queried_recently'); })){
+      $().popup({
+        title: 'Warning! You are attempting to ' + action + ' an active table!',
+        titleClass: 'title',
+        body: '<div>You are attempting to perform an action on a recently queried table, Do you wish to continue?</div>',
+        btns: {
+          "Enable": {
+            class: 'danger',
+            func: _.bind(function(){
+              this.move_forward_with_action(action, selected_tables);
+            }, this)
+          },
+          "Cancel": {
+            func: function() {
+              $().closePopup();
+            }
+          }
+        }
+      });
+    } else {
+      this.move_forward_with_action(action, selected_tables);
+    }
+  }
+});
+
+var ClusterCollection = Backbone.StreamCollection.extend({
+  model: Cluster,
+  url: Routes.zookeeper_blur_tables_path(CurrentZookeeper, {format: 'json'}),
+  initialize: function(models, options){
+    this.on('add', function(collection){
+      var container = $('#tables-wrapper');
+      var renderedView = $(collection.view.render().el);
+      container.children('div').length === 0 ? container.html(renderedView.addClass('active')) : container.append(renderedView);
+    });
+  }
+});
+
+var ClusterView = Backbone.View.extend({
+  className: 'tab-pane cluster',
+  template: JST['templates/blur_table/cluster_view'],
+  events: {
+    'click .bulk-action-checkbox' : 'set_table_state',
+    'click .check-all' : 'check_all_boxes',
+    'click .btn[data-action=enable]' : 'enable_tables',
+    'click .btn[data-action=disable]' : 'disable_tables',
+    'click .btn[data-action=delete]' : 'delete_tables'
+  },
+  colspan_lookup : {'active': 6, 'disabled': 4},
+  render: function(){
+    this.$el.html(this.template({cluster: this.model}));
+    this.populate_tables();
+    return this;
+  },
+  populate_tables: function(){
+    var el = $(this.el);
+    this.model.get('tables').each(function(table){
+      elementToAdd = table.view.el.rendered ? table.view.el : table.view.render().el;
+      var table_parent = el.find('.' + table.get('table') + '-table');
+      table_parent.append(elementToAdd);
+      table_parent.siblings('thead').find('.check-all').removeAttr('disabled');
+      sorttable.makeSortable(table_parent.parent()[0]);
+    });
+    this.set_table_values();
+  },
+  set_table_values: function(){
+    var table_prefixes = ['active', 'disabled'];
+    for (var index = 0; index < table_prefixes.length; index++){
+      var table = this.$el.find('.' + table_prefixes[index] + '-table');
+      table.find('.no-data').remove();
+      var table_children_count = table.children().length;
+      this.$el.find('.' + table_prefixes[index] + '-counter').text(table_children_count);
+      if (this.model.get('tables').where({table: table_prefixes[index]}).length <= 0){
+        table.append(this.no_table(this.colspan_lookup[table_prefixes[index]]));
+      }
+    }
+  },
+  set_table_state: function(){
+    var checked_count = this.$el.find('tbody tr.highlighted-row').length;
+    var set_checkbox_state = _.bind(function(){
+      var row_count = this.$el.find('tbody:visible tr:not(.no-data, .changing-state)').length;
+      var check_all = this.$el.find('.tab-pane.active .check-all');
+      if (checked_count === row_count){
+        if (checked_count === 0){
+          check_all.removeAttr('checked');
+          check_all.attr('disabled', 'disabled');
+        } else {
+          check_all.attr('checked', 'checked');
+        }
+      } else {
+        check_all.removeAttr('checked');
+      }
+    }, this);
+    var set_button_state = _.bind(function(){
+      var toggle_button = this.$el.find('.tab-pane.active button');
+      checked_count > 0 ? toggle_button.removeAttr('disabled') : toggle_button.attr('disabled', 'disabled');
+    }, this);
+    set_checkbox_state();
+    set_button_state();
+  },
+  check_all_boxes: function(){
+    var check_all = this.$el.find('.tab-pane.active .check-all');
+    if (check_all.is(':checked')){
+      this.$el.find('.tab-pane.active .bulk-action-checkbox:not(:checked)').click();
+    } else {
+      this.$el.find('.tab-pane.active .bulk-action-checkbox:checked').click();
+    }
+  },
+  no_table: function(colspan){
+    return $('<tr class="no-data"><td/><td colspan="' + colspan + '">No Tables for this Section</td></tr>')
+  },
+  enable_tables: function(event){
+    this.model.enable_tables();
+    this.model.change();
+  },
+  disable_tables: function(event){
+    this.model.disable_tables();
+    this.model.change();
+  },
+  delete_tables: function(event){
+    this.model.delete_tables();
+  }
+});

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/688e9d08/contrib/blur-console-old/blur-admin/app/assets/javascripts/blur_table/table.js
----------------------------------------------------------------------
diff --git a/contrib/blur-console-old/blur-admin/app/assets/javascripts/blur_table/table.js b/contrib/blur-console-old/blur-admin/app/assets/javascripts/blur_table/table.js
new file mode 100644
index 0000000..e8faa7b
--- /dev/null
+++ b/contrib/blur-console-old/blur-admin/app/assets/javascripts/blur_table/table.js
@@ -0,0 +1,205 @@
+/**
+ * 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.
+ */
+//= require flot/flot
+
+var Table = Backbone.Model.extend({
+  defaults: {
+    'checked' : false,
+  },
+  state_lookup : ['deleted', 'deleting', 'disabled', 'disabling', 'active', 'enabling'],
+  table_lookup : ['deleted', 'disabled', 'disabled', 'active', 'active', 'disabled'],
+  colspan_lookup : {'active': 6, 'disabled': 5},
+  initialize: function(){
+    this.view = new TableView({model: this});
+    this.view.render();
+    this.set({
+      state: this.state_lookup[this.get('table_status')],
+      table: this.table_lookup[this.get('table_status')]
+    });
+    this.on('change:table_status', function(){
+      var table = this.get('table')
+      this.set({
+        state: this.state_lookup[this.get('table_status')],
+        table: this.table_lookup[this.get('table_status')],
+        checked: false
+      }, {
+        silent: true
+      });
+      if (this.get('table') !== table){
+        var table_parent = this.collection.cluster.view.$el.find('.' + this.get('table') + '-table');
+        table_parent.append(this.view.el);
+        table_parent.siblings('thead').find('.check-all').removeAttr('disabled');
+        sorttable.makeSortable(table_parent.parent()[0]);
+      }
+    });
+    this.on('change:queried_recently', function(){
+      this.collection.cluster.trigger('table_has_been_queried');
+    });
+    this.on('change', function(){
+      this.view.render();
+    });
+  },
+  parse_uri: function(piece){
+    var parse_url = /^(?:([A-Za-z]+):)?(\/{0,3})([0-9.\-A-Za-z]+)(?::(\d+))?(?:\/([^?#]*))?(?:\?([^#]*))?(?:#(.*))?$/;
+    var result = parse_url.exec(this.get('table_uri'));
+    var index = _.indexOf(['url', 'scheme', 'slash', 'host', 'port', 'path', 'query', 'hash'], piece);
+    if (index === -1) throw 'The index, ' + piece + ' does not exist as a part of a uri.';
+    return result[index];
+  },
+  get_terms: function(request_data, success){
+    $.ajax({
+      type: 'GET',
+      url: Routes.terms_blur_table_path(this.get('id'), {format: 'json'}),
+      data: request_data,
+      success: success,
+      error:function (xhr, ajaxOptions, thrownError){
+        alert(thrownError + ": Terms Currently Unavailable");
+      }
+    });
+  },
+  capitalize_first: function(word){
+    return word.charAt(0).toUpperCase() + word.slice(1);
+  }
+});
+
+var TableCollection = Backbone.StreamCollection.extend({
+  model: Table,
+  initialize: function(models, options){
+    this.cluster = options.cluster;
+    this.on('add', function(table){
+      var table_parent = table.collection.cluster.view.$el.find('.' + this.get('table') + '-table');
+      table_parent.append(table.view.el);
+      table_parent.siblings('thead').find('.check-all').removeAttr('disabled');
+      sorttable.makeSortable(table_parent.parent()[0]);
+    });
+    this.on('remove', function(table){
+      table.view.destroy();
+    });
+  }
+});
+
+var TableView = Backbone.View.extend({
+  tagName: 'tr',
+  className: 'blur_table',
+  events: {
+    'click .bulk-action-checkbox' : 'toggle_row',
+    'click .hosts' : 'show_hosts',
+    'click .info' : 'show_schema',
+    'click .comments' : 'show_comments'
+  },
+  template: JST['templates/blur_table/table_row'],
+  render: function(){
+    this.rendered = true;
+    this.$el.removeClass('changing-state')
+    this.$el.attr('blur_table_id', this.model.get('id')).html(this.template({table: this.model})).removeClass('highlighted-row');
+    if (this.model.get('checked')) this.$el.addClass('highlighted-row').find('.bulk-action-checkbox').prop('checked', 'checked');
+    if (['disabling', 'enabling', 'deleting'].indexOf(this.model.get('state')) >= 0) this.$el.addClass('changing-state');
+    return this;
+  },
+  toggle_row: function(){
+    this.model.set({checked: !this.model.get('checked')}, {silent: true});
+    this.$el.toggleClass('highlighted-row');
+  },
+  show_hosts: function(){
+    $.ajax({
+      type: 'GET',
+      url: Routes.hosts_blur_table_path(this.model.get('id'), {format: 'json'}) ,
+      success: _.bind(function(data){
+        var host_modal = $(JST['templates/blur_table/hosts']({table: this.model, hosts: data}));
+        this.setup_filter_tree(host_modal.find('.table_info_tree'));
+        $().popup({
+          title: 'Additional Host/Shard Info',
+          titleClass: 'title',
+          body: host_modal
+        });
+      }, this)
+    });
+    return false;
+  },
+  show_schema: function(){
+    $.ajax({
+      type: 'GET',
+      url: Routes.schema_blur_table_path(this.model.get('id'), {format: 'json'}) ,
+      success: _.bind(function(data){
+        var schema_modal = $(JST['templates/blur_table/schema']({table: this.model, schema: data}));
+        this.setup_filter_tree(schema_modal.find('.table_info_tree'));
+        $().popup({
+          title: 'Additional Schema Info',
+          titleClass: 'title',
+          body: schema_modal,
+        });
+        var table_model = this.model;
+        schema_modal.on('click', '.terms', function(){
+          var clicked_element = $(this);
+          var request_data =
+          {
+            family: $(this).attr('data-family-name'),
+            column: $(this).attr('data-column-name'),
+            startwith: ' ',
+            size: 20
+          };
+          table_model.get_terms(request_data, _.bind(function(data) {
+            new TermsView({
+              clicked_element: clicked_element,
+              parent: this,
+              terms: data,
+              family: request_data.family,
+              column: request_data.column,
+              table_id: this.get('id')})
+            .render();
+          }, table_model));
+        });
+      }, this)
+    });
+    return false;
+  },
+  show_comments: function(){
+    var comment_modal = $(JST['templates/blur_table/comments']({table: this.model}));
+    $().popup({
+      title: 'Comments',
+      titleClass: 'title',
+      body: comment_modal ,
+      btns: {
+        "Submit": {
+          "class": "primary",
+          func: _.bind(function() {
+            var input_comment = document.getElementById("comments").value;
+            $.ajax({
+              type: 'PUT',
+              url: Routes.comment_blur_table_path(this.model.get('id'), {format: 'json'}) ,
+              data: {comment: input_comment},
+              success: _.bind(function(){
+                this.model.set({comments: input_comment});
+              }, this)
+            });
+
+            $().closePopup();
+          }, this)
+        },
+        "Cancel": {
+          func: function() {
+            $().closePopup();
+          }
+        }
+      }
+    });
+    return false;
+  },
+  setup_filter_tree: function(selector) {
+    return selector.dynatree();
+  }
+});

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/688e9d08/contrib/blur-console-old/blur-admin/app/assets/javascripts/blur_table/terms.js
----------------------------------------------------------------------
diff --git a/contrib/blur-console-old/blur-admin/app/assets/javascripts/blur_table/terms.js b/contrib/blur-console-old/blur-admin/app/assets/javascripts/blur_table/terms.js
new file mode 100644
index 0000000..8c210a1
--- /dev/null
+++ b/contrib/blur-console-old/blur-admin/app/assets/javascripts/blur_table/terms.js
@@ -0,0 +1,115 @@
+/**
+ * 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 TermsView = Backbone.View.extend({
+  className: 'terms-view',
+  template: JST['templates/blur_table/terms_view'],
+  render: function(){
+    this.popover = this.options.clicked_element.popover({
+      title: this.options.column + " terms<i class='icon-remove popover-close' style='position:absolute; top:15px;right:15px'></i>",
+      content: this.template(this.options),
+      trigger: 'focus',
+      placement: 'right'
+    }).popover('show');
+    this.set_buttons_state();
+
+    // Declare all events separate of the events hash
+    // because the popover clones the html and reference
+    // is lost
+    $('.popover')
+      .on('click', function(event){event.stopPropagation();})
+      .on('click', '.popover-close', _.bind(this.close_popover, this))
+      .on('click', '.more-terms-btn:not(.disabled)', _.bind(this.get_more_terms, this))
+      .on('click', '.reset-terms', _.bind(this.refresh_list, this))
+      .on('click', '.search-term-link', _.bind(this.redirect_to_search, this))
+      .on('click', '.term-search-btn', _.bind(this.search_for_terms, this))
+      .on('keydown', _.bind(this.search_using_enter, this));
+    $('html').on('click', _.bind(this.close_popover, this));
+  },
+  close_popover: function(){
+    this.popover.popover('hide');
+    $('.popover').off('click');
+    $('html').off('click');
+    this.destroy();
+  },
+  get_terms: function(request_data, success){
+    this.options.parent.get_terms(request_data, success);
+  },
+  // Get another set of terms starting at the last list position
+  // append it to the current list
+  get_more_terms: function(){
+    var spinner = Spinner.clone();
+    $('.more-terms').append(spinner);
+    var last_term = $('.term-li:last-child > span:last-child > span').text();
+    this.get_terms({
+      family: this.options.family,
+      column: this.options.column,
+      startwith: last_term,
+      size: 21
+    }, _.bind(function(data) {
+      data.shift(1);
+      spinner.remove();
+      $('.popover .terms-list').append(JST['templates/blur_table/terms_list']({terms: data}));
+    }, this));
+  },
+  // Get the first set of terms resetting the search
+  // overwrites the list
+  refresh_list: function(){
+    var spinner = Spinner.clone();
+    $('.more-terms').append(spinner);
+    this.get_terms({
+      family: this.options.family,
+      column: this.options.column,
+      startwith: ' ',
+      size: 20
+    }, _.bind(function(data) {
+      spinner.remove();
+      $('.popover .terms-list').html(JST['templates/blur_table/terms_list']({terms: data}));
+    }, this));
+  },
+  search_for_terms: function(){
+    var spinner = Spinner.clone();
+    $('.more-terms').append(spinner);
+    var last_term = $('.popover .term-search').val();
+    this.options.parent.get_terms({
+      family: this.options.family,
+      column: this.options.column,
+      startwith: last_term,
+      size: 20
+    }, _.bind(function(data) {
+      spinner.remove();
+      $('.popover .terms-list').html(JST['templates/blur_table/terms_list']({terms: data}));
+      this.set_buttons_state();
+    }, this));
+  },
+  search_using_enter: function(event){
+    if (event.which === 13) {
+      event.preventDefault();
+      this.search_for_terms();
+    }
+  },
+  redirect_to_search: function(event){
+    var term = $(event.currentTarget).siblings('.input').children('span').text();
+    window.location = Routes.zookeeper_searches_path(CurrentZookeeper)
+      + ("?table_id=" + this.options.table_id + "&query=")
+      + encodeURIComponent(this.options.family + "." + this.options.column + ":" + term);
+  },
+  set_buttons_state: function(){
+    if ($('.popover .terms-list').children().length < 20){
+      $('.popover .more-terms-btn').addClass('disabled');
+    }
+  }
+})
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/688e9d08/contrib/blur-console-old/blur-admin/app/assets/javascripts/dashboard/dashboard.js
----------------------------------------------------------------------
diff --git a/contrib/blur-console-old/blur-admin/app/assets/javascripts/dashboard/dashboard.js b/contrib/blur-console-old/blur-admin/app/assets/javascripts/dashboard/dashboard.js
new file mode 100644
index 0000000..cdeacdb
--- /dev/null
+++ b/contrib/blur-console-old/blur-admin/app/assets/javascripts/dashboard/dashboard.js
@@ -0,0 +1,23 @@
+/**
+ * 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.
+ */
+//= require_tree
+
+$(document).ready(function() {
+  // Create the hdfs and blur instances and start streaming
+  new HdfsCollection().stream({interval: 5000, update: true});
+  new ZookeeperCollection().stream({interval: 5000, update: true});
+});

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/688e9d08/contrib/blur-console-old/blur-admin/app/assets/javascripts/dashboard/hdfs.js
----------------------------------------------------------------------
diff --git a/contrib/blur-console-old/blur-admin/app/assets/javascripts/dashboard/hdfs.js b/contrib/blur-console-old/blur-admin/app/assets/javascripts/dashboard/hdfs.js
new file mode 100644
index 0000000..f1a0e53
--- /dev/null
+++ b/contrib/blur-console-old/blur-admin/app/assets/javascripts/dashboard/hdfs.js
@@ -0,0 +1,71 @@
+/**
+ * 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.
+ */
+//=require flot/flot
+//=require flot/jquery.flot.pie.min.js
+
+var Hdfs = Backbone.Model.extend({
+  initialize: function(){
+    this.view = new HdfsView({model: this});
+    this.on('change', function(){
+      this.view.render();
+    });
+  },
+  node_width: function(){
+    var stats = this.get('most_recent_stats');
+    return Math.round((stats.live_nodes / stats.total_nodes) * 100);
+  },
+  usage_width: function(){
+    var stats = this.get('most_recent_stats');
+    return Math.round((stats.dfs_used_real / stats.config_capacity) * 100);
+  },
+  percent_used: function(){
+    var usage_percent = this.usage_width();
+    if (usage_percent < 1) {
+      return '< 1%';
+    }
+    return usage_percent + '%';
+  }
+});
+
+var HdfsCollection = Backbone.StreamCollection.extend({
+  model: Hdfs,
+  url: Routes.hdfs_index_path({format: 'json'}),
+  initialize: function(models, options){
+    this.on('add', function(hdfs){
+      $('#hdfses').append(hdfs.view.render().el);
+    });
+    this.on('remove', function(hdfs){
+      hdfs.view.destroy();
+    });
+  }
+});
+
+var HdfsView = Backbone.View.extend({
+  className: 'hdfs_info online',
+  events: {
+    'click' : 'navigate_to_hdfs'
+  },
+  template: JST['templates/dashboard/hdfs'],
+  render: function(){
+    this.$el.html(this.template({hdfs: this.model}));
+    return this;
+  },
+  navigate_to_hdfs: function(){
+    var id = this.model.get('id');
+    window.location = Routes.hdfs_index_path() + '/' + id + '/show';
+  }
+});

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/688e9d08/contrib/blur-console-old/blur-admin/app/assets/javascripts/dashboard/long_running.js
----------------------------------------------------------------------
diff --git a/contrib/blur-console-old/blur-admin/app/assets/javascripts/dashboard/long_running.js b/contrib/blur-console-old/blur-admin/app/assets/javascripts/dashboard/long_running.js
new file mode 100644
index 0000000..a125c8d
--- /dev/null
+++ b/contrib/blur-console-old/blur-admin/app/assets/javascripts/dashboard/long_running.js
@@ -0,0 +1,39 @@
+/**
+ * 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 LongRunningView = Backbone.View.extend({
+  tagName: 'ul',
+  className: 'modal-list',
+  events: {
+    'click .icon-remove' : 'cancel_query'
+  },
+  template: JST['templates/dashboard/long_running'],
+  render: function(data){
+    this.$el.html(this.template({data: data}));
+    return this;
+  },
+  cancel_query: function(event){
+    var self = $(event.target);
+    var id = $(event.target.parentElement).attr('data-id');
+    $.ajax({
+      type: 'PUT',
+      url: Routes.cancel_blur_query_path(id, {format: 'json'}),
+      success: function(){
+        self.closest('li').remove();
+      }
+    });
+  }
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/688e9d08/contrib/blur-console-old/blur-admin/app/assets/javascripts/dashboard/zookeeper.js
----------------------------------------------------------------------
diff --git a/contrib/blur-console-old/blur-admin/app/assets/javascripts/dashboard/zookeeper.js b/contrib/blur-console-old/blur-admin/app/assets/javascripts/dashboard/zookeeper.js
new file mode 100644
index 0000000..02b811f
--- /dev/null
+++ b/contrib/blur-console-old/blur-admin/app/assets/javascripts/dashboard/zookeeper.js
@@ -0,0 +1,152 @@
+/**
+ * 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.
+ */
+//= require flot/flot
+//= require flot/jquery.flot.pie.min.js
+
+var Zookeeper = Backbone.Model.extend({
+  initialize: function(){
+    this.view = new ZookeeperView({model: this});
+    this.on('change', function(){
+      this.view.render();
+    });
+  },
+  consistent_controller_versions: function(){
+    return this.get('controller_version') === 1;
+  },
+  consistent_shard_versions: function(){
+    return this.get('shard_version') === 1;
+  },
+  online_controller_nodes: function(){
+    return this.get('controller_total') - this.get('controller_offline_node');
+  },
+  online_shard_nodes: function(){
+    return this.get('shard_total') - this.get('shard_offline_node');
+  },
+  controller_progress_width: function(){
+    return Math.round((this.online_controller_nodes() / this.get('controller_total')) * 100)
+  },
+  shard_progress_width: function(){
+    return Math.round((this.online_shard_nodes() / this.get('shard_total')) * 100)
+  },
+  status_image: function(){
+    var state, img;
+    switch(this.get('zookeeper_status'))
+    {
+      case 0:
+        state = "offline.";
+        img = 'offline';
+        break;
+      case 1:
+        state = "online.";
+        img = "online";
+        break;
+      case 2:
+        state = "in a quorum warning state.";
+        img = "warning";
+        break;
+      case 3:
+        state = "experiencing a quorum failure.";
+        img = 'failure';
+        break;
+      default:
+        state = "offline.";
+        img = 'offline';
+        break;
+    }
+    return '<img src="/assets/' + img + '.png" title="Zookeeper is ' + state + '"/>'
+  }
+});
+
+var ZookeeperCollection = Backbone.StreamCollection.extend({
+  model: Zookeeper,
+  url: Routes.zookeepers_path({format: 'json'}),
+  initialize: function(models, options){
+    this.on('add', function(zookeeper){
+      $('#zookeepers').append(zookeeper.view.render().el);
+    });
+    this.on('remove', function(zookeeper){
+      zookeeper.view.destroy();
+    });
+  }
+});
+
+var ZookeeperView = Backbone.View.extend({
+  className: 'zookeeper_info',
+  events: {
+    'click' : 'navigate_to_zookeeper',
+    'click .warning' : 'show_long_running'
+  },
+  template: JST['templates/dashboard/zookeeper'],
+  render: function(){
+    this.$el.html(this.template({zookeeper: this.model}));
+    if (this.$el.find('.cont-chart')[0]){
+      this.draw_zk_charts(this.$el.find('.cont-chart')[0], this.model.get('controller_total'), this.model.get('controller_offline_node'));
+    }
+    if (this.$el.find('.shard-chart')[0]){
+      this.draw_zk_charts(this.$el.find('.shard-chart')[0], this.model.get('shard_total'), this.model.get('shard_offline_node'));
+    }
+    return this;
+  },
+  navigate_to_zookeeper: function(){
+    window.location = Routes.zookeeper_path(this.model.get('id'));
+  },
+  show_long_running: function(){
+    $.ajax({
+      type: 'GET',
+      url: Routes.long_running_queries_zookeeper_path(this.model.get('id'), {format: 'json'}),
+      success: function(data){
+        $().popup({
+          title: "Long Running Queries",
+          titleClass: 'title',
+          body: new LongRunningView().render(data).el
+        });
+      }
+    })
+    return false;
+  },
+  draw_zk_charts: function(target, total, offline){
+    var options = {
+      series: {
+        pie: {
+          show: true,
+          radius: 1,
+          innerRadius: 0.63,
+          label: {
+            show: false
+          }
+        }
+      },
+      legend: {
+        show: false
+      }
+    };
+    if (total == 0) {
+      var data = [
+        { label: "None", data: 1, color: "#CED7DA" }
+      ];
+    }
+    else {
+      var data = [
+        { label: "Online", data: total - offline, color: "#7DC77D" },
+        { label: "Offline", data: offline, color: "#FF1919" }
+      ];
+    }
+    target.style.width = '135px';
+    target.style.height = '135px';
+    $.plot(target, data, options);
+  }
+});

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/688e9d08/contrib/blur-console-old/blur-admin/app/assets/javascripts/environment/cluster.js
----------------------------------------------------------------------
diff --git a/contrib/blur-console-old/blur-admin/app/assets/javascripts/environment/cluster.js b/contrib/blur-console-old/blur-admin/app/assets/javascripts/environment/cluster.js
new file mode 100644
index 0000000..e61a715
--- /dev/null
+++ b/contrib/blur-console-old/blur-admin/app/assets/javascripts/environment/cluster.js
@@ -0,0 +1,85 @@
+/**
+ * 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 ClusterModel = Backbone.Model.extend({
+  initialize: function(){
+    this.view = new ClusterView({model: this});
+    this.on('change', function(){
+      this.view.render();
+    });
+  },
+  url: function(){
+    return '/clusters/' + this.get('id') + '.json';
+  },
+  safe_mode: function(){
+    return this.get('safe_mode') ? 'Yes' : 'No';
+  },
+  remove: function(){
+    this.destroy({
+      success: function(){
+        Notification("Successfully forgot the Cluster!", true);
+      },
+      error: function(){
+        Notification("Failed to forget the Cluster", false);
+      }
+    });
+  }
+});
+
+var ClusterCollection = Backbone.StreamCollection.extend({
+  url: "/zookeepers/" + CurrentZookeeper + "/cluster/",
+  model: ClusterModel,
+  initialize: function(models, options){
+    this.on('add', function(clusters){
+      if (this.length == 1){
+        $('#clusters .no_children').hide();
+        $('#clusters tbody').append(clusters.view.render().$el);
+      } else {
+        $('#clusters tbody').append(clusters.view.render().$el);
+      }
+    });
+    this.on('remove', function(clusters){
+      if (this.length <= 1){
+        $('#clusters .no_children').show();
+        clusters.view.destroy();
+      } else {
+        clusters.view.destroy();
+      }
+    });
+  }
+});
+
+var ClusterView = Backbone.View.extend({
+  tagName: 'tr',
+  template: JST['templates/environment/cluster'],
+  events:{
+    "click .more-shard-info" : "show_shards",
+    "click .destroy-cluster" : "destroy_cluster"
+  },
+  render: function(){
+    this.$el.attr('data-cluster-id', this.model.get('id')).html(this.template({cluster: this.model}));
+    return this;
+  },
+  show_shards: function(event){
+    new ShardCollection(null, {cluster_id: this.model.get('id')});
+  },
+  destroy_cluster: function(){
+    Confirm_Delete({
+      message: "forget this cluster and its associated shards",
+      confirmed_action: _.bind(this.model.remove, this.model)
+    });
+  }
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/688e9d08/contrib/blur-console-old/blur-admin/app/assets/javascripts/environment/controller.js
----------------------------------------------------------------------
diff --git a/contrib/blur-console-old/blur-admin/app/assets/javascripts/environment/controller.js b/contrib/blur-console-old/blur-admin/app/assets/javascripts/environment/controller.js
new file mode 100644
index 0000000..c0a2a95
--- /dev/null
+++ b/contrib/blur-console-old/blur-admin/app/assets/javascripts/environment/controller.js
@@ -0,0 +1,97 @@
+/**
+ * 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 ControllerModel = Backbone.Model.extend({
+  initialize: function(){
+    this.view = new ControllerView({model: this});
+    this.on('change', function(){
+      this.view.render();
+    });
+  },
+  url: function(){
+    return '/blur_controllers/' + this.get('id') + '.json';
+  },
+  remove: function(){
+    if(this.get('controller_status') == 0){
+      this.destroy({
+        success: function(){
+          Notification("Successfully forgot the Controller!", true);
+        },
+        error: function(){
+          Notification("Failed to forget the Controller", false);
+        }
+      });
+    } else {
+      Notification("Cannot forget a Controller that is online!", false);
+    }
+  }
+});
+
+var ControllerCollection = Backbone.StreamCollection.extend({
+  url: "/zookeepers/" + CurrentZookeeper + "/controller/",
+  model: ControllerModel,
+  initialize: function(models, options){
+    this.on('add', function(controller){
+      if (this.length == 1){
+        $('#controllers .no_children').hide();
+        $('#controllers tbody').append(controller.view.render().$el);
+      } else {
+        $('#controllers tbody').append(controller.view.render().$el);
+      }
+    });
+    this.on('remove', function(controller){
+      if (this.length == 0){
+        $('#controllers .no_children').show();
+        controller.view.destroy();
+      } else {
+        controller.view.destroy();
+      }
+    });
+  }
+});
+
+var ControllerView = Backbone.View.extend({
+  tagName: 'tr',
+  template: JST['templates/environment/controller'],
+  events:{
+    "click .destroy-controller" : "destroy_controller"
+  },
+  render: function(){
+    this.$el.attr('data-controller-id', this.model.get('id')).html(this.template({controller: this.model}));
+    this.setRowStatus();
+    return this;
+  },
+  setRowStatus: function(){
+    switch(this.model.get('controller_status'))
+    {
+      case 0:
+        this.$el.attr('class', 'error');
+        return;
+      case 1:
+        this.$el.attr('class', '');
+        return;
+      case 2:
+        this.$el.attr('class', 'warning');
+        return;
+    }
+  },
+  destroy_controller: function(){
+    Confirm_Delete({
+      message: "forget this controller",
+      confirmed_action: _.bind(this.model.remove, this.model)
+    });
+  }
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/688e9d08/contrib/blur-console-old/blur-admin/app/assets/javascripts/environment/environment.js
----------------------------------------------------------------------
diff --git a/contrib/blur-console-old/blur-admin/app/assets/javascripts/environment/environment.js b/contrib/blur-console-old/blur-admin/app/assets/javascripts/environment/environment.js
new file mode 100644
index 0000000..8488b32
--- /dev/null
+++ b/contrib/blur-console-old/blur-admin/app/assets/javascripts/environment/environment.js
@@ -0,0 +1,47 @@
+/**
+ * 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.
+ */
+//= require bootstrap-tooltip
+//= require bootstrap-popover
+//= require_tree .
+
+// Confirmation popup for forgetting parts of the ZK
+var Confirm_Delete = function(options){
+  $().popup({
+      title: "Are you sure?",
+      titleClass: 'title',
+      body: '<div>Are you sure that you want to ' + options.message + '?</div>',
+      btns: {
+        "Remove": {
+          "class": "danger",
+          func: function(){
+            options.confirmed_action();
+            $().closePopup();
+          }
+        },
+        "Cancel": {
+          func: function() {
+            $().closePopup();
+          }
+        }
+      }
+    });
+};
+
+$(document).ready(function(){
+  // Start streaming the model on 5 sec intervals
+  new ZookeeperModel().stream(5000);
+});

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/688e9d08/contrib/blur-console-old/blur-admin/app/assets/javascripts/environment/shard.js
----------------------------------------------------------------------
diff --git a/contrib/blur-console-old/blur-admin/app/assets/javascripts/environment/shard.js b/contrib/blur-console-old/blur-admin/app/assets/javascripts/environment/shard.js
new file mode 100644
index 0000000..adc61e5
--- /dev/null
+++ b/contrib/blur-console-old/blur-admin/app/assets/javascripts/environment/shard.js
@@ -0,0 +1,119 @@
+/**
+ * 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 ShardModel = Backbone.Model.extend({
+  initialize: function(){
+    this.view = new ShardView({model: this});
+  },
+  url: function(){
+    return '/blur_shards/' + this.get('id') + '.json';
+  },
+  status: function(){
+    var statusString = this.get('node_name');
+    statusString += " | Blur Version: " + this.get('blur_version');
+    statusString += " | Status: " + this.onlineStatus();
+    if (this.get('shard_status') != 1) {
+      statusString += " at " + this.offlineDate();
+    }
+    return statusString;
+  },
+  onlineStatus: function(){
+    switch(this.get('shard_status'))
+    {
+      case 0:
+        return "Offline"
+      case 1:
+        return "Online"
+      case 2:
+        return "Quorum Issue"
+    }
+  },
+  remove: function(){
+    if(this.get('shard_status') == 0){
+      this.destroy({
+        success: function(){
+          Notification("Successfully forgot the Shard!", true);
+        },
+        error: function(){
+          Notification("Failed to forget the Shard", false);
+        }
+      });
+    } else {
+      Notification("Cannot forget a Shard that is online!", false);
+    }
+  },
+  offlineDate: function(){
+    var date = new Date(this.get('updated_at').toLocaleString())
+    var formattedDate = date.getMonth() + '/' + date.getDay() + '/' + date.getFullYear();
+    var formattedTime = date.getHours() + ':' + date.getMinutes();
+    return formattedDate + ' ' + formattedTime;
+  }
+});
+
+var ShardCollection = Backbone.Collection.extend({
+  model: ShardModel,
+  initialize: function(models, options){
+    this.url = Routes.cluster_blur_shards_path(options.cluster_id, {format: 'json'});
+    this.view = new ShardCollectionView({collection: this});
+    this.fetch({
+      success: _.bind(function(){
+        this.view.render();
+      }, this)
+    });
+  },
+  comparator: function(shard){
+    return [shard.get('shard_status'), shard.get('node_name')];
+  }
+});
+
+var ShardCollectionView = Backbone.View.extend({
+  tagName: 'ul',
+  className: 'modal-list no-well',
+  render: function(){
+    this.collection.each(_.bind(function(shard){
+      this.$el.append(shard.view.render().$el);
+    }, this));
+    this.show_shards();
+  },
+  show_shards: function(){
+    $().popup({
+      title: "Shards",
+      titleClass: 'title',
+      body: this.$el
+    });
+    this.$el.find('.icon').tooltip();
+  }
+});
+
+var ShardView = Backbone.View.extend({
+  tagName: 'li',
+  template: JST['templates/environment/shard'],
+  events:{
+    "click .icon" : "destroy_shard"
+  },
+  render: function(){
+    errorClass = (this.model.get('shard_status') == 1) ? 'no-error' : 'error';
+    this.$el.attr('class', errorClass);
+    this.$el.html(this.template({shard: this.model}));
+    return this;
+  },
+  destroy_shard: function(){
+    Confirm_Delete({
+      message: "forget this shard",
+      confirmed_action: _.bind(this.model.remove, this.model)
+    });
+  }
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/688e9d08/contrib/blur-console-old/blur-admin/app/assets/javascripts/environment/zookeeper.js
----------------------------------------------------------------------
diff --git a/contrib/blur-console-old/blur-admin/app/assets/javascripts/environment/zookeeper.js b/contrib/blur-console-old/blur-admin/app/assets/javascripts/environment/zookeeper.js
new file mode 100644
index 0000000..5fb597e
--- /dev/null
+++ b/contrib/blur-console-old/blur-admin/app/assets/javascripts/environment/zookeeper.js
@@ -0,0 +1,141 @@
+/**
+ * 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 ZookeeperModel = Backbone.Model.extend({
+  clusters: new ClusterCollection(),
+  controllers: new ControllerCollection(),
+  initialize: function(){
+    this.view = new ZookeeperView({model: this, el: '#zookeeper'});
+    // Whenever a property changes re-render the view
+    this.on('change', function(){
+      this.view.render();
+    });
+    this.initial_load = true;
+  },
+  url: function(){
+    return '/zookeepers/' + this.get('id') + '.json';
+  },
+  parse: function(response){
+    if (this.initial_load){
+      if (response.clusters.length <= 0){
+        this.clusters.view.$el.find('.no_children').show();
+      }
+      if (response.blur_controllers.length <= 0){
+        this.blur_controllers.view.$el.find('.no_children').show();
+      }
+      this.initial_load = false;
+    }
+    this.clusters.update(response.clusters);
+    this.controllers.update(response.blur_controllers);
+
+    delete response.clusters
+    delete response.blur_controllers
+
+    this.set(response);
+  },
+  // Model streaming, fetches on every interval
+  stream: function(interval){
+    var _update = _.bind(function() {
+      this.fetch({
+        url: Routes.zookeeper_path(CurrentZookeeper, {format: 'json'})
+      });
+      window.setTimeout(_update, interval);
+    }, this);
+    _update();
+  },
+  // Destroys the zookeeper on the server side
+  remove: function(){
+    if(this.get('zookeeper_status') == 0){
+      this.destroy({
+        success: function(){
+          window.location = window.location.origin;
+        },
+        error: function(){
+          Notification("Failed to forget the Zookeeper", false);
+        }
+      });
+    } else {
+      Notification("Cannot forget a Zookeeper that is online!", false);
+    }
+  },
+  header: function(){
+    return this.get('name') + " - Zookeeper - " + this.translated_status();
+  },
+  quarum_failed: function(){
+    return this.get('zookeeper_status') == 3
+  },
+  offline_nodes: function(){
+    var allNodes = this.get('url').split(',')
+    var online = this.get('ensemble');
+    var offline = [];
+    for (var i = 0; i < allNodes.length; i++){
+      var node = allNodes[i];
+      if (online.indexOf(node) < 0){
+        offline.push(node)
+      }
+    }
+    return offline;
+  },
+  // The translated status
+  translated_status: function(){
+    switch(this.get('zookeeper_status'))
+    {
+      case 0:
+        return "Offline"
+      case 1:
+        return "Online"
+      case 2:
+        return "Ensemble Warning"
+      case 3:
+        return "Quorum Failure"
+    }
+  },
+  // Determines the class for the state of the zookeeper
+  translated_class: function(){
+    switch(this.get('zookeeper_status'))
+    {
+      case 0:
+        return "btn-danger"
+      case 1:
+        return "btn-success"
+      case 2:
+        return "btn-warning"
+      case 3:
+        return "btn-danger"
+    }
+  }
+});
+
+var ZookeeperView = Backbone.View.extend({
+  events: {
+    "click .destroy-zk" : "destroy_zookeeper"
+  },
+  template: JST['templates/environment/zookeeper'],
+  render: function(){
+    this.$el.html(this.template({zookeeper: this.model}));
+    this.$el.removeClass('btn-danger btn-success btn-warning');
+    this.$el.addClass(this.model.translated_class());
+    this.$('i').tooltip();
+    this.$('span.states').tooltip({placement: 'bottom'});
+    return this;
+  },
+  destroy_zookeeper: function(){
+    Confirm_Delete({
+      message: "forget this zookeeper",
+      confirmed_action: _.bind(this.model.remove, this.model)
+    });
+  }
+});
\ No newline at end of file


Mime
View raw message