Эх сурвалжийг харах

HUE-6688 [autocomplete] Switch to foreachVisible for the autocomplete results

This speeds up the initial rendering when there are lots of suggestions
Johan Ahlen 8 жил өмнө
parent
commit
64f58abae1

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

@@ -5384,19 +5384,31 @@
 
       var huePubSubs = [];
 
-      var scrollToIndex = function (idx, offset, entry) {
+      var scrollToIndex = function (idx, offset, instant, callback) {
         var lastKnownHeights = $parentFVOwnerElement.data('lastKnownHeights');
-        if (! lastKnownHeights) {
+        if (! lastKnownHeights || lastKnownHeights.length <= idx) {
           return;
         }
         var top = 0;
         for (var i = 0; i < idx; i++) {
           top += lastKnownHeights[i];
         }
+        var bottom = top + lastKnownHeights[idx];
         window.setTimeout(function () {
-          $('.assist-db-scrollable').stop().animate({ scrollTop: top + offset }, '500', 'swing', function () {
-            huePubSub.publish('assist.db.scrollToComplete', entry);
-          });
+          var newScrollTop = top + offset;
+          if (instant) {
+            if (newScrollTop >= $container.height() + $container.scrollTop()) {
+              $container.scrollTop(bottom - $container.height());
+            } else if (newScrollTop <= $container.scrollTop()) {
+              $container.scrollTop(newScrollTop);
+            }
+          } else {
+            $container.stop().animate({ scrollTop: newScrollTop }, '500', 'swing', function () {
+              if (callback) {
+                callback();
+              }
+            });
+          }
         }, 0);
 
       };
@@ -5411,10 +5423,21 @@
         });
         if (foundIndex !== -1) {
           var offset = depth > 0 ? $parentFVOwnerElement.position().top : 0;
-          scrollToIndex(foundIndex, offset, targetEntry);
+          scrollToIndex(foundIndex, offset, false, function () {
+            huePubSub.publish('assist.db.scrollToComplete', targetEntry);
+          });
         }
       }));
 
+      if (ko.isObservable(viewModel.foreachVisible)) {
+        viewModel.foreachVisible({
+          scrollToIndex: function (index) {
+            var offset = depth > 0 ? $parentFVOwnerElement.position().top : 0;
+            scrollToIndex(index, offset, true);
+          }
+        })
+      }
+
       var childBindingContext = bindingContext.createChildContext(
           bindingContext.$rawData,
           null,

+ 12 - 20
desktop/core/src/desktop/templates/hue_ace_autocompleter.mako

@@ -34,14 +34,16 @@ from desktop.views import _ko
           <div class="autocompleter-spinner"><!-- ko hueSpinner: { spin: suggestions.loading, size: 'small' } --><!-- /ko --></div>
         </div>
         <!-- /ko -->
-        <div class="autocompleter-entries" data-bind="foreach: suggestions.filtered, niceScroll">
-          <div class="autocompleter-suggestion" data-bind="click: function () { $parent.selectedIndex($index()); $parent.insertSuggestion(); $parent.editor().focus(); },
-              css: { 'selected': $index() === $parent.selectedIndex() },
-              event: { 'mouseover': function () { $parent.hoveredIndex($index()); }, 'mouseout': function () { $parent.hoveredIndex(null); } }">
-            <div class="autocompleter-suggestion-value">
-              <div class="autocompleter-dot" data-bind="style: { 'background-color': category.color }"></div> <span data-bind="matchedText: { suggestion: $data, filter: $parent.suggestions.filter }"></span> <!-- ko if: details && details.primary_key === 'true' --><i class="fa fa-key"></i><!-- /ko -->
+        <div class="autocompleter-entries">
+          <div data-bind="foreachVisible: { data: suggestions.filtered, minHeight: 25, container: '.autocompleter-entries' }">
+            <div class="autocompleter-suggestion" data-bind="click: function () { $parent.selectedIndex($index() + $indexOffset()); $parent.insertSuggestion(); $parent.editor().focus(); },
+                css: { 'selected': $index() + $indexOffset() === $parent.selectedIndex() },
+                event: { 'mouseover': function () { $parent.hoveredIndex($index() + $indexOffset()); }, 'mouseout': function () { $parent.hoveredIndex(null); } }">
+              <div class="autocompleter-suggestion-value">
+                <div class="autocompleter-dot" data-bind="style: { 'background-color': category.color }"></div> <span data-bind="matchedText: { suggestion: $data, filter: $parent.suggestions.filter }"></span> <!-- ko if: details && details.primary_key === 'true' --><i class="fa fa-key"></i><!-- /ko -->
+              </div>
+              <div class="autocompleter-suggestion-meta"><!-- ko if: popular --><i class="fa fa-star-o popular-color"></i> <!-- /ko --><span data-bind="text: meta"></span></div>
             </div>
-            <div class="autocompleter-suggestion-meta"><!-- ko if: popular --><i class="fa fa-star-o popular-color"></i> <!-- /ko --><span data-bind="text: meta"></span></div>
           </div>
         </div>
       </div>
@@ -299,6 +301,7 @@ from desktop.views import _ko
         self.disposeFunctions = [];
         self.editor = params.editor;
         self.snippet = params.snippet || {};
+        self.foreachVisible = ko.observable();
 
         self.autocompleter = params.autocompleter || new SqlAutocompleter3(params);
         self.suggestions = self.autocompleter.suggestions;
@@ -564,19 +567,8 @@ from desktop.views import _ko
 
       HueAceAutocompleter.prototype.scrollSelectionIntoView = function () {
         var self = this;
-        var $autocompleterList = $('.autocompleter-entries');
-        var selected = $autocompleterList.children().eq(self.selectedIndex());
-        var selectedTop = selected.position().top;
-        if (selectedTop < 0) {
-          $autocompleterList.scrollTop($autocompleterList.scrollTop() + selectedTop);
-          return;
-        }
-        var selectedHeight = selected.outerHeight(true);
-        var listHeight = $autocompleterList.innerHeight();
-
-        var diff = (selectedHeight + selectedTop) - listHeight;
-        if (diff > 0) {
-          $autocompleterList.scrollTop($autocompleterList.scrollTop() + diff);
+        if (self.foreachVisible()) {
+          self.foreachVisible().scrollToIndex(self.selectedIndex());
         }
       };