Browse Source

[impala] Add a new facet with drag and drop

Romain Rigaux 11 years ago
parent
commit
5052357cc0

+ 30 - 1
apps/impala/src/impala/templates/dashboard.mako

@@ -156,11 +156,35 @@ ${ dashboard.layout_skeleton() }
 </div>
 </script>
 
-<script type="text/html" id="pie-widget">
+
+<script type="text/html" id="facet-widget">
   <!-- 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>
+  
+    <span data-bind="foreach: data()">
+      <a href="javascript: void(0)">
+        <span data-bind="text: $data, click: function(){ $root.query.toggleFacet({facet: $data, widget: $parent}) }"></span>
+      </a>
+    </span>
+  </div>
+  <!-- /ko -->
+  <!-- ko ifnot: $root.getFacetFromResult(id()) -->
+    <a href="javascript:void(0)" data-bind="click: $root.dashboard.addFacet">
+      <i class="fa fa-plus"></i>
+    </a>
+  <!-- /ko -->
+</script>
+
+
+<script type="text/html" id="pie-widget">
+  <!-- ko if: $root.getFacetFromResult(id()) -->
+  <div class="row-fluid" data-bind="with: $root.getFacetFromResult(id())">
+    PIE widget
+    <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>
@@ -172,6 +196,11 @@ ${ dashboard.layout_skeleton() }
     </span>
   </div>
   <!-- /ko -->
+  <!-- ko ifnot: $root.getFacetFromResult(id()) -->
+    <a href="javascript:void(0)" data-bind="click: $root.dashboard.addFacet">
+      <i class="fa fa-plus"></i>
+    </a>
+  <!-- /ko -->  
 </script>
 
 

+ 3 - 1
apps/impala/src/impala/urls.py

@@ -22,7 +22,9 @@ from beeswax.urls import urlpatterns as beeswax_urls
 
 urlpatterns = patterns('impala.views',
   url(r'^dashboard$', 'dashboard', name='dashboard'),
-  url(r'^query', 'query', name='query'),
+  url(r'^dashboard/query', 'query', name='query'),
+  
+  url(r'^dashboard/new_facet$', 'new_facet', name='new_facet'),
 )
 
 urlpatterns += beeswax_urls

+ 59 - 3
apps/impala/src/impala/views.py

@@ -37,14 +37,14 @@ def dashboard(request):
   return render('dashboard.mako', request, {
     'query_json': json.dumps({}),
     'dashboard_json': json.dumps({'layout': [
-              {"size":2,"rows":[{"widgets":[{"size":12,"name":"Pie Results","id":"52f07188-f30f-1296-2450-f77e02e1a5c1","widgetType":"pie-widget",
+              {"size":2,"rows":[{"widgets":[{"size":12,"name":"Pie Results","id":"52f07188-f30f-1296-2450-f77e02e1a5c1","widgetType":"facet-widget",
                    "properties":{},"offset":0,"isLoading":True,"klass":"card card-widget span12"}]}],"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"}
          ],
-        'facets': [{'id': '52f07188-f30f-1296-2450-f77e02e1a5c1', 'label': 'Top salaries', 'field': 'salary', 'widget_type': 'pie', 
+        'facets': [{'id': '52f07188-f30f-1296-2450-f77e02e1a5c1', 'label': 'Top salaries', 'field': 'salary', 'widget_type': 'facet-widget', 
                     'properties': {'limit': 10}}],
         'properties': [{'database': 'default', 'table': 'sample_07'}]
         }), 
@@ -63,7 +63,10 @@ def query(request):
     facet = json.loads(request.POST['facet'])
     database = 'default'
     table = 'sample_07'  
-    hql = "SELECT salary FROM %s.%s WHERE salary IS NOT NULL ORDER BY salary DESC LIMIT %s" % (database, table, facet['properties']['limit'])
+    hql = "SELECT %(field)s FROM %(database)s.%(table)s WHERE %(field)s IS NOT NULL ORDER BY %(field)s DESC LIMIT %(limit)s" % {
+        'database': database, 'table': table, 'limit': facet['properties']['limit'],
+        'field': facet['field']
+    }
     result['id'] = facet['id']
     result['field'] = facet['field']
   else:
@@ -84,3 +87,56 @@ def query(request):
     db.close(handle)
     
   return HttpResponse(json.dumps(result), mimetype="application/json")
+
+
+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_id = request.POST['id']
+#    facet_label = request.POST['label']
+#    facet_field = request.POST['field']
+#    widget_type = request.POST['widget_type']
+
+    result['message'] = ''
+    result['facet'] =  {
+        'id': facet_json['id'], 'label': 'Top salaries', 'field': 'total_emp', 'widget_type': facet_json['widgetType'], 
+        'properties': {'limit': 10}
+    }
+    result['status'] = 0
+  except Exception, e:
+    result['message'] = unicode(str(e), "utf8")
+
+  return HttpResponse(json.dumps(result), mimetype="application/json")
+
+
+def _create_facet(collection, user, facet_id, facet_label, facet_field, widget_type):
+  properties = {
+    'sort': 'desc',
+    'canRange': False,
+    'stacked': False,
+    'limit': 10,
+    'mincount': 0,
+    'isDate': False,
+    'andUp': False,  # Not used yet
+  }
+
+  facet_type = 'field'
+
+  if widget_type == 'map-widget':
+    properties['scope'] = 'world'
+    properties['mincount'] = 1
+    properties['limit'] = 100
+
+  return {
+    'id': facet_id,
+    'label': facet_label,
+    'field': facet_field,
+    'type': facet_type,
+    'widgetType': widget_type,
+    'properties': properties
+  }

+ 30 - 6
apps/impala/static/js/impala-dashboard.ko.js

@@ -98,10 +98,34 @@ var Query = function (vm, query) {
 var Dashboard = function (vm, dashboard) { 
   var self = this;
   
-  self.facets = ko.observable(dashboard.facets);
+  self.facets = ko.mapping.fromJS(dashboard.facets);
   self.properties = ko.observable(dashboard.properties);
   
-  self.addFacet = function(data) {
+  self.fields = ko.mapping.fromJS([{'name': 'code', 'name': 'description', 'name': 'total_emp', 'name': 'salary'}]);
+  self.fieldNames = ko.computed(function () {
+	return $.map(self.fields(), function (field) { return field.name()});
+  });
+  
+  self.addFacet = function(facet_json) {
+   $.post("/impala/dashboard/new_facet", {
+       "dashboard": ko.mapping.toJSON(self),
+       "facet_json": ko.mapping.toJSON(facet_json),
+       //"id": facet_json.widget_id,
+       //"label": facet_json.name,
+       //"field": facet_json.name,
+       //"widget_type": facet_json.widgetType
+     }, 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) {
@@ -126,7 +150,7 @@ var ImpalaDashboardViewModel = function (query_json, dashboard_json) {
     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);
@@ -145,7 +169,7 @@ var ImpalaDashboardViewModel = function (query_json, dashboard_json) {
       self.results.removeAll();
     	
       var multiQs = $.map(self.dashboard.facets(), function(facet) {
-        return $.post("/impala/query", {
+        return $.post("/impala/dashboard/query", {
            "query": ko.mapping.toJSON(self.query),
            "dashboard": ko.mapping.toJSON(self.dashboard),
            "layout": ko.mapping.toJSON(self.columns),
@@ -154,7 +178,7 @@ var ImpalaDashboardViewModel = function (query_json, dashboard_json) {
       });    	
     	
       $.when.apply($, [
-          $.post("/impala/query", {
+          $.post("/impala/dashboard/query", {
             "query": ko.mapping.toJSON(self.query),
             "dashboard": ko.mapping.toJSON(self.dashboard),
             "layout": ko.mapping.toJSON(self.columns),
@@ -181,7 +205,7 @@ var ImpalaDashboardViewModel = function (query_json, dashboard_json) {
           }          
         })
       .fail(function (xhr, textStatus, errorThrown) {
-    	  $(document).trigger("error", data.message);
+    	  $(document).trigger("error", textStatus);
        });
     };