Bladeren bron

HUE-5084 [core] Add indexes as Assist Panel

Enrico Berti 9 jaren geleden
bovenliggende
commit
e5cc8d8

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

@@ -31,6 +31,7 @@ var ApiHelper = (function () {
   var NAV_DELETE_TAGS_API = '/metadata/api/navigator/delete_tags';
   var NAV_LIST_TAGS_API = '/metadata/api/navigator/list_tags';
   var NAV_FIND_ENTITY_API = '/metadata/api/navigator/find_entity';
+  var SOLR_COLLECTIONS_API = '/indexer/api/collections/';
 
   /**
    * @param {Object} i18n
@@ -59,6 +60,10 @@ var ApiHelper = (function () {
     huePubSub.subscribe('assist.clear.s3.cache', function () {
       $.totalStorage("hue.assist." + self.getTotalStorageUserPrefix('s3'), {});
     });
+
+    huePubSub.subscribe('assist.clear.collections.cache', function () {
+      $.totalStorage("hue.assist." + self.getTotalStorageUserPrefix('collections'), {});
+    });
   }
 
   ApiHelper.prototype.hasExpired = function (timestamp) {
@@ -333,6 +338,54 @@ var ApiHelper = (function () {
     }));
   };
 
+  /**
+   * @param {Object} options
+   * @param {Function} options.successCallback
+   * @param {Function} [options.errorCallback]
+   * @param {boolean} [options.silenceErrors]
+   * @param {Number} [options.timeout]
+   * @param {Object} [options.editor] - Ace editor
+   *
+   * @param {string[]} options.pathParts
+   * @param {number} [options.pageSize] - Default 500
+   * @param {number} [options.page] - Default 1
+   */
+  ApiHelper.prototype.fetchSolrCollections = function (options) {
+    var self = this;
+    var url = SOLR_COLLECTIONS_API + '?format=json';
+    var fetchFunction = function (storeInCache) {
+      if (options.timeout === 0) {
+        self.assistErrorCallback(options)({ status: -1 });
+        return;
+      }
+      $.ajax({
+        dataType: "json",
+        url: url,
+        timeout: options.timeout,
+        success: function (data) {
+          if (!data.error && !self.successResponseIsError(data) && typeof data.collections !== 'undefined' && data.collections.length) {
+            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
+    }));
+  };
+
   ApiHelper.prototype.getFetchQueue = function (fetchFunction, identifier) {
     var self = this;
     if (! self.fetchQueue[fetchFunction]) {

+ 91 - 0
desktop/core/src/desktop/static/desktop/js/assist/assistCollectionEntry.js

@@ -0,0 +1,91 @@
+// 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.
+
+var AssistCollectionEntry = (function () {
+
+  /**
+   * @param {object} options
+   * @param {object} options.definition
+   * @param {string} options.definition.name
+   * @param {ApiHelper} options.apiHelper
+   * @constructor
+   */
+  function AssistCollectionEntry (options) {
+    var self = this;
+
+    self.definition = options.definition;
+    self.apiHelper = options.apiHelper;
+    self.path = self.definition.name;
+
+    self.entries = ko.observableArray([]);
+
+    self.loaded = false;
+    self.loading = ko.observable(false);
+    self.hasErrors = ko.observable(false);
+
+    self.hasEntries = ko.computed(function() {
+      return self.entries().length > 0;
+    });
+  }
+
+  AssistCollectionEntry.prototype.loadEntries = function(callback) {
+    var self = this;
+    if (self.loading()) {
+      return;
+    }
+    self.loading(true);
+    self.hasErrors(false);
+
+    var successCallback = function(data) {
+      self.entries($.map(data.collections, function (collection) {
+        if (!collection.isCoreOnly) {
+          return new AssistCollectionEntry({
+            definition: collection,
+            apiHelper: self.apiHelper
+          })
+        }
+      }));
+      self.loaded = true;
+      self.loading(false);
+      if (callback) {
+        callback();
+      }
+    };
+
+    var errorCallback = function () {
+      self.hasErrors(true);
+      self.loading(false);
+      if (callback) {
+        callback();
+      }
+    };
+
+    self.apiHelper.fetchSolrCollections({
+      successCallback: successCallback,
+      errorCallback: errorCallback
+    })
+  };
+
+  AssistCollectionEntry.prototype.click = function () {
+    huePubSub.publish('assist.clickCollectionItem', this);
+  };
+
+  AssistCollectionEntry.prototype.dblClick = function () {
+    huePubSub.publish('assist.dblClickCollectionItem', this);
+  };
+
+  return AssistCollectionEntry;
+})();

+ 96 - 2
desktop/core/src/desktop/templates/assist.mako

@@ -801,6 +801,49 @@ from metadata.conf import has_navigator
     </div>
   </script>
 
+  <script type="text/html" id="assist-collections-header-actions">
+    <div class="assist-db-header-actions" style="margin-top: -1px;">
+      <a class="inactive-action" href="javascript:void(0)" data-bind="click: function () { huePubSub.publish('assist.collections.refresh'); }"><i class="pointer fa fa-refresh" data-bind="css: { 'fa-spin blue' : loading }" title="${_('Manual refresh')}"></i></a>
+    </div>
+  </script>
+
+  <script type="text/html" id="assist-collections-inner-panel">
+    <div class="assist-inner-panel">
+      <div class="assist-flex-panel">
+        <!-- ko with: selectedCollectionEntry -->
+        <div class="assist-inner-header assist-breadcrumb" >
+          ${_('Collections')}
+          <!-- ko template: 'assist-collections-header-actions' --><!-- /ko -->
+        </div>
+        <div class="assist-flex-fill assist-collections-scrollable">
+          <div data-bind="visible: ! loading() && ! hasErrors()" style="position: relative;">
+            <ul class="assist-tables" data-bind="foreachVisible: { data: entries, minHeight: 20, container: '.assist-collections-scrollable' }">
+              <li class="assist-entry assist-table-link" style="position: relative;" data-bind="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>
+                  <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" style="font-style: italic;">${_('No collections available.')}</li>
+            </ul>
+            <!-- /ko -->
+          </div>
+          <!-- ko hueSpinner: { spin: loading, center: true, size: 'large' } --><!-- /ko -->
+          <div class="assist-errors" data-bind="visible: ! loading() && hasErrors()">
+            <span>${ _('Error loading contents.') }</span>
+          </div>
+        </div>
+        <!-- /ko -->
+      </div>
+      <!-- ko with: $parents[1] -->
+      <!-- ko template: { if: searchActive() && searchInput() !== '' && navigatorEnabled(), name: 'nav-search-result' } --><!-- /ko -->
+      <!-- /ko -->
+    </div>
+  </script>
+
   <script type="text/html" id="assist-sources-template">
     <div class="assist-flex-header">
       <div class="assist-inner-header">
@@ -1096,7 +1139,7 @@ from metadata.conf import has_navigator
        * @param {string} options.icon
        * @param {boolean} options.visible
        * @param {boolean} [options.showNavSearch] - Default true
-       * @param {(AssistDbPanel|AssistHdfsPanel|AssistDocumentsPanel)} panelData
+       * @param {(AssistDbPanel|AssistHdfsPanel|AssistDocumentsPanel|AssistS3Panel|AssistCollectionsPanel)} panelData
        * @constructor
        */
       function AssistInnerPanel (options) {
@@ -1382,6 +1425,45 @@ from metadata.conf import has_navigator
         });
       }
 
+      /**
+       * @param {Object} options
+       * @param {ApiHelper} options.apiHelper
+       * @constructor
+       **/
+      function AssistCollectionsPanel (options) {
+        var self = this;
+        self.apiHelper = options.apiHelper;
+
+        self.selectedCollectionEntry = ko.observable();
+        var reload = function () {
+          var currentEntry = new AssistCollectionEntry({
+            definition: {
+              name: '/',
+              type: 'collection'
+            },
+            apiHelper: self.apiHelper
+          });
+          self.selectedCollectionEntry(currentEntry);
+
+          currentEntry.loadEntries();
+        };
+
+        reload();
+
+        huePubSub.subscribe('assist.clickCollectionItem', function (entry) {
+
+        });
+
+        huePubSub.subscribe('assist.dblClickCollectionItem', function (entry) {
+          window.open('/indexer/#edit/' + entry.definition.name);
+        });
+
+        huePubSub.subscribe('assist.collections.refresh', function () {
+          huePubSub.publish('assist.clear.collections.cache');
+          reload();
+        });
+      }
+
       var NAV_FACET_ICON = 'fa-tags';
       var NAV_TYPE_ICONS = {
         'DATABASE': 'fa-database',
@@ -1394,7 +1476,8 @@ from metadata.conf import has_navigator
         'OPERATION_EXECUTION': 'fa-cog',
         'DIRECTORY': 'fa-folder-o',
         'FILE': 'fa-file-o',
-        'SUB_OPERATION': 'fa-code-fork'
+        'SUB_OPERATION': 'fa-code-fork',
+        'COLLECTION': 'fa-search'
       };
 
       /**
@@ -1494,6 +1577,17 @@ from metadata.conf import has_navigator
           showNavSearch: false,
           visible: params.visibleAssistPanels && params.visibleAssistPanels.indexOf('documents') !== -1
         }));
+
+        self.availablePanels.push(new AssistInnerPanel({
+          panelData: new AssistCollectionsPanel({
+            apiHelper: self.apiHelper
+          }),
+          apiHelper: self.apiHelper,
+          name: '${ _("Collections") }',
+          type: 'collections',
+          icon: 'fa-search-plus',
+          minHeight: 50
+        }));
         % endif
 
         self.performSearch = function () {

+ 1 - 0
desktop/libs/notebook/src/notebook/templates/editor_components.mako

@@ -74,6 +74,7 @@ from notebook.conf import ENABLE_QUERY_BUILDER, ENABLE_QUERY_SCHEDULING, ENABLE_
 <script src="${ static('desktop/js/assist/assistDbSource.js') }"></script>
 <script src="${ static('desktop/js/assist/assistHdfsEntry.js') }"></script>
 <script src="${ static('desktop/js/assist/assistS3Entry.js') }"></script>
+<script src="${ static('desktop/js/assist/assistCollectionEntry.js') }"></script>
 <script src="${ static('desktop/js/document/hueDocument.js') }"></script>
 <script src="${ static('desktop/js/document/hueFileEntry.js') }"></script>