Pārlūkot izejas kodu

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 gadi atpakaļ
vecāks
revīzija
522583959a

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 0 - 0
desktop/core/src/desktop/static/desktop/css/hue.css


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 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 {AssistDbEntry} parent
    * @param {AssistDbSource} assistDbSource
    * @param {AssistDbSource} assistDbSource
    * @param {Object} filter
    * @param {Object} filter
-   * @param {function} filter.query (observable)
+   * @param {function} filter.querySpec (observable)
    * @param {function} filter.showViews (observable)
    * @param {function} filter.showViews (observable)
    * @param {function} filter.showTables (observable)
    * @param {function} filter.showTables (observable)
    * @param {Object} i18n
    * @param {Object} i18n
@@ -78,15 +78,32 @@ var AssistDbEntry = (function () {
     });
     });
 
 
     self.filteredEntries = ko.pureComputed(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();
         return self.entries();
       }
       }
+
       var result = [];
       var result = [];
       $.each(self.entries(), function (index, entry) {
       $.each(self.entries(), function (index, entry) {
         if ((entry.definition.isTable && !self.filter.showTables()) || (entry.definition.isView && !self.filter.showViews()) ) {
         if ((entry.definition.isTable && !self.filter.showTables()) || (entry.definition.isView && !self.filter.showViews()) ) {
           return;
           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);
           result.push(entry);
         }
         }
       });
       });

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

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

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

@@ -557,6 +557,10 @@
   margin-right: 8px;
   margin-right: 8px;
 }
 }
 
 
+.assist-filter .inline-autocomplete-container {
+  height: 25px;
+}
+
 .assist-filter input {
 .assist-filter input {
   -webkit-box-sizing: border-box;
   -webkit-box-sizing: border-box;
   -moz-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;
   margin-top: 5px;
   height: 30px;
   height: 30px;
   width: 100%;
   width: 100%;
+
+  > div {
+    right: 10px !important;
+  }
 }
 }
 
 
 .inline-autocomplete-container {
 .inline-autocomplete-container {
@@ -330,7 +334,7 @@ body {
   > div {
   > div {
     position:absolute;
     position:absolute;
     left: 0;
     left: 0;
-    right: 10px;
+    right: 0;
     height: 30px;
     height: 30px;
 
 
     input {
     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>
     </div>
     <div class="assist-flex-search" data-bind="visible: hasEntries() && ! hasErrors()">
     <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>
     <div class="assist-flex-fill assist-db-scrollable" data-bind="visible: ! hasErrors() && ! loading() && hasEntries()">
     <div class="assist-flex-fill assist-db-scrollable" data-bind="visible: ! hasErrors() && ! loading() && hasEntries()">
       <!-- ko if: ! loading() && filteredEntries().length == 0 -->
       <!-- ko if: ! loading() && filteredEntries().length == 0 -->
@@ -942,7 +951,16 @@ from notebook.conf import ENABLE_QUERY_BUILDER, ENABLE_QUERY_SCHEDULING, get_ord
       <!-- /ko -->
       <!-- /ko -->
     </div>
     </div>
     <div class="assist-flex-search" data-bind="visible: hasEntries() && !$parent.loading() && !$parent.hasErrors()">
     <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>
     <div class="assist-flex-fill assist-db-scrollable" data-bind="visible: ! hasErrors() && ! loading()">
     <div class="assist-flex-fill assist-db-scrollable" data-bind="visible: ! hasErrors() && ! loading()">
       <!-- ko template: 'assist-db-entries' --><!-- /ko -->
       <!-- 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>
         </div>
         <div class="assist-flex-search" data-bind="visible: activeTables().length > 0">
         <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>
         <div class="assist-flex-half assist-db-scrollable">
         <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>
           <div class="assist-no-entries">${ _('No tables identified.') }</div>
           <!-- /ko -->
           <!-- /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>
           <div class="assist-no-entries">${ _('No entries found.') }</div>
           <!-- /ko -->
           <!-- /ko -->
           <!-- ko if: filteredTables().length > 0 -->
           <!-- ko if: filteredTables().length > 0 -->
@@ -2325,7 +2352,7 @@ from notebook.conf import ENABLE_QUERY_BUILDER, ENABLE_QUERY_SCHEDULING, get_ord
         var activeTableIndex = {};
         var activeTableIndex = {};
 
 
         self.filter = {
         self.filter = {
-          query: ko.observable(''),
+          querySpec: ko.observable({}),
           showViews: ko.observable(true),
           showViews: ko.observable(true),
           showTables: 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 = [];
         var openedByFilter = [];
 
 
         self.filteredTables = ko.pureComputed(function () {
         self.filteredTables = ko.pureComputed(function () {
-          if (self.filter.query() === '') {
+          if (!self.filter.querySpec() || self.filter.querySpec().query === '') {
             while (openedByFilter.length) {
             while (openedByFilter.length) {
               openedByFilter.pop().open(false);
               openedByFilter.pop().open(false);
             }
             }
@@ -2346,7 +2373,7 @@ from notebook.conf import ENABLE_QUERY_BUILDER, ENABLE_QUERY_SCHEDULING, get_ord
                 openedByFilter.push(table);
                 openedByFilter.push(table);
               }
               }
               return true;
               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 true;
             }
             }
             return false;
             return false;
@@ -2654,13 +2681,22 @@ from notebook.conf import ENABLE_QUERY_BUILDER, ENABLE_QUERY_SCHEDULING, get_ord
           </div>
           </div>
         </div>
         </div>
         <div class="assist-flex-search" data-bind="visible: activeCollection() && activeCollection().fields().length > 0">
         <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>
         <div class="assist-flex-half assist-db-scrollable">
         <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>
           <div class="assist-no-entries">${ _('No fields available.') }</div>
           <!-- /ko -->
           <!-- /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>
           <div class="assist-no-entries">${ _('No fields found.') }</div>
           <!-- /ko -->
           <!-- /ko -->
           <!-- ko if: filteredFields().length > 0 -->
           <!-- 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.activeCollection = ko.observable();
 
 
         self.filter = {
         self.filter = {
-          query: ko.observable('')
+          querySpec: ko.observable({})
         };
         };
 
 
         var activeDashboardCollection = huePubSub.subscribe('set.active.dashboard.collection', function(collection) {
         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()){
           if (!self.activeCollection()){
             return [];
             return [];
           }
           }
-          if (self.filter.query() === '') {
+          if (!self.filter.querySpec() || self.filter.querySpec().query === '') {
             return self.activeCollection().fields();
             return self.activeCollection().fields();
           }
           }
           var result = self.activeCollection().fields().filter(function (field) {
           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 true;
             }
             }
             return false;
             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 InlineAutocomplete = function (params) {
         var self = this;
         var self = this;
-        self.placeHolder = params.placeHolder;
+        self.disposals = [];
+
+        self.placeHolder = params.placeHolder || '${ _('Filter...') }';
         self.hasFocus = params.hasFocus || ko.observable();
         self.hasFocus = params.hasFocus || ko.observable();
-        self.searchInput = ko.observable('');
         self.querySpec = params.querySpec;
         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.inlineAutocomplete = ko.observable('');
         self.lastNonPartial = null;
         self.lastNonPartial = null;
         self.lastResult = {};
         self.lastResult = {};
-        self.autocompleteFromEntries = params.autocompleteFromEntries;
-        self.disposals = [];
 
 
-        self.facets = params.facets;
-        self.knownFacetValues = params.knownFacetValues;
+        self.querySpec({
+          query: '',
+          facets: {},
+          text: []
+        });
 
 
         self.onClear = function () {
         self.onClear = function () {
           if (params.onClear) {
           if (params.onClear) {
@@ -695,11 +702,17 @@ from desktop.views import _ko
           }
           }
           if (newValue !== '') {
           if (newValue !== '') {
             self.triggerAutocomplete(newValue);
             self.triggerAutocomplete(newValue);
+          } else {
+            self.querySpec({
+              query: '',
+              facets: {},
+              text: []
+            })
           }
           }
         });
         });
 
 
         self.disposals.push(function () {
         self.disposals.push(function () {
-          inputSub.remove();
+          inputSub.dispose();
         });
         });
 
 
         var onKeyDown = function (event) {
         var onKeyDown = function (event) {
@@ -738,7 +751,7 @@ from desktop.views import _ko
         });
         });
 
 
         self.disposals.push(function () {
         self.disposals.push(function () {
-          focusSub.remove();
+          focusSub.dispose();
         });
         });
       };
       };
 
 
@@ -781,8 +794,9 @@ from desktop.views import _ko
         }
         }
 
 
         if (self.lastResult.suggestFacetValues && !newAutocomplete) {
         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) {
               if (value.toLowerCase().indexOf(partialLower) === 0) {
                 newAutocomplete = self.lastNonPartial + partial + value.substring(partial.length, value.length);
                 newAutocomplete = self.lastNonPartial + partial + value.substring(partial.length, value.length);
                 return false;
                 return false;
@@ -819,6 +833,15 @@ from desktop.views import _ko
 
 
         if (self.lastNonPartial && self.lastNonPartial === nonPartial) {
         if (self.lastNonPartial && self.lastNonPartial === nonPartial) {
           self.updateInlineAutocomplete(partial);
           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;
           return;
         }
         }
 
 
@@ -1127,12 +1150,13 @@ from desktop.views import _ko
 
 
         navPromise.done(function (data) {
         navPromise.done(function (data) {
           if (data.facets) {
           if (data.facets) {
+            var facetValues = ko.unwrap(self.knownFacetValues);
             Object.keys(data.facets).forEach(function (facet) {
             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) {
               Object.keys(data.facets[facet]).forEach(function (facetKey) {
-                self.knownFacetValues()[facet][facetKey] = data.facets[facet][facetKey];
+                facetValues[facet][facetKey] = data.facets[facet][facetKey];
               });
               });
             })
             })
           }
           }

Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels