瀏覽代碼

HUE-7359 [assist] Enable show in assist for documents in the global search results

Johan Ahlen 8 年之前
父節點
當前提交
51c269d

+ 1 - 0
desktop/core/src/desktop/api2.py

@@ -637,6 +637,7 @@ def search_entities_interactive(request):
           'doc_type': escape(e.type),
           'type': 'HUE',
           'uuid': e.uuid,
+          'parentUuid': e.parent_directory.uuid,
           'originalName': escape(e.name)
         } for e in entities['documents']
       ],

+ 25 - 1
desktop/core/src/desktop/static/desktop/js/document/hueFileEntry.js

@@ -86,6 +86,7 @@ var HueFileEntry = (function () {
     self.superuser = options.superuser;
     self.serverTypeFilter = options.serverTypeFilter || ko.observable({ type: 'all' });
     self.statsVisible = ko.observable(false);
+    self.highlight = ko.observable(false);
 
     self.document = ko.observable();
     self.selectedDocsWithDependents = ko.observable([]);
@@ -93,7 +94,6 @@ var HueFileEntry = (function () {
     self.showTable = ko.observable();
     self.entries = ko.observableArray([]);
 
-
     // Filter is only used in the assist panel at the moment
     self.isFilterVisible = ko.observable(false);
     self.filter = ko.observable('').extend({ rateLimit: 400 });
@@ -298,6 +298,30 @@ var HueFileEntry = (function () {
     }
   };
 
+  HueFileEntry.prototype.highlightInside = function (uuid) {
+    var self = this;
+    self.typeFilter(self.availableTypeFilters()[0]);
+    var foundEntry;
+    self.entries().forEach(function (entry) {
+      entry.highlight(false);
+      if (entry.definition() && entry.definition().uuid === uuid) {
+        foundEntry = entry;
+      }
+    });
+    if (foundEntry) {
+      window.setTimeout(function () {
+        huePubSub.subscribeOnce('assist.db.scrollToComplete', function () {
+          foundEntry.highlight(true);
+          // Timeout is for animation effect
+          window.setTimeout(function () {
+            foundEntry.highlight(false);
+          }, 1800);
+        });
+        huePubSub.publish('assist.db.scrollTo', foundEntry);
+      }, 0);
+    }
+  };
+
   HueFileEntry.prototype.showContextPopover = function (entry, event, positionAdjustment) {
     var self = this;
     var $source = $(event.target);

+ 56 - 3
desktop/core/src/desktop/templates/assist.mako

@@ -636,7 +636,7 @@ from notebook.conf import ENABLE_QUERY_BUILDER, ENABLE_QUERY_SCHEDULING, get_ord
              </div>
              <a href="javascript:void(0)" class="assist-entry assist-document-link" data-bind="click: open, attr: {'title': name }">
                <!-- ko template: { name: 'document-icon-template', data: { document: $data, showShareAddon: false } } --><!-- /ko -->
-               <span data-bind="draggableText: { text: definition().name, meta: {'type': 'document', 'definition': definition()} }, text: definition().name"></span>
+               <span class="highlightable" data-bind="css: { 'highlight': highlight }, draggableText: { text: definition().name, meta: {'type': 'document', 'definition': definition()} }, text: definition().name"></span>
              </a>
            </li>
          </ul>
@@ -1307,6 +1307,51 @@ from notebook.conf import ENABLE_QUERY_BUILDER, ENABLE_QUERY_SCHEDULING, get_ord
           huePubSub.publish('assist.clear.document.cache');
           self.reload();
         });
+
+        huePubSub.subscribe('assist.doc.highlight', function (details) {
+          huePubSub.publish('left.assist.show');
+          huePubSub.publish('assist.show.documents');
+          huePubSub.publish('context.popover.hide');
+          var whenLoaded = $.Deferred().done(function () {
+            self.activeEntry().highlightInside(details.docUuid);
+          });
+          if (self.activeEntry() && self.activeEntry().definition() && self.activeEntry().definition().uuid === details.parentUuid) {
+            if (self.activeEntry().loaded() && !self.activeEntry().hasErrors()) {
+              whenLoaded.resolve();
+            } else {
+              var loadedSub = self.activeEntry().loaded.subscribe(function (newVal) {
+                if (newVal) {
+                  if (!self.activeEntry().hasErrors()) {
+                    whenLoaded.resolve();
+                  }
+                  whenLoaded.reject();
+                  loadedSub.remove();
+                }
+              })
+            }
+            self.activeEntry().highlight(details.docUuid);
+          } else {
+            self.activeEntry(new HueFileEntry({
+              activeEntry: self.activeEntry,
+              trashEntry: ko.observable(),
+              apiHelper: self.apiHelper,
+              app: 'documents',
+              user: self.user,
+              activeSort: ko.observable('name'),
+              typeFilter: self.typeFilter,
+              definition: {
+                uuid: details.parentUuid,
+                type: 'directory'
+              }
+            }));
+            self.activeEntry().load(function() {
+              whenLoaded.resolve();
+            }, function () {
+              whenLoaded.reject();
+              self.fallbackToRoot();
+            });
+          }
+        });
       }
 
       AssistDocumentsPanel.prototype.fallbackToRoot = function () {
@@ -1884,7 +1929,7 @@ from notebook.conf import ENABLE_QUERY_BUILDER, ENABLE_QUERY_SCHEDULING, get_ord
                 }));
               }
 
-              panels.push(new AssistInnerPanel({
+              var documentsPanel = new AssistInnerPanel({
                 panelData: new AssistDocumentsPanel({
                   user: params.user,
                   apiHelper: self.apiHelper
@@ -1897,7 +1942,15 @@ from notebook.conf import ENABLE_QUERY_BUILDER, ENABLE_QUERY_SCHEDULING, get_ord
                 minHeight: 50,
                 rightAlignIcon: true,
                 visible: params.visibleAssistPanels && params.visibleAssistPanels.indexOf('documents') !== -1
-              }));
+              });
+
+              panels.push(documentsPanel);
+
+              huePubSub.subscribe('assist.show.documents', function () {
+                if (self.visiblePanel !== documentsPanel) {
+                  self.visiblePanel(documentsPanel);
+                }
+              });
 
               var vcsKeysLength = ${ len(VCS.keys()) };
               if (vcsKeysLength > 0) {

+ 41 - 14
desktop/core/src/desktop/templates/context_popover.mako

@@ -30,24 +30,24 @@ from metadata.conf import has_navigator
   <script type="text/html" id="context-popover-footer">
     <div class="context-popover-flex-bottom-links">
       <div class="context-popover-link-row">
-        <a class="inactive-action pointer" data-bind="visible: showInAssistEnabled && (isDatabase || isTable || isColumn), click: function() { huePubSub.publish('context.popover.show.in.assist') }">
+        <a class="inactive-action pointer" data-bind="visible: showInAssistEnabled, click: function() { huePubSub.publish('context.popover.show.in.assist') }">
           <i style="font-size: 11px;" title="${ _("Show in Assist...") }" class="fa fa-search"></i> ${ _("Assist") }
         </a>
         % if HAS_SQL_ENABLED.get():
-        <a class="inactive-action pointer" data-bind="visible: (typeof isTable !== 'undefined' && isTable) || (typeof isView !== 'undefined' && isView) || (typeof isDatabase !== 'undefined' && isDatabase), click: function() { huePubSub.publish('context.popover.open.in.dashboard') }">
+        <a class="inactive-action pointer" data-bind="visible: openInDashboardEnabled, click: function() { huePubSub.publish('context.popover.open.in.dashboard') }">
           <i style="font-size: 11px;" title="${ _("Open in Dashboard...") }" class="fa fa-external-link"></i> ${ _("Dashboard") }
         </a>
         % endif
-        <a class="inactive-action pointer" data-bind="visible: (typeof isTable !== 'undefined' && isTable) || (typeof isView !== 'undefined' && isView) || (typeof isDatabase !== 'undefined' && isDatabase), click: function() { huePubSub.publish('context.popover.open.in.metastore', isTable ? 'table' : 'db') }">
+        <a class="inactive-action pointer" data-bind="visible: openInTableBrowserEnabled, click: function() { huePubSub.publish('context.popover.open.in.metastore', isTable ? 'table' : 'db') }">
           <i style="font-size: 11px;" title="${ _("Open in Table Browser...") }" class="fa fa-external-link"></i> ${ _("Table Browser") }
         </a>
-        <a class="inactive-action pointer" data-bind="visible: typeof isHdfs !== 'undefined' && isHdfs, click: function() { huePubSub.publish('context.popover.replace.in.editor') }">
+        <a class="inactive-action pointer" data-bind="visible: replaceEditorContentEnabled, click: function() { huePubSub.publish('context.popover.replace.in.editor') }">
           <i style="font-size: 11px;" title="${ _("Replace the editor content...") }" class="fa fa-pencil"></i> ${ _("Insert in the editor") }
         </a>
-        <a class="inactive-action pointer" data-bind="visible: typeof isHdfs !== 'undefined' && isHdfs, click: function() { huePubSub.publish('context.popover.open.in.file.browser') }">
+        <a class="inactive-action pointer" data-bind="visible: openInFileBrowserEnabled, click: function() { huePubSub.publish('context.popover.open.in.file.browser') }">
           <i style="font-size: 11px;" title="${ _("Open in File Browser...") }" class="fa fa-external-link"></i> ${ _("File Browser") }
         </a>
-        <!-- ko if: typeof isAsterisk !== 'undefined' && isAsterisk -->
+        <!-- ko if: expandColumnsEnabled -->
         <!-- ko with: contents.data -->
         <!-- ko if: selectedColumns().length > 0 -->
         <a class="inactive-action pointer" data-bind="click: expand">${ _("Expand to selected columns") }</a>
@@ -285,7 +285,6 @@ from metadata.conf import has_navigator
     </div>
   </script>
 
-
   <script type="text/html" id="generic-document-context-template">
     <div style="width:100%; text-align: center; margin-top: 40px; font-size: 140px; color: #787878;" data-bind="template: { name: 'document-icon-template', data: { document: { isDirectory: type === 'directory', definition: function() { return $data } } } }"></div>
     <div style="width: 100%; margin-top: 20px; text-align:center">
@@ -372,7 +371,7 @@ from metadata.conf import has_navigator
       <!-- ko if: !loading() && !hasErrors() -->
       <!-- ko template: { name: template } --><!-- /ko -->
       <!-- /ko -->
-      <!-- ko template: { name: 'context-popover-footer' } --><!-- /ko -->
+      <!-- ko template: { name: 'context-popover-footer', data: $parent } --><!-- /ko -->
       <!-- /ko -->
       <!-- /ko -->
     </div>
@@ -1021,6 +1020,7 @@ from metadata.conf import has_navigator
 
       function DocumentContext(data) {
         var self = this;
+        self.disposals = [];
 
         // Adapt some details to a common format, the global search endpoint has different structure than the docs one
         self.details = {
@@ -1033,13 +1033,30 @@ from metadata.conf import has_navigator
         self.loading = ko.observable(true);
         self.hasErrors = ko.observable(false);
         self.errorText = ko.observable();
-        self.showInAssistEnabled = false; // TODO: Enable for documents
         self.template = 'context-document-details';
 
         self.documentContents = ko.observable();
         self.loadDocument();
+
+        var showInAssistPubSub = huePubSub.subscribe('context.popover.show.in.assist', function () {
+          huePubSub.publish('assist.doc.highlight', {
+            parentUuid: self.data.parentUuid,
+            docUuid: self.data.uuid
+          });
+        });
+
+        self.disposals.push(function () {
+          showInAssistPubSub.remove();
+        })
       }
 
+      DocumentContext.prototype.dispose = function () {
+        var self = this;
+        while (self.disposals.length) {
+          self.disposals.pop()();
+        }
+      };
+
       DocumentContext.prototype.loadDocument = function () {
         var self = this;
         self.hasErrors(false);
@@ -1209,8 +1226,6 @@ from metadata.conf import has_navigator
         self.left = ko.observable(0);
         self.top = ko.observable(0);
 
-        self.showInAssistEnabled = typeof params.showInAssistEnabled !== 'undefined' ? params.showInAssistEnabled : true;
-
         var popoverSize = apiHelper.getFromTotalStorage('assist', 'popover.size', {
           width: 450,
           height: 400
@@ -1305,6 +1320,13 @@ from metadata.conf import has_navigator
         self.isView = params.data.type === 'view';
         self.isDocument = params.data.type.toLowerCase() === 'hue';
 
+        self.showInAssistEnabled = (typeof params.showInAssistEnabled !== 'undefined' ? params.showInAssistEnabled : true) && (self.isDocument || self.isDatabase || self.isTable || self.isColumn);
+        self.openInDashboardEnabled = self.isTable || self.isView || self.isDatabase;
+        self.openInTableBrowserEnabled = self.isTable || self.isView || self.isDatabase;
+        self.replaceEditorContentEnabled = self.isHdfs;
+        self.openInFileBrowserEnabled = self.isHdfs;
+        self.expandColumnsEnabled = self.isAsterisk;
+
         if ((self.isColumn || self.isComplex) && self.data.tables && self.data.tables.length > 0) {
           var identifierChain = self.data.identifierChain;
           var foundTable = $.grep(self.data.tables, function (table) {
@@ -1504,20 +1526,25 @@ from metadata.conf import has_navigator
 
         self.disposals = [];
 
-        self.showInAssistEnabled = true;
-
         self.isDatabase = params.data.type.toLowerCase() === 'database';
         self.isTable = params.data.type.toLowerCase() === 'table';
         self.isColumn = params.data.type.toLowerCase() === 'field';
         self.isView = params.data.type.toLowerCase() === 'view';
         self.isDocument = params.data.type.toLowerCase() === 'hue';
 
-        // TODO: Handle HDFS, Complex and Function ?
+        // These are currently not in the global search results
         self.isHdfs = false;
         self.isAsterisk = false;
         self.isComplex = false;
         self.isFunction = false;
 
+        self.showInAssistEnabled = true;
+        self.openInDashboardEnabled = self.isTable || self.isView || self.isDatabase;
+        self.openInTableBrowserEnabled = self.isTable || self.isView || self.isDatabase;
+        self.replaceEditorContentEnabled = self.isHdfs;
+        self.openInFileBrowserEnabled = self.isHdfs;
+        self.expandColumnsEnabled = self.isAsterisk;
+
         var adaptedData = { identifierChain: [] };
 
         var path = params.data.originalName.split('.');