Browse Source

HUE-4487 [editor] Result table search

Enrico Berti 9 years ago
parent
commit
9cec497

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

@@ -1257,6 +1257,12 @@ a#advanced-btn:hover {
   filter: alpha(opacity=85);
 }
 
+.hueAnchor input {
+  min-height: 19px!important;
+  height: 19px!important;
+  margin: 0;
+}
+
 #jHueScrollUpAnchor {
   bottom: 20px;
   right: 20px;

+ 166 - 56
desktop/core/src/desktop/static/desktop/js/jquery.huedatatable.js

@@ -43,11 +43,11 @@
       var data = self.$table.data('data');
 
       var idx = obj.originalIndex;
-      if (way === 0){
+      if (way === 0) {
         idx = 0;
       }
 
-      if (way === -1 || way === 0){
+      if (way === -1 || way === 0) {
         data.sort(function (a, b) {
           if (a[idx] > b[idx]) {
             return 1;
@@ -73,6 +73,109 @@
       self.fnDraw(true);
     }
 
+    self.fnShowSearch = function () {
+      if ($('.hue-datatable-search').length == 0) {
+        var search = $('<div>').css({
+          'position': 'fixed',
+          'bottom': '20px',
+          'right': '70px'
+        }).addClass('hueAnchor hue-datatable-search').appendTo($('body'));
+        search.html('<input type="text"> <i class="fa fa-chevron-down pointer muted"></i> <i class="fa fa-chevron-up pointer muted"></i> <i class="fa fa-times"></i>');
+
+        search.find('.fa-times').on('click', function () {
+          search.hide();
+        });
+
+        search.find('.fa-chevron-down').on('click', function () {
+          self.fnScrollToNextResult();
+        });
+
+        search.find('.fa-chevron-up').on('click', function () {
+          self.fnScrollToPreviousResult();
+        });
+
+        search.find('input').jHueDelayedInput(function () {
+          self.fnSearch(search.find('input').val());
+        }, 300);
+
+        search.find('input').focus();
+      }
+      else {
+        $('.hue-datatable-search').show();
+        $('.hue-datatable-search').find('input').focus();
+      }
+    }
+
+    self.fnSearch = function (what) {
+      $('.hue-datatable-search').find('.fa-chevron-down').addClass('muted');
+      $('.hue-datatable-search').find('.fa-chevron-up').addClass('muted');
+      var coords = [];
+      var $t = self.$table;
+      $t.data('searchCoords', []);
+      $t.data('searchCoordHighlighted', 0);
+      var data = self.$table.data('data');
+      data.forEach(function (row, rowIdx) {
+        row.forEach(function (fld, fldIdx) {
+          if ((fld + "").replace(/\&nbsp;/, ' ').toLowerCase().indexOf(what.toLowerCase()) > -1) {
+            coords.push({
+              row: rowIdx,
+              col: fldIdx
+            });
+          }
+        });
+      });
+      $t.data('searchCoords', coords);
+      if (coords.length > 0) {
+        if ($('.hue-datatable-search').find('input').val() !== '') {
+          $('.hue-datatable-search').find('.fa-chevron-down').removeClass('muted');
+          $('.hue-datatable-search').find('.fa-chevron-up').removeClass('muted');
+        }
+        self.fnScrollTo(coords[0].row, coords[0].col);
+      }
+    };
+
+    self.fnScrollToPreviousResult = function () {
+      var $t = self.$table;
+      if ($t.data('searchCoords').length > 0) {
+        var high = $t.data('searchCoordHighlighted');
+        high = high == 0 ? $t.data('searchCoords').length - 1 : high - 1;
+        $t.data('searchCoordHighlighted', high);
+        self.fnScrollTo($t.data('searchCoords')[high].row, $t.data('searchCoords')[high].col);
+      }
+    }
+
+    self.fnScrollToNextResult = function () {
+      var $t = self.$table;
+      if ($t.data('searchCoords').length > 0) {
+        var high = $t.data('searchCoordHighlighted');
+        high = high == $t.data('searchCoords').length - 1 ? 0 : high + 1;
+        $t.data('searchCoordHighlighted', high);
+        self.fnScrollTo($t.data('searchCoords')[high].row, $t.data('searchCoords')[high].col);
+      }
+    }
+
+    self.fnScrollTo = function (row, col) {
+      var $t = self.$table;
+      var colSel = $t.find("tr th:nth-child(" + (col + 1) + ")");
+      $t.parent().animate({
+        scrollLeft: colSel.position().left + $t.parent().scrollLeft() - $t.parent().offset().left - 30
+      }, 300);
+      try {
+        $t.parents($t.data('oInit')['scrollable']).animate({
+          scrollTop: $t.find('tbody tr').find('td:eq(0)').filter(function () {
+            return $(this).text() == row
+          }).position().top + 73
+        });
+      }
+      catch (e) {
+      }
+
+      colSel = $t.find("tr td:nth-child(" + (col + 1) + ")");
+      $t.data('scrollToCol', col);
+      $t.data('scrollToRow', row);
+      $t.parent().trigger('scroll');
+    }
+
     self.isDrawing = false;
 
     self.fnDraw = function (force) {
@@ -85,11 +188,11 @@
         var appendable = $t.children('tbody').length > 0 ? $t.children('tbody') : $t;
         var startCol = -1;
         var endCol = -1;
-        $t.find("thead>tr th").each(function(i){
-          if ($(this).position().left > 0 && startCol == -1){
+        $t.find("thead>tr th").each(function (i) {
+          if ($(this).position().left > 0 && startCol == -1) {
             startCol = i;
           }
-          if ($(this).position().left < $t.parent().width() + $t.parent().position().left){
+          if ($(this).position().left < $t.parent().width() + $t.parent().position().left) {
             endCol = i;
           }
         });
@@ -107,78 +210,84 @@
         var endRow = startRow + visibleRows + invisibleOffset;
 
         if (endRow != $t.data('endRow') || (endRow == $t.data('endRow') && endCol > $t.data('endCol')) || force) {
-            $t.data('endCol', endCol);
-            $t.data('endRow', endRow);
+          $t.data('endCol', endCol);
+          $t.data('endRow', endRow);
 
-            if ($t.data('fnDraws') == 0) {
+          if ($t.data('fnDraws') == 0) {
+            var html = '';
+            for (var i = 0; i < data.length; i++) {
+              html += '<tr class="ht-visible-row ht-visible-row-' + i + '"><td>' + data[i][0] + '</td><td colspan="' + (aoColumns.length - 1) + '" class="stripe"></td></tr>';
+            }
+            appendable.html(html);
+            if ($t.data('plugin_jHueTableExtender')) {
+              $t.data('plugin_jHueTableExtender').drawFirstColumn();
+            }
+          }
+          else {
+            if (force) {
               var html = '';
-              for (var i = 0; i < data.length; i++) {
+              for (var i = $t.find('.ht-visible-row').length; i < data.length; i++) {
                 html += '<tr class="ht-visible-row ht-visible-row-' + i + '"><td>' + data[i][0] + '</td><td colspan="' + (aoColumns.length - 1) + '" class="stripe"></td></tr>';
               }
-              appendable.html(html);
+              appendable.html(appendable.html() + html);
               if ($t.data('plugin_jHueTableExtender')) {
                 $t.data('plugin_jHueTableExtender').drawFirstColumn();
               }
             }
-            else {
-              if (force) {
-                var html = '';
-                for (var i = $t.find('.ht-visible-row').length; i < data.length; i++) {
-                  html += '<tr class="ht-visible-row ht-visible-row-' + i + '"><td>' + data[i][0] + '</td><td colspan="' + (aoColumns.length - 1) + '" class="stripe"></td></tr>';
-                }
-                appendable.html(appendable.html() + html);
-                if ($t.data('plugin_jHueTableExtender')) {
-                  $t.data('plugin_jHueTableExtender').drawFirstColumn();
+          }
+
+          for (var i = 0; i < data.length; i++) {
+            var html = '';
+            if (i >= startRow && i <= endRow) {
+              var row = data[i];
+              if (row) {
+                for (var j = 0; j < endCol; j++) {
+                  html += '<td ' + (!aoColumns[j].bVisible ? 'style="display: none"' : '') + '>' + row[j] + '</td>';
                 }
-              }
-            }
 
-            for (var i = 0; i < data.length; i++) {
-              var html = '';
-              if (i >= startRow && i <= endRow) {
-                var row = data[i];
-                if (row) {
-                  for (var j = 0; j < endCol; j++) {
-                    html += '<td ' + (!aoColumns[j].bVisible ? 'style="display: none"' : '') +'>' + row[j] + '</td>';
-                  }
-
-                  if (endCol < aoColumns.length) {
-                    html += '<td colspan="' + (aoColumns.length - endCol) + '" class="stripe"></td>';
-                  }
+                if (endCol < aoColumns.length) {
+                  html += '<td colspan="' + (aoColumns.length - endCol) + '" class="stripe"></td>';
                 }
               }
-              else {
-                html = '<td>' + data[i][0] + '</td><td colspan="' + (aoColumns.length - 1) + '" class="stripe"></td>';
-              }
-              appendable.children().eq(i).html(html);
             }
-
-            if ($t.data('scrollToCol')){
-              var colSel = $t.find("tr th:nth-child(" + ($t.data('scrollToCol') + 1) + ")");
-              $t.parent().animate({
-                scrollLeft: colSel.position().left + $t.parent().scrollLeft() - $t.parent().offset().left - 30
-              }, 300);
-              colSel = $t.find("tr td:nth-child(" + ($t.data('scrollToCol') + 1) + ")");
-              colSel.addClass("columnSelected");
-              $t.data('scrollToCol', null);
+            else {
+              html = '<td>' + data[i][0] + '</td><td colspan="' + (aoColumns.length - 1) + '" class="stripe"></td>';
             }
+            appendable.children().eq(i).html(html);
+          }
 
-            if ($t.data('plugin_jHueTableExtender')) {
-              $t.data('plugin_jHueTableExtender').drawHeader(typeof force === 'undefined');
-              $t.data('plugin_jHueTableExtender').drawLockedRows();
+          if ($t.data('scrollToCol')) {
+            var colSel = $t.find("tr th:nth-child(" + ($t.data('scrollToCol') + 1) + ")");
+            $t.parent().animate({
+              scrollLeft: colSel.position().left + $t.parent().scrollLeft() - $t.parent().offset().left - 30
+            }, 300);
+            colSel = $t.find("tr td:nth-child(" + ($t.data('scrollToCol') + 1) + ")");
+            if ($t.data('scrollToRow') == null) {
+              colSel.addClass("columnSelected");
             }
-
-            if (force) {
-              $t.data('plugin_jHueTableExtender').drawFirstColumn();
+            else {
+              $t.find("tr:nth-child(" + ($t.data('scrollToRow') + 1) + ") td:nth-child(" + ($t.data('scrollToCol') + 1) + ")").addClass('columnSelected');
+              $t.data('scrollToRow', null);
             }
+            $t.data('scrollToCol', null);
+          }
 
+          if ($t.data('plugin_jHueTableExtender')) {
+            $t.data('plugin_jHueTableExtender').drawHeader(typeof force === 'undefined');
+            $t.data('plugin_jHueTableExtender').drawLockedRows();
           }
-          $t.data('fnDraws', $t.data('fnDraws') + 1);
-          if ($t.data('oInit')['fnDrawCallback']) {
-            $t.data('oInit')['fnDrawCallback']();
+
+          if (force) {
+            $t.data('plugin_jHueTableExtender').drawFirstColumn();
           }
 
-          $t.trigger('headerpadding');
+        }
+        $t.data('fnDraws', $t.data('fnDraws') + 1);
+        if ($t.data('oInit')['fnDrawCallback']) {
+          $t.data('oInit')['fnDrawCallback']();
+        }
+
+        $t.trigger('headerpadding');
 
         self.isDrawing = false;
       }
@@ -235,6 +344,7 @@
 
     return self.each(function () {
       self.$table = $(this);
+      $('.hue-datatable-search').remove();
       var parent = self.$table.parent();
       if (parent.hasClass('dataTables_wrapper')) {
         return;

+ 12 - 2
desktop/libs/notebook/src/notebook/templates/editor_components.mako

@@ -1216,8 +1216,9 @@ ${ hueIcons.symbols() }
         <!-- ko if: result.hasSomeResults -->
         <li data-bind="click: function(){ currentQueryTab('queryResults'); }, css: {'active': currentQueryTab() == 'queryResults'}">
           <a class="inactive-action" href="#queryResults" data-toggle="tab">${_('Results')}
-            <div class="inline-block inactive-action margin-left-10 pointer" title="${_('Expand results')}" rel="tooltip" data-bind="visible: !$root.isFullscreenMode() && !$root.isPlayerMode(), click: function(){ $root.isPlayerMode(true); }"><i class="snippet-icon fa fa-expand"></i></div>
-            <div class="inline-block inactive-action margin-left-10 pointer" title="${_('Collapse results')}" rel="tooltip" data-bind="visible: !$root.isFullscreenMode() && $root.isPlayerMode(), click: function(){ $root.isPlayerMode(false); }"><i class="snippet-icon fa fa-compress"></i></div>
+            <div class="inline-block inactive-action margin-left-10 pointer" title="${_('Search the results')}" data-bind="click: function(data, e){ $(e.target).parents('table').hueDataTable().fnShowSearch() }"><i class="snippet-icon fa fa-search"></i></div>
+            <div class="inline-block inactive-action pointer" title="${_('Expand results')}" rel="tooltip" data-bind="visible: !$root.isFullscreenMode() && !$root.isPlayerMode(), click: function(){ $root.isPlayerMode(true); }"><i class="snippet-icon fa fa-expand"></i></div>
+            <div class="inline-block inactive-action pointer" title="${_('Collapse results')}" rel="tooltip" data-bind="visible: !$root.isFullscreenMode() && $root.isPlayerMode(), click: function(){ $root.isPlayerMode(false); }"><i class="snippet-icon fa fa-compress"></i></div>
           </a>
         </li>
         <!-- /ko -->
@@ -3193,6 +3194,15 @@ ${ hueIcons.symbols() }
         return false;
       });
 
+      $(window).bind("keydown", "ctrl+f alt+f meta+f", function (e) {
+        if (viewModel.editorMode() && viewModel.selectedNotebook().snippets()[0].currentQueryTab() == 'queryResults') {
+          e.preventDefault();
+          var $t = $("#snippet_" + viewModel.selectedNotebook().snippets()[0].id()).find(".resultTable");
+          $t.hueDataTable().fnShowSearch();
+          return false;
+        }
+      });
+
       huePubSub.subscribe('editor.create.new', newKeyHandler);
 
       var initialResizePosition = 100;