فهرست منبع

HUE-7362 [assist] Use the new inline autocomplete input for assist filters

With this the inline autocomplete component is used for SQL and Collections assist. It only has facets for sql views and tables at this point.
Johan Ahlen 8 سال پیش
والد
کامیت
522583959a

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


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


+ 20 - 3
desktop/core/src/desktop/static/desktop/js/assist/assistDbEntry.js

@@ -28,7 +28,7 @@ var AssistDbEntry = (function () {
    * @param {AssistDbEntry} parent
    * @param {AssistDbSource} assistDbSource
    * @param {Object} filter
-   * @param {function} filter.query (observable)
+   * @param {function} filter.querySpec (observable)
    * @param {function} filter.showViews (observable)
    * @param {function} filter.showTables (observable)
    * @param {Object} i18n
@@ -78,15 +78,32 @@ var AssistDbEntry = (function () {
     });
 
     self.filteredEntries = ko.pureComputed(function () {
-      if (self.filter == null || (self.filter.showTables && self.filter.showTables() && self.filter.showViews() && self.filter.query().length === 0)) {
+      if (self.filter == null || (self.filter.showTables && self.filter.showTables() && self.filter.showViews && self.filter.showViews() && (!self.filter.querySpec().facets || self.filter.querySpec().facets === {}) && (!self.filter.querySpec().text || self.filter.querySpec().text.length === 0))) {
         return self.entries();
       }
+
       var result = [];
       $.each(self.entries(), function (index, entry) {
         if ((entry.definition.isTable && !self.filter.showTables()) || (entry.definition.isView && !self.filter.showViews()) ) {
           return;
         }
-        if (entry.definition.name.toLowerCase().indexOf(self.filter.query().toLowerCase()) > -1) {
+        var facets = self.filter.querySpec().facets;
+        var facetMatch = !facets || !facets['type'];
+        if (!facetMatch) {
+          facets['type'].every(function (typeFacet) {
+            facetMatch = (typeFacet === 'table' && entry.definition.isTable) || (typeFacet === 'view' && entry.definition.isView);
+            return !facetMatch;
+          });
+        }
+        var textMatch = !self.filter.querySpec().text || self.filter.querySpec().text.length === 0;
+        if (!textMatch) {
+          var nameLower = entry.definition.name.toLowerCase();
+          self.filter.querySpec().text.every(function (text) {
+            textMatch = nameLower.indexOf(text.toLowerCase()) !== -1;
+            return !textMatch;
+          });
+        }
+        if (facetMatch && textMatch) {
           result.push(entry);
         }
       });

+ 5 - 5
desktop/core/src/desktop/static/desktop/js/assist/assistDbSource.js

@@ -73,11 +73,11 @@ var AssistDbSource = (function () {
     });
 
     self.filter = {
-      query: ko.observable("").extend({ rateLimit: 150 })
+      querySpec: ko.observable({})
     };
 
     self.filterActive = ko.pureComputed(function () {
-      return self.filter.query().length !== 0;
+      return self.filter.querySpec() && self.filter.querySpec().query !== '';
     });
 
     var storageSearchVisible = $.totalStorage(self.sourceType + ".assist.searchVisible");
@@ -94,12 +94,12 @@ var AssistDbSource = (function () {
     });
 
     self.filteredEntries = ko.pureComputed(function () {
-      if (self.filter.query().length === 0) {
+      if (!self.filter.querySpec() || typeof self.filter.querySpec().query === 'undefined' || !self.filter.querySpec().query) {
         return self.databases();
       }
       var result = [];
       $.each(self.databases(), function (index, database) {
-        if (database.definition.name.toLowerCase().indexOf(self.filter.query().toLowerCase()) > -1) {
+        if (database.definition.name.toLowerCase().indexOf(self.filter.querySpec().query.toLowerCase()) > -1) {
           result.push(database);
         }
       });
@@ -184,7 +184,7 @@ var AssistDbSource = (function () {
     self.loading = ko.observable(false);
     var dbIndex = {};
     var nestedFilter = {
-      query: ko.observable("").extend({ rateLimit: { timeout: 250, method: 'notifyWhenChangesStop' } }),
+      querySpec: ko.observable({}),
       showTables: ko.observable(true),
       showViews: ko.observable(true),
       activeEditorTables: ko.observableArray([])

+ 4 - 0
desktop/core/src/desktop/static/desktop/less/hue-assist.less

@@ -557,6 +557,10 @@
   margin-right: 8px;
 }
 
+.assist-filter .inline-autocomplete-container {
+  height: 25px;
+}
+
 .assist-filter input {
   -webkit-box-sizing: border-box;
   -moz-box-sizing: border-box;

+ 5 - 1
desktop/core/src/desktop/static/desktop/less/hue.less

@@ -320,6 +320,10 @@ body {
   margin-top: 5px;
   height: 30px;
   width: 100%;
+
+  > div {
+    right: 10px !important;
+  }
 }
 
 .inline-autocomplete-container {
@@ -330,7 +334,7 @@ body {
   > div {
     position:absolute;
     left: 0;
-    right: 10px;
+    right: 0;
     height: 30px;
 
     input {

+ 50 - 14
desktop/core/src/desktop/templates/assist.mako

@@ -874,7 +874,16 @@ from notebook.conf import ENABLE_QUERY_BUILDER, ENABLE_QUERY_SCHEDULING, get_ord
       </div>
     </div>
     <div class="assist-flex-search" data-bind="visible: hasEntries() && ! hasErrors()">
-      <div class="assist-filter"><input class="clearable" type="text" placeholder="${ _('Filter...') }" data-bind="clearable: filter.query, value: filter.query, valueUpdate: 'afterkeydown'"/></div>
+      <div class="assist-filter">
+        <!-- ko component: {
+            name: 'inline-autocomplete',
+            params: {
+              querySpec: filter.querySpec,
+              facets: [],
+              knownFacetValues: {}
+            }
+          } --><!-- /ko -->
+      </div>
     </div>
     <div class="assist-flex-fill assist-db-scrollable" data-bind="visible: ! hasErrors() && ! loading() && hasEntries()">
       <!-- ko if: ! loading() && filteredEntries().length == 0 -->
@@ -942,7 +951,16 @@ from notebook.conf import ENABLE_QUERY_BUILDER, ENABLE_QUERY_SCHEDULING, get_ord
       <!-- /ko -->
     </div>
     <div class="assist-flex-search" data-bind="visible: hasEntries() && !$parent.loading() && !$parent.hasErrors()">
-      <div class="assist-filter"><input class="clearable" type="text" placeholder="${ _('Filter...') }" data-bind="clearable: filter.query, value: filter.query, valueUpdate: 'afterkeydown'"/></div>
+      <div class="assist-filter">
+        <!-- ko component: {
+          name: 'inline-autocomplete',
+          params: {
+            querySpec: filter.querySpec,
+            facets: ['type'],
+            knownFacetValues: { 'type': {'table': -1, 'view': -1 } }
+          }
+        } --><!-- /ko -->
+      </div>
     </div>
     <div class="assist-flex-fill assist-db-scrollable" data-bind="visible: ! hasErrors() && ! loading()">
       <!-- ko template: 'assist-db-entries' --><!-- /ko -->
@@ -2211,13 +2229,22 @@ from notebook.conf import ENABLE_QUERY_BUILDER, ENABLE_QUERY_SCHEDULING, get_ord
           </div>
         </div>
         <div class="assist-flex-search" data-bind="visible: activeTables().length > 0">
-          <div class="assist-filter"><input class="clearable" type="text" data-bind="clearable: filter.query, value: filter.query, valueUpdate: 'afterkeydown'" placeholder="${ _('Filter...') }" /></div>
+          <div class="assist-filter">
+            <!-- ko component: {
+              name: 'inline-autocomplete',
+              params: {
+                querySpec: filter.querySpec,
+                facets: ['type'],
+                knownFacetValues: { 'type': {'table': -1, 'view': -1, 'column': -1, 'string': -1 } }
+              }
+            } --><!-- /ko -->
+          </div>
         </div>
         <div class="assist-flex-half assist-db-scrollable">
-          <!-- ko if: filteredTables().length === 0 && filter.query() === '' -->
+          <!-- ko if: filteredTables().length === 0 && (!filter.querySpec() || filter.querySpec().query === '') -->
           <div class="assist-no-entries">${ _('No tables identified.') }</div>
           <!-- /ko -->
-          <!-- ko if: filteredTables().length === 0 && filter.query() !== '' -->
+          <!-- ko if: filteredTables().length === 0 && filter.querySpec() && filter.querySpec().query !== '' -->
           <div class="assist-no-entries">${ _('No entries found.') }</div>
           <!-- /ko -->
           <!-- ko if: filteredTables().length > 0 -->
@@ -2325,7 +2352,7 @@ from notebook.conf import ENABLE_QUERY_BUILDER, ENABLE_QUERY_SCHEDULING, get_ord
         var activeTableIndex = {};
 
         self.filter = {
-          query: ko.observable(''),
+          querySpec: ko.observable({}),
           showViews: ko.observable(true),
           showTables: ko.observable(true)
         };
@@ -2333,7 +2360,7 @@ from notebook.conf import ENABLE_QUERY_BUILDER, ENABLE_QUERY_SCHEDULING, get_ord
         var openedByFilter = [];
 
         self.filteredTables = ko.pureComputed(function () {
-          if (self.filter.query() === '') {
+          if (!self.filter.querySpec() || self.filter.querySpec().query === '') {
             while (openedByFilter.length) {
               openedByFilter.pop().open(false);
             }
@@ -2346,7 +2373,7 @@ from notebook.conf import ENABLE_QUERY_BUILDER, ENABLE_QUERY_SCHEDULING, get_ord
                 openedByFilter.push(table);
               }
               return true;
-            } else if (table.definition.name.toLowerCase().indexOf(self.filter.query().toLowerCase()) > -1) {
+            } else if (self.filter.querySpec() && table.definition.name.toLowerCase().indexOf(self.filter.querySpec().query.toLowerCase()) > -1) {
               return true;
             }
             return false;
@@ -2654,13 +2681,22 @@ from notebook.conf import ENABLE_QUERY_BUILDER, ENABLE_QUERY_SCHEDULING, get_ord
           </div>
         </div>
         <div class="assist-flex-search" data-bind="visible: activeCollection() && activeCollection().fields().length > 0">
-          <div class="assist-filter"><input class="clearable" type="text" data-bind="clearable: filter.query, value: filter.query, valueUpdate: 'afterkeydown'" placeholder="${ _('Filter...') }" /></div>
+          <div class="assist-filter">
+            <!-- ko component: {
+              name: 'inline-autocomplete',
+              params: {
+                querySpec: filter.querySpec,
+                facets: [],
+                knownFacetValues: {}
+              }
+            } --><!-- /ko -->
+          </div>
         </div>
         <div class="assist-flex-half assist-db-scrollable">
-          <!-- ko if: filteredFields().length === 0 && filter.query() === '' -->
+          <!-- ko if: filteredFields().length === 0 && (!filter.querySpec() || filter.querySpec().query === '') -->
           <div class="assist-no-entries">${ _('No fields available.') }</div>
           <!-- /ko -->
-          <!-- ko if: filteredFields().length === 0 && filter.query() !== '' -->
+          <!-- ko if: filteredFields().length === 0 && filter.querySpec() && filter.querySpec().query !== '' -->
           <div class="assist-no-entries">${ _('No fields found.') }</div>
           <!-- /ko -->
           <!-- ko if: filteredFields().length > 0 -->
@@ -2686,7 +2722,7 @@ from notebook.conf import ENABLE_QUERY_BUILDER, ENABLE_QUERY_SCHEDULING, get_ord
         self.activeCollection = ko.observable();
 
         self.filter = {
-          query: ko.observable('')
+          querySpec: ko.observable({})
         };
 
         var activeDashboardCollection = huePubSub.subscribe('set.active.dashboard.collection', function(collection) {
@@ -2697,11 +2733,11 @@ from notebook.conf import ENABLE_QUERY_BUILDER, ENABLE_QUERY_SCHEDULING, get_ord
           if (!self.activeCollection()){
             return [];
           }
-          if (self.filter.query() === '') {
+          if (!self.filter.querySpec() || self.filter.querySpec().query === '') {
             return self.activeCollection().fields();
           }
           var result = self.activeCollection().fields().filter(function (field) {
-            if (field.name().toLowerCase().indexOf(self.filter.query().toLowerCase()) > -1) {
+            if (field.name().toLowerCase().indexOf(self.filter.querySpec().query.toLowerCase()) > -1) {
               return true;
             }
             return false;

+ 37 - 13
desktop/core/src/desktop/templates/ko_components.mako

@@ -660,18 +660,25 @@ from desktop.views import _ko
 
       var InlineAutocomplete = function (params) {
         var self = this;
-        self.placeHolder = params.placeHolder;
+        self.disposals = [];
+
+        self.placeHolder = params.placeHolder || '${ _('Filter...') }';
         self.hasFocus = params.hasFocus || ko.observable();
-        self.searchInput = ko.observable('');
         self.querySpec = params.querySpec;
+        self.autocompleteFromEntries = params.autocompleteFromEntries || function () {};
+        self.facets = params.facets || [];
+        self.knownFacetValues = params.knownFacetValues || {};
+
+        self.searchInput = ko.observable('');
         self.inlineAutocomplete = ko.observable('');
         self.lastNonPartial = null;
         self.lastResult = {};
-        self.autocompleteFromEntries = params.autocompleteFromEntries;
-        self.disposals = [];
 
-        self.facets = params.facets;
-        self.knownFacetValues = params.knownFacetValues;
+        self.querySpec({
+          query: '',
+          facets: {},
+          text: []
+        });
 
         self.onClear = function () {
           if (params.onClear) {
@@ -695,11 +702,17 @@ from desktop.views import _ko
           }
           if (newValue !== '') {
             self.triggerAutocomplete(newValue);
+          } else {
+            self.querySpec({
+              query: '',
+              facets: {},
+              text: []
+            })
           }
         });
 
         self.disposals.push(function () {
-          inputSub.remove();
+          inputSub.dispose();
         });
 
         var onKeyDown = function (event) {
@@ -738,7 +751,7 @@ from desktop.views import _ko
         });
 
         self.disposals.push(function () {
-          focusSub.remove();
+          focusSub.dispose();
         });
       };
 
@@ -781,8 +794,9 @@ from desktop.views import _ko
         }
 
         if (self.lastResult.suggestFacetValues && !newAutocomplete) {
-          if (self.knownFacetValues()[self.lastResult.suggestFacetValues.toLowerCase()]) {
-            Object.keys(self.knownFacetValues()[self.lastResult.suggestFacetValues.toLowerCase()]).every(function (value) {
+          var facetValues = ko.unwrap(self.knownFacetValues);
+          if (facetValues[self.lastResult.suggestFacetValues.toLowerCase()]) {
+            Object.keys(facetValues[self.lastResult.suggestFacetValues.toLowerCase()]).every(function (value) {
               if (value.toLowerCase().indexOf(partialLower) === 0) {
                 newAutocomplete = self.lastNonPartial + partial + value.substring(partial.length, value.length);
                 return false;
@@ -819,6 +833,15 @@ from desktop.views import _ko
 
         if (self.lastNonPartial && self.lastNonPartial === nonPartial) {
           self.updateInlineAutocomplete(partial);
+          self.lastResult = globalSearchParser.parseGlobalSearch(newValue, '');
+          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);
           return;
         }
 
@@ -1127,12 +1150,13 @@ from desktop.views import _ko
 
         navPromise.done(function (data) {
           if (data.facets) {
+            var facetValues = ko.unwrap(self.knownFacetValues);
             Object.keys(data.facets).forEach(function (facet) {
-              if (!self.knownFacetValues()[facet] && Object.keys(data.facets[facet]).length > 0) {
-                self.knownFacetValues()[facet] = {};
+              if (!facetValues[facet] && Object.keys(data.facets[facet]).length > 0) {
+                facetValues[facet] = {};
               }
               Object.keys(data.facets[facet]).forEach(function (facetKey) {
-                self.knownFacetValues()[facet][facetKey] = data.facets[facet][facetKey];
+                facetValues[facet][facetKey] = data.facets[facet][facetKey];
               });
             })
           }

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