Pārlūkot izejas kodu

HUE-4884 [editor] Make the context-popover pinnable

Johan Ahlen 9 gadi atpakaļ
vecāks
revīzija
dc22578e83

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

@@ -138,7 +138,7 @@
     });
   }
 
-  AssistDbEntry.prototype.showContextPopover = function (entry, event) {
+  AssistDbEntry.prototype.showContextPopover = function (entry, event, pinEnabled) {
     var $source = $(event.target);
     var offset = $source.offset();
     entry.statsVisible(true);
@@ -150,12 +150,13 @@
       orientation: 'right',
       sourceType: entry.sourceType,
       defaultDatabase: entry.databaseName,
+      pinEnabled: pinEnabled,
       source: {
         element: event.target,
         left: offset.left,
-        top: offset.top - 2,
+        top: offset.top - 3,
         right: offset.left + $source.width() + 1,
-        bottom: offset.top + $source.height() - 2
+        bottom: offset.top + $source.height() - 3
       }
     });
     huePubSub.subscribeOnce('sql.context.popover.hidden', function () {

+ 1 - 0
desktop/core/src/desktop/static/desktop/js/ko.hue-bindings.js

@@ -3003,6 +3003,7 @@
                 data: token.parseLocation,
                 sourceType: snippet.type(),
                 defaultDatabase: snippet.database(),
+                pinEnabled: true,
                 source: {
                   left: startCoordinates.pageX - 3,
                   top: startCoordinates.pageY,

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

@@ -419,7 +419,7 @@ from metadata.conf import has_navigator
 
   <script type="text/html" id="assist-entry-actions">
     <div class="assist-actions" data-bind="css: { 'table-actions' : definition.isTable || definition.isView, 'column-actions': definition.isColumn, 'database-actions' : definition.isDatabase } " style="opacity: 0">
-      <a class="inactive-action" href="javascript:void(0)" data-bind="visible: navigationSettings.showStats, click: showContextPopover, css: { 'blue': statsVisible }"><i class="fa fa-bar-chart" title="${_('Show details')}"></i></a>
+      <a class="inactive-action" href="javascript:void(0)" data-bind="visible: navigationSettings.showStats, click: function (data, event) { showContextPopover(data, event, navigationSettings.pinEnabled); }, css: { 'blue': statsVisible }"><i class="fa fa-bar-chart" title="${_('Show details')}"></i></a>
       <a class="inactive-action" href="javascript:void(0)" data-bind="visible: navigationSettings.openItem || (navigationSettings.openDatabase && definition.isDatabase), click: openItem"><i class="fa fa-long-arrow-right" title="${_('Open')}"></i></a>
     </div>
   </script>
@@ -427,7 +427,7 @@ from metadata.conf import has_navigator
   <script type="text/html" id="assist-table-entry">
     <li class="assist-table" data-bind="visibleOnHover: { override: statsVisible, selector: '.table-actions' }">
       <div class="assist-actions table-actions" style="opacity: 0">
-        <a class="inactive-action" href="javascript:void(0)" data-bind="visible: navigationSettings.showStats, click: showContextPopover, css: { 'blue': statsVisible }"><i class="fa fa-bar-chart" title="${_('Show details')}"></i></a>
+        <a class="inactive-action" href="javascript:void(0)" data-bind="visible: navigationSettings.showStats, click: function (data, event) { showContextPopover(data, event, navigationSettings.pinEnabled); }, css: { 'blue': statsVisible }"><i class="fa fa-bar-chart" title="${_('Show details')}"></i></a>
         <a class="inactive-action" href="javascript:void(0)" data-bind="visible: navigationSettings.openItem, click: openItem"><i class="fa fa-long-arrow-right" title="${_('Open')}"></i></a>
       </div>
       <a class="assist-entry assist-table-link" href="javascript:void(0)" data-bind="multiClick: { click: toggleOpen, dblClick: dblClick }, attr: {'title': definition.title }, draggableText: { text: editorText,  meta: {'type': 'sql', 'table': tableName, 'database': databaseName} }"><i class="fa fa-fw fa-table muted valign-middle"></i><span data-bind="text: definition.displayName, css: { 'highlight': highlight }"></span></a>
@@ -988,6 +988,7 @@ from metadata.conf import has_navigator
        * @param {Object} options.navigationSettings - enable/disable the links
        * @param {boolean} options.navigationSettings.openItem
        * @param {boolean} options.navigationSettings.showStats
+       * @param {boolean} options.navigationSettings.pinEnabled
        * @constructor
        **/
       function AssistDbPanel (options) {

+ 42 - 25
desktop/core/src/desktop/templates/sql_context_popover.mako

@@ -16,9 +16,10 @@
 
 <%!
 from desktop import conf
+from desktop.conf import USE_NEW_SIDE_PANELS
 from desktop.lib.i18n import smart_unicode
-from django.utils.translation import ugettext as _
 from desktop.views import _ko
+from django.utils.translation import ugettext as _
 from metadata.conf import has_navigator
 %>
 
@@ -402,36 +403,42 @@ from metadata.conf import has_navigator
       <div class="sql-context-popover-title">
         <i class="pull-left fa muted" data-bind="css: iconClass" style="margin-top: 3px"></i> <span data-bind="text: title"></span>
         <a class="pull-right pointer inactive-action" data-bind="click: close"><i class="fa fa-fw fa-times"></i></a>
+        <a class="pull-right pointer inactive-action" data-bind="visible: pinEnabled, click: pin"><i class="fa fa-fw fa-thumb-tack"></i></a>
       </div>
-      <div class="sql-context-popover-content">
-        <!-- ko with: contents -->
-          <ul class="nav nav-pills sql-context-tabs" data-bind="foreach: tabs">
-            <li data-bind="click: function () { $parent.activeTab(id); }, css: { 'active' : $parent.activeTab() === id }">
-              <a class="sql-context-tab" data-toggle="tab" data-bind="text: label, attr: { href: '#' + id }"></a>
-            </li>
-          </ul>
-          <div class="sql-context-tab-container" data-bind="foreach: tabs">
-            <div class="tab-pane" id="sampleTab" data-bind="visible : $parent.activeTab() === id, attr: { id: id }, css: { 'active' : $parent.activeTab() === id }" style="height: 100%; overflow: hidden; display: none;">
-              <div class="sql-context-flex">
-                <!-- ko with: templateData -->
-                <div class="sql-context-flex-fill" data-bind="visible: loading"><!-- ko hueSpinner: { spin: loading, center: true, size: 'large' } --><!-- /ko --></div>
-                <!-- ko if: ! loading() && hasErrors() -->
-                <div class="sql-context-flex-fill">
-                  <div class="alert" data-bind="text: $parent.errorText"></div>
-                </div>
-                <!-- /ko -->
-                <!-- ko if: ! loading() && ! hasErrors() -->
-                <!-- ko template: { name: $parent.template } --><!-- /ko -->
-                <!-- /ko -->
-                <!-- /ko -->
-                <!-- ko template: { name: 'sql-context-footer', data: $parents[1] } --><!-- /ko -->
-              </div>
+      <!-- ko template: 'sql-context-contents' --><!-- /ko -->
+    </div>
+  </script>
+
+  <script type="text/html" id="sql-context-contents">
+    <div class="sql-context-popover-content">
+      <!-- ko with: contents -->
+      <ul class="nav nav-pills sql-context-tabs" data-bind="foreach: tabs">
+        <li data-bind="click: function () { $parent.activeTab(id); }, css: { 'active' : $parent.activeTab() === id }">
+          <a class="sql-context-tab" data-toggle="tab" data-bind="text: label, attr: { href: '#' + id }"></a>
+        </li>
+      </ul>
+      <div class="sql-context-tab-container" data-bind="foreach: tabs">
+        <div class="tab-pane" id="sampleTab" data-bind="visible : $parent.activeTab() === id, attr: { id: id }, css: { 'active' : $parent.activeTab() === id }" style="height: 100%; overflow: hidden; display: none;">
+          <div class="sql-context-flex">
+            <!-- ko with: templateData -->
+            <div class="sql-context-flex-fill" data-bind="visible: loading"><!-- ko hueSpinner: { spin: loading, center: true, size: 'large' } --><!-- /ko --></div>
+            <!-- ko if: ! loading() && hasErrors() -->
+            <div class="sql-context-flex-fill">
+              <div class="alert" data-bind="text: $parent.errorText"></div>
             </div>
+            <!-- /ko -->
+            <!-- ko if: ! loading() && ! hasErrors() -->
+            <!-- ko template: { name: $parent.template } --><!-- /ko -->
+            <!-- /ko -->
+            <!-- /ko -->
+            <!-- ko template: { name: 'sql-context-footer', data: $parents[1] } --><!-- /ko -->
           </div>
-        <!-- /ko -->
+        </div>
       </div>
+      <!-- /ko -->
     </div>
   </script>
+
   <script type="text/javascript" charset="utf-8">
     (function (factory) {
       if(typeof require === "function") {
@@ -873,6 +880,10 @@ from metadata.conf import has_navigator
         self.sourceType = params.sourceType;
         self.defaultDatabase = params.defaultDatabase;
         self.close = hidePopover;
+        self.pinEnabled = false;
+        % if USE_NEW_SIDE_PANELS.get():
+          self.pinEnabled = params.pinEnabled || false;
+        % endif
         var orientation = params.orientation || 'bottom';
         self.contents = null;
         self.resizeHelper = new ResizeHelper(orientation, self.leftAdjust, self.topAdjust);
@@ -961,6 +972,12 @@ from metadata.conf import has_navigator
         self.orientationClass = 'sql-context-popover-' + orientation;
       }
 
+      SqlContextPopoverViewModel.prototype.pin = function () {
+        var self = this;
+        huePubSub.publish('sql.context.pin', self);
+        hidePopover();
+      };
+
       SqlContextPopoverViewModel.prototype.dispose = function () {
         hidePopover();
       };

+ 15 - 0
desktop/libs/notebook/src/notebook/static/notebook/js/notebook.ko.js

@@ -301,6 +301,21 @@
     // History is currently in Notebook, same with saved queries by snippets, might be better in assist
     self.currentQueryTab = ko.observable(typeof snippet.currentQueryTab != "undefined" && snippet.currentQueryTab != null ? snippet.currentQueryTab : 'queryHistory');
 
+    self.pinnedContextTabs = ko.observableArray(typeof snippet.pinnedContextTabs != "undefined" && snippet.pinnedContextTabs != null ? snippet.pinnedContextTabs : []);
+
+    huePubSub.subscribe('sql.context.pin', function (contextData) {
+      contextData.tabId = 'context' + self.pinnedContextTabs().length;
+      self.pinnedContextTabs.push(contextData);
+      self.currentQueryTab(contextData.tabId);
+    });
+
+    self.removeContextTab = function (context) {
+      if (context.tabId === self.currentQueryTab()) {
+        self.currentQueryTab('queryHistory');
+      }
+      self.pinnedContextTabs.remove(context);
+    };
+
     self.errorLoadingQueries = ko.observable(false);
     self.loadingQueries = ko.observable(false);
 

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

@@ -979,7 +979,8 @@ ${ hueIcons.symbols() }
             navigationSettings: {
               openDatabase: false,
               openItem: false,
-              showStats: true
+              showStats: true,
+              pinEnabled: true
             },
           },
           visibleAssistPanels: editorMode() ? ['sql'] : []
@@ -1258,6 +1259,14 @@ ${ hueIcons.symbols() }
         <!-- ko if: result.explanation().length > 0 -->
         <li data-bind="click: function(){ currentQueryTab('queryExplain'); }, css: {'active': currentQueryTab() == 'queryExplain'}"><a class="inactive-action" href="#queryExplain" data-toggle="tab">${_('Explain')}</a></li>
         <!-- /ko -->
+        <!-- ko foreach: pinnedContextTabs -->
+        <li data-bind="click: function() { $parent.currentQueryTab(tabId) }, css: { 'active': $parent.currentQueryTab() === tabId }">
+          <a class="inactive-action" data-toggle="tab" data-bind="attr: { 'href': '#' + tabId }">
+            <i class="snippet-icon fa" data-bind="css: iconClass"></i> <span data-bind="text: title"></span>
+            <div class="inline-block inactive-action margin-left-10 pointer" data-bind="click: function () { $parent.removeContextTab($data); }"><i class="snippet-icon fa fa-times"></i></div>
+          </a>
+        </li>
+        <!-- /ko -->
       </ul>
       <div class="tab-content" style="border: none">
         <div class="tab-pane" id="queryHistory" data-bind="css: {'active': currentQueryTab() == 'queryHistory'}">
@@ -1380,8 +1389,13 @@ ${ hueIcons.symbols() }
           <!-- ko template: { name: 'snippet-explain' } --><!-- /ko -->
         </div>
         <!-- /ko -->
-      </div>
 
+        <!-- ko foreach: pinnedContextTabs -->
+        <div class="tab-pane" style="height: 300px; position: relative; overflow: hidden;" data-bind="attr: { 'id': tabId }, css: {'active': $parent.currentQueryTab() === tabId }">
+          <div style="display: flex; flex-direction: column; margin-top: 10px; overflow: hidden; height: 100%; position: relative;" data-bind="template: 'sql-context-contents'"></div>
+        </div>
+        <!-- /ko -->
+      </div>
     </div>
   </div>
 </script>