Browse Source

HUE-5833 [impala] Remove the old dashboards

Romain Rigaux 8 years ago
parent
commit
718844e

+ 0 - 3
apps/impala/src/impala/dashboard_api.py

@@ -26,13 +26,10 @@ from itertools import groupby
 
 
 from django.utils.html import escape
 from django.utils.html import escape
 
 
-from libsolr.api import GAPS
-
 from notebook.models import make_notebook
 from notebook.models import make_notebook
 from notebook.connectors.base import get_api, OperationTimeout
 from notebook.connectors.base import get_api, OperationTimeout
 
 
 from dashboard.models import Collection2, augment_response
 from dashboard.models import Collection2, augment_response
-from dashboard.facet_builder import _compute_range_facet
 
 
 
 
 LOG = logging.getLogger(__name__)
 LOG = logging.getLogger(__name__)

+ 0 - 314
apps/impala/src/impala/dashboards.py

@@ -1,314 +0,0 @@
-#!/usr/bin/env python
-# Licensed to Cloudera, Inc. under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  Cloudera, Inc. 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.
-
-
-import logging
-import json
-
-from math import log
-
-from django.utils.encoding import force_unicode
-from django.utils.translation import ugettext as _
-
-from desktop.lib.django_util import JsonResponse, render
-from desktop.models import Document2
-
-from beeswax.design import hql_query
-from beeswax.server import dbms
-from beeswax.server.dbms import get_query_server_config
-
-from impala.models import Dashboard, Controller
-
-
-LOG = logging.getLogger(__name__)
-
-
-def dashboard(request):
-  dashboard_id = request.GET.get('dashboard')
-  
-  if dashboard_id:
-    dashboard = Dashboard(document=Document2.objects.get(id=dashboard_id))
-  else:
-    dashboard = Dashboard()
-
-  return render('dashboard.mako', request, {
-    'query_json': json.dumps({}),
-    'dashboard_json': dashboard.get_json(request.user), 
-    'initial_json': json.dumps('')
-  })
-
-
-def query(request):  
-  result = {
-    'status': -1,
-    'data': {}
-  }
-
-  try:
-    dashboard = json.loads(request.POST['dashboard'])
-    fqs = json.loads(request.POST['query'])['fqs']
-
-    database = dashboard['properties'][0]['database']
-    table = dashboard['properties'][0]['table']
-
-    if fqs:
-      filters = ' AND '.join(['%s = %s' % (fq['field'], _get_escaped_value(value, fq['field'], dashboard)) for fq in fqs for value in fq['filter']])
-    else:
-      filters = ''
-
-    if 'facet' in request.POST:
-      facet = json.loads(request.POST.get('facet'))
-      slot = None
-
-      if facet['type'] == 'field':
-        template = "SELECT %(field)s, COUNT(*) AS top FROM %(database)s.%(table)s WHERE %(field)s IS NOT NULL %(filters)s GROUP BY %(field)s ORDER BY top DESC LIMIT %(limit)s"
-      elif facet['type'] == 'range':
-        slot = (facet['properties']['end'] - facet['properties']['start']) / facet['properties']['limit']
-        template = """select cast(%(field)s / %(slot)s AS int) * %(slot)s, count(*) AS top, cast(%(field)s / %(slot)s as int) as s
-         FROM %(database)s.%(table)s WHERE %(field)s IS NOT NULL GROUP BY s ORDER BY s DESC LIMIT %(limit)s"""
-      else:
-        # Simple Top
-        template = "SELECT DISTINCT %(field)s FROM %(database)s.%(table)s WHERE %(field)s IS NOT NULL %(filters)s ORDER BY %(field)s DESC LIMIT %(limit)s"
-
-      facet = json.loads(request.POST['facet'])
-      hql = template % {
-          'database': database,
-          'table': table,
-          'limit': facet['properties']['limit'],
-          'field': facet['field'],
-          'filters': (' AND ' + filters) if filters else '',
-          'slot': slot
-      }
-      result['id'] = facet['id']
-      result['field'] = facet['field']
-      fields = [fq['field'] for fq in fqs]
-      result['selected'] = facet['field'] in fields
-    else:
-      dashboard['resultsetSelectedFields'] = map(lambda f: '`%s`' % f if f in ('date',) else f, dashboard['resultsetSelectedFields'])
-      fields = ', '.join(dashboard['resultsetSelectedFields']) if dashboard['resultsetSelectedFields'] else '*'
-      hql = "SELECT %(fields)s FROM %(database)s.%(table)s" % {
-          'database': database,
-          'table': table,
-          'fields': fields
-      }
-      if filters:
-        hql += ' WHERE ' + filters
-      hql += ' LIMIT 100'
-
-    query_server = get_query_server_config(name='impala')
-    db = dbms.get(request.user, query_server=query_server)
-
-    query = hql_query(hql)
-    handle = db.execute_and_wait(query, timeout_sec=35.0)
-
-    if handle:
-      data = db.fetch(handle, rows=100)
-      if 'facet' in request.POST:
-        facet = json.loads(request.POST.get('facet'))
-        result['type'] = facet['type']
-        if facet['type'] == 'top':
-          result['data'] = [{"value": row[0], "count": None, "selected": False, "cat": facet['field']} for row in data.rows()]
-        else:
-          result['data'] = [{"value": row[0], "count": row[1], "selected": False, "cat": facet['field']} for row in data.rows()]
-      else:
-        result['data'] = list(data.rows())
-
-      result['cols'] = list(data.cols())
-      result['status'] = 0
-      db.close(handle)
-  except Exception, e:
-    LOG.exception(e)
-    result['message'] = force_unicode(e)
-
-  return JsonResponse(result)
-
-
-
-def _get_field_type(name, dashboard):
-  return [f for f in dashboard['properties'][0]['fields'] if f['name'] == name][0]['type']
-
-def _get_escaped_value(value, field_name, dashboard):
-  if _get_field_type(field_name, dashboard) == 'string':
-    return "'%s'" % value
-  else:
-    return value
-
-
-def new_facet(request):
-  result = {'status': -1, 'message': 'Error'}
-
-  try:
-    dashboard = json.loads(request.POST.get('dashboard', '{}')) # Perms
-    facet_json = json.loads(request.POST.get('facet_json', '{}'))
-    facet_field = request.POST['field']
-
-    result['message'] = ''
-    result['facet'] = _create_facet(dashboard, request.user, facet_json, facet_field)
-
-    result['status'] = 0
-  except Exception, e:
-    result['message'] = unicode(str(e), "utf8")
-
-  return JsonResponse(result)
-
-
-def new_search(request):
-
-  return render('dashboard.mako', request, {
-    'query_json': json.dumps({}),
-    'dashboard_json': json.dumps({
-      'id': None,
-      'layout': [],
-      'dashboard': {
-          'facets': [],
-          'properties': [{'database': '', 'table': '', 'fields': []}]
-        }
-      }),
-     'initial_json': json.dumps({
-        'layout': [
-           {"size":2,"rows":[{"widgets":[]}],"drops":["temp"],"klass":"card card-home card-column span2"},
-           {"size":10,"rows":[{"widgets":[
-               {"size":12,"name":"Grid Results","id":"52f07188-f30f-1296-2450-f77e02e1a5c0","widgetType":"resultset-widget",
-                "properties":{},"offset":0,"isLoading":True,"klass":"card card-widget span12"}]}],
-               "drops":["temp"],"klass":"card card-home card-column span10"}
-         ]
-     })
-  })
-
-
-def save(request):
-  response = {'status': -1}
-
-  dashboard = json.loads(request.POST.get('dashboard', '{}')) # TODO perms
-  layout = json.loads(request.POST.get('layout', '{}'))
-
-  if dashboard:
-    name = '%s.%s' % (dashboard['properties'][0]['database'], dashboard['properties'][0]['table']) # Dynamic currently
-
-    if dashboard.get('id'):
-      dashboard_doc = Document2.objects.get(id=dashboard['id'])
-    else:
-      dashboard_doc = Document2.objects.create(name=name, type='impala-dashboard', owner=request.user)
-
-    dashboard_doc.update_data({'dashboard': dashboard})
-    dashboard_doc.update_data({'layout': layout})
-    dashboard_doc.name = name
-    dashboard_doc.save()
-    response['status'] = 0
-    response['id'] = dashboard_doc.id
-    response['message'] = _('Page saved !')
-  else:
-    response['message'] = _('There is no dashboard to search.')
-
-  return JsonResponse(response)
-
-
-def get_fields(request):
-  result = {'status': -1, 'message': 'Error'}
-
-  try:
-    database = request.POST.get('database')
-    table = request.POST.get('table')
-
-    result['message'] = ''
-    result['fields'] = Controller(request.user).get_fields(database, table)
-    result['status'] = 0
-  except Exception, e:
-    result['message'] = unicode(str(e), "utf8")
-
-  return JsonResponse(result)
-
-
-def _round_number_range(n):
-  if n <= 10:
-    return n, n + 1
-  else:
-    i = int(log(n, 10))
-    end = round(n, -i)
-    start = end - 10 ** i
-    return start, end
-  
-
-def _guess_range(user, dashboard, field):
-    
-    hql = "SELECT MIN(%(field)s), MAX(%(field)s) FROM %(database)s.%(table)s" % {
-      'field': field['name'],
-      'database': dashboard['properties'][0]['database'],
-      'table': dashboard['properties'][0]['table']      
-    }
-    
-    query_server = get_query_server_config(name='impala')
-    db = dbms.get(user, query_server=query_server)
-    
-    query = hql_query(hql)
-    handle = db.execute_and_wait(query, timeout_sec=35.0)    
-
-    data = db.fetch(handle, rows=1)
-    stats_min, stats_max = list(data.rows())[0]
-    db.close(handle)
-    
-    _min, _m = _round_number_range(stats_min)
-    _m, _max = _round_number_range(stats_max)    
-
-    properties = {
-      'min': stats_min,
-      'max': stats_max,
-      'start': _min,
-      'end': _max,
-      #'gap': gap,
-      'canRange': True,
-      'isDate': False,
-    }
-    
-    return properties
-
-
-def _create_facet(dashboard, user, facet_json, facet_field):
-  properties = {
-    'sort': 'desc',
-    'canRange': False,
-    'stacked': False,
-    'limit': 10,
-    'mincount': 0,
-    'isDate': False,
-  }
-
-  field = [field for field in dashboard['fields'] if field['name'] == facet_field][0]
-
-  if field['type'] == 'int':
-    facet_type = 'range'
-    _props = _guess_range(user, dashboard, field)
-    properties.update(_props)
-  else:
-    facet_type = 'field'
-  
-  # facet_type = 'top'
-  
-
-  if facet_json['widgetType'] == 'map-widget':
-    properties['scope'] = 'world'
-    properties['mincount'] = 1
-    properties['limit'] = 100
-
-  return {
-    'id': facet_json['id'],
-    'label': facet_field,
-    'field': facet_field,
-    'type': facet_type,
-    'widgetType': facet_json['widgetType'],
-    'properties': properties
-  }

+ 0 - 390
apps/impala/src/impala/static/impala/js/impala-dashboard.ko.js

@@ -1,390 +0,0 @@
-// Licensed to Cloudera, Inc. under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  Cloudera, Inc. 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 magicLayout(vm) {
-  loadLayout(vm, vm.initial.layout);
-  $(document).trigger("magicLayout");
-}
-
-function loadLayout(viewModel, json_layout) {
-  var _columns = [];
-
-  $(json_layout).each(function (cnt, json_col) {
-    var _rows = [];
-    $(json_col.rows).each(function (rcnt, json_row) {
-      var row = new Row([], viewModel);
-      $(json_row.widgets).each(function (wcnt, widget) {
-        row.addWidget(new Widget({
-          size:widget.size,
-          id: widget.id,
-          name: widget.name,
-          widgetType: widget.widgetType,
-          properties: widget.properties,
-          offset: widget.offset,
-          loading: true,
-          vm: viewModel
-        }));
-      });
-      _rows.push(row);
-    });
-    var column = new Column(json_col.size, _rows);
-    _columns = _columns.concat(column);
-  });
-
-  viewModel.columns(_columns);
-}
-
-// End dashboard lib
-
-var Query = function (vm, query) {
-  var self = this;
-
-  self.qs = ko.mapping.fromJS([{'q': ''}]);
-  self.fqs = ko.mapping.fromJS([]);
-  
-  self.toggleFacet = function (data) {
-    var fq = self.getFacetFilter(data.widget.id());
-
-    if (fq == null) {
-      self.fqs.push(ko.mapping.fromJS({
-        'id': data.widget.id(),
-        'field': data.widget.field(),
-        'filter': [data.facet.value()],
-        'type': 'field'
-      }));
-    } else {
-      $.each(self.fqs(), function (index, fq) {
-        if (fq.id() == data.widget.id()) {
-          if (fq.filter.indexOf(data.facet.value()) > -1) {
-            fq.filter.remove(data.facet.value());
-            if (fq.filter().length == 0) {
-              self.fqs.remove(fq);
-            }
-          } else {
-            fq.filter.push(data.facet.value());
-          }
-        }
-      });
-    }
-
-    vm.search();
-  }  
-  
-  self.selectRangeFacet = function (data) {
-    var fq = self.getFacetFilter(data.widget_id);
-
-    if (fq == null) {
-      self.fqs.push(ko.mapping.fromJS({
-          'id': data.widget_id,
-          'field': data.cat,
-          'filter': [{'value': data.from, 'exclude': false}],
-          'properties': [{'from': data.from, 'to': data.to}],
-          'type': 'range'
-      }));
-    } else {
-      var f = $.grep(fq.filter(), function(f) { return f.value() == data.from; });
-      if (f.length > 0) { // Unselect
-        fq.filter.remove(f[0]);
-        $.each(fq.properties(), function (index, prop) {
-          if (prop && prop.from() == data.from) {
-            fq.properties.remove(prop);
-          }
-        });
-        if (fq.filter().length == 0) {
-          self.removeFilter(ko.mapping.fromJS({'id': data.widget_id}));
-        }
-      } else {
-       fq.filter.push(ko.mapping.fromJS({'exclude': data.exclude ? true : false, 'value': data.from}));
-       fq.properties.push(ko.mapping.fromJS({'from': data.from, 'to': data.to}));
-      }
-    }
-  };  
-  
-  self.getFacetFilter = function (facet_id) {
-    var _facet = null;
-    $.each(self.fqs(), function (index, facet) {
-      if (facet.id() == facet_id) {
-        _facet = facet;
-        return false;
-      }
-    });
-    return _facet;	  
-  }
-}
-
-var Dashboard = function (vm, dashboard) { 
-  var self = this;
-
-  self.id = ko.mapping.fromJS(dashboard.id);
-  self.facets = ko.mapping.fromJS(dashboard.facets);
-  self.properties = ko.mapping.fromJS(dashboard.properties);
-
-  self.dropdownDbs = ko.observableArray([]);
-  self.selectedDropdownDb = ko.observable("");
-  self.selectedDropdownDb.subscribe(function(value) {
-	self.properties()[0].database(self.selectedDropdownDb());
-	if (self.selectedDropdownDb() && self.selectedDropdownTable()) {
-	  self.updateFields(); 
-	  getTables();
-	}
-  });  
-
-  self.dropdownTables = ko.observableArray(["customers", "sample_07", "sample_08", "web_logs"]);
-  self.selectedDropdownTable = ko.observable("");
-  self.selectedDropdownTable.subscribe(function(value) {
-	self.properties()[0].table(self.selectedDropdownTable());
-	if (self.selectedDropdownDb() && self.selectedDropdownTable()) {
-	  self.updateFields(); 
-	}
-  });
-  
-  self.updateDropdownDatabases = function(databases) {
-    if (databases) {
-      var i = databases.indexOf("_impala_builtins"); // Blacklist of system databases
-      if (i != -1) {
-        databases.splice(i, 1);
-      }
-      self.dropdownDbs(databases);
-    }
-  };
-
-  self.fields = ko.computed(function () {
-    if (self.properties() != null && self.properties().length > 0 && self.properties()[0].fields != null){
-	  return self.properties()[0].fields();
-    }
-    return [];
-  });
-  self.fieldNames = ko.computed(function () {
-	return $.map(self.fields(), function (field) { return field.name() });
-  });
-
-  self.resultsetShowFieldList = ko.observable(true);
-  self.resultsetFieldsFilter = ko.observable(""); // For UI
-
-  self.resultsetSelectedFields = ko.observableArray(self.fieldNames());
-  /**self.resultsetSelectedFields.subscribe(function(value) {
-    vm.search();
-  });*/
-
-  self.resultsetFilteredFields = ko.computed(function() {
-    var _fields = [];
-    $.each(self.fields(), function (index, field) {
-      if (self.resultsetFieldsFilter() == "" || field.name().toLowerCase().indexOf(self.resultsetFieldsFilter().toLowerCase()) > -1){
-        _fields.push(field);
-      }
-    });
-    return _fields;
-  });
-
-  self.selectedNewFacetField = ko.observable();
-  
-  self.addFacet = function(facet_json) {
-   $.post("/impala/dashboard/new_facet", {
-       "dashboard": ko.mapping.toJSON(self),
-       "facet_json": ko.mapping.toJSON(facet_json),
-       "field": self.selectedNewFacetField(),
-     }, function (data) {
-       if (data.status == 0) {
-         var facet = ko.mapping.fromJS(data.facet);
-         facet.properties.limit.subscribe(function () {
-           vm.search();
-         });
-         self.facets.push(facet);
-         vm.search();
-       } else {
-         $(document).trigger("error", data.message);
-       }
-    }).fail(function (xhr, textStatus, errorThrown) {});
-  }
-  
-  self.getFacetById = function (facet_id) {
-    var _facet = null;
-    $.each(self.facets(), function (index, facet) {
-      if (facet.id() == facet_id) {
-        _facet = facet;
-        return false;
-      }
-    });
-    return _facet;
-  }   
-  
-  self.updateFields = function(database, table) {
-    $.post("/impala/dashboard/get_fields", {
-    	"database": self.properties()[0].database(),
-    	"table": self.properties()[0].table()
-    }, function (data) {
-      if (data.status == 0) {
-        self.properties()[0].fields.removeAll();
-        self.resultsetSelectedFields.removeAll();
-    	$.each(data.fields, function (index, field) {
-    	  self.properties()[0].fields.push(ko.mapping.fromJS(field));
-    	  self.resultsetSelectedFields.push(field.name);
-      	});        
-      }
-    }).fail(function (xhr, textStatus, errorThrown) {});
-  }  
-}
-
-var ImpalaDashboardViewModel = function (query_json, dashboard_json, initial_json) {
-    var self = this;
-
-    self.isEditing = ko.observable(true);
-    self.toggleEditing = function () {
-      self.isEditing(! self.isEditing());
-    };
-    self.isRetrievingResults = ko.observable(false);
-    self.previewColumns = ko.observable("");
-    self.columns = ko.observable([]);
-    
-    loadLayout(self, dashboard_json.layout);
-
-    self.query = new Query(self, query_json);
-    self.dashboard = new Dashboard(self, dashboard_json.dashboard);
-    self.initial = initial_json;
-
-    self.results = ko.observableArray([]);
-    self.results_facet = ko.observableArray([]);
-    self.results_cols = ko.observableArray([]);
-
-    self.inited = ko.observable(self.columns().length > 0);
-
-    self.selectedQDefinition = ko.observable();
-    self.isNested = ko.observable(false);
-
-    self.init = function(callback) {
-      if (self.inited()){
-        self.search();
-      }
-      callback();
-    }
-    
-    self.search = function (callback) {
-      self.isRetrievingResults(true);
-      self.results.removeAll();
-    	
-      var multiQs = $.map(self.dashboard.facets(), function(facet) {
-        return $.post("/impala/dashboard/query", {
-           "query": ko.mapping.toJSON(self.query),
-           "dashboard": ko.mapping.toJSON(self.dashboard),
-           "layout": ko.mapping.toJSON(self.columns),
-           "facet": ko.mapping.toJSON(facet),
-        }, function (data) {return data});
-      });    	
-    	
-      $.when.apply($, [
-          $.post("/impala/dashboard/query", {
-            "query": ko.mapping.toJSON(self.query),
-            "dashboard": ko.mapping.toJSON(self.dashboard),
-            "layout": ko.mapping.toJSON(self.columns),
-            }, function (data) {
-              self.isRetrievingResults(false);
-              if (data.status == 0) {
-            	self.results_cols(data.cols)
-            	$.each(data.data, function (index, row) {
-            	  self.results.push(row);
-            	});
-              } else {
-                $(document).trigger("error", data.message);
-              }
-            })
-          ].concat(multiQs)
-      )
-      .done(function() {
-          if (multiQs.length > 0) {
-            for (var i = 1; i < arguments.length; i++) {
-              var facet = arguments[i][0];
-              removeFrom(self.results_facet, facet.id);
-              self.results_facet.push(ko.mapping.fromJS(facet));
-            }
-          }          
-        })
-      .fail(function (xhr, textStatus, errorThrown) {
-    	  $(document).trigger("error", errorThrown);
-       });
-    };
-
-    function removeFrom(collection, item_id) {
-      $.each(collection(), function (index, item) {
-        if (item.id() == item_id) {
-          collection.remove(item);
-          return false;
-        }
-      });
-    }
-    
-    self.getFacetFromResult = function (facet_id) {
-      var _facet = null;
-      $.each(self.results_facet(), function (index, facet) {
-        if (facet.id() == facet_id) {
-          _facet = facet;
-          return false;
-        }
-      });
-      return _facet;
-    }
-
-    self.getWidgetById = function (widget_id) {
-      var _widget = null;
-      $.each(self.columns(), function (i, col) {
-        $.each(col.rows(), function (j, row) {
-          $.each(row.widgets(), function (z, widget) {
-            if (widget.id() == widget_id){
-              _widget = widget;
-            }
-          });
-        });
-      });
-      return _widget;
-    }
-    
-    self.save = function () {
-      $.post("/impala/dashboard/save", {
-          "dashboard": ko.mapping.toJSON(self.dashboard),
-          "layout": ko.mapping.toJSON(self.columns)
-      }, function (data) {
-        if (data.status == 0) {
-          self.dashboard.id(data.id);
-          $(document).trigger("info", data.message);
-          if (window.location.search.indexOf("dashboard") == -1) {
-            window.location.hash = '#dashboard=' + data.id;
-          }
-        }
-        else {
-          $(document).trigger("error", data.message);
-        }
-      }).fail(function (xhr, textStatus, errorThrown) {
-        $(document).trigger("error", xhr.responseText);
-      });
-    };
-    
-    function bareWidgetBuilder(name, type){
-      return new Widget({
-        size: 12,
-        id: UUID(),
-        name: name,
-        widgetType: type
-      });
-    }
-
-    self.draggableFacet = ko.observable(bareWidgetBuilder("Facet", "facet-widget"));
-    self.draggableResultset = ko.observable(bareWidgetBuilder("Grid Results", "resultset-widget"));
-    self.draggableHistogram = ko.observable(bareWidgetBuilder("Histogram", "histogram-widget"));
-    self.draggableBar = ko.observable(bareWidgetBuilder("Bar Chart", "bar-widget"));
-    self.draggableMap = ko.observable(bareWidgetBuilder("Map", "map-widget"));
-    self.draggableLine = ko.observable(bareWidgetBuilder("Line Chart", "line-widget"));
-    self.draggablePie = ko.observable(bareWidgetBuilder("Pie Chart", "pie-widget"));
-    self.draggableFilter = ko.observable(bareWidgetBuilder("Filter Bar", "filter-widget"));
-};

+ 0 - 693
apps/impala/src/impala/templates/dashboard.mako

@@ -1,693 +0,0 @@
-## Licensed to Cloudera, Inc. under one
-## or more contributor license agreements.  See the NOTICE file
-## distributed with this work for additional information
-## regarding copyright ownership.  Cloudera, Inc. 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.
-<%!
-from desktop.views import commonheader, commonfooter, _ko
-from django.utils.translation import ugettext as _
-%>
-
-<%namespace name="dashboard" file="common_dashboard.mako" />
-
-${ commonheader(None, "impala", user, request) | n,unicode }
-
-<%dashboard:layout_toolbar>
-  <%def name="widgets()">
-    <div data-bind="css: { 'draggable-widget': true},
-          draggable: {data: draggableResultset(), isEnabled: true,
-              options: {'start': function(event, ui){lastWindowScrollPosition = $(window).scrollTop();$('.card-body').slideUp('fast');},
-                        'stop': function(event, ui){$('.card-body').slideDown('fast'); }}}"
-         title="${_('Grid Results')}" rel="tooltip" data-placement="top">
-         <a class="draggable-icon"><i class="fa fa-table"></i></a>
-    </div>
-
-    <div data-bind="css: { 'draggable-widget': true },
-                    draggable: {data: draggableFacet(), isEnabled: true,
-                    options: {'start': function(event, ui){lastWindowScrollPosition = $(window).scrollTop();$('.card-body').slideUp('fast');},
-                              'stop': function(event, ui){$('.card-body').slideDown('fast', function(){$(window).scrollTop(lastWindowScrollPosition)});}}}"
-         title="${_('Text Facet')}" rel="tooltip" data-placement="top">
-         <a  class="draggable-icon"><i class="fa fa-sort-amount-asc"></i></a>
-    </div>
-    <div data-bind="css: { 'draggable-widget': true },
-                    draggable: {data: draggablePie(), isEnabled: true,
-                    options: {'start': function(event, ui){lastWindowScrollPosition = $(window).scrollTop();$('.card-body').slideUp('fast');},
-                              'stop': function(event, ui){$('.card-body').slideDown('fast', function(){$(window).scrollTop(lastWindowScrollPosition)});}}}"
-         title="${_('Pie Chart')}" rel="tooltip" data-placement="top">
-         <a class="draggable-icon"><i class="hcha hcha-pie-chart"></i></a>
-    </div>
-    <div data-bind="css: { 'draggable-widget': true },
-                    draggable: {data: draggableBar(), isEnabled: true,
-                    options: {'start': function(event, ui){lastWindowScrollPosition = $(window).scrollTop();$('.card-body').slideUp('fast');},
-                              'stop': function(event, ui){$('.card-body').slideDown('fast', function(){$(window).scrollTop(lastWindowScrollPosition)});}}}"
-         title="${_('Bar Chart')}" rel="tooltip" data-placement="top">
-         <a class="draggable-icon"><i class="hcha hcha-bar-chart"></i></a>
-    </div>
-    <div data-bind="css: { 'draggable-widget': true },
-                    draggable: {data: draggableLine(), isEnabled: true,
-                    options: {'start': function(event, ui){lastWindowScrollPosition = $(window).scrollTop();$('.card-body').slideUp('fast');},
-                              'stop': function(event, ui){$('.card-body').slideDown('fast', function(){$(window).scrollTop(lastWindowScrollPosition)});}}}"
-         title="${_('Line Chart')}" rel="tooltip" data-placement="top">
-         <a class="draggable-icon"><i class="hcha hcha-line-chart"></i></a>
-    </div>
-    <div data-bind="css: { 'draggable-widget': true },
-                    draggable: {data: draggableHistogram(), isEnabled: true,
-                    options: {'start': function(event, ui){lastWindowScrollPosition = $(window).scrollTop();$('.card-body').slideUp('fast');},
-                              'stop': function(event, ui){$('.card-body').slideDown('fast', function(){$(window).scrollTop(lastWindowScrollPosition)});}}}"
-         title="${_('Timeline')}" rel="tooltip" data-placement="top">
-         <a class="draggable-icon"><i class="hcha hcha-timeline-chart"></i></a>
-    </div>
-    <div data-bind="css: { 'draggable-widget': true },
-                    draggable: {data: draggableFilter(),
-                    options: {'start': function(event, ui){lastWindowScrollPosition = $(window).scrollTop();$('.card-body').slideUp('fast');},
-                              'stop': function(event, ui){$('.card-body').slideDown('fast', function(){$(window).scrollTop(lastWindowScrollPosition)});}}}"
-         title="${_('Filter Bar')}" rel="tooltip" data-placement="top">
-         <a class="draggable-icon"><i class="fa fa-filter"></i></a>
-    </div>
-    <div data-bind="css: { 'draggable-widget': true },
-                    draggable: {data: draggableMap(),
-                    options: {'start': function(event, ui){lastWindowScrollPosition = $(window).scrollTop();$('.card-body').slideUp('fast');},
-                              'stop': function(event, ui){$('.card-body').slideDown('fast', function(){$(window).scrollTop(lastWindowScrollPosition)});}}}"
-         title="${_('Map')}" rel="tooltip" data-placement="top">
-         <a class="draggable-icon"><i class="hcha hcha-map-chart"></i></a>
-    </div>
-</%def>
-</%dashboard:layout_toolbar>
-
-
-<div class="search-bar">
-  <div class="pull-right" style="padding-right:50px">
-    % if user.is_superuser:
-      <a title="${ _('Edit') }" rel="tooltip" data-placement="bottom" data-bind="click: toggleEditing, css: {'btn': true, 'btn-inverse': isEditing}"><i class="fa fa-pencil"></i></a>
-      &nbsp;&nbsp;&nbsp;
-      <button type="button" title="${ _('Save') }" rel="tooltip" data-placement="bottom" data-loading-text="${ _("Saving...") }" data-bind="click: $root.save, css: {'btn': true}"><i class="fa fa-save"></i></button>
-      <a class="btn" href="${ url('impala:new_search') }" title="${ _('New') }" rel="tooltip" data-placement="bottom" data-bind="css: {'btn': true}"><i class="fa fa-file-o"></i></a>
-    % endif
-  </div>
-
-  <form class="form-search" style="margin: 0" data-bind="visible: $root.isEditing() && columns().length == 0">
-    ${ _('Select a database and a table') }
-    <!-- ko if: columns().length == 0 -->
-    <select data-bind="options: $root.dashboard.dropdownDbs, value: $root.dashboard.selectedDropdownDb" class="input-medium" data-placeholder="${_('Choose a database...')}"></select>
-    <select data-bind="options: $root.dashboard.dropdownTables, value: $root.dashboard.selectedDropdownTable" class="input-medium" data-placeholder="${_('Choose a table...')}"></select>
-
-    <a title="${_('Manually refresh the dropdowns')}" rel="tooltip" data-placement="bottom" class="pointer" data-bind="click: resetDropdownsCache"><i class="fa fa-refresh"></i></a>
-    <!-- /ko -->
-  </form>
-
-  <form class="form-search" style="margin: 0" data-bind="submit: search, visible: columns().length != 0">
-    <strong>${_("Search")}</strong>
-    <!-- ko if: $root.dashboard.properties().length > 0 -->
-    <a href="javascript:void(0)"><span data-bind="editable: $root.dashboard.properties()[0].database, editableOptions: {enabled: true, placement: 'right', emptytext: '${_ko('Database name...')}'}"></span></a>.<a href="javascript:void(0)"><span data-bind="editable: $root.dashboard.properties()[0].table, editableOptions: {enabled: true, placement: 'right', emptytext: '${_ko('Table name...')}'}"></span></a></span>
-    <!-- /ko -->
-    <div class="input-append">
-      <span data-bind="foreach: query.qs">
-        <input data-bind="clearable: q" maxlength="4096" type="text" class="search-query input-xlarge">
-        <button type="submit" id="search-btn" class="btn btn-inverse"><i class="fa fa-search"></i></button>
-      </span>
-    </div>
-  </form>
-</div>
-
-
-${ dashboard.layout_skeleton() }
-
-<script type="text/html" id="resultset-widget">
-<div style="float:left; margin-right: 10px">
-  <div data-bind="visible: ! $root.dashboard.resultsetShowFieldList()" style="padding-top: 5px; display: inline-block">
-    <a href="javascript: void(0)"  data-bind="click: function(){ $root.dashboard.resultsetShowFieldList(true) }">
-      <i class="fa fa-chevron-right"></i>
-    </a>
-  </div>
-</div>
-<div data-bind="visible: $root.dashboard.resultsetShowFieldList()" style="float:left; margin-right: 10px; background-color: #F6F6F6; padding: 5px">
-  <span data-bind="visible: $root.dashboard.resultsetShowFieldList()">
-    <div>
-      <a href="javascript: void(0)" class="pull-right" data-bind="click: function(){ $root.dashboard.resultsetShowFieldList(false) }">
-        <i class="fa fa-chevron-left"></i>
-      </a>
-      <input type="text" data-bind="clearable: $root.dashboard.resultsetFieldsFilter, valueUpdate:'afterkeydown'" placeholder="${_('Filter fields')}" style="width: 70%; margin-bottom: 10px" />
-    </div>
-    <div style="border-bottom: 1px solid #CCC; padding-bottom: 4px;">
-      <a href="javascript: void(0)" class="btn btn-mini"
-        data-bind="click: toggleGridFieldsSelection, css: { 'btn-inverse': $root.dashboard.resultsetSelectedFields().length == $root.dashboard.fields().length }"
-        style="margin-right: 2px;">
-        <i class="fa fa-square-o"></i>
-      </a>
-      <strong>${_('Field Name')}</strong>
-    </div>
-    <div class="fields-list" data-bind="foreach: $root.dashboard.resultsetFilteredFields" style="max-height: 230px; overflow-y: auto; padding-left: 4px">
-      <div style="margin-bottom: 3px">
-        <input type="checkbox" data-bind="checkedValue: name, checked: $root.dashboard.resultsetSelectedFields" style="margin: 0" />
-        <div data-bind="text: name, css:{'field-selector': true, 'hoverable': $root.dashboard.resultsetSelectedFields.indexOf(name()) > -1}, click: highlightColumn"></div>
-      </div>
-    </div>
-    <div data-bind="visible: $root.dashboard.resultsetFilteredFields().length == 0" style="padding-left: 4px; padding-top: 5px; font-size: 40px; color: #CCC">
-      <i class="fa fa-frown-o"></i>
-    </div>
-  </span>
-</div>
-
-<div>
-  <div class="widget-spinner" data-bind="visible: $root.isRetrievingResults()">
-    <!--[if !IE]> --><i class="fa fa-spinner fa-spin"></i><!-- <![endif]-->
-    <!--[if IE]><img src="${ static('desktop/art/spinner.gif') }" /><![endif]-->
-  </div>
-
-  <div data-bind="visible: !$root.isRetrievingResults() && $root.results().length == 0">
-    <br/>
-    ${ _('Your search did not match any documents.') }
-  </div>
-
-  <div data-bind="visible: !$root.isRetrievingResults() && $root.results().length > 0">
-    <div id="result-main" style="overflow-x: auto">
-      <table id="result-container" style="margin-top: 0; width: 100%">
-        <thead>
-          <tr>
-            <th style="width: 18px">&nbsp;</th>
-            <!-- ko foreach: $root.results_cols -->
-              <th data-bind="text: $data"></th>
-            <!-- /ko -->
-          </tr>
-        </thead>
-        <tbody data-bind="foreach: { data: $root.results, as: 'row'}" class="result-tbody">
-          <tr class="result-row">
-            <td>
-              <a href="javascript:void(0)">
-                <i class="fa" data-bind="css: {'fa-caret-right' : true }"></i>
-              </a>
-            </td>
-            <!-- ko foreach: row -->
-              <td data-bind="html: $data"></td>
-            <!-- /ko -->
-          </tr>
-        </tbody>
-      </table>
-    </div>
-  </div>
-</div>
-</script>
-
-
-<script type="text/html" id="select-field">
-  <!-- ko ifnot: $root.getFacetFromResult(id()) -->
-    <select data-bind="options: $root.dashboard.fieldNames, value: $root.dashboard.selectedNewFacetField"></select>
-    <a href="javascript:void(0)" data-bind="click: function(){ $root.getWidgetById(id()).isLoading(true); $root.dashboard.addFacet($data);}">
-      <i class="fa fa-plus"></i>
-    </a>
-  <!-- /ko -->
-</script>
-
-
-<script type="text/html" id="facet-widget">
-  <div class="widget-spinner" data-bind="visible: isLoading()">
-    <!--[if !IE]> --><i class="fa fa-spinner fa-spin"></i><!-- <![endif]-->
-    <!--[if IE]><img src="${ static('desktop/art/spinner.gif') }" /><![endif]-->
-  </div>
-  <!-- ko if: $root.getFacetFromResult(id()) -->
-  <div class="row-fluid" data-bind="with: $root.getFacetFromResult(id())">
-    <div data-bind="visible: $root.isEditing, with: $root.dashboard.getFacetById($parent.id())">
-      <input type="text" data-bind="value: field" />
-      <input type="text" data-bind="value: properties.limit" />
-      <input type="text" data-bind="value: $data.type" />
-    </div>
-
-    <!-- ko if: type() == 'field' -->
-      <span data-bind="foreach: {data: data(), afterRender: function(){ $root.getWidgetById($parent.id()).isLoading(false); }}">
-        <div>
-          <a href="javascript: void(0)">
-            <span data-bind="text: $data.value, click: function(){ $root.query.toggleFacet({facet: $data, widget: $parent}) }"></span>
-            (<span data-bind="text: $data.count, click: function(){ $root.query.toggleFacet({facet: $data, widget: $parent}) }"></span>)
-            <i class="fa fa-times" data-bind="visible: $parent.data().length == 1"></i>
-          </a>
-        </div>
-      </span>
-    <!-- /ko -->
-
-    <!-- ko if: type() == 'range' -->
-      <div data-bind="foreach: {data: data(), afterRender: function(){ $root.getWidgetById($parent.id()).isLoading(false); }}">
-        <div class="trigger-exclude">
-          <!-- ko if: ! selected() -->
-            <a class="pointer" data-bind="text: $data.value(), click: function(){ $root.query.selectRangeFacet({count: $data.value, widget_id: $parent.id(), from: $data.from, to: $data.to, cat: $data.field}) }"></a>
-            <span class="pointer counter" data-bind="text: ' (' + $data.count() + ')', click: function(){ $root.query.selectRangeFacet({count: $data.value, widget_id: $parent.id(), from: $data.from, to: $data.to, cat: $data.field}) }"></span>
-            <a class="exclude pointer" data-bind="click: function(){ $root.query.selectRangeFacet({count: $data.value, widget_id: $parent.id(), from: $data.from, to: $data.to, cat: $data.field, 'exclude': true}) }" title="${ _('Exclude this value') }"><i class="fa fa-minus"></i></a>
-          <!-- /ko -->
-          <!-- ko if: selected -->
-            <span class="pointer" data-bind="click: function(){ $root.query.selectRangeFacet({count: $data.value, widget_id: $parent.id(), from: $data.from, to: $data.to, cat: $data.field}) }">
-              <strong data-bind="text: $data.value()"></strong>
-              <a class="pointer" data-bind="visible: ! exclude()"><i class="fa fa-times"></i></a>
-              <a class="pointer" data-bind="visible: exclude"><i class="fa fa-plus"></i></a>
-            </span>
-          <!-- /ko -->
-        </div>
-      </div>
-    <!-- /ko -->
-
-  </div>
-  <!-- /ko -->
-
-  <span data-bind="template: { name: 'select-field' }, visible: ! isLoading()"></span>
-</script>
-
-
-<script type="text/html" id="pie-widget">
-
-  <div class="widget-spinner" data-bind="visible: isLoading()">
-    <!--[if !IE]> --><i class="fa fa-spinner fa-spin"></i><!-- <![endif]-->
-    <!--[if IE]><img src="${ static('desktop/art/spinner.gif') }" /><![endif]-->
-  </div>
-
-  <!-- ko if: $root.getFacetFromResult(id()) -->
-  <div class="row-fluid" data-bind="with: $root.getFacetFromResult(id())">
-    <div data-bind="visible: $root.isEditing, with: $root.dashboard.getFacetById($parent.id())" style="margin-bottom: 20px">
-      <input type="text" data-bind="value: field" />
-      <input type="text" data-bind="value: properties.limit" />
-    </div>
-
-    <div data-bind="pieChart: {data: {counts: data, widget_id: id()}, field: field, fqs: $root.query.fqs,
-        transformer: pieChartDataTransformer,
-        maxWidth: 250,
-        onClick: function(d){viewModel.query.toggleFacet({facet: d.data.obj, widget_id: d.data.obj.widget_id})},
-        onComplete: function(){viewModel.getWidgetById(id()).isLoading(false)}}" />
-    </div>
-  <!-- /ko -->
-
-  <span data-bind="template: { name: 'select-field' }, visible: ! isLoading()"></span>
-</script>
-
-<script type="text/html" id="bar-widget">
-
-  <div class="widget-spinner" data-bind="visible: isLoading()">
-    <!--[if !IE]> --><i class="fa fa-spinner fa-spin"></i><!-- <![endif]-->
-    <!--[if IE]><img src="${ static('desktop/art/spinner.gif') }" /><![endif]-->
-  </div>
-
-  <!-- ko if: $root.getFacetFromResult(id()) -->
-  <div class="row-fluid" data-bind="with: $root.getFacetFromResult(id())">
-    <div data-bind="visible: $root.isEditing, with: $root.dashboard.getFacetById($parent.id())" style="margin-bottom: 20px">
-      <input type="text" data-bind="value: field" />
-      <input type="text" data-bind="value: properties.limit" />
-    </div>
-
-    <div data-bind="barChart: {datum: {counts: data, widget_id: id()}, stacked: false, field: field,
-      fqs: $root.query.fqs,
-      transformer: barChartDataTransformer,
-      onStateChange: function(state){ console.log(state); },
-      onClick: function(d) {
-        if (d.obj.field != undefined) {
-          viewModel.query.selectRangeFacet({count: d.obj.value, widget_id: d.obj.widget_id, from: d.obj.from, to: d.obj.to, cat: d.obj.field});
-        } else {
-          viewModel.query.toggleFacet({facet: d.obj, widget_id: d.obj.widget_id});
-        }
-      },
-      onSelectRange: function(from, to){ viewModel.collection.selectTimelineFacet({from: from, to: to, cat: field, widget_id: id}) },
-      onComplete: function(){ viewModel.getWidgetById(id()).isLoading(false) } }"
-    />
-    </div>
-  <!-- /ko -->
-
-  <span data-bind="template: { name: 'select-field' }, visible: ! isLoading()"></span>
-</script>
-
-<script type="text/html" id="line-widget">
-
-  <div class="widget-spinner" data-bind="visible: isLoading()">
-    <!--[if !IE]> --><i class="fa fa-spinner fa-spin"></i><!-- <![endif]-->
-    <!--[if IE]><img src="${ static('desktop/art/spinner.gif') }" /><![endif]-->
-  </div>
-
-  <!-- ko if: $root.getFacetFromResult(id()) -->
-  <div class="row-fluid" data-bind="with: $root.getFacetFromResult(id())">
-    <div data-bind="visible: $root.isEditing, with: $root.dashboard.getFacetById($parent.id())" style="margin-bottom: 20px">
-      <input type="text" data-bind="value: field" />
-      <input type="text" data-bind="value: properties.limit" />
-    </div>
-
-    <div data-bind="lineChart: {datum: {counts: data, widget_id: id()}, field: field,
-      transformer: lineChartDataTransformer,
-      onClick: function(d){ viewModel.query.selectRangeFacet({count: d.obj.value, widget_id: d.obj.widget_id, from: d.obj.from, to: d.obj.to, cat: d.obj.field}) },
-      onSelectRange: function(from, to){ viewModel.collection.selectTimelineFacet({from: from, to: to, cat: field, widget_id: $parent.id()}) },
-      onComplete: function(){ viewModel.getWidgetById(id()).isLoading(false) } }"
-    />
-
-    </div>
-  <!-- /ko -->
-
-  <span data-bind="template: { name: 'select-field' }, visible: ! isLoading()"></span>
-</script>
-
-<script type="text/html" id="histogram-widget">
-
-  <div class="widget-spinner" data-bind="visible: isLoading()">
-    <!--[if !IE]> --><i class="fa fa-spinner fa-spin"></i><!-- <![endif]-->
-    <!--[if IE]><img src="${ static('desktop/art/spinner.gif') }" /><![endif]-->
-  </div>
-
-  <!-- ko if: $root.getFacetFromResult(id()) -->
-  <div class="row-fluid" data-bind="with: $root.getFacetFromResult(id())">
-    <div data-bind="visible: $root.isEditing, with: $root.dashboard.getFacetById($parent.id())" style="margin-bottom: 20px">
-      <input type="text" data-bind="value: field" />
-      <input type="text" data-bind="value: properties.limit" />
-    </div>
-
-    <div data-bind="timelineChart: {datum: {counts: data, extraSeries: extraSeries, widget_id: id()}, stacked: $root.collection.getFacetById(id()).properties.stacked(), field: field, transformer: timelineChartDataTransformer,
-      fqs: $root.query.fqs,
-      onSelectRange: function(from, to){ viewModel.collection.selectTimelineFacet({from: from, to: to, cat: field, widget_id: $parent.id()}) },
-      onStateChange: function(state){ $root.collection.getFacetById(id()).properties.stacked(state.stacked); },
-      onClick: function(d){ viewModel.query.selectRangeFacet({count: d.obj.value, widget_id: $parent.id(), from: d.obj.from, to: d.obj.to, cat: d.obj.field}) },
-      onComplete: function(){ viewModel.getWidgetById(id()).isLoading(false) }}" />
-    </div>
-  <!-- /ko -->
-
-  <span data-bind="template: { name: 'select-field' }, visible: ! isLoading()"></span>
-</script>
-
-<script type="text/html" id="filter-widget">
-  <div data-bind="visible: $root.query.fqs().length == 0" style="margin-top: 10px">${_('There are currently no filters applied.')}</div>
-  <div data-bind="foreach: { data: $root.query.fqs, afterRender: function(){ isLoading(false); } }">
-    <!-- ko if: $data.type() == 'field' -->
-    <div class="filter-box">
-      <a href="javascript:void(0)" class="pull-right" data-bind="click: function(){ chartsUpdatingState(); viewModel.query.removeFilter($data); viewModel.search() }"><i class="fa fa-times"></i></a>
-      <strong>${_('field')}</strong>:
-      <span data-bind="text: $data.field"></span>
-      <br/>
-      <strong>${_('value')}</strong>:
-      <span data-bind="text: $data.filter"></span>
-    </div>
-    <!-- /ko -->
-    <!-- ko if: $data.type() == 'range' -->
-    <div class="filter-box">
-      <a href="javascript:void(0)" class="pull-right" data-bind="click: function(){ chartsUpdatingState(); viewModel.query.removeFilter($data); viewModel.search() }"><i class="fa fa-times"></i></a>
-      <strong>${_('field')}</strong>:
-      <span data-bind="text: $data.field"></span>
-      <br/>
-      <span data-bind="foreach: $data.properties" style="font-weight: normal">
-        <strong>${_('from')}</strong>: <span data-bind="text: $data.from"></span>
-        <br/>
-        <strong>${_('to')}</strong>: <span data-bind="text: $data.to"></span>
-      </span>
-    </div>
-    <!-- /ko -->
-  </div>
-  <div class="clearfix"></div>
-  <div class="widget-spinner" data-bind="visible: isLoading() &&  $root.query.fqs().length > 0">
-    <!--[if !IE]> --><i class="fa fa-spinner fa-spin"></i><!-- <![endif]-->
-    <!--[if IE]><img src="${ static('desktop/art/spinner.gif') }" /><![endif]-->
-  </div>
-</script>
-
-
-<script type="text/html" id="map-widget">
-
-  <div class="widget-spinner" data-bind="visible: isLoading()">
-    <!--[if !IE]> --><i class="fa fa-spinner fa-spin"></i><!-- <![endif]-->
-    <!--[if IE]><img src="${ static('desktop/art/spinner.gif') }" /><![endif]-->
-  </div>
-
-  <!-- ko if: $root.getFacetFromResult(id()) -->
-  <div class="row-fluid" data-bind="with: $root.getFacetFromResult(id())">
-    <div data-bind="visible: $root.isEditing, with: $root.dashboard.getFacetById($parent.id())" style="margin-bottom: 20px">
-      <input type="text" data-bind="value: field" />
-      <input type="text" data-bind="value: properties.limit" />
-    </div>
-
-    <div data-bind="mapChart: {data: {counts: data, scope: $root.collection.getFacetById(id()).properties.scope()},
-        transformer: mapChartDataTransformer,
-        maxWidth: 750,
-        isScale: true,
-        onClick: function(d){ viewModel.query.toggleFacet({facet: d, widget_id: $parent.id}) },
-        onComplete: function(){ var widget = viewModel.getWidgetById(id()); if (widget != null) {widget.isLoading(false)};} }" />
-
-    </div>
-  <!-- /ko -->
-
-  <span data-bind="template: { name: 'select-field' }, visible: ! isLoading()"></span>
-
-</script>
-
-
-
-
-<link rel="stylesheet" href="${ static('impala/css/impala-dashboard.css') }">
-<link rel="stylesheet" href="${ static('desktop/ext/css/hue-filetypes.css') }">
-<link rel="stylesheet" href="${ static('desktop/ext/css/hue-charts.css') }">
-<link rel="stylesheet" href="${ static('desktop/ext/chosen/chosen.min.css') }">
-
-${ dashboard.import_layout() }
-
-<script src="${ static('desktop/ext/js/bootstrap-editable.min.js') }" type="text/javascript" charset="utf-8"></script>
-<script src="${ static('desktop/js/ko.editable.js') }" type="text/javascript" charset="utf-8"></script>
-<script src="${ static('desktop/ext/js/shortcut.js') }" type="text/javascript" charset="utf-8"></script>
-<script src="${ static('desktop/ext/js/mustache.js') }" type="text/javascript" charset="utf-8"></script>
-<script src="${ static('desktop/ext/chosen/chosen.jquery.min.js') }" type="text/javascript" charset="utf-8"></script>
-
-${ dashboard.import_bindings() }
-
-<script src="${ static('beeswax/js/autocomplete.utils.js') }" type="text/javascript" charset="utf-8"></script>
-<script src="${ static('impala/js/impala-dashboard.ko.js') }" type="text/javascript" charset="utf-8"></script>
-
-${ dashboard.import_charts() }
-
-
-<script type="text/javascript">
-  var viewModel = new ImpalaDashboardViewModel(${ query_json | n,unicode }, ${ dashboard_json | n,unicode  },  ${ initial_json | n,unicode  });
-  ko.applyBindings(viewModel);
-
-  var HIVE_AUTOCOMPLETE_BASE_URL = "/impala/api/autocomplete/";
-  var HIVE_AUTOCOMPLETE_FAILS_QUIETLY_ON = [500]; // error codes from beeswax/views.py - autocomplete
-  var HIVE_AUTOCOMPLETE_USER = "${ user }";
-
-  function pieChartDataTransformer(data) {
-    var _data = [];
-    $(data.counts()).each(function (cnt, item) {
-      var _item = {
-        widget_id: data.widget_id,
-        count: item.count(),
-        value: item.value()
-      }
-      item.widget_id = data.widget_id;
-      _data.push({
-        label: _item.value,
-        value: _item.count,
-        obj: _item
-      });
-    });
-    return _data;
-  }
-
-  function barChartDataTransformer(rawDatum) {
-    var _datum = [];
-    var _data = [];
-
-    $(rawDatum.counts()).each(function (cnt, item) {
-      var _item = {
-        widget_id: rawDatum.widget_id,
-        count: item.count(),
-        value: item.value()
-      }
-      item.widget_id = rawDatum.widget_id;
-      _data.push({
-        series: 0,
-        x: _item.value,
-        y: _item.count,
-        obj: _item
-      });
-    });
-    _datum.push({
-      key: "LABEL",
-      values: _data
-    });
-    return _datum;
-  }
-
-  function lineChartDataTransformer(rawDatum) {
-    var _datum = [];
-    var _data = [];
-    $(rawDatum.counts()).each(function (cnt, item) {
-      var _item = {
-        widget_id: rawDatum.widget_id,
-        count: parseInt(Math.random()*1000),
-        value: item[0]
-      }
-      item.widget_id = rawDatum.widget_id;
-      _data.push({
-        series: 0,
-        x: _item.value,
-        y: _item.count,
-        obj: _item
-      });
-    });
-    _datum.push({
-      key: "LABEL",
-      values: _data
-    });
-    return _datum;
-  }
-
-  function timelineChartDataTransformer(rawDatum) {
-    var _datum = [];
-    var _data = [];
-
-    $(rawDatum.counts).each(function (cnt, item) {
-      _data.push({
-        series: 0,
-        x: new Date(moment(item.from).valueOf()),
-        y: item.value,
-        obj: item
-      });
-    });
-
-    _datum.push({
-      key: rawDatum.label,
-      values: _data
-    });
-
-
-    // If multi query
-    $(rawDatum.extraSeries).each(function (cnt, item) {
-      if (cnt == 0) {
-        _datum = [];
-      }
-      var _data = [];
-      $(item.counts).each(function (cnt, item) {
-        _data.push({
-          series: cnt + 1,
-          x: new Date(moment(item.from).valueOf()),
-          y: item.value,
-          obj: item
-        });
-      });
-
-      _datum.push({
-        key: item.label,
-        values: _data
-      });
-    });
-
-    return _datum;
-  }
-
-  function mapChartDataTransformer(data) {
-    var _data = [];
-    $(data.counts).each(function (cnt, item) {
-      _data.push({
-        label: item.value,
-        value: item.count,
-        obj: item
-      });
-    });
-    return _data;
-  }
-
-
-
-  function resetDropdownsCache(){
-    $.totalStorage(hac_getTotalStorageUserPrefix() + 'databases', null);
-    getDatabases(function(){
-      $.totalStorage(hac_getTotalStorageUserPrefix() + 'tables_' + viewModel.dashboard.selectedDropdownDb(), null);
-      $.totalStorage(hac_getTotalStorageUserPrefix() + 'timestamp_tables_' + viewModel.dashboard.selectedDropdownDb(), null);
-    });
-  }
-
-  function getDatabases(callback){
-    $(document).one('fetched.databases', function() {
-      window.setTimeout(function(){
-        $(".chosen-server").chosen({
-          disable_search_threshold: 5,
-          width: "130px",
-          no_results_text: "${_('Oops, no database found!')}"
-        }).change(function () {
-          getTables();
-        });
-        $(".chosen-select").trigger("chosen:updated");
-      }, 200)
-    });
-
-    hac_getDatabases(function (dbs) {
-      viewModel.dashboard.updateDropdownDatabases(dbs);
-      if (typeof callback != "undefined"){
-        callback(dbs);
-      }
-      $(document).trigger('fetched.databases', [dbs]);
-    });
-  }
-
-  function getTables(callback) {
-    $.get("/impala/api/autocomplete/" + viewModel.dashboard.selectedDropdownDb(), function (data) {
-      var tables = [];
-      $.each(data.tables_meta, function(i, table) {
-        tables.push(table.name);
-      });
-      viewModel.dashboard.dropdownTables(tables);
-      viewModel.dashboard.dropdownTables.valueHasMutated();
-    }).fail(function (xhr, textStatus, errorThrown) {
-      $(document).trigger("error", xhr.responseText);
-    });
-  }
-
-  $(document).ready(function(){
-    window.setTimeout(function(){
-      viewModel.init(function(){
-        if (! viewModel.inited()){
-          getDatabases(function(){
-            getTables();
-          });
-        }
-      });
-    }, 50);
-  });
-
-  function toggleGridFieldsSelection() {
-    if (viewModel.dashboard.resultsetSelectedFields().length > 0) {
-      viewModel.dashboard.resultsetSelectedFields([]);
-    }
-    else {
-      selectAllCollectionFields();
-    }
-  }
-
-  function selectAllCollectionFields() {
-    viewModel.dashboard.resultsetSelectedFields(viewModel.dashboard.fieldNames());
-  }
-
-  function highlightColumn(column) {
-    var _colName = $.trim(column.name());
-    if (viewModel.dashboard.resultsetSelectedFields.indexOf(_colName) > -1) {
-      var _t = $("#result-container");
-      var _col = _t.find("th").filter(function () {
-        return $.trim($(this).text()) == _colName;
-      });
-      if (_t.find("tr td:nth-child(" + (_col.index() + 1) + ").columnSelected").length == 0) {
-        _t.find(".columnSelected").removeClass("columnSelected");
-        _t.find("tr td:nth-child(" + (_col.index() + 1) + ")").addClass("columnSelected");
-        _t.parent().animate({
-          scrollLeft: _t.find("tr td:nth-child(" + (_col.index() + 1) + ")").position().left + _t.parent().scrollLeft() - _t.parent().offset().left - 30
-        }, 300);
-      }
-      else {
-        _t.find(".columnSelected").removeClass("columnSelected");
-      }
-    }
-  }
-
-  function columnDropAdditionalHandler(widget){
-    console.log("column drop")
-  }
-
-  function widgetDraggedAdditionalHandler(widget){
-    console.log("boom")
-  }
-
-</script>
-
-${ commonfooter(request, messages) | n,unicode }

+ 0 - 10
apps/impala/src/impala/urls.py

@@ -27,14 +27,4 @@ urlpatterns = patterns('impala.api',
   url(r'^api/query/(?P<query_history_id>\d+)/runtime_profile', 'get_runtime_profile', name='get_runtime_profile'),
   url(r'^api/query/(?P<query_history_id>\d+)/runtime_profile', 'get_runtime_profile', name='get_runtime_profile'),
 )
 )
 
 
-urlpatterns += patterns('impala.dashboards',
-  url(r'^dashboard/$', 'dashboard', name='dashboard'),
-  url(r'^dashboard/query', 'query', name='query'),
-
-  url(r'^dashboard/new_facet$', 'new_facet', name='new_facet'),
-  url(r'^dashboard/new_search$', 'new_search', name='new_search'),
-  url(r'^dashboard/save$', 'save', name='save'),
-  url(r'^dashboard/get_fields', 'get_fields', name='get_fields'),
-)
-
 urlpatterns += beeswax_urls
 urlpatterns += beeswax_urls