Browse Source

HUE-7362 [assist] Include free text parts in the query specification from the global search parser

Johan Ahlen 8 years ago
parent
commit
825900f

File diff suppressed because it is too large
+ 0 - 0
desktop/core/src/desktop/static/desktop/js/autocomplete/globalSearchParser.js


+ 34 - 13
desktop/core/src/desktop/static/desktop/js/autocomplete/jison/globalSearchParser.jison

@@ -46,7 +46,7 @@
 
 <doubleQuote>\"                                 { this.popState(); return 'QUOTE'; }
 
-[^"'\s\u2020]+                                    { return 'TEXT'; }
+[^"'\s\u2020]+                                  { return 'TEXT'; }
 
 <<EOF>>                                         { return 'EOF'; }
 
@@ -59,27 +59,43 @@
 GlobalSearchAutocomplete
  : SearchParts 'EOF'
    {
-     return {};
+     return $1;
    }
  | SearchParts_EDIT 'EOF'
    {
      if (!$1.facets) {
        $1.facets = {};
      }
+     if (!$1.text) {
+       $1.text = [];
+     }
      return $1;
    }
  | 'EOF'
    {
-     return {};
+     return { facets: {}, text: [] };
    }
  ;
 
 SearchParts
- : SearchPart                   -->  { facets: $1.facets ? $1.facets : {} }
+ : SearchPart
+   {
+     $$ = {
+       facets: $1.facets ? $1.facets : {},
+       text: $1.text ? $1.text : []
+     };
+   }
  | SearchParts SearchPart
    {
+     $$ = {
+       facets: $1.facets ? $1.facets : {},
+       text: $1.text ? $1.text : []
+     };
      if ($2.facets) {
-       parser.mergeFacets($1.facets, $2.facets);
+       parser.mergeFacets($$.facets, $2.facets);
+     }
+     if ($2.text && $2.text.length) {
+       $$.text = $$.text.concat($2.text);
      }
    }
  ;
@@ -88,24 +104,29 @@ SearchParts_EDIT
  : SearchPart_EDIT
  | SearchParts SearchPart_EDIT
    {
-     $2.facets = $1.facets;
      $$ = $2;
+     $$.facets = $1.facets;
+     $$.text = $1.text;
    }
  | SearchPart_EDIT SearchParts
    {
-     $1.facets = $2.facets;
+     $$ = $1;
+     $$.facets = $2.facets;
+     $$.text = $2.text;
    }
  | SearchParts SearchPart_EDIT SearchParts
    {
-     $2.facets = $1.facets;
-     parser.mergeFacets($2.facets, $3.facets);
      $$ = $2;
+     $$.facets = $1.facets;
+     $$.text = $1.text;
+     parser.mergeFacets($$.facets, $3.facets);
+     $$.text = $$.text.concat($3.text);
    }
  ;
 
 SearchPart
  : Facet
- | FreeText
+ | FreeText  --> { text: [ $1 ] }
  ;
 
 SearchPart_EDIT
@@ -137,12 +158,12 @@ FreeText_EDIT
  ;
 
 QuotedValue
- : 'QUOTE' 'VALUE' 'QUOTE'
- | 'QUOTE' 'QUOTE'
+ : 'QUOTE' 'VALUE' 'QUOTE'  --> $2
+ | 'QUOTE' 'QUOTE'          --> ''
  ;
 
 QuotedValue_EDIT
- : 'QUOTE' 'PARTIAL_VALUE'
+ : 'QUOTE' 'PARTIAL_VALUE'  --> $2
  ;
 
 %%

+ 24 - 12
desktop/core/src/desktop/static/desktop/js/autocomplete/sqlParseSupport.js

@@ -1915,23 +1915,35 @@ var SqlParseSupport = (function () {
       }
     };
 
-    parser.parseGlobalSearch = function (beforeCursor, afterCursor, debug) {
-      delete parser.yy.cursorFound;
-
-      parser.yy.partialLengths = parser.identifyPartials(beforeCursor, afterCursor);
-
-      if (parser.yy.partialLengths.left > 0) {
-        beforeCursor = beforeCursor.substring(0, beforeCursor.length - parser.yy.partialLengths.left);
+    parser.handleQuotedValueWithCursor = function (lexer, yytext, yylloc, quoteChar) {
+      if (yytext.indexOf('\u2020') !== -1 || yytext.indexOf('\u2021') !== -1) {
+        var cursorIndex = yytext.indexOf('\u2020');
+        parser.yy.cursorFound = {
+          first_line: yylloc.first_line,
+          last_line: yylloc.last_line,
+          first_column: yylloc.first_column + cursorIndex,
+          last_column: yylloc.first_column + cursorIndex + 1
+        };
+        var remainder = yytext.substring(cursorIndex + 1);
+        var remainingQuotes = (lexer.upcomingInput().match(new RegExp(quoteChar, 'g')) || []).length;
+        if (remainingQuotes > 0 && remainingQuotes & 1 != 0) {
+          parser.yy.missingEndQuote = false;
+          lexer.input();
+        } else {
+          parser.yy.missingEndQuote = true;
+          lexer.unput(remainder);
+        }
+        lexer.popState();
+        return true;
       }
+      return false;
+    };
 
-      if (parser.yy.partialLengths.right > 0) {
-        afterCursor = afterCursor.substring(parser.yy.partialLengths.right);
-      }
+    parser.parseGlobalSearch = function (beforeCursor, afterCursor, debug) {
+      delete parser.yy.cursorFound;
 
       var result;
       try {
-        // \u2020 represents the cursor, \u2021 represent partial
-        // TODO: Handle partial cursor
         result = parser.parse(beforeCursor + '\u2020' + afterCursor);
       } catch (err) {
         if (debug) {

+ 42 - 5
desktop/core/src/desktop/static/desktop/spec/autocomplete/globalSearchParserSpec.js

@@ -25,7 +25,8 @@
       testParser('', '', {
         suggestFacets: true,
         suggestResults: true,
-        facets: {}
+        facets: {},
+        text: []
       });
     });
 
@@ -35,7 +36,8 @@
         suggestResults: true,
         facets: {
           'TAGS' : ['asdf']
-        }
+        },
+        text: []
       });
     });
 
@@ -44,7 +46,8 @@
         suggestFacetValues: 'tags',
         facets: {
           'type': ['table']
-        }
+        },
+        text: []
       });
     });
 
@@ -54,14 +57,48 @@
         suggestResults: true,
         facets: {
           'type': ['table', 'column']
-        }
+        },
+        text: []
+      });
+    });
+
+    it('should give correct text values for "some text goes |here \'quoted value\'"', function() {
+      testParser('some text goes ', 'here \'quoted value\'', {
+        suggestFacets: true,
+        suggestResults: true,
+        facets: {},
+        text: ['some', 'text', 'goes', 'here', 'quoted value']
+      });
+    });
+
+    it('should give correct text and values for "some boo:\'asdfa adsf\' text goes |here \'quoted value\' foo:bar"', function() {
+      testParser('some boo:\'asdfa adsf\' text goes ', 'here \'quoted value\' foo:bar', {
+        suggestFacets: true,
+        suggestResults: true,
+        facets: {
+          boo: ['asdfa adsf'],
+          foo: ['bar']
+        },
+        text: ['some', 'text', 'goes', 'here', 'quoted value']
+      });
+    });
+
+    it('should give correct text and values for "type:foo bar|"', function() {
+      testParser('type:foo bar', '', {
+        suggestFacets: true,
+        suggestResults: true,
+        facets: {
+          type: ['foo']
+        },
+        text: ['bar']
       });
     });
 
     it('should suggest facet values for "tags: |"', function () {
       testParser('tags: ', '', {
         suggestFacetValues: 'tags',
-        facets: {}
+        facets: {},
+        text: []
       });
     });
   });

+ 30 - 21
desktop/core/src/desktop/templates/ko_components.mako

@@ -649,7 +649,7 @@ from desktop.views import _ko
   <script type="text/html" id="inline-autocomplete-template">
     <div class="inline-autocomplete-container">
       <div>
-        <input class="inline-autocomplete-input" type="text" data-bind="attr: { 'placeHolder' : hasFocus() ? '' : placeHolder }, textInput: value, hasFocus: hasFocus, clearable: { value: value, onClear: onClear }">
+        <input class="inline-autocomplete-input" type="text" data-bind="attr: { 'placeHolder' : hasFocus() ? '' : placeHolder }, textInput: searchInput, hasFocus: hasFocus, clearable: { value: searchInput, onClear: onClear }">
         <input class="inline-autocomplete-autocomplete" disabled type="text" data-bind="value: inlineAutocomplete">
       </div>
     </div>
@@ -662,7 +662,8 @@ from desktop.views import _ko
         var self = this;
         self.placeHolder = params.placeHolder;
         self.hasFocus = params.hasFocus || ko.observable();
-        self.value = params.value;
+        self.searchInput = ko.observable('');
+        self.querySpec = params.querySpec;
         self.inlineAutocomplete = ko.observable('');
         self.lastNonPartial = null;
         self.lastResult = {};
@@ -681,14 +682,14 @@ from desktop.views import _ko
 
         if (params.triggerObservable) {
           var triggerSub = params.triggerObservable.subscribe(function () {
-            self.triggerAutocomplete(self.value(), true);
+            self.triggerAutocomplete(self.searchInput(), true);
           });
           self.disposals.push(function () {
             triggerSub.remove();
           })
         }
 
-        var valueSub = self.value.subscribe(function (newValue) {
+        var inputSub = self.searchInput.subscribe(function (newValue) {
           if (self.inlineAutocomplete().indexOf(newValue) !== 0 || newValue === '') {
             self.inlineAutocomplete(newValue);
           }
@@ -698,7 +699,7 @@ from desktop.views import _ko
         });
 
         self.disposals.push(function () {
-          valueSub.remove();
+          inputSub.remove();
         });
 
         var onKeyDown = function (event) {
@@ -706,16 +707,16 @@ from desktop.views import _ko
             return;
           }
           if (event.keyCode === 32 && event.ctrlKey) { // Ctrl-Space
-            self.triggerAutocomplete(self.value(), true);
+            self.triggerAutocomplete(self.searchInput(), true);
             return;
           }
-          if (event.keyCode === 39 && self.inlineAutocomplete() !== '' && self.inlineAutocomplete() !== self.value()) { // Right arrow
+          if (event.keyCode === 39 && self.inlineAutocomplete() !== '' && self.inlineAutocomplete() !== self.searchInput()) { // Right arrow
             // TODO: Check that cursor is last
-            self.value(self.inlineAutocomplete());
+            self.searchInput(self.inlineAutocomplete());
             return;
           }
-          if (event.keyCode === 9 && self.inlineAutocomplete() !== self.value()) { // Tab
-            self.value(self.inlineAutocomplete());
+          if (event.keyCode === 9 && self.inlineAutocomplete() !== self.searchInput()) { // Tab
+            self.searchInput(self.inlineAutocomplete());
             event.preventDefault();
           }
         };
@@ -728,8 +729,8 @@ from desktop.views import _ko
           if (!newVal) {
             self.inlineAutocomplete('');
             $(document).off('keydown', onKeyDown);
-          } else if (self.value() !== '') {
-            self.triggerAutocomplete(self.value());
+          } else if (self.searchInput() !== '') {
+            self.triggerAutocomplete(self.searchInput());
             $(document).on('keydown', onKeyDown);
           } else {
             $(document).on('keydown', onKeyDown);
@@ -831,6 +832,14 @@ from desktop.views import _ko
             console.log(self.lastResult);
           }
           if (self.lastResult) {
+            var querySpec = { query: newValue };
+            if (self.lastResult.facets) {
+              querySpec.facets = self.lastResult.facets
+            }
+            if (self.lastResult.text) {
+              querySpec.text = self.lastResult.text;
+            }
+            self.querySpec(querySpec);
             self.updateInlineAutocomplete(partial);
           } else {
             self.lastNonPartial = null;
@@ -851,7 +860,7 @@ from desktop.views import _ko
       params: {
         hasFocus: searchHasFocus,
         placeHolder: '${ _ko('Search data and saved documents...') }',
-        value: searchInput,
+        querySpec: querySpec,
         onClear: function () { selectedIndex(null); searchResultVisible(false); },
         facets: ['type', 'tags'],
         knownFacetValues: knownFacetValues,
@@ -906,7 +915,7 @@ from desktop.views import _ko
         self.fetchThrottle = -1;
 
         self.searchHasFocus = ko.observable(false);
-        self.searchInput = ko.observable('');
+        self.querySpec = ko.observable();
         self.searchActive = ko.observable(false);
         self.searchResultVisible = ko.observable(false);
         self.heightWhenDragging = ko.observable(null);
@@ -940,11 +949,11 @@ from desktop.views import _ko
           }
         });
 
-        self.searchInput.subscribe(function (newValue) {
-          if (newValue !== '') {
+        self.querySpec.subscribe(function (newValue) {
+          if (newValue && newValue.query !== '') {
             window.clearTimeout(self.fetchThrottle);
             self.fetchThrottle = window.setTimeout(function () {
-              self.fetchResults(newValue);
+              self.fetchResults(newValue.query);
             }, 500);
           } else {
             self.selectedIndex(undefined);
@@ -971,7 +980,7 @@ from desktop.views import _ko
         };
 
         self.searchHasFocus.subscribe(function (newVal) {
-          if (newVal && self.searchInput() !== '') {
+          if (newVal && self.querySpec() && self.querySpec().query !== '') {
             if (!self.searchResultVisible()) {
               self.searchResultVisible(true);
             }
@@ -992,9 +1001,9 @@ from desktop.views import _ko
             return;
           }
 
-          if (event.keyCode === 13 && self.searchHasFocus() && self.searchInput() !== '') {
+          if (event.keyCode === 13 && self.searchHasFocus() && self.querySpec() && self.querySpec().query !== '') {
             window.clearTimeout(self.fetchThrottle);
-            self.fetchResults(self.searchInput());
+            self.fetchResults(self.querySpec().query);
             return;
           }
 
@@ -1034,7 +1043,7 @@ from desktop.views import _ko
       GlobalSearch.prototype.close = function () {
         var self = this;
         self.searchResultVisible(false);
-        self.searchInput('');
+        self.querySpec({});
       };
 
       GlobalSearch.prototype.openResult = function () {

Some files were not shown because too many files changed in this diff