Selaa lähdekoodia

HUE-3425 [metastore] Lack of horizontal scroll on sample tab

Moved common horizontal scrollbar to new external plugin
Added fixed header and column to the sample table
Enrico Berti 9 vuotta sitten
vanhempi
commit
403245b454

+ 75 - 31
apps/metastore/src/metastore/templates/metastore.mako

@@ -135,7 +135,7 @@ ${ assist.assistPanel() }
     <table class="table table-striped table-condensed table-nowrap">
       <thead>
         <tr>
-          <th style="width: 10px"></th>
+          <th style="width: 1%">&nbsp;</th>
           <th>${_('Name')}</th>
           <th>${_('Type')}</th>
         </tr>
@@ -158,7 +158,7 @@ ${ assist.assistPanel() }
     <table class="table table-striped table-condensed table-nowrap">
       <thead>
         <tr>
-          <th style="width: 10px"></th>
+          <th style="width: 1%">&nbsp;</th>
           <th>${_('Values')}</th>
           <th>${_('Spec')}</th>
           <th>${_('Browse')}</th>
@@ -182,28 +182,26 @@ ${ assist.assistPanel() }
 </script>
 
 <script type="text/html" id="metastore-samples-table">
-  <div style="overflow-x: auto; overflow-y: hidden">
-    <table class="table table-striped table-condensed table-nowrap">
-      <thead>
+  <table class="table table-striped table-condensed table-nowrap sample-table">
+    <thead>
+      <tr>
+        <th style="width: 1%">&nbsp;</th>
+        <!-- ko foreach: headers -->
+        <th data-bind="text: $data"></th>
+        <!-- /ko -->
+      </tr>
+    </thead>
+    <tbody>
+      <!-- ko foreach: rows -->
         <tr>
-          <th style="width: 10px"></th>
-          <!-- ko foreach: headers -->
-          <th data-bind="text: $data"></th>
+          <td data-bind="text: $index()+1"></td>
+          <!-- ko foreach: $data -->
+            <td data-bind="text: $data"></td>
           <!-- /ko -->
         </tr>
-      </thead>
-      <tbody>
-        <!-- ko foreach: rows -->
-          <tr>
-            <td data-bind="text: $index()+1"></td>
-            <!-- ko foreach: $data -->
-              <td data-bind="text: $data"></td>
-            <!-- /ko -->
-          </tr>
-        <!-- /ko -->
-      </tbody>
-    </table>
-  </div>
+      <!-- /ko -->
+    </tbody>
+  </table>
 
   <div id="jumpToColumnAlert" class="alert hide" style="margin-top: 12px;">
     <button type="button" class="close" data-dismiss="alert">&times;</button>
@@ -811,25 +809,71 @@ ${ assist.assistPanel() }
         $('.right-panel').getNiceScroll().resize();
       });
 
-      ko.applyBindings(viewModel);
-
-      if (location.getParameter('refresh') === 'true') {
-        huePubSub.publish('assist.db.refresh', 'hive');
-        hueUtils.replaceURL('?');
-      }
-
-      // TODO: Use ko for this and the put the queries in the MetastoreTable
-      $('a[data-toggle="tab"]').on('shown', function (e) {
-        if ($(e.target).attr("href") == "#queries") {
+      viewModel.currentTab.subscribe(function(tab){
+        if (tab == 'table-queries') {
           viewModel.loadingQueries(true);
           $.getJSON('/metastore/table/' + viewModel.database().name + '/' + viewModel.database().table().name + '/queries', function (data) {
             viewModel.queries(data.queries);
             viewModel.loadingQueries(false);
           });
         }
+        if (tab == 'table-sample') {
+          var selector = '#sample .sample-table';
+          if ($(selector).parents('.dataTables_wrapper').length == 0){
+            hueUtils.waitForRendered(selector, function(el){ return el.find('td').length > 0 }, function(){
+              $(selector).dataTable({
+                "bPaginate": false,
+                "bLengthChange": false,
+                "bInfo": false,
+                "bDestroy": true,
+                "bFilter": false,
+                "bAutoWidth": false,
+                "oLanguage": {
+                  "sEmptyTable": "${_('No data available')}",
+                  "sZeroRecords": "${_('No matching records')}"
+                },
+                "fnDrawCallback": function (oSettings) {
+                  $(selector).parents('.dataTables_wrapper').css('overflow-x', 'hidden');
+                  $(selector).jHueTableExtender({
+                    fixedHeader: true,
+                    fixedFirstColumn: true,
+                    includeNavigator: false,
+                    parentId: 'sample',
+                    classToRemove: 'sample-table',
+                    mainScrollable: '.right-panel',
+                    stickToTopPosition: 73,
+                    clonedContainerPosition: "fixed"
+                  });
+                  $(selector).jHueHorizontalScrollbar();
+                },
+                "aoColumnDefs": [
+                  {
+                    "sType": "numeric",
+                    "aTargets": [ "sort-numeric" ]
+                  },
+                  {
+                    "sType": "string",
+                    "aTargets": [ "sort-string" ]
+                  },
+                  {
+                    "sType": "date",
+                    "aTargets": [ "sort-date" ]
+                  }
+                ]
+              });
+            });
+          }
+        }
         $('.right-panel').getNiceScroll().resize();
       });
 
+      ko.applyBindings(viewModel);
+
+      if (location.getParameter('refresh') === 'true') {
+        huePubSub.publish('assist.db.refresh', 'hive');
+        hueUtils.replaceURL('?');
+      }
+
       window.scrollToColumn = function (col) {
         if (!col.table.samples.loading()) {
           $('a[href="#sample"]').click();

+ 19 - 0
desktop/core/src/desktop/static/desktop/js/hue.utils.js

@@ -183,6 +183,25 @@ Array.prototype.diff = function (a) {
     return element.scrollHeight > element.clientHeight || element.scrollWidth > element.clientWidth;
   }
 
+  /**
+   * @param {string} selector
+   * @param {Function} condition
+   * @param {Function} callback
+   * @param {number} [timeout]
+   * @constructor
+   */
+  hueUtils.waitForRendered = function (selector, condition, callback, timeout) {
+    var $el = $(selector);
+    if (condition($el)) {
+      callback($el);
+    }
+    else {
+      window.setTimeout(function () {
+        hueUtils.waitForRendered(selector, condition, callback);
+      }, timeout || 100)
+    }
+  }
+
 
 }(hueUtils = window.hueUtils || {}));
 

+ 74 - 0
desktop/core/src/desktop/static/desktop/js/jquery.horizontalscrollbar.js

@@ -0,0 +1,74 @@
+// 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.
+/*
+ * jHue horizontal scrollbar for dataTables_wrapper
+ *
+ */
+;
+(function ($, window, document, undefined) {
+
+  var pluginName = "jHueHorizontalScrollbar",
+    defaults = {};
+
+  function Plugin(element, options) {
+    this.element = element;
+    this.options = $.extend({}, defaults, options);
+    this._defaults = defaults;
+    this._name = pluginName;
+    this.init();
+  }
+
+  Plugin.prototype.init = function () {
+    var el = this.element;
+    if ($(el).parents('.dataTables_wrapper').length > 0) {
+      var scrollingRatio = function () {
+        return $(el).parents('.dataTables_wrapper').width() - $(el).parents('.dataTables_wrapper').find('hue-scrollbar-x').width()
+      };
+      if ($(el).parents('.dataTables_wrapper').find('.hue-scrollbar-x-rail').length == 0 && $(el).parents('.dataTables_wrapper').width() < $(el).parents('.dataTables_wrapper')[0].scrollWidth) {
+        var colWidth = $(el).parents('.dataTables_wrapper').find('.jHueTableExtenderClonedContainerColumn').width() + 5;
+        var scrollbarRail = $('<div>');
+        var scrollbar = $('<div>').addClass('hue-scrollbar-x');
+        scrollbar.width(Math.max(20, $(el).parents('.dataTables_wrapper').width() * ($(el).parents('.dataTables_wrapper').width() / $(el).parents('.dataTables_wrapper')[0].scrollWidth)));
+        scrollbar.appendTo(scrollbarRail);
+        scrollbar.draggable({
+          axis: 'x',
+          containment: 'parent',
+          drag: function (e, ui) {
+            $(el).parents('.dataTables_wrapper').scrollLeft(($(el).parents('.dataTables_wrapper')[0].scrollWidth - $(el).parents('.dataTables_wrapper').width()) * (ui.position.left / (scrollbarRail.width() - $(this).width())))
+          }
+        });
+        scrollbarRail.addClass('hue-scrollbar-x-rail').appendTo($(el).parents(".dataTables_wrapper"));
+        scrollbarRail.width($(el).parents(".dataTables_wrapper").width() - colWidth);
+        scrollbarRail.css("marginLeft", (colWidth) + "px");
+      }
+      else {
+        var colWidth = $(el).parents('.dataTables_wrapper').find('.jHueTableExtenderClonedContainerColumn').width() + 5;
+        $(el).parents('.dataTables_wrapper').find('.hue-scrollbar-x-rail').width($(el).parents(".dataTables_wrapper").width() - colWidth);
+        var scrollbarRail = $(el).parents('.dataTables_wrapper').find('.hue-scrollbar-x-rail');
+        var scrollbar = $(el).parents('.dataTables_wrapper').find('.hue-scrollbar-x');
+        scrollbar.width(Math.max(20, $(el).parents('.dataTables_wrapper').width() * ($(el).parents('.dataTables_wrapper').width() / $(el).parents('.dataTables_wrapper')[0].scrollWidth)));
+        scrollbar.css("left", ((scrollbarRail.width() - scrollbar.width()) * ($(el).parents('.dataTables_wrapper').scrollLeft() / ($(el).parents('.dataTables_wrapper')[0].scrollWidth - $(el).parents('.dataTables_wrapper').width()))) + "px");
+      }
+    }
+  };
+
+  $.fn[pluginName] = function (options) {
+    return this.each(function () {
+      $.data(this, 'plugin_' + pluginName, new Plugin(this, options));
+    });
+  }
+
+})(jQuery, window, document);

+ 4 - 4
desktop/core/src/desktop/static/desktop/js/jquery.tableextender.js

@@ -25,6 +25,7 @@
       fixedHeader: false,
       fixedFirstColumn: false,
       firstColumnTooltip: false,
+      classToRemove: 'resultTable',
       hintElement: null,
       includeNavigator: true,
       mainScrollable: window,
@@ -53,7 +54,6 @@
     }
     this._defaults = defaults;
     this._name = pluginName;
-    this.previousPath = "";
     this.init();
   }
 
@@ -198,7 +198,7 @@
     $("#" + $(plugin.element).attr("id") + "jHueTableExtenderClonedContainerCell").remove();
     var clonedCell = $(plugin.element).clone();
     clonedCell.css("margin-bottom", "0").css("table-layout", "fixed");
-    clonedCell.removeAttr("id").removeClass("resultTable").find("tbody").remove();
+    clonedCell.removeAttr("id").removeClass(plugin.options.classToRemove).find("tbody").remove();
     clonedCell.find("thead>tr th:not(:eq(0))").remove();
     clonedCell.find("thead>tr th:eq(0)").width(originalTh.width()).css("background-color", "#FFFFFF");
     clonedCell.find("thead>tr th:eq(0)").click(function () {
@@ -218,7 +218,7 @@
     $("#" + $(plugin.element).attr("id") + "jHueTableExtenderClonedContainerColumn").remove();
     var clonedTable = $(plugin.element).clone();
     clonedTable.css("margin-bottom", "0").css("table-layout", "fixed");
-    clonedTable.removeAttr("id").removeClass("resultTable");
+    clonedTable.removeAttr("id").removeClass(plugin.options.classToRemove);
     clonedTable.find("thead>tr th:not(:eq(0))").remove();
     clonedTable.find("tbody>tr").each(function () {
       $(this).find("td:not(:eq(0))").remove();
@@ -287,7 +287,7 @@
     $("#" + $(plugin.element).attr("id") + "jHueTableExtenderClonedContainer").remove();
     var clonedTable = $(plugin.element).clone();
     clonedTable.css("margin-bottom", "0").css("table-layout", "fixed");
-    clonedTable.removeAttr("id").removeClass("resultTable").find("tbody").remove();
+    clonedTable.removeAttr("id").removeClass(plugin.options.classToRemove).find("tbody").remove();
     $(plugin.element).find("thead>tr th").each(function (i) {
       var originalTh = $(this);
       clonedTable.find("thead>tr th:eq(" + i + ")").width(originalTh.width()).css("background-color", "#FFFFFF");

+ 1 - 0
desktop/core/src/desktop/templates/common_header.mako

@@ -185,6 +185,7 @@ if USE_NEW_EDITOR.get():
   <script src="${ static('desktop/js/jquery.rowselector.js') }"></script>
   <script src="${ static('desktop/js/jquery.notify.js') }"></script>
   <script src="${ static('desktop/js/jquery.titleupdater.js') }"></script>
+  <script src="${ static('desktop/js/jquery.horizontalscrollbar.js') }"></script>
   <script src="${ static('desktop/js/jquery.tablescroller.js') }"></script>
   <script src="${ static('desktop/js/jquery.tableextender.js') }"></script>
   <script src="${ static('desktop/js/jquery.scrollup.js') }"></script>

+ 3 - 34
desktop/libs/notebook/src/notebook/templates/editor_components.mako

@@ -1395,37 +1395,6 @@ ${ require.config() }
     return _width;
   };
 
-  function createXScrollbar(el) {
-    if ($(el).parents('.dataTables_wrapper').length > 0) {
-      var scrollingRatio = function() { return $(el).parents('.dataTables_wrapper').width() - $(el).parents('.dataTables_wrapper').find('hue-scrollbar-x').width() };
-      if ($(el).parents('.dataTables_wrapper').find('.hue-scrollbar-x-rail').length == 0 && $(el).parents('.dataTables_wrapper').width() < $(el).parents('.dataTables_wrapper')[0].scrollWidth) {
-        var colWidth = $(el).parents('.dataTables_wrapper').find('.jHueTableExtenderClonedContainerColumn').width() + 5;
-        var scrollbarRail = $('<div>');
-        var scrollbar = $('<div>').addClass('hue-scrollbar-x');
-        scrollbar.width(Math.max(20, $(el).parents('.dataTables_wrapper').width() * ($(el).parents('.dataTables_wrapper').width() / $(el).parents('.dataTables_wrapper')[0].scrollWidth)));
-        scrollbar.appendTo(scrollbarRail);
-        scrollbar.draggable({
-          axis: 'x',
-          containment: 'parent',
-          drag: function (e, ui) {
-            $(el).parents('.dataTables_wrapper').scrollLeft(($(el).parents('.dataTables_wrapper')[0].scrollWidth - $(el).parents('.dataTables_wrapper').width()) * (ui.position.left/(scrollbarRail.width() - $(this).width())))
-          }
-        });
-        scrollbarRail.addClass('hue-scrollbar-x-rail').appendTo($(el).parents(".dataTables_wrapper"));
-        scrollbarRail.width($(el).parents(".dataTables_wrapper").width() - colWidth);
-        scrollbarRail.css("marginLeft", (colWidth) + "px");
-      }
-      else {
-        var colWidth = $(el).parents('.dataTables_wrapper').find('.jHueTableExtenderClonedContainerColumn').width() + 5;
-        $(el).parents('.dataTables_wrapper').find('.hue-scrollbar-x-rail').width($(el).parents(".dataTables_wrapper").width() - colWidth);
-        var scrollbarRail = $(el).parents('.dataTables_wrapper').find('.hue-scrollbar-x-rail');
-        var scrollbar = $(el).parents('.dataTables_wrapper').find('.hue-scrollbar-x');
-        scrollbar.width(Math.max(20, $(el).parents('.dataTables_wrapper').width() * ($(el).parents('.dataTables_wrapper').width() / $(el).parents('.dataTables_wrapper')[0].scrollWidth)));
-        scrollbar.css("left", ((scrollbarRail.width() - scrollbar.width()) * ($(el).parents('.dataTables_wrapper').scrollLeft() / ($(el).parents('.dataTables_wrapper')[0].scrollWidth - $(el).parents('.dataTables_wrapper').width()))) + "px");
-      }
-    }
-  }
-
   function createDatatable(el, snippet, vm) {
     $(el).addClass("dt");
     var DATATABLES_MAX_HEIGHT = 330;
@@ -1454,7 +1423,7 @@ ${ require.config() }
             stickToTopPosition: vm.isPlayerMode() ? 48 : 73,
             clonedContainerPosition: "fixed"
           });
-          createXScrollbar(el);
+          $(el).jHueHorizontalScrollbar();
         }
         else {
           $(el).parents(".dataTables_wrapper").jHueTableScroller({
@@ -1497,7 +1466,7 @@ ${ require.config() }
         stickToTopPosition: vm.isPlayerMode() ? 48 : 73,
         clonedContainerPosition: "fixed"
       });
-      createXScrollbar(el);
+      $(el).jHueHorizontalScrollbar();
     }
     else {
       $(el).parents(".dataTables_wrapper").jHueTableScroller({
@@ -1969,7 +1938,7 @@ ${ require.config() }
                 parentId: 'snippet_' + snippet.id(),
                 clonedContainerPosition: "fixed"
               });
-              createXScrollbar(_el);
+              _el.jHueHorizontalScrollbar();
             }
             else {
               _el.jHueTableExtender({