Browse Source

HUE-8330 [editor] Fix namespace and compute selection and update the assist when changed in the editor

Johan Ahlen 7 years ago
parent
commit
4eb8c72094

+ 104 - 88
desktop/libs/notebook/src/notebook/static/notebook/js/notebook.ko.js

@@ -356,52 +356,15 @@ var EditorViewModel = (function() {
       return ApiHelper.getInstance(vm);
       return ApiHelper.getInstance(vm);
     };
     };
 
 
+    self.loadingNamespaces = ko.observable(true);
     self.namespaceRefreshEnabled = ko.observable(false);
     self.namespaceRefreshEnabled = ko.observable(false);
     self.availableNamespaces = ko.observableArray();
     self.availableNamespaces = ko.observableArray();
     self.namespace = ko.observable();
     self.namespace = ko.observable();
-    self.availableComputes = ko.observableArray();/*ko.pureComputed(function () {
-      if (self.namespace()) {
-        return self.namespace().computes;
-      }
-      return [];
-    });*/
-
-    self.compute = ko.observable();
-    self.compute.subscribe(function(newCompute) {
-      $.each(self.availableNamespaces(), function(index, namespace) {
-        if (namespace.name == newCompute.namespace) {
-          self.namespace(namespace);
-          return;
-        }
-      });
-    });
-
-    var computesPromise = ContextCatalog.getComputes({ sourceType: self.type() }).done(function (computes) {
-      self.availableComputes(computes);
-      if (!snippet.compute || !computes.some(function (compute) {
-        if (compute.id === snippet.compute.id) {
-          self.compute(compute);
-          return true;
-        }
-      })) {
-        self.compute(computes[0]);
-      }
-    });
-    /*
-    self.availableComputes.subscribe(function (newComputes) {
-      if (!self.compute() || !newComputes.some(function (newCompute) {
-        if (newCompute.id === self.compute().id) {
-          self.compute(newCompute);
-          return true;
-        }
-      })) {
-        self.compute(newComputes.length ? newComputes[0] : undefined);
-      }
-    });*/
 
 
-    var namespacesPromise;
+    self.lastNamespacePromise = undefined;
     self.reloadNamespaces = function () {
     self.reloadNamespaces = function () {
-      namespacesPromise = ContextCatalog.getNamespaces({ sourceType: self.type() }).done(function (context) {
+      self.loadingNamespaces(true);
+      self.lastNamespacePromise = ContextCatalog.getNamespaces({ sourceType: self.type() }).done(function (context) {
         self.namespaceRefreshEnabled(context.dynamic);
         self.namespaceRefreshEnabled(context.dynamic);
         self.availableNamespaces(context.namespaces);
         self.availableNamespaces(context.namespaces);
         if (!snippet.namespace || !context.namespaces.some(function (namespace) {
         if (!snippet.namespace || !context.namespaces.some(function (namespace) {
@@ -410,32 +373,32 @@ var EditorViewModel = (function() {
             return true;
             return true;
           }})) {
           }})) {
           self.namespace(context.namespaces[0]);
           self.namespace(context.namespaces[0]);
-/*
-          var previousComputeId;
-          var newCompute;
-          if (self.compute()) {
-            previousComputeId = self.compute().id;
-          } else if (snippet.compute) {
-            previousComputeId = snippet.compute.id;
-          }
-          if (previousComputeId) {
-            self.namespace().computes.some(function (compute) {
-              if (compute.id === previousComputeId) {
-                newCompute = compute;
-                return true;
-              }
-            })
-          }
-          if (!newCompute && self.namespace().computes.length) {
-            newCompute = self.namespace().computes[0];
-          }
-          self.compute(newCompute);*/
         }
         }
+      }).always(function () {
+        self.loadingNamespaces(false);
       });
       });
     };
     };
-
     self.reloadNamespaces();
     self.reloadNamespaces();
 
 
+    self.loadingComputes = ko.observable(true);
+    self.availableComputes = ko.observableArray();
+    self.compute = ko.observable();
+
+    self.lastComputesPromise = ContextCatalog.getComputes({ sourceType: self.type() }).done(function (computes) {
+      self.availableComputes(computes);
+      if (!snippet.compute || !computes.some(function (compute) {
+        if (compute.id === snippet.compute.id) {
+          self.compute(compute);
+          return true;
+        }
+      })) {
+        self.compute(computes[0]);
+      }
+    }).always(function () {
+      self.loadingComputes(false);
+    });
+
+    self.loadingDatabases = ko.observable(false);
     self.database = ko.observable();
     self.database = ko.observable();
     var previousDatabase = null;
     var previousDatabase = null;
 
 
@@ -448,44 +411,97 @@ var EditorViewModel = (function() {
         previousDatabase = newValue;
         previousDatabase = newValue;
       }
       }
     });
     });
-    self.database(typeof snippet.database != "undefined" && snippet.database != null ? snippet.database : null);
+    self.database(typeof snippet.database !== "undefined" && snippet.database != null ? snippet.database : null);
     self.availableDatabases = ko.observableArray();
     self.availableDatabases = ko.observableArray();
 
 
-    self.availableDatabases.subscribe(function (newDatabases) {
-      if (self.database() && newDatabases.indexOf(self.database()) === -1) {
-        if (newDatabases.length === 0 || newDatabases.indexOf('default') !== -1) {
-          self.database('default');
-        } else {
-          self.database(newDatabases[0])
-        }
-      }
-    });
-
+    var updateDatabaseThrottle = -1;
     self.updateDatabases = function () {
     self.updateDatabases = function () {
       if (self.isSqlDialect()) {
       if (self.isSqlDialect()) {
-        namespacesPromise.done(function () {
-          DataCatalog.getEntry({ sourceType: self.type(), namespace: self.namespace(), compute: self.compute(), path: [], definition: { type: 'source' }}).done(function (sourceEntry) {
-            sourceEntry.getChildren({ silenceErrors: true }).done(function (databaseEntries) {
-              var databaseNames = [];
-              databaseEntries.forEach(function (databaseEntry) {
-                databaseNames.push(databaseEntry.name);
+        self.loadingDatabases(true);
+        $.when(self.lastNamespacePromise, self.lastComputesPromise).done(function () {
+          window.clearTimeout(updateDatabaseThrottle);
+          updateDatabaseThrottle = window.setTimeout(function () {
+            DataCatalog.getEntry({
+              sourceType: self.type(),
+              namespace: self.namespace(),
+              compute: self.compute(),
+              path: [],
+              definition: {type: 'source'}
+            }).done(function (sourceEntry) {
+              sourceEntry.getChildren({silenceErrors: true}).done(function (databaseEntries) {
+                var databaseNames = [];
+                databaseEntries.forEach(function (databaseEntry) {
+                  databaseNames.push(databaseEntry.name);
+                });
+                self.availableDatabases(databaseNames);
+              }).fail(function () {
+                self.availableDatabases([]);
+              }).always(function () {
+                if (self.database() && self.availableDatabases().indexOf(self.database()) === -1) {
+                  if (self.availableDatabases().length === 0 || self.availableDatabases().indexOf('default') !== -1) {
+                    self.database('default');
+                  } else {
+                    self.database(self.availableDatabases()[0])
+                  }
+                }
+                self.loadingDatabases(false);
+
+                huePubSub.publish('assist.set.database', {
+                  source: self.type(),
+                  namespace: self.namespace(),
+                  name: self.database()
+                });
               });
               });
-              self.availableDatabases(databaseNames);
-            }).fail(function () {
-              self.availableDatabases([]);
             });
             });
-          });
+          }, 10);
         });
         });
       } else {
       } else {
         self.availableDatabases([]);
         self.availableDatabases([]);
+        self.database(undefined);
       }
       }
     };
     };
 
 
-    namespacesPromise.done(function () {
-      self.compute.subscribe(function () {
-        window.setTimeout(function () {
-          self.updateDatabases();
-        }, 0)
+    self.loadingContext = ko.pureComputed(function () {
+      return self.loadingNamespaces() || self.loadingComputes() || self.loadingDatabases();
+    });
+
+    $.when(self.lastNamespacePromise, self.lastComputesPromise).done(function () {
+      self.compute.subscribe(function (newCompute) {
+        // When the compute changes we set the corresponding namespace and update the databases
+        if (newCompute) {
+          var found = self.availableNamespaces().some(function (namespace) {
+            // TODO: Remove name check once compute.namespace is a namespace ID
+            if (namespace.name === newCompute.namespace || namespace.id === newCompute.namespace) {
+              if (!self.namespace() || self.namespace().id !== namespace.id) {
+                self.namespace(namespace);
+                self.updateDatabases();
+              }
+              return true;
+            }
+          });
+          if (!found) {
+            self.namespace(undefined);
+          }
+        }
+      });
+
+      self.namespace.subscribe(function (newNamespace) {
+        if (newNamespace) {
+          // When the namespace changes we set the corresponding compute and update the databases
+          var found = self.availableComputes().some(function (compute) {
+            // TODO: Remove name check once compute.namespace is a namespace ID
+            if (compute.namespace === newNamespace.name || compute.namespace === newNamespace.id) {
+              if (!self.compute() || self.compute().id !== compute.id) {
+                self.compute(compute);
+                self.updateDatabases();
+              }
+              return true;
+            }
+          });
+          if (!found) {
+            self.compute(undefined);
+          }
+        }
       })
       })
     });
     });
 
 

+ 13 - 2
desktop/libs/notebook/src/notebook/templates/editor_components.mako

@@ -941,6 +941,11 @@ ${ sqlSyntaxDropdown.sqlSyntaxDropdown() }
     <!-- ko template: { name: 'longer-operation${ suffix }' } --><!-- /ko -->
     <!-- ko template: { name: 'longer-operation${ suffix }' } --><!-- /ko -->
     <span class="execution-timer" data-bind="visible: type() != 'text' && status() != 'ready' && status() != 'loading', text: result.executionTime().toHHMMSS()" title="${ _('Execution time') }"></span>
     <span class="execution-timer" data-bind="visible: type() != 'text' && status() != 'ready' && status() != 'loading', text: result.executionTime().toHHMMSS()" title="${ _('Execution time') }"></span>
 
 
+    <!-- ko if: loadingContext() && isSqlDialect()  -->
+    <i class="fa fa-spinner fa-spin muted"></i>
+    <!-- /ko -->
+
+    <!-- ko if: !loadingContext() && isSqlDialect() -->
     <!-- ko if: availableComputes().length > 1 || namespaceRefreshEnabled() -->
     <!-- ko if: availableComputes().length > 1 || namespaceRefreshEnabled() -->
     <!-- ko if: availableComputes().length > 0-->
     <!-- ko if: availableComputes().length > 0-->
     <span class="editor-header-title">${ _('Compute') }</span>
     <span class="editor-header-title">${ _('Compute') }</span>
@@ -950,16 +955,22 @@ ${ sqlSyntaxDropdown.sqlSyntaxDropdown() }
     <span class="editor-header-title"><i class="fa fa-warning"></i> ${ _('No computes found') }</span>
     <span class="editor-header-title"><i class="fa fa-warning"></i> ${ _('No computes found') }</span>
     <!-- /ko -->
     <!-- /ko -->
     <!-- /ko -->
     <!-- /ko -->
+
     <!-- ko if: (availableNamespaces().length > 1 || namespaceRefreshEnabled()) -->
     <!-- ko if: (availableNamespaces().length > 1 || namespaceRefreshEnabled()) -->
     <span class="editor-header-title">${ _('Namespace') }</span>
     <span class="editor-header-title">${ _('Namespace') }</span>
     <div data-bind="component: { name: 'hue-drop-down', params: { value: namespace, entries: availableNamespaces, labelAttribute: 'name', searchable: true, linkTitle: '${ _ko('Active namespace') }' } }" style="display: inline-block"></div>
     <div data-bind="component: { name: 'hue-drop-down', params: { value: namespace, entries: availableNamespaces, labelAttribute: 'name', searchable: true, linkTitle: '${ _ko('Active namespace') }' } }" style="display: inline-block"></div>
     <!-- /ko -->
     <!-- /ko -->
-    <!-- ko if: availableDatabases().length > 0 && isSqlDialect() -->
+
+    <!-- ko if: availableDatabases().length > 0 -->
     <span class="editor-header-title">${ _('Database') }</span>
     <span class="editor-header-title">${ _('Database') }</span>
     <div data-bind="component: { name: 'hue-drop-down', params: { value: database, entries: availableDatabases, foreachVisible: true, searchable: true, linkTitle: '${ _ko('Active database') }' } }" style="display: inline-block"></div>
     <div data-bind="component: { name: 'hue-drop-down', params: { value: database, entries: availableDatabases, foreachVisible: true, searchable: true, linkTitle: '${ _ko('Active database') }' } }" style="display: inline-block"></div>
     <!-- /ko -->
     <!-- /ko -->
+    <!-- ko if: availableDatabases().length === 0-->
+    <span class="editor-header-title"><i class="fa fa-warning"></i> ${ _('No databases found') }</span>
+    <!-- /ko -->
 
 
-   <!-- ko template: { name: 'snippet-header-statement-type${ suffix }' } --><!-- /ko -->
+    <!-- /ko -->
+    <!-- ko template: { name: 'snippet-header-statement-type${ suffix }' } --><!-- /ko -->
 
 
     <a class="inactive-action margin-left-10" href="javascript:void(0)" data-bind="toggle: settingsVisible, visible: hasProperties, css: { 'blue' : settingsVisible }" title="${ _('Query settings') }"><i class="fa fa-cog"></i></a>
     <a class="inactive-action margin-left-10" href="javascript:void(0)" data-bind="toggle: settingsVisible, visible: hasProperties, css: { 'blue' : settingsVisible }" title="${ _('Query settings') }"><i class="fa fa-cog"></i></a>
     <a class="inactive-action margin-left-10 pointer" title="${ _('Show editor help') }" data-toggle="modal" data-target="#helpModal${ suffix }"><i class="fa fa-question"></i></a>
     <a class="inactive-action margin-left-10 pointer" title="${ _('Show editor help') }" data-toggle="modal" data-target="#helpModal${ suffix }"><i class="fa fa-question"></i></a>