Răsfoiți Sursa

HUE-3228 [dashboard] Create a new dashboard by selecting a table or and index

Romain Rigaux 8 ani în urmă
părinte
comite
f94965f

+ 1 - 1
apps/search/src/search/api_engines.py

@@ -31,7 +31,7 @@ def get_engine(user, engine='solr'):
   if isinstance(engine, dict):
     engine = engine.get('engine', 'solr')
 
-  if engine == 'db':
+  if engine == 'impala':
     from impala.dashboard_api import SQLApi
     return SQLApi(user)
   else:

+ 11 - 0
apps/search/src/search/models.py

@@ -32,6 +32,7 @@ from desktop.lib.i18n import smart_unicode, smart_str
 from desktop.models import get_data_link
 
 from libsolr.api import SolrApi
+from notebook.conf import get_ordered_interpreters
 
 from search.conf import SOLR_URL, LATEST
 
@@ -1140,6 +1141,16 @@ def _convert_nested_to_augmented_pivot_nd(facet_fields, facet_id, counts, select
     c['fq_values'] = fq_values
 
 
+def get_engines(user):
+  return [
+      {'name': _('index (Solr)'), 'type': 'solr'}] + [{
+        'name': _('table (%s)') % interpreter['name'],
+        'type': interpreter['type']
+      }
+      for interpreter in get_ordered_interpreters(user) if interpreter['interface'] == 'hiveserver2'
+  ]
+
+
 def augment_solr_exception(response, collection):
   response.update(
   {

+ 11 - 5
apps/search/src/search/static/search/js/search.ko.js

@@ -452,6 +452,9 @@ var Collection = function (vm, collection) {
   self.description = ko.observable(typeof collection.description != "undefined" && collection.description != null ? collection.description : "");
   self.suggest = ko.mapping.fromJS(collection.suggest);
   self.engine = ko.observable(typeof collection.engine != "undefined" && collection.engine != null ? collection.engine : "solr");
+  self.engine.subscribe(function() {
+    self.name(null);
+  });
   self.nested = ko.mapping.fromJS(collection.nested);
   self.nestedNames = ko.computed(function() {
     function flatten(values) {
@@ -1353,6 +1356,7 @@ var NewTemplate = function (vm, initial) {
   var self = this;
 
   self.collections = ko.mapping.fromJS(initial.collections);
+  self.engines = ko.mapping.fromJS(initial.engines);
   self.layout = initial.layout;
   self.inited = ko.observable(self.collections().length > 0); // No collection if not a new dashboard
 
@@ -1360,9 +1364,11 @@ var NewTemplate = function (vm, initial) {
     if (self.inited()) {
       // If new dashboard
       vm.collection.name.subscribe(function(newValue) {
-        vm.collection.label(newValue);
-        vm.collection.switchCollection();
-        vm.search();
+        if (newValue) {
+          vm.collection.label(newValue);        
+          vm.collection.switchCollection();
+          vm.search();
+        }
       });
     } else {
       self.syncCollections();
@@ -1629,7 +1635,7 @@ var SearchViewModel = function (collection_json, query_json, initial_json) {
       });
     }
 
-    if (self.collection.engine() == 'db') {
+    if (self.collection.engine() == 'impala') {
       multiQs = $.map(self.collection.facets(), function(facet) {
         return $.post("/search/search", {
             collection: ko.mapping.toJSON(self.collection),
@@ -1700,7 +1706,7 @@ var SearchViewModel = function (collection_json, query_json, initial_json) {
     )
       .done(function () {
         if (arguments[0] instanceof Array) {
-          if (self.collection.engine() != 'db') { // If multi queries
+          if (self.collection.engine() != 'impala') { // If multi queries
 	          var histograms = self.collection.getHistogramFacets();
 	          for (var h = 0; h < histograms.length; h++) { // Do not use $.each here
 	            var histoFacetId = histograms[h].id();

+ 29 - 13
apps/search/src/search/templates/common_search.mako

@@ -83,22 +83,31 @@ from desktop.views import commonheader, commonfooter, _ko
   </div>
 
   <form data-bind="visible: $root.isEditing() && columns().length == 0">
-    ${ _('Select a search index') }
-    <!-- ko if: columns().length == 0 -->
-      <select data-bind="options: $root.initial.collections, value: $root.collection.name, disable: isSyncingCollections">
-      </select>
+    ${ _('Select one') }
+    <select class="input-medium" data-bind="options: $root.initial.engines, value: $root.collection.engine, optionsText: 'name',  optionsValue: 'type', disable: isSyncingCollections"></select>
 
-      <label class="checkbox" style="display:inline-block; margin-left: 10px">
-        <input type="checkbox" data-bind="checked: showCores" />${ _('Show cores') }
-        <i class="fa fa-spinner fa-spin" data-bind="visible: isSyncingCollections"></i>
-      </label>
-    <!-- /ko -->
+    <!-- ko if: $root.collection.engine() == 'solr' -->
+      <!-- ko if: columns().length == 0 -->      
+      <select data-bind="options: $root.initial.collections, value: $root.collection.name, disable: isSyncingCollections"></select>
 
-    <select data-bind="options: $root.availableDateFields, value: collection.timeFilter.field, optionsValue: 'name', visible: $root.isEditing() && $root.availableDateFields().length > 0" class="input-medium" style="margin-left: 4px"></select>
-    <span class="time-filter" data-bind="template: {name: 'time-filter'}, visible: collection.timeFilter.type() == 'rolling'"></span>
-    <span class="time-fixed-filter" data-bind="template: {name: 'time-fixed-filter'}, visible: collection.timeFilter.type() == 'fixed'"></span>
+        <label class="checkbox" style="display:inline-block; margin-left: 10px">
+          <input type="checkbox" data-bind="checked: showCores" />${ _('Show cores') }
+          <i class="fa fa-spinner fa-spin" data-bind="visible: isSyncingCollections"></i>
+        </label>
+      <!-- /ko -->
 
-    <span data-bind="template: {name: 'nested-document-filter'}"></span>
+      <select data-bind="options: $root.availableDateFields, value: collection.timeFilter.field, optionsValue: 'name', visible: $root.isEditing() && $root.availableDateFields().length > 0" class="input-medium" style="margin-left: 4px"></select>
+      <span class="time-filter" data-bind="template: {name: 'time-filter'}, visible: collection.timeFilter.type() == 'rolling'"></span>
+      <span class="time-fixed-filter" data-bind="template: {name: 'time-fixed-filter'}, visible: collection.timeFilter.type() == 'fixed'"></span>
+  
+      <span data-bind="template: {name: 'nested-document-filter'}"></span>
+    <!-- /ko -->
+    
+    <!-- ko if: $root.collection.engine() != 'solr' -->
+      <!-- ko if: columns().length == 0 -->      
+        <input type="text" class="no-margin" data-bind="value: $root.collection.name, hivechooser: $root.collection.name, skipColumns: true" placeholder="${ _('Table name or <database>.<table>') }">
+      <!-- /ko -->
+    <!-- /ko -->
   </form>
 
   <form class="form-search" style="margin: 0" data-bind="submit: searchBtn, visible: columns().length != 0">
@@ -1478,6 +1487,11 @@ ${ dashboard.layout_skeleton() }
                   <i class="hfo hfo-file-json"></i> JSON
                 </a>
               </li>
+              <li>
+                <a class="inactive-action download" href="javascript:void(0)" data-bind="click: function(widget, event){ var $f = $(event.currentTarget).parents('form'); $f.find('[name=\'type\']').val('json'); $f.submit()}" title="${ _('Download first rows as JSON') }">
+                  <i class="fa fa-w fa-save"></i> ${_('Save')}
+                </a>
+              </li>
             </ul>
           </div>
         </form>
@@ -2455,6 +2469,7 @@ ${ dashboard.layout_skeleton() }
           <fieldset>
             <legend><i class="fa fa-cogs"></i> ${ _('General settings') }</legend>
             <!-- ko if: $root.initial.inited() -->
+            <!-- ko if: $root.collection.engine() == 'solr' -->
             <div class="control-group">
               <label class="control-label" for="settingssolrindex">${ _('Solr index') }</label>
               <div class="controls">
@@ -2493,6 +2508,7 @@ ${ dashboard.layout_skeleton() }
               </div>
             </div>
             <!-- /ko -->
+            <!-- /ko -->
           </fieldset>
         </form>
       </div>

+ 6 - 3
apps/search/src/search/views.py

@@ -33,7 +33,7 @@ from search.conf import LATEST
 from search.data_export import download as export_download
 from search.decorators import allow_owner_only, allow_viewer_only
 from search.management.commands import search_setup
-from search.models import Collection2
+from search.models import Collection2, get_engines
 from search.search_controller import SearchController, can_edit_index
 
 from django.core.urlresolvers import reverse
@@ -76,10 +76,12 @@ def index(request, is_mobile=False, is_embeddable=False):
   return render(template, request, {
     'collection': collection,
     'query': json.dumps(query),
-    'initial': json.dumps({'collections': [], 'layout': [], 'is_latest': LATEST.get()}),
+    'initial': json.dumps({'collections': [], 'layout': [], 'is_latest': LATEST.get(),
+        'engines': get_engines(request.user)
+    }),
     'is_owner': collection_doc.doc.get().can_write(request.user),
     'can_edit_index': can_edit_index(request.user),
-    'mobile': is_mobile
+    'mobile': is_mobile,
   })
 
 def index_m(request):
@@ -117,6 +119,7 @@ def new_search(request, is_embeddable=False):
                  "drops":["temp"],"klass":"card card-home card-column span10"},
          ],
          'is_latest': LATEST.get(),
+         'engines': get_engines(request.user)
      }),
     'is_owner': True,
     'can_edit_index': can_edit_index(request.user)

+ 1 - 1
desktop/core/src/desktop/static/desktop/js/ko.hue-bindings.js

@@ -2736,7 +2736,7 @@
         self.val(options());
       }
       else {
-        if (options.data){
+        if (options && options.data){
           self.val(options.data);
           complexConfiguration = true;
         }