You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by gr...@apache.org on 2019/05/30 17:37:37 UTC

[incubator-superset] branch master updated: Fix SQL Lab window resizing layout bug (#7615)

This is an automated email from the ASF dual-hosted git repository.

graceguo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git


The following commit(s) were added to refs/heads/master by this push:
     new 145d72c  Fix SQL Lab window resizing layout bug (#7615)
145d72c is described below

commit 145d72c52b0dbb44e1d77a2562cfe68fc9a7b3b7
Author: Erik Ritter <er...@gmail.com>
AuthorDate: Thu May 30 10:37:24 2019 -0700

    Fix SQL Lab window resizing layout bug (#7615)
---
 .../spec/javascripts/sqllab/SqlEditor_spec.jsx     | 38 +++++++++++++++-
 .../assets/src/SqlLab/components/SqlEditor.jsx     | 50 ++++++++++++++++------
 .../src/SqlLab/components/SqlEditorLeftBar.jsx     |  3 +-
 superset/assets/src/SqlLab/constants.js            |  5 +++
 4 files changed, 80 insertions(+), 16 deletions(-)

diff --git a/superset/assets/spec/javascripts/sqllab/SqlEditor_spec.jsx b/superset/assets/spec/javascripts/sqllab/SqlEditor_spec.jsx
index 046b2e6..17bb4d8 100644
--- a/superset/assets/spec/javascripts/sqllab/SqlEditor_spec.jsx
+++ b/superset/assets/spec/javascripts/sqllab/SqlEditor_spec.jsx
@@ -20,10 +20,19 @@ import React from 'react';
 import { shallow } from 'enzyme';
 
 import { defaultQueryEditor, initialState, queries, table } from './fixtures';
+import {
+  SQL_EDITOR_GUTTER_HEIGHT,
+  SQL_EDITOR_GUTTER_MARGIN,
+  SQL_TOOLBAR_HEIGHT,
+} from '../../../src/SqlLab/constants';
+import AceEditorWrapper from '../../../src/SqlLab/components/AceEditorWrapper';
 import LimitControl from '../../../src/SqlLab/components/LimitControl';
+import SouthPane from '../../../src/SqlLab/components/SouthPane';
 import SqlEditor from '../../../src/SqlLab/components/SqlEditor';
 import SqlEditorLeftBar from '../../../src/SqlLab/components/SqlEditorLeftBar';
 
+const MOCKED_SQL_EDITOR_HEIGHT = 500;
+
 describe('SqlEditor', () => {
   const mockedProps = {
     actions: {},
@@ -40,7 +49,7 @@ describe('SqlEditor', () => {
   };
 
   beforeAll(() => {
-    jest.spyOn(SqlEditor.prototype, 'getSqlEditorHeight').mockImplementation(() => 500);
+    jest.spyOn(SqlEditor.prototype, 'getSqlEditorHeight').mockImplementation(() => MOCKED_SQL_EDITOR_HEIGHT);
   });
 
   it('is valid', () => {
@@ -52,6 +61,33 @@ describe('SqlEditor', () => {
     const wrapper = shallow(<SqlEditor {...mockedProps} />);
     expect(wrapper.find(SqlEditorLeftBar)).toHaveLength(1);
   });
+  it('render an AceEditorWrapper', () => {
+    const wrapper = shallow(<SqlEditor {...mockedProps} />);
+    expect(wrapper.find(AceEditorWrapper)).toHaveLength(1);
+  });
+  it('render an SouthPane', () => {
+    const wrapper = shallow(<SqlEditor {...mockedProps} />);
+    expect(wrapper.find(SouthPane)).toHaveLength(1);
+  });
+  it('does not overflow the editor window', () => {
+    const wrapper = shallow(<SqlEditor {...mockedProps} />);
+    const totalSize = parseFloat(wrapper.find(AceEditorWrapper).props().height)
+      + wrapper.find(SouthPane).props().height
+      + SQL_TOOLBAR_HEIGHT
+      + (SQL_EDITOR_GUTTER_MARGIN * 2)
+      + SQL_EDITOR_GUTTER_HEIGHT;
+    expect(totalSize).toEqual(MOCKED_SQL_EDITOR_HEIGHT);
+  });
+  it('does not overflow the editor window after resizing', () => {
+    const wrapper = shallow(<SqlEditor {...mockedProps} />);
+    wrapper.setState({ height: 450 });
+    const totalSize = parseFloat(wrapper.find(AceEditorWrapper).props().height)
+      + wrapper.find(SouthPane).props().height
+      + SQL_TOOLBAR_HEIGHT
+      + (SQL_EDITOR_GUTTER_MARGIN * 2)
+      + SQL_EDITOR_GUTTER_HEIGHT;
+    expect(totalSize).toEqual(450);
+  });
   it('render a LimitControl with default limit', () => {
     const defaultQueryLimit = 101;
     const updatedProps = { ...mockedProps, defaultQueryLimit };
diff --git a/superset/assets/src/SqlLab/components/SqlEditor.jsx b/superset/assets/src/SqlLab/components/SqlEditor.jsx
index a4aabb7..84e5106 100644
--- a/superset/assets/src/SqlLab/components/SqlEditor.jsx
+++ b/superset/assets/src/SqlLab/components/SqlEditor.jsx
@@ -31,6 +31,7 @@ import {
 import Split from 'react-split';
 import { t } from '@superset-ui/translation';
 import debounce from 'lodash/debounce';
+import throttle from 'lodash/throttle';
 
 import Button from '../../components/Button';
 import LimitControl from './LimitControl';
@@ -43,17 +44,20 @@ import Timer from '../../components/Timer';
 import Hotkeys from '../../components/Hotkeys';
 import SqlEditorLeftBar from './SqlEditorLeftBar';
 import AceEditorWrapper from './AceEditorWrapper';
-import { STATE_BSSTYLE_MAP } from '../constants';
+import {
+  STATE_BSSTYLE_MAP,
+  SQL_EDITOR_GUTTER_HEIGHT,
+  SQL_EDITOR_GUTTER_MARGIN,
+  SQL_TOOLBAR_HEIGHT,
+} from '../constants';
 import RunQueryActionButton from './RunQueryActionButton';
 import { FeatureFlag, isFeatureEnabled } from '../../featureFlags';
 
 const SQL_EDITOR_PADDING = 10;
-const SQL_TOOLBAR_HEIGHT = 51;
-const GUTTER_HEIGHT = 5;
-const GUTTER_MARGIN = 3;
 const INITIAL_NORTH_PERCENT = 30;
 const INITIAL_SOUTH_PERCENT = 70;
 const VALIDATION_DEBOUNCE_MS = 600;
+const WINDOW_RESIZE_THROTTLE_MS = 100;
 
 const propTypes = {
   actions: PropTypes.object.isRequired,
@@ -83,6 +87,8 @@ class SqlEditor extends React.PureComponent {
     this.state = {
       autorun: props.queryEditor.autorun,
       ctas: '',
+      northPercent: INITIAL_NORTH_PERCENT,
+      southPercent: INITIAL_SOUTH_PERCENT,
       sql: props.queryEditor.sql,
     };
     this.sqlEditorRef = React.createRef();
@@ -103,6 +109,10 @@ class SqlEditor extends React.PureComponent {
       this.requestValidation.bind(this),
       VALIDATION_DEBOUNCE_MS,
     );
+    this.handleWindowResize = throttle(
+      this.handleWindowResize.bind(this),
+      WINDOW_RESIZE_THROTTLE_MS,
+    );
   }
   componentWillMount() {
     if (this.state.autorun) {
@@ -116,6 +126,11 @@ class SqlEditor extends React.PureComponent {
     // the south pane so it gets rendered properly
     // eslint-disable-next-line react/no-did-mount-set-state
     this.setState({ height: this.getSqlEditorHeight() });
+
+    window.addEventListener('resize', this.handleWindowResize);
+  }
+  componentWillUnmount() {
+    window.removeEventListener('resize', this.handleWindowResize);
   }
   onResizeStart() {
     // Set the heights on the ace editor and the ace content area after drag starts
@@ -124,8 +139,7 @@ class SqlEditor extends React.PureComponent {
     document.getElementsByClassName('ace_content')[0].style.height = '100%';
   }
   onResizeEnd([northPercent, southPercent]) {
-    this.setState(this.getAceEditorAndSouthPaneHeights(
-      this.state.height, northPercent, southPercent));
+    this.setState({ northPercent, southPercent });
 
     if (this.northPaneRef.current && this.northPaneRef.current.clientHeight) {
       this.props.actions.persistEditorHeight(this.props.queryEditor,
@@ -149,9 +163,11 @@ class SqlEditor extends React.PureComponent {
   // given the height of the sql editor, north pane percent and south pane percent.
   getAceEditorAndSouthPaneHeights(height, northPercent, southPercent) {
     return {
-      aceEditorHeight: height * northPercent / 100 - (GUTTER_HEIGHT / 2 + GUTTER_MARGIN)
+      aceEditorHeight: height * northPercent / 100
+        - (SQL_EDITOR_GUTTER_HEIGHT / 2 + SQL_EDITOR_GUTTER_MARGIN)
         - SQL_TOOLBAR_HEIGHT,
-      southPaneHeight: height * southPercent / 100 - (GUTTER_HEIGHT / 2 + GUTTER_MARGIN),
+      southPaneHeight: height * southPercent / 100
+        - (SQL_EDITOR_GUTTER_HEIGHT / 2 + SQL_EDITOR_GUTTER_MARGIN),
     };
   }
   getHotkeyConfig() {
@@ -194,9 +210,12 @@ class SqlEditor extends React.PureComponent {
   setQueryLimit(queryLimit) {
     this.props.actions.queryEditorSetQueryLimit(this.props.queryEditor, queryLimit);
   }
+  handleWindowResize() {
+    this.setState({ height: this.getSqlEditorHeight() });
+  }
   elementStyle(dimension, elementSize, gutterSize) {
     return {
-      [dimension]: `calc(${elementSize}% - ${gutterSize + GUTTER_MARGIN}px)`,
+      [dimension]: `calc(${elementSize}% - ${gutterSize + SQL_EDITOR_GUTTER_MARGIN}px)`,
     };
   }
   requestValidation() {
@@ -257,15 +276,18 @@ class SqlEditor extends React.PureComponent {
   queryPane() {
     const hotkeys = this.getHotkeyConfig();
     const { aceEditorHeight, southPaneHeight } = this.getAceEditorAndSouthPaneHeights(
-      this.state.height, INITIAL_NORTH_PERCENT, INITIAL_SOUTH_PERCENT);
+      this.state.height,
+      this.state.northPercent,
+      this.state.southPercent,
+    );
     return (
       <Split
         className="queryPane"
-        sizes={[INITIAL_NORTH_PERCENT, INITIAL_SOUTH_PERCENT]}
+        sizes={[this.state.northPercent, this.state.southPercent]}
         elementStyle={this.elementStyle}
         minSize={200}
         direction="vertical"
-        gutterSize={GUTTER_HEIGHT}
+        gutterSize={SQL_EDITOR_GUTTER_HEIGHT}
         onDragStart={this.onResizeStart}
         onDragEnd={this.onResizeEnd}
       >
@@ -277,7 +299,7 @@ class SqlEditor extends React.PureComponent {
             queryEditor={this.props.queryEditor}
             sql={this.props.queryEditor.sql}
             tables={this.props.tables}
-            height={`${this.state.aceEditorHeight || aceEditorHeight}px`}
+            height={`${aceEditorHeight}px`}
             hotkeys={hotkeys}
           />
           {this.renderEditorBottomBar(hotkeys)}
@@ -286,7 +308,7 @@ class SqlEditor extends React.PureComponent {
           editorQueries={this.props.editorQueries}
           dataPreviewQueries={this.props.dataPreviewQueries}
           actions={this.props.actions}
-          height={this.state.southPaneHeight || southPaneHeight}
+          height={southPaneHeight}
         />
       </Split>
     );
diff --git a/superset/assets/src/SqlLab/components/SqlEditorLeftBar.jsx b/superset/assets/src/SqlLab/components/SqlEditorLeftBar.jsx
index 43ea487..f389641 100644
--- a/superset/assets/src/SqlLab/components/SqlEditorLeftBar.jsx
+++ b/superset/assets/src/SqlLab/components/SqlEditorLeftBar.jsx
@@ -33,9 +33,10 @@ const propTypes = {
 };
 
 const defaultProps = {
-  tables: [],
   actions: {},
+  height: 500,
   offline: false,
+  tables: [],
 };
 
 export default class SqlEditorLeftBar extends React.PureComponent {
diff --git a/superset/assets/src/SqlLab/constants.js b/superset/assets/src/SqlLab/constants.js
index 3bf8ce0..4dd2118 100644
--- a/superset/assets/src/SqlLab/constants.js
+++ b/superset/assets/src/SqlLab/constants.js
@@ -43,3 +43,8 @@ export const TIME_OPTIONS = [
   '90 days ago',
   '1 year ago',
 ];
+
+// SqlEditor layout constants
+export const SQL_EDITOR_GUTTER_HEIGHT = 5;
+export const SQL_EDITOR_GUTTER_MARGIN = 3;
+export const SQL_TOOLBAR_HEIGHT = 51;