Forráskód Böngészése

HUE-3276 [assist] Load more HDFS entries on scroll to the end

Johan Ahlen 9 éve
szülő
commit
b79e8ae504

+ 15 - 0
desktop/core/src/desktop/static/desktop/css/hue3.css

@@ -2577,6 +2577,21 @@ body {
   vertical-align: center;
 }
 
+.hue-spinner-overlay {
+  position: absolute;
+  z-index: 10000;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  background: rgba(255,255,255,.5);
+  -webkit-animation: fadein 2s; /* Safari, Chrome and Opera > 12.1 */
+  -moz-animation: fadein 2s; /* Firefox < 16 */
+  -ms-animation: fadein 2s; /* Internet Explorer */
+  -o-animation: fadein 2s; /* Opera < 12.1 */
+  animation: fadein 2s;
+}
+
 .hue-spinner-center {
   position: absolute;
   left: 50%;

+ 3 - 3
desktop/core/src/desktop/static/desktop/js/apiHelper.js

@@ -29,7 +29,6 @@
   var DOCUMENTS_API = "/desktop/api2/doc/";
   var DOCUMENTS_SEARCH_API = "/desktop/api2/docs/";
   var HDFS_API_PREFIX = "/filebrowser/view=";
-  var HDFS_PARAMETERS = "?pagesize=100&format=json";
   var IMPALA_INVALIDATE_API = '/impala/api/invalidate';
   var CONFIG_SAVE_API = '/desktop/api/configurations/save/';
   var CONFIG_APPS_API = '/desktop/api/configurations';
@@ -243,11 +242,12 @@
    * @param {Object} [options.editor] - Ace editor
    *
    * @param {string[]} options.pathParts
+   * @param {number} [options.pageSize] - Default 500
+   * @param {number} [options.page] - Default 1
    */
   ApiHelper.prototype.fetchHdfsPath = function (options) {
     var self = this;
-    var url = HDFS_API_PREFIX + "/" + options.pathParts.join("/") + HDFS_PARAMETERS;
-
+    var url = HDFS_API_PREFIX + "/" + options.pathParts.join("/") + '?format=json&sortby=name&descending=false&pagesize=' + (options.pageSize || 500) + '&pagenum=' + (options.page || 1);
     var fetchFunction = function (storeInCache) {
       if (options.timeout === 0) {
         self.assistErrorCallback(options)({ status: -1 });

+ 41 - 1
desktop/core/src/desktop/static/desktop/js/assist/assistHdfsEntry.js

@@ -22,6 +22,8 @@
   }
 }(this, function (ko) {
 
+  var PAGE_SIZE = 50;
+
   /**
    * @param {object} options
    * @param {object} options.definition
@@ -45,11 +47,14 @@
       }
     }
     self.path += self.definition.name;
+    self.currentPage = 1;
+    self.hasMorePages = true;
 
     self.entries = ko.observableArray([]);
 
     self.loaded = false;
     self.loading = ko.observable(false);
+    self.loadingMore = ko.observable(false);
     self.hasErrors = ko.observable(false);
     self.open = ko.observable(false);
 
@@ -75,9 +80,10 @@
       return;
     }
     self.loading(true);
+    self.hasErrors(false);
 
     var successCallback = function(data) {
-      self.hasErrors(false);
+      self.hasMorePages = data.page.next_page_number > self.currentPage;
       var filteredFiles = $.grep(data.files, function (file) {
         return file.name !== '.' && file.name !== '..';
       });
@@ -104,6 +110,8 @@
     };
 
     self.apiHelper.fetchHdfsPath({
+      pageSize: PAGE_SIZE,
+      page: self.currentPage,
       pathParts: self.getHierarchy(),
       successCallback: successCallback,
       errorCallback: errorCallback
@@ -164,5 +172,37 @@
     }
   };
 
+  AssistHdfsEntry.prototype.fetchMore = function () {
+    var self = this;
+    if (!self.hasMorePages || self.loadingMore()) {
+      return;
+    }
+    self.currentPage++;
+    self.loadingMore(true);
+    self.hasErrors(false);
+    self.apiHelper.fetchHdfsPath({
+      pageSize: PAGE_SIZE,
+      page: self.currentPage,
+      pathParts: self.getHierarchy(),
+      successCallback: function (data) {
+        self.hasMorePages = data.page.next_page_number > self.currentPage;
+        var filteredFiles = $.grep(data.files, function (file) {
+          return file.name !== '.' && file.name !== '..';
+        });
+        self.entries(self.entries().concat($.map(filteredFiles, function (file) {
+          return new AssistHdfsEntry({
+            definition: file,
+            parent: self,
+            apiHelper: self.apiHelper
+          })
+        })));
+        self.loadingMore(false);
+      },
+      errorCallback: function () {
+        self.hasErrors(true);
+      }
+    });
+  };
+
   return AssistHdfsEntry;
 }));

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

@@ -225,18 +225,18 @@
    */
   ko.bindingHandlers.hueSpinner = {
     update: function (element, valueAccessor) {
-      var value = ko.unwrap(valueAccessor);
+      var value = ko.unwrap(valueAccessor());
 
       var options = {
         size: 'default',
-        center: false
+        center: false,
+        overlay: false
       };
 
       var spin = false;
       if (ko.isObservable(valueAccessor())) {
         spin = value();
       } else {
-        var value = valueAccessor();
         $.extend(options, value);
         spin = ko.isObservable(value.spin) ? value.spin() : value.spin;
       }
@@ -244,18 +244,20 @@
       ko.virtualElements.emptyNode(element);
 
       if (spin) {
-        var container = document.createElement('DIV');
-        container.className = 'hue-spinner';
-        var spinner = document.createElement('I');
-        spinner.className = 'fa fa-spinner fa-spin';
-        if (options.size === 'large') {
-          spinner.className += ' hue-spinner-large';
-        }
-        if (options.center) {
-          spinner.className += ' hue-spinner-center';
-        }
-        container.appendChild(spinner);
-        ko.virtualElements.prepend(element, container);
+        var $container = $('<div>');
+        $container.addClass(options.overlay ? 'hue-spinner-overlay' : 'hue-spinner');
+        if (!options.overlay) {
+          var $spinner = $('<i>');
+          $spinner.addClass('fa fa-spinner fa-spin');
+          if (options.size === 'large') {
+            $spinner.addClass('hue-spinner-large');
+          }
+          if (options.center) {
+            $spinner.addClass('hue-spinner-center');
+          }
+        }
+        $container.append($spinner);
+        ko.virtualElements.prepend(element, $container[0]);
       }
     }
   };
@@ -3697,14 +3699,8 @@
       updateVisibleEntryCount();
 
       // In case this element was rendered before use the last known indices
-      var startIndex = $parentFVOwnerElement.data('startIndex') || 0;
-      var endIndex = $parentFVOwnerElement.data('endIndex') || (visibleEntryCount + elementIncrement);
-      if (startIndex > (allEntries.length-1)) {
-        startIndex = 0
-      }
-      if (endIndex > (allEntries.length - 1)) {
-        endIndex = allEntries.length - 1;
-      }
+      var startIndex = Math.max($parentFVOwnerElement.data('startIndex') || 0, 0);
+      var endIndex = Math.min($parentFVOwnerElement.data('endIndex') || (visibleEntryCount + elementIncrement), allEntries.length - 1);
 
       var huePubSubs = [];
 
@@ -3953,7 +3949,13 @@
           return;
         }
         lastScrollTop = $container.scrollTop();
+
+        var lastEndIndex = endIndex;
         setStartAndEndFromScrollTop();
+        if (typeof options.fetchMore !== 'undefined' && endIndex !== lastEndIndex && endIndex === allEntries.length - 1) {
+          options.fetchMore();
+        };
+
         clearTimeout(renderThrottle);
         if (Math.abs($parentFVOwnerElement.data('startIndex') - startIndex) > incrementLimit ||
             Math.abs($parentFVOwnerElement.data('endIndex') - endIndex) > incrementLimit) {

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

@@ -576,8 +576,9 @@ from metadata.conf import has_navigator
           <!-- ko template: 'assist-hdfs-header-actions' --><!-- /ko -->
         </div>
         <div class="assist-flex-fill assist-hdfs-scrollable">
-          <div data-bind="visible: ! loading() && ! hasErrors()">
-            <ul class="assist-tables" data-bind="foreachVisible: {data: entries, minHeight: 20, container: '.assist-hdfs-scrollable' }">
+          <div data-bind="visible: ! loading() && ! hasErrors()" style="position: relative;">
+            <!-- ko hueSpinner: { spin: loadingMore, overlay: true } --><!-- /ko -->
+            <ul class="assist-tables" data-bind="foreachVisible: { data: entries, minHeight: 20, container: '.assist-hdfs-scrollable', fetchMore: $data.fetchMore.bind($data) }">
               <li class="assist-entry assist-table-link" style="position: relative;" data-bind="visibleOnHover: { 'selector': '.assist-actions' }">
                 <div class="assist-actions table-actions" style="opacity: 0;" >
                   <a style="padding: 0 3px;" class="inactive-action" href="javascript:void(0);" data-bind="templatePopover : { contentTemplate: 'hdfs-details-content', titleTemplate: 'hdfs-details-title', minWidth: '320px' }">