瀏覽代碼

HUE-7022 [assist] Enable listing the Solr collection fields

Enrico Berti 8 年之前
父節點
當前提交
8d3d5263c0

+ 51 - 0
desktop/core/src/desktop/static/desktop/js/apiHelper.js

@@ -63,6 +63,8 @@ var ApiHelper = (function () {
   var CONFIG_SAVE_API = '/desktop/api/configurations/save/';
   var CONFIG_APPS_API = '/desktop/api/configurations';
   var SOLR_COLLECTIONS_API = '/indexer/api/indexes/list/';
+  var SOLR_FIELDS_API = '/indexer/api/index/list/';
+
   var HBASE_API_PREFIX = '/hbase/api/';
   var SAVE_TO_FILE = '/filebrowser/save';
 
@@ -576,6 +578,55 @@ var ApiHelper = (function () {
     }));
   };
 
+  /**
+   * @param {Object} options
+   * @param {String} options.collectionName
+   * @param {Function} options.successCallback
+   * @param {Function} [options.errorCallback]
+   * @param {boolean} [options.silenceErrors]
+   * @param {Number} [options.timeout]
+   *
+   */
+  ApiHelper.prototype.fetchSolrCollection = function (options) {
+    var self = this;
+    var url = SOLR_FIELDS_API;
+    var fetchFunction = function (storeInCache) {
+      if (options.timeout === 0) {
+        self.assistErrorCallback(options)({ status: -1 });
+        return;
+      }
+      $.ajax({
+        dataType: "json",
+        url: url,
+        data: {
+          name: options.collectionName
+        },
+        type: 'POST',
+        timeout: options.timeout,
+        success: function (data) {
+          if (!data.error && !self.successResponseIsError(data) && typeof data.schema !== 'undefined' && data.schema !== null) {
+            storeInCache(data);
+            options.successCallback(data);
+          } else {
+            self.assistErrorCallback(options)(data);
+          }
+        }
+      })
+      .fail(self.assistErrorCallback(options))
+      .always(function () {
+        if (typeof options.editor !== 'undefined' && options.editor !== null) {
+          options.editor.hideSpinner();
+        }
+      });
+    };
+
+    fetchCached.bind(self)($.extend({}, options, {
+      sourceType: 'collections',
+      url: url,
+      fetchFunction: fetchFunction
+    }));
+  };
+
   /**
    * @param {Object} options
    * @param {Function} options.successCallback

+ 43 - 14
desktop/core/src/desktop/static/desktop/js/assist/assistCollectionEntry.js

@@ -29,6 +29,8 @@ var AssistCollectionEntry = (function () {
     self.definition = options.definition;
     self.apiHelper = options.apiHelper;
     self.path = self.definition.name;
+    self.parent = options.parent;
+    self.key = ko.observable(options.key);
     self.filter = filter;
     self.showCores = showCores;
 
@@ -69,12 +71,25 @@ var AssistCollectionEntry = (function () {
     self.hasErrors(false);
 
     var successCallback = function(data) {
-      self.entries($.map(data.collections, function (collection) {
-        return new AssistCollectionEntry({
-          definition: collection,
-          apiHelper: self.apiHelper
-        }, self.filter, self.showCores)
-      }));
+      if (data.collections) {
+        self.entries($.map(data.collections, function (collection) {
+          return new AssistCollectionEntry({
+            definition: collection,
+            parent: self,
+            apiHelper: self.apiHelper
+          }, self.filter, self.showCores)
+        }));
+      }
+      else if (data.schema && data.schema.fields) {
+        self.key(data.schema.uniqueKey);
+        self.entries($.map(data.schema.fields, function (field) {
+          return new AssistCollectionEntry({
+            definition: field,
+            parent: self,
+            apiHelper: self.apiHelper
+          }, self.filter, self.showCores)
+        }));
+      }
       self.loaded = true;
       self.loading(false);
       if (callback) {
@@ -90,18 +105,32 @@ var AssistCollectionEntry = (function () {
       }
     };
 
-    self.apiHelper.fetchSolrCollections({
-      successCallback: successCallback,
-      errorCallback: errorCallback
-    })
+    if (self.path === '/') {
+      self.apiHelper.fetchSolrCollections({
+        successCallback: successCallback,
+        errorCallback: errorCallback
+      });
+    }
+    else {
+      self.apiHelper.fetchSolrCollection({
+        collectionName: self.definition.name,
+        successCallback: successCallback,
+        errorCallback: errorCallback
+      });
+    }
+
   };
 
-  AssistCollectionEntry.prototype.open = function () {
-    huePubSub.publish('assist.clickCollectionItem', this);
+  AssistCollectionEntry.prototype.openInBrowser = function () {
+    huePubSub.publish('assist.openCollectionItem', this);
   };
 
-  AssistCollectionEntry.prototype.browse = function () {
-    huePubSub.publish('open.link', '/hue/search/browse/' + this.definition.name);
+  AssistCollectionEntry.prototype.openInDashboard = function () {
+    var definitionName = this.definition.name;
+    if (this.parent && this.parent.definition.name !== '/') {
+      definitionName = this.parent.definition.name;
+    }
+    huePubSub.publish('open.link', '/hue/search/browse/' + definitionName);
   };
 
   AssistCollectionEntry.prototype.click = function () {

+ 70 - 25
desktop/core/src/desktop/templates/assist.mako

@@ -192,8 +192,8 @@ from notebook.conf import ENABLE_QUERY_BUILDER, ENABLE_QUERY_SCHEDULING, get_ord
   </script>
 
   <script type="text/html" id="collections-context-items">
-    <li><a href="javascript: void(0);" data-bind="click: open"><!-- ko template: { name: 'app-icon-template', data: { icon: 'indexes' } } --><!-- /ko --> ${ _('Open in Browser') }</a></li>
-    <li><a href="javascript: void(0);" data-bind="click: browse"><!-- ko template: { name: 'app-icon-template', data: { icon: 'dashboard' } } --><!-- /ko --> ${ _('Open in Dashboard') }</a></li>
+    <li><a href="javascript: void(0);" data-bind="click: openInBrowser"><!-- ko template: { name: 'app-icon-template', data: { icon: 'indexes' } } --><!-- /ko --> ${ _('Open in Browser') }</a></li>
+    <li><a href="javascript: void(0);" data-bind="click: openInDashboard"><!-- ko template: { name: 'app-icon-template', data: { icon: 'dashboard' } } --><!-- /ko --> ${ _('Open in Dashboard') }</a></li>
   </script>
 
   <script type="text/html" id="assist-database-entry">
@@ -604,7 +604,16 @@ from notebook.conf import ENABLE_QUERY_BUILDER, ENABLE_QUERY_SCHEDULING, get_ord
   <script type="text/html" id="assist-collections-inner-panel">
     <!-- ko with: selectedCollectionEntry -->
     <div class="assist-inner-header assist-breadcrumb">
+      <!-- ko if: parent -->
+      <a href="javascript: void(0);" data-bind="click: function () { huePubSub.publish('assist.clickCollectionItem', parent); }">
+        <i class="fa fa-fw fa-chevron-left"></i>
+        <i class="fa fa-fw fa-search"></i>
+        <span data-bind="text: definition.name, tooltip: {'title': path, 'placement': 'bottom' }"></span>
+      </a>
+      <!-- /ko -->
+      <!-- ko ifnot: parent -->
       ${_('Collections')}
+      <!-- /ko -->
       <!-- ko template: 'assist-collections-header-actions' --><!-- /ko -->
     </div>
     <div class="assist-flex-table-search" data-bind="visible: $parent.isSearchVisible() && !loading() && !hasErrors() && entries().length > 0">
@@ -617,15 +626,37 @@ from notebook.conf import ENABLE_QUERY_BUILDER, ENABLE_QUERY_SCHEDULING, get_ord
       <div data-bind="visible: ! loading() && ! hasErrors()" style="position: relative;">
         <ul class="assist-tables" data-bind="foreachVisible: { data: filteredEntries, minHeight: 22, container: '.assist-collections-scrollable' }">
           <li class="assist-entry assist-table-link" style="position: relative;" data-bind="appAwareTemplateContextMenu: { template: 'collections-context-items', scrollContainer: '.assist-collections-scrollable' }, visibleOnHover: { 'selector': '.assist-actions' }">
-            <a href="javascript:void(0)" class="assist-entry assist-table-link" data-bind="multiClick: { click: click, dblClick: dblClick }, attr: {'title': definition.name }">
-              <i class="fa fa-fw fa-search muted valign-middle"></i>
+            <a href="javascript:void(0)" class="assist-entry assist-table-link" data-bind="multiClick: { click: click, dblClick: dblClick }, attr: {'title': definition.name + (definition.type != 'collection' && definition.type != 'alias' ? ' - ' + definition.type : '') }">
+              <!-- ko switch: definition.type -->
+                <!-- ko case: 'collection' -->
+                <i class="fa fa-fw fa-search muted valign-middle"></i>
+                <!-- /ko -->
+                <!-- ko case: 'alias' -->
+                <i class="fa fa-fw fa-eye muted valign-middle"></i>
+                <!-- /ko -->
+                <!-- ko case: $default -->
+                  <!-- ko if: parent.key() === definition.name -->
+                    <i class="fa fa-fw fa-key muted valign-middle"></i>
+                  <!-- /ko -->
+                  <!-- ko ifnot: parent.key() === definition.name -->
+                    <i class="fa fa-fw fa-genderless muted valign-middle"></i>
+                  <!-- /ko -->
+                <!-- /ko -->
+              <!-- /ko -->
               <span draggable="true" data-bind="text: definition.name, draggableText: { text: '\'' + path + '\'', meta: {'type': 'collection', 'definition': definition} }"></span>
             </a>
           </li>
         </ul>
         <!-- ko if: !loading() && entries().length === 0 -->
         <ul class="assist-tables">
-          <li class="assist-entry"><span class="assist-no-entries">${_('No collections available.')}</span></li>
+          <li class="assist-entry"><span class="assist-no-entries">
+            <!-- ko if: parent -->
+            ${_('No available fields.')}
+            <!-- /ko -->
+            <!-- ko ifnot: parent -->
+            ${_('No available collections.')}
+            <!-- /ko -->
+          </span></li>
         </ul>
         <!-- /ko -->
       </div>
@@ -1359,33 +1390,47 @@ from notebook.conf import ENABLE_QUERY_BUILDER, ENABLE_QUERY_SCHEDULING, get_ord
         };
 
         huePubSub.subscribe('assist.clickCollectionItem', function (entry) {
-          % if ENABLE_NEW_INDEXER.get():
-          if (IS_HUE_4) {
-            huePubSub.publish('open.link', '/indexer/indexes/' + entry.definition.name);
+          if (entry.definition.type === 'collection' || entry.definition.type === 'alias') {
+            entry.loadEntries();
+            self.selectedCollectionEntry(entry);
           }
           else {
-            window.open('/indexer/indexes/' + entry.definition.name);
+            huePubSub.publish('assist.openCollectionItem', entry);
+          }
+        });
+
+        huePubSub.subscribe('assist.openCollectionItem', function (entry) {
+          var definitionName = entry.definition.name;
+          if (entry.parent && entry.parent.definition.name !== '/') {
+            definitionName = entry.parent.definition.name;
           }
+          % if ENABLE_NEW_INDEXER.get():
+            if (IS_HUE_4) {
+              huePubSub.publish('open.link', '/indexer/indexes/' + definitionName);
+            }
+            else {
+              window.open('/indexer/indexes/' + definitionName);
+            }
           % else:
-          var hash = '#edit/' + entry.definition.name;
-          if (IS_HUE_4) {
-            if (window.location.pathname.startsWith('/hue/indexer') && !window.location.pathname.startsWith('/hue/indexer/importer')) {
-              window.location.hash = hash;
+            var hash = '#edit/' + definitionName;
+            if (IS_HUE_4) {
+              if (window.location.pathname.startsWith('/hue/indexer') && !window.location.pathname.startsWith('/hue/indexer/importer')) {
+                window.location.hash = hash;
+              }
+              else {
+                huePubSub.subscribeOnce('app.gained.focus', function (app) {
+                  if (app === 'indexes') {
+                    window.setTimeout(function () {
+                      window.location.hash = hash;
+                    }, 0)
+                  }
+                });
+                huePubSub.publish('open.link', '/indexer');
+              }
             }
             else {
-              huePubSub.subscribeOnce('app.gained.focus', function(app){
-                if (app === 'indexes'){
-                  window.setTimeout(function(){
-                    window.location.hash = hash;
-                  }, 0)
-                }
-              });
-              huePubSub.publish('open.link', '/indexer');
+              window.open('/indexer/' + hash);
             }
-          }
-          else {
-            window.open('/indexer/' + hash);
-          }
           % endif
         });