Ver código fonte

[editor] Add expand/collapse actions for editor area and bottom tabs

Johan Ahlen 4 anos atrás
pai
commit
a6afc3bc3b

+ 26 - 1
desktop/core/src/desktop/js/apps/editor/EditorViewModel.js

@@ -113,7 +113,32 @@ export default class EditorViewModel {
         this.selectedNotebook().snippets().length === 1 &&
         this.selectedNotebook().snippets()[0].isSqlDialect()
     );
-    this.isResultFullScreenMode = ko.observable(false);
+
+    this.bottomExpanded = ko.observable(false);
+    this.topExpanded = ko.observable(false);
+
+    this.bottomExpanded.subscribe(newVal => {
+      if (newVal) {
+        if (this.topExpanded()) {
+          this.topExpanded(false);
+        }
+        huePubSub.publish('both.assists.hide', true);
+      } else {
+        huePubSub.publish('both.assists.revert', true);
+      }
+    });
+
+    this.topExpanded.subscribe(newVal => {
+      if (newVal) {
+        if (this.bottomExpanded()) {
+          this.bottomExpanded(false);
+        }
+        huePubSub.publish('left.assist.hide', true);
+      } else {
+        huePubSub.publish('both.assists.revert', true);
+      }
+    });
+
     this.isPresentationMode = ko.pureComputed(
       () => this.selectedNotebook() && this.selectedNotebook().isPresentationMode()
     );

+ 6 - 11
desktop/core/src/desktop/js/apps/editor/app.js

@@ -324,25 +324,20 @@ huePubSub.subscribe('app.dom.loaded', app => {
       huePubSub.publish('selected.notebook.changed', newVal);
     });
 
-    let wasResultFullScreenMode = false;
+    let wasBottomExpanded = false;
     let isAssistAvailable = viewModel.assistAvailable();
     let wasLeftPanelVisible = viewModel.isLeftPanelVisible();
     let wasRightPanelVisible = viewModel.isRightPanelVisible();
 
     const exitPlayerMode = () => {
-      if (!wasResultFullScreenMode) {
+      if (!wasBottomExpanded) {
         viewModel.selectedNotebook().isPresentationMode(false);
       } else {
-        viewModel.isResultFullScreenMode(false);
+        viewModel.bottomExpanded(false);
       }
-      wasResultFullScreenMode = false;
+      wasBottomExpanded = false;
     };
 
-    viewModel.isResultFullScreenMode.subscribe(newValue => {
-      wasResultFullScreenMode = newValue;
-      huePubSub.publish('editor.presentation.operate.toggle', newValue);
-    });
-
     viewModel.isLeftPanelVisible.subscribe(value => {
       huePubSub.publish(REDRAW_FIXED_HEADERS_EVENT);
     });
@@ -583,7 +578,7 @@ huePubSub.subscribe('app.dom.loaded', app => {
           wasLeftPanelVisible = viewModel.isLeftPanelVisible();
           wasRightPanelVisible = viewModel.isRightPanelVisible();
 
-          if (wasResultFullScreenMode) {
+          if (wasBottomExpanded) {
             huePubSub.publish('both.assists.hide', true);
           } else {
             huePubSub.publish('right.assist.hide', true);
@@ -610,7 +605,7 @@ huePubSub.subscribe('app.dom.loaded', app => {
           $(window).bind('keydown', 'esc', exitPlayerMode);
         } else {
           huePubSub.publish(HIDE_FIXED_HEADERS_EVENT);
-          huePubSub.publish('both.assists.show', true);
+          huePubSub.publish('both.assists.revert', true);
           viewModel.assistWithoutStorage(true);
           viewModel.isLeftPanelVisible(wasLeftPanelVisible);
           viewModel.isRightPanelVisible(wasRightPanelVisible);

+ 5 - 5
desktop/core/src/desktop/js/apps/editor/components/result/ResultTable.vue

@@ -41,7 +41,7 @@
     <div v-else-if="isStreaming">
       <h1 class="empty">{{ I18n('Waiting for streaming data...') }}</h1>
     </div>
-    <div v-else-if="!rows.length && !executable.result">
+    <div v-else-if="!rows.length && (!executable || !executable.result)">
       <h1 class="empty">{{ I18n('Select and execute a query to see the result.') }}</h1>
     </div>
   </div>
@@ -106,7 +106,7 @@
 
     get hasEmptyResult(): boolean {
       return (
-        this.rows.length === 0 &&
+        !this.rows.length &&
         this.hasResultSet &&
         this.status === ExecutionStatus.available &&
         this.fetchedOnce
@@ -115,7 +115,7 @@
 
     get hasEmptySuccessResult(): boolean {
       return (
-        this.rows.length === 0 &&
+        !this.rows.length &&
         !this.hasResultSet &&
         this.status === ExecutionStatus.available &&
         this.fetchedOnce
@@ -127,11 +127,11 @@
     }
 
     get isExpired(): boolean {
-      return this.status === ExecutionStatus.expired && this.rows.length > 0;
+      return this.status === ExecutionStatus.expired && !this.rows.length;
     }
 
     get isStreaming(): boolean {
-      return this.streaming && this.rows.length === 0 && this.status !== ExecutionStatus.running;
+      return this.streaming && !this.rows.length && this.status !== ExecutionStatus.running;
     }
 
     get tableColumns(): Column<ResultRow>[] {

+ 1 - 1
desktop/core/src/desktop/js/apps/editor/components/result/ResultTableKoBridge.vue

@@ -17,7 +17,7 @@
 -->
 
 <template>
-  <ResultTable :executable="executable" />
+  <ResultTable :executable="executable" :show-maximize="true" />
 </template>
 
 <script lang="ts">

+ 4 - 4
desktop/core/src/desktop/js/apps/editor/components/resultChart/ko.resultChart.js

@@ -135,11 +135,11 @@ const TEMPLATE = `
     </button>
   </div>
   <div class="btn-group pull-right">
-    <button class="btn btn-editor btn-mini disable-feedback" data-bind="toggle: isResultFullScreenMode">
-      <!-- ko if: isResultFullScreenMode -->
+    <button class="btn btn-editor btn-mini disable-feedback" data-bind="toggle: bottomExpanded">
+      <!-- ko if: bottomExpanded -->
       <i class="fa fa-compress"></i> ${ I18n('Collapse') }
       <!-- /ko -->
-      <!-- ko ifnot: isResultFullScreenMode -->
+      <!-- ko ifnot: bottomExpanded -->
       <i class="fa fa-expand"></i> ${ I18n('Expand') }
       <!-- /ko -->
     </button>
@@ -526,7 +526,7 @@ class ResultChart extends DisposableComponent {
 
     this.editorMode = params.editorMode;
     this.isPresentationMode = params.isPresentationMode;
-    this.isResultFullScreenMode = params.isResultFullScreenMode;
+    this.bottomExpanded = params.bottomExpanded;
     this.resultsKlass = params.resultsKlass;
     this.id = params.id; // TODO: Get rid of
 

+ 1 - 1
desktop/core/src/desktop/js/apps/editor/components/resultGrid/ko.resultGrid.js

@@ -199,7 +199,7 @@ class ResultGrid extends DisposableComponent {
     this.element = element;
     this.activeExecutable = params.activeExecutable;
 
-    this.isResultFullScreenMode = params.isResultFullScreenMode;
+    this.bottomExpanded = params.bottomExpanded;
     this.notebookMode = params.notebookMode;
     this.hasMore = params.hasMore;
     this.fetchResult = params.fetchResult;

+ 1 - 1
desktop/core/src/desktop/js/apps/notebook/app.js

@@ -1043,7 +1043,7 @@ huePubSub.subscribe('app.dom.loaded', app => {
           $(window).bind('keydown', 'esc', exitPlayerMode);
         } else {
           hideFixedHeaders();
-          huePubSub.publish('both.assists.show', true);
+          huePubSub.publish('both.assists.revert', true);
           viewModel.assistWithoutStorage(true);
           viewModel.isLeftPanelVisible(wasLeftPanelVisible);
           viewModel.isRightPanelVisible(wasRightPanelVisible);

+ 38 - 25
desktop/core/src/desktop/js/sidePanelViewModel.js

@@ -22,6 +22,7 @@ import huePubSub from 'utils/huePubSub';
 import { ACTIVE_SNIPPET_CONNECTOR_CHANGED_EVENT } from 'apps/editor/events';
 import { SHOW_LEFT_ASSIST_EVENT, SHOW_RIGHT_ASSIST_EVENT } from 'ko/components/assist/events';
 import { getFromLocalStorage, setInLocalStorage } from 'utils/storageUtils';
+import { defer } from './utils/hueUtils';
 
 class SidePanelViewModel {
   constructor() {
@@ -110,36 +111,48 @@ class SidePanelViewModel {
 
     huePubSub.publish('get.current.app.view.model');
 
-    let previousVisibilityValues = {};
-    huePubSub.subscribe('both.assists.hide', withoutStorage => {
-      previousVisibilityValues = {
-        left: self.leftAssistVisible(),
-        right: self.rightAssistVisible()
-      };
-      self.assistWithoutStorage(withoutStorage);
-      self.leftAssistVisible(false);
-      self.rightAssistVisible(false);
-      window.setTimeout(() => {
+    const previousVisibilityValues = {
+      left: undefined,
+      right: undefined
+    };
+
+    const hideAssists = (left, right, preventStorage) => {
+      previousVisibilityValues.left = undefined;
+      previousVisibilityValues.right = undefined;
+      self.assistWithoutStorage(preventStorage);
+      if (left) {
+        previousVisibilityValues.left = self.leftAssistVisible();
+        self.leftAssistVisible(false);
+      }
+      if (right) {
+        previousVisibilityValues.right = self.rightAssistVisible();
+        self.rightAssistVisible(false);
+      }
+      defer(() => {
         self.assistWithoutStorage(false);
-      }, 0);
+      });
+    };
+
+    huePubSub.subscribe('both.assists.hide', preventStorage => {
+      hideAssists(true, true, preventStorage);
     });
 
-    huePubSub.subscribe('both.assists.show', withoutStorage => {
-      self.assistWithoutStorage(withoutStorage);
-      self.leftAssistVisible(previousVisibilityValues.left);
-      self.rightAssistVisible(previousVisibilityValues.right);
-      window.setTimeout(() => {
-        self.assistWithoutStorage(false);
-      }, 0);
+    huePubSub.subscribe('right.assist.hide', preventStorage => {
+      hideAssists(false, true, preventStorage);
     });
 
-    huePubSub.subscribe('right.assist.hide', withoutStorage => {
-      previousVisibilityValues = {
-        left: self.leftAssistVisible(),
-        right: self.rightAssistVisible()
-      };
-      self.assistWithoutStorage(withoutStorage);
-      self.rightAssistVisible(false);
+    huePubSub.subscribe('left.assist.hide', preventStorage => {
+      hideAssists(true, false, preventStorage);
+    });
+
+    huePubSub.subscribe('both.assists.revert', preventStorage => {
+      self.assistWithoutStorage(preventStorage);
+      if (typeof previousVisibilityValues.left !== 'undefined') {
+        self.leftAssistVisible(previousVisibilityValues.left);
+      }
+      if (typeof previousVisibilityValues.right !== 'undefined' && self.rightAssistAvailable()) {
+        self.rightAssistVisible(previousVisibilityValues.right);
+      }
       window.setTimeout(() => {
         self.assistWithoutStorage(false);
       }, 0);

+ 21 - 0
desktop/core/src/desktop/static/desktop/less/hue-mixins.less

@@ -74,6 +74,27 @@
   transition: @value 0.2s ease;
 }
 
+.icon-only-button {
+  color: @cui-gray-600;
+  background-color: transparent;
+  border: none;
+  cursor: pointer;
+  display: inline;
+  margin: 0;
+  padding: 2px 6px;
+  font-size: 15px;
+
+  &:hover {
+    color: @hue-primary-color-dark;
+  }
+
+  &:hover,
+  &:focus {
+    text-decoration: none;
+    outline: none;
+  }
+}
+
 .hue-box-shadow-top {
   .hue-box-shadow(0, -2px);
 }

Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
desktop/libs/notebook/src/notebook/static/notebook/css/editor2.css


+ 49 - 0
desktop/libs/notebook/src/notebook/static/notebook/less/editor2.less

@@ -49,6 +49,10 @@
           > * {
             margin-left: 10px;
           }
+
+          button {
+            .icon-only-button;
+          }
         }
       }
 
@@ -94,11 +98,25 @@
 
       .editor-bottom-tabs {
         .flexRowLayoutRow(0 0 38px);
+
+        li.editor-bottom-tab-actions {
+          .hue-ease-transition(opacity);
+
+          float: right;
+          padding: 6px;
+          opacity: 0;
+
+          button {
+            .icon-only-button;
+          }
+        }
       }
 
       .editor-bottom-tab-content {
         .flexRowLayoutRow(0 1 100%);
 
+        overflow: hidden;
+
         .tab-pane {
           .fillAbsolute();
 
@@ -190,6 +208,7 @@
               }
             }
           }
+
           .execution-results-tab-panel {
             .fillAbsolute();
 
@@ -206,11 +225,41 @@
           }
         }
       }
+
+      &:hover {
+        .editor-bottom-tabs li.editor-bottom-tab-actions {
+          opacity: 1;
+        }
+      }
+    }
+  }
+
+  &.editor-top-expanded {
+    .editor-app .editor-top {
+      .flex-basis(100%);
+    }
+
+    .editor-nav-bar,
+    .editor-app .editor-divider,
+    .editor-app .editor-bottom {
+      display: none;
     }
   }
 
+  &.editor-bottom-expanded {
+    .editor-nav-bar,
+    .editor-app .editor-top,
+    .editor-app .editor-divider {
+      display: none;
+    }
+
+    .editor-app .editor-bottom {
+      .flex-basis(100%);
+    }
+  }
 
 
+  // TODO: Clean-out below
 
 
   .snippet-move-placeholder {

+ 15 - 13
desktop/libs/notebook/src/notebook/templates/editor2.mako

@@ -214,7 +214,7 @@
 </script>
 
 <script type="text/html" id="editor-optimizer-alerts">
-  <!-- ko if: window.HAS_OPTIMIZER && (dialect() == 'impala' || dialect() == 'hive') && ! $root.isPresentationMode() && ! $root.isResultFullScreenMode() -->
+  <!-- ko if: window.HAS_OPTIMIZER && (dialect() == 'impala' || dialect() == 'hive') && ! $root.isPresentationMode() -->
   <div class="optimizer-container" data-bind="css: { 'active': showOptimizer }">
     <!-- ko if: hasSuggestion() -->
     <!-- ko with: suggestion() -->
@@ -795,7 +795,7 @@
 </script>
 
 <script type="text/html" id="editor-navbar">
-  <div class="navbar hue-title-bar" data-bind="visible: ! $root.isPresentationMode() && ! $root.isResultFullScreenMode()">
+  <div class="navbar hue-title-bar" data-bind="visible: ! $root.isPresentationMode()">
     <div class="navbar-inner">
       <div class="container-fluid">
         <!-- ko template: { name: 'editor-menu-buttons' } --><!-- /ko -->
@@ -881,12 +881,6 @@
     </div>
   </div>
 
-  <!-- ko if: $root.isResultFullScreenMode() -->
-  <a class="hueAnchor collapse-results" href="javascript:void(0)" title="${ _('Collapse results') }" data-bind="click: function(){ $root.isResultFullScreenMode(false); }">
-    <i class="fa fa-times fa-fw"></i>
-  </a>
-  <!-- /ko -->
-
   <!-- ko if: $root.isPresentationMode() -->
   <a class="hueAnchor collapse-results" href="javascript:void(0)" title="${ _('Exit presentation') }" data-bind="click: function(){ $root.selectedNotebook().isPresentationMode(false); }">
     <i class="fa fa-times fa-fw"></i>
@@ -916,21 +910,24 @@
   </div>
 </script>
 
-<div id="editorComponents" class="editor">
+<div id="editorComponents" class="editor" data-bind="css: { 'editor-bottom-expanded': bottomExpanded, 'editor-top-expanded': topExpanded }">
   <!-- ko template: { name: 'editor-modals' } --><!-- /ko -->
   <div class="editor-nav-bar">
     <!-- ko template: { name: 'editor-navbar' } --><!-- /ko -->
   </div>
-  <div class="editor-app"  data-bind="with: firstSnippet">
+  <div class="editor-app" data-bind="with: firstSnippet">
     <div class="editor-top">
       <div class="editor-top-actions">
         <!-- ko template: { name: 'editor-query-redacted' } --><!-- /ko -->
         <!-- ko template: { name: 'editor-longer-operation' } --><!-- /ko -->
         <div class="editor-top-right-actions">
           <!-- ko template: { name: 'snippet-header-database-selection' } --><!-- /ko -->
-          <a href="javascript: void(0);" title="${ _('Show editor help') }" data-toggle="modal" data-target="#editorHelpModal">
+          <button title="${ _('Show editor help') }" data-toggle="modal" data-target="#editorHelpModal">
             <i class="fa fa-question"></i>
-          </a>
+          </button>
+          <button title="${ _('Expand editor') }" data-bind="toggle: $root.topExpanded">
+            <i class="fa" data-bind="css: { 'fa-expand': !$root.topExpanded(), 'fa-compress': $root.topExpanded() }"></i>
+          </button>
         </div>
       </div>
       <div class="editor-settings-drawer">
@@ -992,6 +989,12 @@
         <!-- ko if: HAS_WORKLOAD_ANALYTICS && dialect() === 'impala' -->
         <li data-bind="visible: showExecutionAnalysis, click: function(){ currentQueryTab('executionAnalysis'); }, css: {'active': currentQueryTab() == 'executionAnalysis'}"><a class="inactive-action" href="#executionAnalysis" data-toggle="tab" data-bind="click: function(){ $('a[href=\'#executionAnalysis\']').tab('show'); }, event: {'shown': fetchExecutionAnalysis }"><span>${_('Execution Analysis')} </span><span></span></a></li>
         <!-- /ko -->
+
+        <li class="editor-bottom-tab-actions">
+          <button data-bind="toggle: $root.bottomExpanded">
+            <i class="fa" data-bind="css: { 'fa-expand': !$root.bottomExpanded(), 'fa-compress': $root.bottomExpanded() }"></i>
+          </button>
+        </li>
       </ul>
       <div class="editor-bottom-tab-content tab-content">
         <div class="tab-pane" id="queryHistory" data-bind="css: { 'active': currentQueryTab() === 'queryHistory' }">
@@ -1036,7 +1039,6 @@
               editorMode: parentVm.editorMode,
               id: id,
               isPresentationMode: parentNotebook.isPresentationMode,
-              isResultFullScreenMode: parentVm.isResultFullScreenMode,
               resultsKlass: resultsKlass
             }} --><!-- /ko -->
           </div>

Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff