Ver Fonte

[core] Keep track of databases in assist helper

With this change the list of available databases is moved from the assist panel component to the assist helper. This allows us to load the list of databases on demand for snippets and the assist panel separately.
Johan Ahlen há 10 anos atrás
pai
commit
06d2c680e0

+ 41 - 9
desktop/core/src/desktop/static/desktop/js/assistHelper.js

@@ -32,8 +32,49 @@ function AssistHelper (options) {
   }
   self.notebook = options.notebook;
   self.user = options.user;
+  self.availableDatabases = ko.observableArray();
+  self.loaded = ko.observable(false);
+  self.loading = ko.observable(false);
 }
 
+AssistHelper.prototype.load = function (snippet) {
+  var self = this;
+  if (self.loading() || self.loaded()) {
+    return;
+  }
+  self.fetchAssistData(snippet, NOTEBOOK_API_PREFIX, function(data) {
+    // Blacklist of system databases
+    self.availableDatabases($.grep(data.databases, function(database) { return database !== "_impala_builtins" }));
+
+    if ($.inArray(self.activeDatabase(), self.availableDatabases()) > -1) {
+      return;
+    }
+    var lastSelectedDb = $.totalStorage("hue.assist.lastSelectedDb." + self.getTotalStorageUserPrefix(snippet));
+    if ($.inArray(lastSelectedDb, self.availableDatabases()) > -1) {
+      self.activeDatabase(lastSelectedDb);
+    } else if ($.inArray("default", self.availableDatabases()) > -1) {
+      self.activeDatabase("default");
+    } else if (self.availableDatabases().length > 0) {
+      self.activeDatabase(self.availableDatabases()[0]);
+    }
+    self.loaded(true);
+    self.loading(false);
+  }, function(message) {
+    if (message.statusText) {
+      $(document).trigger("error", "There was a problem loading the databases:" + message.statusText);
+    } else if (message) {
+      $(document).trigger("error", message);
+    } else {
+      $(document).trigger("error", "There was a problem loading the databases");
+    }
+  });
+};
+
+AssistHelper.prototype.setActiveDatabase = function (snippet, database) {
+  $.totalStorage("hue.assist.lastSelectedDb." + self.getTotalStorageUserPrefix(snippet), database);
+  self.activeDatabase(database);
+};
+
 AssistHelper.prototype.hasExpired = function (timestamp) {
   return (new Date()).getTime() - timestamp > TIME_TO_LIVE_IN_MILLIS;
 };
@@ -114,15 +155,6 @@ AssistHelper.prototype.fetchTerms = function(snippet, tableName, columnName, pre
   });
 };
 
-AssistHelper.prototype.fetchDatabases = function(snippet, successCallback, errorCallback) {
-  var self = this;
-  self.fetchAssistData(snippet, NOTEBOOK_API_PREFIX, function(data) {
-    // Blacklist of system databases
-    data.databases = $.grep(data.databases, function(database) { return database !== "_impala_builtins" });
-    successCallback(data);
-  }, errorCallback);
-};
-
 AssistHelper.prototype.fetchTables = function(snippet, successCallback, errorCallback) {
   var self = this;
   self.fetchAssistData(snippet, NOTEBOOK_API_PREFIX + self.activeDatabase(), successCallback, errorCallback);

+ 3 - 0
desktop/core/src/desktop/static/desktop/js/autocomplete.js

@@ -29,6 +29,9 @@ function Autocompleter(options) {
   self.snippet = options.snippet;
   self.notebook = options.notebook;
   self.assistHelper = options.assistHelper;
+  if (! self.assistHelper.loaded() && self.snippet.isSqlDialect()) {
+    self.assistHelper.load(self.snippet);
+  }
 }
 
 Autocompleter.prototype.setAssistHelper = function (assistHelper) {

+ 41 - 71
desktop/core/src/desktop/templates/ko_components.mako

@@ -190,11 +190,11 @@ from desktop.views import _ko
         </div>
       </li>
 
-      <li data-bind="visible: ! hasErrors() && ! loadingDatabases()" >
-        <select data-bind="options: availableDatabaseNames, select2: { width: '100%', placeholder: '${ _ko("Choose a database...") }', update: assistHelper.activeDatabase }" class="input-medium" data-placeholder="${_('Choose a database...')}"></select>
+      <li data-bind="visible: ! hasErrors() && ! assistHelper.loading()" >
+        <select data-bind="options: assistHelper.availableDatabases, select2: { width: '100%', placeholder: '${ _ko("Choose a database...") }', update: assistHelper.activeDatabase }" class="input-medium" data-placeholder="${_('Choose a database...')}"></select>
       </li>
 
-      <li class="center" data-bind="visible: loadingDatabases" >
+      <li class="center" data-bind="visible: assistHelper.loading()" >
         <!--[if !IE]><!--><i class="fa fa-spinner fa-spin" style="font-size: 20px; color: #BBB"></i><!--<![endif]-->
         <!--[if IE]><img src="${ static('desktop/art/spinner.gif') }"/><![endif]-->
       </li>
@@ -203,7 +203,7 @@ from desktop.views import _ko
         <span>${ _('The database list cannot be loaded.') }</span>
       </li>
 
-      <li class="nav-header" style="margin-top:10px;" data-bind="visible: ! loadingDatabases() && ! hasErrors()">
+      <li class="nav-header" style="margin-top:10px;" data-bind="visible: ! assistHelper.loading() && ! hasErrors()">
         ${_('tables')}
         <div class="pull-right" data-bind="visible: selectedDatabase() != null && selectedDatabase().hasEntries(), css: { 'hover-actions': ! filter(), 'blue': filter }">
           <a href="javascript:void(0)" data-bind="click: toggleSearch"><i class="pointer fa fa-search" title="${_('Search')}"></i></a>
@@ -635,10 +635,19 @@ from desktop.views import _ko
         self.sourceIndex = {};
         $.each(notebookViewModel.availableSnippets(), function (index, snippet) {
           var settings = notebookViewModel.getSnippetViewSettings(snippet.type());
-          var fakeSnippet = new Snippet(notebookViewModel, notebook, {
-            type: snippet.type(),
-            result: {}
-          });
+
+          var fakeSnippet = {
+            type: snippet.type,
+            getContext: function() {
+              return {
+                type: snippet.type()
+              }
+            },
+            getAssistHelper: function() {
+              return notebook.getAssistHelper(snippet.type());
+            }
+          };
+
           if (settings.sqlDialect) {
             self.sourceIndex[snippet.name()] = new AssistSource(fakeSnippet);
           }
@@ -650,7 +659,11 @@ from desktop.views import _ko
         self.selectedSource = ko.observable();
 
         self.selectedSourceType.subscribe(function (newSourceType) {
-          self.selectedSource(self.sourceIndex[newSourceType]);
+          var source = self.sourceIndex[newSourceType];
+          if (! source.assistHelper.loaded()) {
+            source.assistHelper.load(source.snippet);
+          }
+          self.selectedSource(source);
         });
 
         self.selectedSourceType(self.availableSourceTypes[0]);
@@ -671,8 +684,7 @@ from desktop.views import _ko
         });
 
         self.options = ko.mapping.fromJS($.extend({
-          isSearchVisible: false,
-          lastSelectedDb: null
+          isSearchVisible: false
         }, $.totalStorage(snippet.type() + ".assist.options") || {}));
 
         $.each(Object.keys(self.options), function (index, key) {
@@ -687,7 +699,6 @@ from desktop.views import _ko
         self.selectedDatabase = ko.observable();
 
         self.reloading = ko.observable(false);
-        self.loadingDatabases = ko.observable(true);
 
         self.loadingTables = ko.computed(function() {
           return typeof self.selectedDatabase() != "undefined" && self.selectedDatabase() !== null && self.selectedDatabase().loading();
@@ -699,30 +710,26 @@ from desktop.views import _ko
           }
         });
 
-        // We need the names because select2 does not support objects
-        self.availableDatabaseNames = ko.observableArray();
-
-        self.fetchDatabases(function() {
-          self.assistHelper.activeDatabase.subscribe(function(newValue) {
-            window.setTimeout(function() {
-              self.setDatabase(newValue);
-            }, 10);
-          });
+        var updateDatabases = function (names) {
+          self.databases($.map(names, function(name) {
+            return new AssistEntry({
+              name: name,
+              displayName: name,
+              title: name,
+              isDatabase: true
+            }, null, self, self.filter);
+          }));
 
-          if ($.inArray(self.assistHelper.activeDatabase(), self.availableDatabaseNames()) > -1) {
-            self.setDatabase(self.assistHelper.activeDatabase());
-            return;
-          }
-          if ($.inArray(self.options.lastSelectedDb(), self.availableDatabaseNames()) > -1) {
-            self.assistHelper.activeDatabase(self.options.lastSelectedDb());
-          } else if ($.inArray("default", self.availableDatabaseNames()) > -1) {
-            self.assistHelper.activeDatabase("default");
-          } else if (self.availableDatabaseNames().length > 0) {
-            self.assistHelper.activeDatabase(self.availableDatabaseNames()[0]);
-          }
+          self.setDatabase(self.assistHelper.activeDatabase());
+        };
 
+        self.assistHelper.activeDatabase.subscribe(function(newValue) {
+          self.setDatabase(newValue);
         });
 
+        updateDatabases(self.assistHelper.availableDatabases());
+        self.assistHelper.availableDatabases.subscribe(updateDatabases);
+
         self.modalItem = ko.observable();
         self.analysisStats = ko.observable();
 
@@ -765,7 +772,6 @@ from desktop.views import _ko
         if (name == null) {
           return;
         }
-        self.options.lastSelectedDb(name);
 
         self.selectedDatabase(ko.utils.arrayFirst(self.databases(), function(database) {
           return name === database.definition.name;
@@ -780,46 +786,10 @@ from desktop.views import _ko
       AssistSource.prototype.reloadAssist = function() {
         var self = this;
         self.reloading(true);
-        self.loadingDatabases(true);
         self.selectedDatabase(null);
         self.assistHelper.clearCache(self.snippet);
-        self.fetchDatabases(function() {
-          self.setDatabase(self.options.lastSelectedDb());
-        });
-      };
-
-      AssistSource.prototype.fetchDatabases = function(callback) {
-        var self = this;
-
-        self.assistHelper.fetchDatabases(self.snippet, function(data) {
-          self.databases($.map(data.databases, function(databaseName) {
-            return new AssistEntry({
-              name: databaseName,
-              displayName: databaseName,
-              title: databaseName,
-              isDatabase: true
-            }, null, self, self.filter);
-          }));
-          self.availableDatabaseNames(data.databases);
-
-          self.reloading(false);
-          self.loadingDatabases(false);
-          if (callback) {
-            callback();
-          }
-        }, function(message) {
-          if (message.statusText) {
-            $(document).trigger("error", "${ _('There was a problem loading the databases') }: " + message.statusText);
-          } else if (message) {
-            $(document).trigger("error", message);
-          } else {
-            $(document).trigger("error", "${ _('There was a problem loading the databases.') }");
-          }
-
-          self.loadingDatabases(false);
-          self.reloading(false);
-          self.hasErrors(true);
-        });
+        self.assistHelper.loaded(false);
+        self.assistHelper.load(self.snippet);
       };
 
       ko.components.register('assist-panel', {