瀏覽代碼

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 10 年之前
父節點
當前提交
403245b

+ 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({