Преглед изворни кода

HUE-7062 [dashboard] Suggest Solr functions in the dashboard formula editor

Johan Ahlen пре 8 година
родитељ
комит
8cfe667

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

@@ -177,6 +177,7 @@ if USE_NEW_EDITOR.get():
   <script src="${ static('desktop/js/autocomplete/sqlParseSupport.js') }"></script>
   <script src="${ static('desktop/js/autocomplete/sqlStatementsParser.js') }"></script>
   <script src="${ static('desktop/js/autocomplete/sqlAutocompleteParser.js') }"></script>
+  <script src="${ static('desktop/js/autocomplete/solrExpressionParser.js') }"></script>
   <script src="${ static('desktop/js/autocomplete/globalSearchParser.js') }"></script>
 
   <script>

+ 2 - 1
desktop/core/src/desktop/templates/common_header_footer_components.mako

@@ -185,7 +185,8 @@ from metadata.conf import has_optimizer, OPTIMIZER
           column: '${ _('Columns') }',
           cte: '${ _('CTEs') }',
           database: '${ _('Databases') }',
-          field: '${ _('FIELD') }',
+          field: '${ _('Field') }',
+          function: '${ _('Functions') }',
           identifier: '${ _('Identifiers') }',
           keyword: '${ _('Keywords') }',
           popular: '${ _('Popular') }',

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

@@ -480,6 +480,7 @@ ${ commonshare() | n,unicode }
 <script src="${ static('desktop/js/autocomplete/sqlParseSupport.js') }"></script>
 <script src="${ static('desktop/js/autocomplete/sqlAutocompleteParser.js') }"></script>
 <script src="${ static('desktop/js/autocomplete/globalSearchParser.js') }"></script>
+<script src="${ static('desktop/js/autocomplete/solrExpressionParser.js') }"></script>
 <script src="${ static('desktop/js/sqlAutocompleter.js') }"></script>
 <script src="${ static('desktop/js/sqlAutocompleter2.js') }"></script>
 <script src="${ static('desktop/js/hdfsAutocompleter.js') }"></script>

+ 3 - 0
desktop/core/src/desktop/templates/hue_ace_autocompleter.mako

@@ -55,6 +55,9 @@ from desktop.views import _ko
   <script type="text/html" id="autocomplete-details-keyword">
   </script>
 
+  <script type="text/html" id="autocomplete-details-solr-field">
+  </script>
+
   <script type="text/html" id="autocomplete-details-udf">
     <div class="autocompleter-details">
       <div class="autocompleter-header"><i class="fa fa-fw fa-superscript"></i> <span data-bind="text: details.signature.substring(0, details.signature.indexOf('('));"></span></div>

+ 66 - 19
desktop/core/src/desktop/templates/ko_components.mako

@@ -1723,21 +1723,34 @@ from desktop.views import _ko
             description: 'Calculates variance (Solr 6.6+).'
           }
         };
-        
+
         var COLORS = {
           ALL: HueColors.BLUE,
-          FIELD: normalizedColors['green'][2]
+          FIELD: normalizedColors['green'][2],
+          FUNCTION: normalizedColors['purple-gray'][3]
         };
 
         var CATEGORIES = {
           ALL: { id: 'all', color: COLORS.ALL, label: AutocompleterGlobals.i18n.category.all },
-          FIELD: { id: 'field', weight: 1000, color: COLORS.FIELD, label: AutocompleterGlobals.i18n.category.field, detailsTemplate: 'field' }
+          FIELD: { id: 'field', weight: 1000, color: COLORS.FIELD, label: AutocompleterGlobals.i18n.category.field, detailsTemplate: 'solr-field' },
+          FUNCTION: { id: 'function', weight: 900, color: COLORS.FUNCTION, label: AutocompleterGlobals.i18n.category.function, detailsTemplate: 'udf' }
         };
 
-        var SolrSuggestions = function () {
+        var SolrFormulaSuggestions = function () {
           var self = this;
+          self.entries = ko.observableArray();
+
           self.filtered = ko.pureComputed(function () {
-            // TODO: Implement autocomplete logic
+            var result = self.entries();
+
+            if (self.filter()) {
+              result = SqlUtils.autocompleteFilter(self.filter(), result);
+              huePubSub.publish('hue.ace.autocompleter.match.updated');
+            }
+
+            SqlUtils.sortSuggestions(result, self.filter(), self.sortOverride);
+
+            return result;
           });
 
           self.availableCategories = ko.pureComputed(function () {
@@ -1750,14 +1763,41 @@ from desktop.views import _ko
           self.cancelRequests = function () {};
         };
 
-        var SolrFormulaAutocompleter = function () {
+        SolrFormulaSuggestions.prototype.update = function (parseResult) {
           var self = this;
+          var syncEntries = [];
+          if (parseResult.suggestFunctions) {
+
+            Object.keys(SOLR_FUNCTIONS).forEach(function (name) {
+              syncEntries.push({
+                category: CATEGORIES.FUNCTION,
+                value: name + '()',
+                meta: SOLR_FUNCTIONS[name].returnTypes.join('|'),
+                weightAdjust: 0, // Add when we type aware
+                popular: ko.observable(false),
+                details: SOLR_FUNCTIONS[name]
+              })
+            });
+          }
 
-          self.suggestions = new SolrSuggestions();
+          self.entries(syncEntries);
+        };
+
+        /**
+         * @param {Object} options
+         * @param {Ace} options.editor
+         * @constructor
+         */
+        var SolrFormulaAutocompleter = function (options) {
+          var self = this;
+          self.editor = options.editor;
+          self.suggestions = new SolrFormulaSuggestions();
         };
 
         SolrFormulaAutocompleter.prototype.autocomplete = function () {
-          // TODO: parse the input and update suggestions
+          var self = this;
+          var parseResult = solrExpressionParser.parseSolrExpression(self.editor.getTextBeforeCursor(), self.editor.getTextAfterCursor());
+          self.suggestions.update(parseResult);
         };
 
         return SolrFormulaAutocompleter;
@@ -1776,16 +1816,6 @@ from desktop.views import _ko
 
         self.singleLine = !!params.singleLine;
 
-        if (params.autocomplete) {
-          if (!AVAILABLE_AUTOCOMPLETERS[params.autocomplete]) {
-            throw new Error('Could not find autocompleter for "' + params.autocomplete + '"');
-          }
-
-          self.autocompleter = new AVAILABLE_AUTOCOMPLETERS[params.autocomplete]();
-        } else {
-          self.autocompleter = null;
-        }
-
         var aceOptions = params.aceOptions || {};
 
         if (!$element.attr('id')) {
@@ -1793,8 +1823,19 @@ from desktop.views import _ko
         }
 
         var editor = ace.edit($element.find('.ace-editor')[0]);
+        editor.$blockScrolling = Infinity;
         self.ace(editor);
 
+        if (params.autocomplete) {
+          if (!AVAILABLE_AUTOCOMPLETERS[params.autocomplete]) {
+            throw new Error('Could not find autocompleter for "' + params.autocomplete + '"');
+          }
+
+          self.autocompleter = new AVAILABLE_AUTOCOMPLETERS[params.autocomplete]({ editor: editor });
+        } else {
+          self.autocompleter = null;
+        }
+
         if (self.value()) {
           editor.setValue(self.value());
           editor.clearSelection();
@@ -1807,7 +1848,13 @@ from desktop.views import _ko
             autoScrollEditorIntoView: true,
             highlightActiveLine: false,
             printMargin: false,
-            showGutter: false,
+            showGutter: false
+          });
+        }
+
+        if (params.autocomplete) {
+          aceOptions = $.extend(aceOptions, {
+            enableLiveAutocompletion: true,
             enableBasicAutocompletion: params.autocomplete
           });
         }

+ 1 - 1
desktop/libs/dashboard/src/dashboard/templates/common_search.mako

@@ -2035,7 +2035,7 @@ ${ dashboard.layout_skeleton(suffix='search') }
       <div class="clearfix"></div>
       <br/>
 
-      <input data-bind="value: formula, visible: $parent.field() == 'formula', valueUpdate: 'afterkeydown'"></input>
+      <div data-bind="component: { name: 'hue-simple-ace-editor', params: { value: formula, autocomplete: 'solrFormula', singleLine: true } }"></div>
       <input data-bind="value: plain_formula" type="hidden"></input>
 
       <!-- ko if: $data.function() != 'field' && $parents[1].widgetType() != 'hit-widget' -->