superset-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From h...@apache.org
Subject [incubator-superset] branch master updated: Hotkeys in Explore View (#6526)
Date Mon, 21 Jan 2019 10:10:57 GMT
This is an automated email from the ASF dual-hosted git repository.

hugh 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 d628907  Hotkeys in Explore View (#6526)
d628907 is described below

commit d628907be3c5fcea8497ea67309ddbf62678c539
Author: Hugh A. Miles II <hughmil3s@gmail.com>
AuthorDate: Mon Jan 21 02:10:46 2019 -0800

    Hotkeys in Explore View (#6526)
    
    * working .... hotkeys in example of hotkeys in explore
    
    * added save functionality
    
    * Added proper overwrite functions
    
    * cleanup
    
    * cleanup
    
    * cleanu
    
    * fixe linting
    
    * add global
    
    * move match to utils
    
    * linting
    
    * change some stuff
    
    * Delete example_filter_immune_slice_fields.json
    
    * hide annoying blue bar
    
    * switch hotkeys to reference s
    
    * remove console.log
    
    * have hotkey generate help
    
    * 🚢
    
    * move functions out of component
    
    * refactor
    
    * Delete yarn.lock
    
    * addressed comments
    
    * remove comments
    
    * remove Hotkeys component from ChartView
    
    * Add hotkeys button next to save&run
    
    * moved keyboard
    
    * cleanup
    
    * checkout package.json
    
    * checkout chart panel
    
    * reference apache
    
    * remove style change
    
    * whitespace
    
    * clean up on hotkey popup
    
    * fds
    
    * linting
    
    * fix all linting errors
---
 superset/assets/src/components/Hotkeys.jsx         |  4 +-
 .../explore/components/ExploreViewContainer.jsx    | 79 ++++++++++++++++++----
 2 files changed, 67 insertions(+), 16 deletions(-)

diff --git a/superset/assets/src/components/Hotkeys.jsx b/superset/assets/src/components/Hotkeys.jsx
index 8936eed..36e7d57 100644
--- a/superset/assets/src/components/Hotkeys.jsx
+++ b/superset/assets/src/components/Hotkeys.jsx
@@ -28,6 +28,7 @@ const propTypes = {
     func: PropTypes.func.isRequired,
   })).isRequired,
   header: PropTypes.string,
+  placement: PropTypes.string,
 };
 
 const defaultProps = {
@@ -42,7 +43,6 @@ export default class Hotkeys extends React.PureComponent {
   }
   renderPopover() {
     const { header, hotkeys } = this.props;
-
     return (
       <Popover id="hotkey-popover" title={header} style={{ width: '300px' }}>
         <table className="table table-condensed">
@@ -68,7 +68,7 @@ export default class Hotkeys extends React.PureComponent {
       <OverlayTrigger
         overlay={this.renderPopover()}
         trigger={['hover', 'focus']}
-        placement="top"
+        placement={this.props.placement || 'top'}
       >
         <i className="fa fa-keyboard-o fa-lg" />
       </OverlayTrigger>
diff --git a/superset/assets/src/explore/components/ExploreViewContainer.jsx b/superset/assets/src/explore/components/ExploreViewContainer.jsx
index b2081c3..2548005 100644
--- a/superset/assets/src/explore/components/ExploreViewContainer.jsx
+++ b/superset/assets/src/explore/components/ExploreViewContainer.jsx
@@ -35,6 +35,25 @@ import * as saveModalActions from '../actions/saveModalActions';
 import * as chartActions from '../../chart/chartAction';
 import { fetchDatasourceMetadata } from '../../dashboard/actions/datasources';
 import { Logger, ActionLog, EXPLORE_EVENT_NAMES, LOG_ACTIONS_MOUNT_EXPLORER } from '../../logger';
+import Hotkeys from '../../components/Hotkeys';
+
+// Prolly need to move this to a global context
+const keymap = {
+    RUN: 'ctrl + r, ctrl + enter',
+    SAVE: 'ctrl + s',
+};
+
+const getHotKeys = () => {
+  const d = [];
+  Object.keys(keymap).forEach((k) => {
+    d.push({
+      name: k,
+      descr: keymap[k],
+      key: k,
+    });
+  });
+  return d;
+};
 
 const propTypes = {
   actions: PropTypes.object.isRequired,
@@ -75,11 +94,13 @@ class ExploreViewContainer extends React.Component {
     this.onStop = this.onStop.bind(this);
     this.onQuery = this.onQuery.bind(this);
     this.toggleModal = this.toggleModal.bind(this);
+    this.handleKeydown = this.handleKeydown.bind(this);
   }
 
   componentDidMount() {
     window.addEventListener('resize', this.handleResize);
     window.addEventListener('popstate', this.handlePopstate);
+    document.addEventListener('keydown', this.handleKeydown);
     this.addHistory({ isReplace: true });
     Logger.append(LOG_ACTIONS_MOUNT_EXPLORER);
   }
@@ -129,6 +150,7 @@ class ExploreViewContainer extends React.Component {
   componentWillUnmount() {
     window.removeEventListener('resize', this.handleResize);
     window.removeEventListener('popstate', this.handlePopstate);
+    document.removeEventListener('keydown', this.handleKeydown);
   }
 
   onQuery() {
@@ -158,6 +180,29 @@ class ExploreViewContainer extends React.Component {
     return `${window.innerHeight - navHeight}px`;
   }
 
+  handleKeydown(event) {
+    const controlOrCommand = event.ctrlKey || event.metaKey;
+    if (controlOrCommand) {
+      const isEnter = event.key === 'Enter' || event.keyCode === 13;
+      const isS = event.key === 's' || event.keyCode === 83;
+      if (isEnter) {
+        this.onQuery();
+      } else if (isS) {
+        if (this.props.slice) {
+            this.props.actions.saveSlice(this.props.form_data, {
+              action: 'overwrite',
+              slice_id: this.props.slice.slice_id,
+              slice_name: this.props.slice.slice_name,
+              add_to_dash: 'noSave',
+              goto_dash: false,
+            }).then(({ data }) => {
+              window.location = data.slice.slice_url;
+            });
+          }
+        }
+      }
+  }
+
   findChangedControlKeys(prevControls, currentControls) {
     return Object.keys(currentControls).filter(
       key =>
@@ -273,10 +318,7 @@ class ExploreViewContainer extends React.Component {
       <div
         id="explore-container"
         className="container-fluid"
-        style={{
-          height: this.state.height,
-          overflow: 'hidden',
-        }}
+        style={{ height: this.state.height, overflow: 'hidden' }}
       >
         {this.state.showModal && (
           <SaveModal
@@ -287,16 +329,25 @@ class ExploreViewContainer extends React.Component {
         )}
         <div className="row">
           <div className="col-sm-4">
-            <QueryAndSaveBtns
-              canAdd="True"
-              onQuery={this.onQuery}
-              onSave={this.toggleModal}
-              onStop={this.onStop}
-              loading={this.props.chart.chartStatus === 'loading'}
-              chartIsStale={this.state.chartIsStale}
-              errorMessage={this.renderErrorMessage()}
-              datasourceType={this.props.datasource_type}
-            />
+            <div style={{ display: 'flex', flexDirection: 'row', alignItems: 'center',
justifyContent: 'space-between' }}>
+              <QueryAndSaveBtns
+                canAdd="True"
+                onQuery={this.onQuery}
+                onSave={this.toggleModal}
+                onStop={this.onStop}
+                loading={this.props.chart.chartStatus === 'loading'}
+                chartIsStale={this.state.chartIsStale}
+                errorMessage={this.renderErrorMessage()}
+                datasourceType={this.props.datasource_type}
+              />
+              <div>
+                <Hotkeys
+                  header="Keyboard shortcuts"
+                  hotkeys={getHotKeys()}
+                  placement="right"
+                />
+              </div>
+            </div>
             <br />
             <ControlPanelsContainer
               actions={this.props.actions}


Mime
View raw message