Pārlūkot izejas kodu

[editor] Improved UX of the result table (sticky header) and enabled custom scrollbar for the right panel

Enrico Berti 9 gadi atpakaļ
vecāks
revīzija
c3399bf

+ 35 - 9
desktop/core/src/desktop/static/desktop/js/jquery.tableextender.js

@@ -27,6 +27,8 @@
       firstColumnTooltip: false,
       hintElement: null,
       includeNavigator: true,
+      mainScrollable: window,
+      stickToTopPosition: -1,
       labels: {
         GO_TO_COLUMN: "Go to column:",
         PLACEHOLDER: "column name..."
@@ -184,12 +186,13 @@
       $(plugin.element).attr("id", "eT" + plugin.options.parentId);
     }
 
+    var mainScrollable = plugin.options.mainScrollable;
     var originalTh = $(plugin.element).find("thead>tr th:eq(0)");
     var topPosition;
     if (plugin.options.clonedContainerPosition == 'absolute') {
-      topPosition = $(plugin.element).parent().position().top - $(window).scrollTop();
+      topPosition = $(plugin.element).parent().position().top - $(mainScrollable).scrollTop();
     } else {
-      topPosition = $(plugin.element).parent().offset().top - $(window).scrollTop();
+      topPosition = $(plugin.element).parent().offset().top - $(mainScrollable).scrollTop();
     }
 
     $("#" + $(plugin.element).attr("id") + "jHueTableExtenderClonedContainerCell").remove();
@@ -252,10 +255,22 @@
 
     clonedTableContainer.css("marginTop", (-$(plugin.element).parent().scrollTop()) + "px");
 
-    $(window).scroll(function () {
-      clonedTableVisibleContainer.css("top", ($(plugin.element).parent().offset().top - $(window).scrollTop()) + "px");
-      clonedCellVisibleContainer.css("top", ($(plugin.element).parent().offset().top - $(window).scrollTop()) + "px");
+    $(mainScrollable).scroll(function () {
+      if (plugin.options.stickToTopPosition > -1){
+        if ($(plugin.element).offset().top < plugin.options.stickToTopPosition){
+          clonedCellVisibleContainer.css("top", plugin.options.stickToTopPosition + "px");
+        }
+        else {
+          clonedCellVisibleContainer.css("top", $(plugin.element).offset().top + "px");
+        }
+        clonedTableVisibleContainer.css("top", $(plugin.element).offset().top + "px");
+      }
+      else {
+        clonedTableVisibleContainer.css("top", ($(plugin.element).parent().offset().top - $(mainScrollable).scrollTop()) + "px");
+        clonedCellVisibleContainer.css("top", ($(plugin.element).parent().offset().top - $(mainScrollable).scrollTop()) + "px");
+      }
     });
+
   }
 
 
@@ -263,6 +278,7 @@
     if (!$(plugin.element).attr("id") && plugin.options.parentId) {
       $(plugin.element).attr("id", "eT" + plugin.options.parentId);
     }
+    var mainScrollable = plugin.options.mainScrollable;
     $("#" + $(plugin.element).attr("id") + "jHueTableExtenderClonedContainer").remove();
     var clonedTable = $(plugin.element).clone();
     clonedTable.css("margin-bottom", "0").css("table-layout", "fixed");
@@ -281,9 +297,9 @@
 
     var topPosition;
     if (plugin.options.clonedContainerPosition == 'absolute') {
-      topPosition = $(plugin.element).parent().position().top - $(window).scrollTop();
+      topPosition = $(plugin.element).parent().position().top - $(mainScrollable).scrollTop();
     } else {
-      topPosition = $(plugin.element).parent().offset().top - $(window).scrollTop();
+      topPosition = $(plugin.element).parent().offset().top - $(mainScrollable).scrollTop();
     }
     var clonedTableVisibleContainer = $("<div>").attr("id", $(plugin.element).attr("id") + "jHueTableExtenderClonedContainer").addClass("jHueTableExtenderClonedContainer").width($(plugin.element).parent().width()).css("overflow-x", "hidden").css("top", topPosition + "px");
     clonedTableVisibleContainer.css("position", plugin.options.clonedContainerPosition || "fixed");
@@ -313,8 +329,18 @@
       clonedTableVisibleContainer.width($(this).width());
     });
 
-    $(window).scroll(function () {
-      clonedTableVisibleContainer.css("top", ($(plugin.element).parent().offset().top - $(window).scrollTop()) + "px");
+    $(mainScrollable).scroll(function () {
+      if (plugin.options.stickToTopPosition > -1){
+        if ($(plugin.element).offset().top < plugin.options.stickToTopPosition){
+          clonedTableVisibleContainer.css("top", plugin.options.stickToTopPosition + "px");
+        }
+        else {
+          clonedTableVisibleContainer.css("top", $(plugin.element).offset().top + "px");
+        }
+      }
+      else {
+        clonedTableVisibleContainer.css("top", ($(plugin.element).parent().offset().top - $(mainScrollable).scrollTop()) + "px");
+      }
     });
   }
 

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

@@ -3429,16 +3429,18 @@
   ko.bindingHandlers.perfectScrollbar = {
     init: function (element, valueAccessor, allBindings) {
       var options = valueAccessor() || {};
-      $(element).perfectScrollbar({
-        minScrollbarLength: options.minScrollbarLength || 20,
-        suppressScrollX: options.suppressScrollX || true
-      });
-      $(element).on('ps-scroll-x', function () {
-        $(element).trigger('scroll');
-      });
-      $(element).on('ps-scroll-y', function () {
-        $(element).trigger('scroll');
-      });
+      if (typeof options.enable === 'undefined' || options.enable) {
+        $(element).perfectScrollbar({
+          minScrollbarLength: options.minScrollbarLength || 20,
+          suppressScrollX: options.suppressScrollX || true
+        });
+        $(element).on('ps-scroll-x', function () {
+          $(element).trigger('scroll');
+        });
+        $(element).on('ps-scroll-y', function () {
+          $(element).trigger('scroll');
+        });
+      }
     }
   };
 

+ 105 - 55
desktop/libs/notebook/src/notebook/templates/editor_components.mako

@@ -336,7 +336,7 @@ ${ require.config() }
       }"></div>
   </div>
   <div class="resizer" data-bind="visible: $root.isLeftPanelVisible() && $root.assistAvailable(), splitDraggable : { appName: 'notebook', leftPanelVisible: $root.isLeftPanelVisible }"><div class="resize-bar">&nbsp;</div></div>
-  <div class="right-panel" data-bind="event: { scroll: function(){ $(document).trigger('hideAutocomplete'); } }">
+  <div class="right-panel" data-bind="event: { scroll: function(){ $(document).trigger('hideAutocomplete'); } }, perfectScrollbar: { enable: $root.editorMode }">
     <div>
       <div class="row-fluid row-container sortable-snippets" data-bind="css: {'is-editing': $root.isEditing},
         sortable: {
@@ -351,10 +351,10 @@ ${ require.config() }
             'greedy': true,
             'stop': function(event, ui) {
               var $element = $(event.target);
-              $element.find('.snippet-body').slideDown('fast', function () { $(window).scrollTop(lastWindowScrollPosition); });
+              $element.find('.snippet-body').slideDown('fast', function () { $('.right-panel').scrollTop(lastWindowScrollPosition); });
             },
             'helper': function(event) {
-              lastWindowScrollPosition = $(window).scrollTop();
+              lastWindowScrollPosition = $('.right-panel').scrollTop();
               var $element = $(event.target);
               $element.find('.snippet-body').slideUp('fast', function () {
                 $('.sortable-snippets').sortable('refreshPositions')
@@ -379,7 +379,7 @@ ${ require.config() }
             }
           },
           dragged: function (widget) {
-            $('.snippet-body').slideDown('fast', function () { $(window).scrollTop(lastWindowScrollPosition); });
+            $('.snippet-body').slideDown('fast', function () { $('.right-panel').scrollTop(lastWindowScrollPosition); });
           }
         }">
       </div>
@@ -1306,18 +1306,31 @@ ${ require.config() }
         if (vm.editorMode){
           DATATABLES_MAX_HEIGHT = $(window).height() - $(el).parent().offset().top - 40;
         }
-        $(el).parents(".dataTables_wrapper").jHueTableScroller({
-          maxHeight: DATATABLES_MAX_HEIGHT,
-          heightAfterCorrection: 0
-        });
-
-        $(el).jHueTableExtender({
-          fixedHeader: true,
-          fixedFirstColumn: true,
-          includeNavigator: false,
-          parentId: 'snippet_' + snippet.id(),
-          clonedContainerPosition: "absolute"
-        });
+        if (vm.editorMode) {
+          $(el).parents(".dataTables_wrapper").css("overflow-x", "auto");
+          $(el).jHueTableExtender({
+            fixedHeader: true,
+            fixedFirstColumn: true,
+            includeNavigator: false,
+            parentId: 'snippet_' + snippet.id(),
+            mainScrollable: '.right-panel',
+            stickToTopPosition: vm.isPlayerMode() ? 48 : 73,
+            clonedContainerPosition: "fixed"
+          });
+        }
+        else {
+          $(el).parents(".dataTables_wrapper").jHueTableScroller({
+            maxHeight: DATATABLES_MAX_HEIGHT,
+            heightAfterCorrection: 0
+          });
+          $(el).jHueTableExtender({
+            fixedHeader: true,
+            fixedFirstColumn: true,
+            includeNavigator: false,
+            parentId: 'snippet_' + snippet.id(),
+            clonedContainerPosition: "absolute"
+          });
+        }
       },
       "aoColumnDefs": [
         {
@@ -1335,45 +1348,69 @@ ${ require.config() }
       ]
     });
 
-    $(el).parents(".dataTables_wrapper").jHueTableScroller({
-      maxHeight: DATATABLES_MAX_HEIGHT,
-      heightAfterCorrection: 0
-    });
-
-    $(el).jHueTableExtender({
-      fixedHeader: true,
-      fixedFirstColumn: true,
-      includeNavigator: false,
-      parentId: 'snippet_' + snippet.id(),
-      clonedContainerPosition: "absolute"
-    });
+    if (vm.editorMode) {
+      $(el).parents(".dataTables_wrapper").css("overflow-x", "auto");
+      $(el).jHueTableExtender({
+        fixedHeader: true,
+        fixedFirstColumn: true,
+        includeNavigator: false,
+        parentId: 'snippet_' + snippet.id(),
+        mainScrollable: '.right-panel',
+        stickToTopPosition: vm.isPlayerMode() ? 48 : 73,
+        clonedContainerPosition: "fixed"
+      });
+    }
+    else {
+      $(el).parents(".dataTables_wrapper").jHueTableScroller({
+        maxHeight: DATATABLES_MAX_HEIGHT,
+        heightAfterCorrection: 0
+      });
+      $(el).jHueTableExtender({
+        fixedHeader: true,
+        fixedFirstColumn: true,
+        includeNavigator: false,
+        parentId: 'snippet_' + snippet.id(),
+        clonedContainerPosition: "absolute"
+      });
+    }
     $(".dataTables_filter").hide();
     var dataTableEl = $(el).parents(".dataTables_wrapper");
 
-    dataTableEl.bind('mousewheel DOMMouseScroll wheel', function (e) {
-      if ($(el).closest(".results").css("overflow") == "hidden") {
-        return;
-      }
-      var _e = e.originalEvent,
-          _deltaX = _e.wheelDeltaX || -_e.deltaX,
-          _deltaY = _e.wheelDeltaY || -_e.deltaY;
-      this.scrollTop += -_deltaY / 2;
-      this.scrollLeft += -_deltaX / 2;
-
-      if (this.scrollTop == 0) {
-        $("body")[0].scrollTop += -_deltaY / 3;
-        $("html")[0].scrollTop += -_deltaY / 3; // for firefox
-      }
-      e.preventDefault();
-    });
+    if (!vm.editorMode) {
+      dataTableEl.bind('mousewheel DOMMouseScroll wheel', function (e) {
+        if ($(el).closest(".results").css("overflow") == "hidden") {
+          return;
+        }
+        var _e = e.originalEvent,
+            _deltaX = _e.wheelDeltaX || -_e.deltaX,
+            _deltaY = _e.wheelDeltaY || -_e.deltaY;
+        this.scrollTop += -_deltaY / 2;
+        this.scrollLeft += -_deltaX / 2;
+
+        if (this.scrollTop == 0) {
+          $("body")[0].scrollTop += -_deltaY / 3;
+          $("html")[0].scrollTop += -_deltaY / 3; // for firefox
+        }
+        e.preventDefault();
+      });
+    }
 
     var _scrollTimeout = -1;
-    dataTableEl.on("scroll", function () {
-      var _lastScrollPosition = dataTableEl.data("scrollPosition") != null ? dataTableEl.data("scrollPosition") : 0;
+
+    var scrollElement = dataTableEl;
+    if (vm.editorMode) {
+      scrollElement = $('.right-panel');
+    }
+
+    scrollElement.on("scroll", function () {
+      var _lastScrollPosition = scrollElement.data("scrollPosition") != null ? scrollElement.data("scrollPosition") : 0;
       window.clearTimeout(_scrollTimeout);
-      dataTableEl.data("scrollPosition", dataTableEl.scrollTop());
+      scrollElement.data("scrollPosition", scrollElement.scrollTop());
       _scrollTimeout = window.setTimeout(function () {
-        if (_lastScrollPosition != dataTableEl.scrollTop() && dataTableEl.scrollTop() + dataTableEl.outerHeight() + 20 > dataTableEl[0].scrollHeight && _dt && snippet.result.hasMore()) {
+        if (vm.editorMode){
+          _lastScrollPosition--; //hack for forcing fetching
+        }
+        if (_lastScrollPosition != scrollElement.scrollTop() && scrollElement.scrollTop() + scrollElement.outerHeight() + 20 >= scrollElement[0].scrollHeight && _dt && snippet.result.hasMore()) {
           dataTableEl.animate({opacity: '0.55'}, 200);
           snippet.fetchResult(100, false);
         }
@@ -1769,13 +1806,26 @@ ${ require.config() }
       viewModel.notebooks().forEach(function (notebook) {
         notebook.snippets().forEach(function (snippet) {
           var _el = $("#snippet_" + snippet.id()).find(".resultTable");
-          _el.jHueTableExtender({
-            fixedHeader: true,
-            fixedFirstColumn: true,
-            includeNavigator: false,
-            parentId: 'snippet_' + snippet.id(),
-            clonedContainerPosition: "absolute"
-          });
+          if (viewModel.editorMode){
+            _el.jHueTableExtender({
+              fixedHeader: true,
+              fixedFirstColumn: true,
+              includeNavigator: false,
+              mainScrollable: '.right-panel',
+              stickToTopPosition: viewModel.isPlayerMode() ? 48 : 73,
+              parentId: 'snippet_' + snippet.id(),
+              clonedContainerPosition: "fixed"
+            });
+          }
+          else {
+            _el.jHueTableExtender({
+              fixedHeader: true,
+              fixedFirstColumn: true,
+              includeNavigator: false,
+              parentId: 'snippet_' + snippet.id(),
+              clonedContainerPosition: "absolute"
+            });
+          }
         });
       });
     };