فهرست منبع

HUE-7062 [frontend] Add a generic Ace editor component that supports the Hue autocomplete dropdown

Johan Ahlen 8 سال پیش
والد
کامیت
6f79f42

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
desktop/core/src/desktop/static/desktop/css/hue.css


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
desktop/core/src/desktop/static/desktop/css/hue3-extra.css


+ 33 - 0
desktop/core/src/desktop/static/desktop/less/components/hue-simple-ace.less

@@ -0,0 +1,33 @@
+/*
+ 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.
+*/
+
+.simple-ace-single-line {
+  position: relative;
+  border: 1px solid @cui-gray-300;
+  border-radius: 4px;
+  width: 100%;
+  height: 26px;
+
+  .ace-editor {
+    position: absolute;
+    top: 4px;
+    right: 3px;
+    bottom: 4px;
+    left: 3px;
+  }
+}

+ 11 - 10
desktop/core/src/desktop/static/desktop/less/hue-cross-version.less

@@ -18,23 +18,24 @@
 @import (reference) "cui/colors.less";
 @import (reference) "hue-mixins.less";
 
+@import "components/hue-breadcrumbs.less";
 @import "components/hue-clearable.less";
+@import "components/hue-demi-modal.less";
 @import "components/hue-filechooser.less";
+@import "components/hue-gridster.less";
+@import "components/hue-inputautocomplete.less";
 @import "components/hue-notify.less";
+@import "components/hue-qq-upload.less";
+@import "components/hue-query-builder.less";
 @import "components/hue-ribbon.less";
-@import "components/hue-selector.less";
-@import "components/hue-tables.less";
 @import "components/hue-scroll-anchor.less";
-@import "components/hue-selectize.less";
-@import "components/hue-demi-modal.less";
-@import "components/hue-spinner.less";
-@import "components/hue-gridster.less";
 @import "components/hue-scrollbar.less";
-@import "components/hue-query-builder.less";
-@import "components/hue-qq-upload.less";
-@import "components/hue-breadcrumbs.less";
-@import "components/hue-inputautocomplete.less";
+@import "components/hue-selectize.less";
+@import "components/hue-selector.less";
 @import "components/hue-shepherd.less";
+@import "components/hue-simple-ace.less";
+@import "components/hue-spinner.less";
+@import "components/hue-tables.less";
 @import "components/hue-wizard.less";
 @import "hue-helpers.less";
 

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

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

+ 2 - 2
desktop/core/src/desktop/templates/hue_ace_autocompleter.mako

@@ -295,9 +295,9 @@ from desktop.views import _ko
         var self = this;
         self.disposeFunctions = [];
         self.editor = params.editor;
-        self.snippet = params.snippet;
+        self.snippet = params.snippet || {};
 
-        self.autocompleter = new SqlAutocompleter3(params);
+        self.autocompleter = params.autocompleter || new SqlAutocompleter3(params);
         self.suggestions = self.autocompleter.suggestions;
 
         self.active = ko.observable(false).extend({ rateLimit: 10 }); // to prevent flickering on empty result

+ 166 - 0
desktop/core/src/desktop/templates/ko_components.mako

@@ -1299,4 +1299,170 @@ from desktop.views import _ko
       <div>${ _('No match found') }</div>
     </div>
   </script>
+
+  <script type="text/html" id="hue-simple-ace-editor-template">
+    <!-- ko if singleLine -->
+    <div class="simple-ace-single-line">
+      <div class="ace-editor"></div>
+    </div>
+    <!-- /ko -->
+    <!-- ko ifnot: singleLine -->
+    <div class="ace-editor"></div>
+    <!-- /ko -->
+    <!-- ko if: autocompleter !== null -->
+    <!-- ko component: { name: 'hueAceAutocompleter', params: { editor: ace, autocompleter: autocompleter } } --><!-- /ko -->
+    <!-- /ko -->
+  </script>
+
+  <script type="text/javascript">
+    (function () {
+      var normalizedColors = HueColors.getNormalizedColors();
+
+      var SolrFormulaAutocompleter = (function () {
+        var COLORS = {
+          ALL: HueColors.BLUE,
+          FIELD: normalizedColors['green'][2]
+        };
+
+        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' }
+        };
+
+        var SolrSuggestions = function () {
+          var self = this;
+          self.filtered = ko.pureComputed(function () {
+            // TODO: Implement autocomplete logic
+          });
+
+          self.availableCategories = ko.pureComputed(function () {
+            // TODO: Implement autocomplete logic
+            return [CATEGORIES.ALL];
+          });
+
+          self.loading = ko.observable(false);
+          self.filter = ko.observable();
+          self.cancelRequests = function () {};
+        };
+
+        var SolrFormulaAutocompleter = function () {
+          var self = this;
+
+          self.suggestions = new SolrSuggestions();
+        };
+
+        SolrFormulaAutocompleter.prototype.autocomplete = function () {
+          // TODO: parse the input and update suggestions
+        };
+
+        return SolrFormulaAutocompleter;
+      })();
+
+      var AVAILABLE_AUTOCOMPLETERS = {
+        'solrFormula': SolrFormulaAutocompleter
+      };
+
+      var SimpleAceEditor = function (params, element) {
+        var $element = $(element);
+        var self = this;
+        self.value = params.value;
+        self.ace = ko.observable();
+        self.disposeFunctions = [];
+
+        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')) {
+          $element.attr('id', UUID());
+        }
+
+        var editor = ace.edit($element.find('.ace-editor')[0]);
+        self.ace(editor);
+
+        if (self.value()) {
+          editor.setValue(self.value());
+          editor.clearSelection();
+        }
+
+        if (self.singleLine) {
+          aceOptions = $.extend(aceOptions, {
+            fontSize: '14px',
+            maxLines: 1, // make it 1 line
+            autoScrollEditorIntoView: true,
+            highlightActiveLine: false,
+            printMargin: false,
+            showGutter: false,
+            enableBasicAutocompletion: params.autocomplete
+          });
+        }
+
+        editor.setOptions(aceOptions);
+
+        if (params.singleLine) {
+          editor.renderer.screenToTextCoordinates = function(x, y) {
+            var pos = this.pixelToScreenCoordinates(x, y);
+            return this.session.screenToDocumentPosition(
+                    Math.min(this.session.getScreenLength() - 1, Math.max(pos.row, 0)),
+                    Math.max(pos.column, 0)
+            );
+          };
+
+          editor.commands.bindKey("Enter|Shift-Enter", "null");
+
+          var pasteListener = editor.on("paste", function(e) {
+            e.text = e.text.replace(/[\r\n]+/g, " ");
+          });
+
+          self.disposeFunctions.push(function () {
+            editor.off('paste', pasteListener);
+          });
+        }
+
+        if (params.autocomplete) {
+          var AceAutocomplete = ace.require("ace/autocomplete").Autocomplete;
+
+          if (!editor.completer) {
+            editor.completer = new AceAutocomplete();
+          }
+          editor.completer.exactMatch = false;
+          editor.useHueAutocompleter = true;
+        }
+
+        var inputListener = editor.on('input', function () {
+          self.value(editor.getValue());
+        });
+
+        self.disposeFunctions.push(function () {
+          editor.off('input', inputListener);
+        });
+      };
+
+      SimpleAceEditor.prototype.dispose = function () {
+        var self = this;
+        self.disposeFunctions.forEach(function (dispose) {
+          dispose();
+        })
+      };
+
+      ko.components.register('hue-simple-ace-editor', {
+        viewModel: {
+          createViewModel: function(params, componentInfo) {
+            return new SimpleAceEditor(params, componentInfo.element);
+          }
+        },
+        template: {element: 'hue-simple-ace-editor-template'}
+      });
+    })();
+  </script>
 </%def>

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است