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
This commit is contained in:
Hugh A. Miles II 2019-01-21 02:10:46 -08:00 committed by GitHub
parent 88283dc2cb
commit d628907be3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 67 additions and 16 deletions

View File

@ -28,6 +28,7 @@ const propTypes = {
func: PropTypes.func.isRequired, func: PropTypes.func.isRequired,
})).isRequired, })).isRequired,
header: PropTypes.string, header: PropTypes.string,
placement: PropTypes.string,
}; };
const defaultProps = { const defaultProps = {
@ -42,7 +43,6 @@ export default class Hotkeys extends React.PureComponent {
} }
renderPopover() { renderPopover() {
const { header, hotkeys } = this.props; const { header, hotkeys } = this.props;
return ( return (
<Popover id="hotkey-popover" title={header} style={{ width: '300px' }}> <Popover id="hotkey-popover" title={header} style={{ width: '300px' }}>
<table className="table table-condensed"> <table className="table table-condensed">
@ -68,7 +68,7 @@ export default class Hotkeys extends React.PureComponent {
<OverlayTrigger <OverlayTrigger
overlay={this.renderPopover()} overlay={this.renderPopover()}
trigger={['hover', 'focus']} trigger={['hover', 'focus']}
placement="top" placement={this.props.placement || 'top'}
> >
<i className="fa fa-keyboard-o fa-lg" /> <i className="fa fa-keyboard-o fa-lg" />
</OverlayTrigger> </OverlayTrigger>

View File

@ -35,6 +35,25 @@ import * as saveModalActions from '../actions/saveModalActions';
import * as chartActions from '../../chart/chartAction'; import * as chartActions from '../../chart/chartAction';
import { fetchDatasourceMetadata } from '../../dashboard/actions/datasources'; import { fetchDatasourceMetadata } from '../../dashboard/actions/datasources';
import { Logger, ActionLog, EXPLORE_EVENT_NAMES, LOG_ACTIONS_MOUNT_EXPLORER } from '../../logger'; 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 = { const propTypes = {
actions: PropTypes.object.isRequired, actions: PropTypes.object.isRequired,
@ -75,11 +94,13 @@ class ExploreViewContainer extends React.Component {
this.onStop = this.onStop.bind(this); this.onStop = this.onStop.bind(this);
this.onQuery = this.onQuery.bind(this); this.onQuery = this.onQuery.bind(this);
this.toggleModal = this.toggleModal.bind(this); this.toggleModal = this.toggleModal.bind(this);
this.handleKeydown = this.handleKeydown.bind(this);
} }
componentDidMount() { componentDidMount() {
window.addEventListener('resize', this.handleResize); window.addEventListener('resize', this.handleResize);
window.addEventListener('popstate', this.handlePopstate); window.addEventListener('popstate', this.handlePopstate);
document.addEventListener('keydown', this.handleKeydown);
this.addHistory({ isReplace: true }); this.addHistory({ isReplace: true });
Logger.append(LOG_ACTIONS_MOUNT_EXPLORER); Logger.append(LOG_ACTIONS_MOUNT_EXPLORER);
} }
@ -129,6 +150,7 @@ class ExploreViewContainer extends React.Component {
componentWillUnmount() { componentWillUnmount() {
window.removeEventListener('resize', this.handleResize); window.removeEventListener('resize', this.handleResize);
window.removeEventListener('popstate', this.handlePopstate); window.removeEventListener('popstate', this.handlePopstate);
document.removeEventListener('keydown', this.handleKeydown);
} }
onQuery() { onQuery() {
@ -158,6 +180,29 @@ class ExploreViewContainer extends React.Component {
return `${window.innerHeight - navHeight}px`; 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) { findChangedControlKeys(prevControls, currentControls) {
return Object.keys(currentControls).filter( return Object.keys(currentControls).filter(
key => key =>
@ -273,10 +318,7 @@ class ExploreViewContainer extends React.Component {
<div <div
id="explore-container" id="explore-container"
className="container-fluid" className="container-fluid"
style={{ style={{ height: this.state.height, overflow: 'hidden' }}
height: this.state.height,
overflow: 'hidden',
}}
> >
{this.state.showModal && ( {this.state.showModal && (
<SaveModal <SaveModal
@ -287,16 +329,25 @@ class ExploreViewContainer extends React.Component {
)} )}
<div className="row"> <div className="row">
<div className="col-sm-4"> <div className="col-sm-4">
<QueryAndSaveBtns <div style={{ display: 'flex', flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between' }}>
canAdd="True" <QueryAndSaveBtns
onQuery={this.onQuery} canAdd="True"
onSave={this.toggleModal} onQuery={this.onQuery}
onStop={this.onStop} onSave={this.toggleModal}
loading={this.props.chart.chartStatus === 'loading'} onStop={this.onStop}
chartIsStale={this.state.chartIsStale} loading={this.props.chart.chartStatus === 'loading'}
errorMessage={this.renderErrorMessage()} chartIsStale={this.state.chartIsStale}
datasourceType={this.props.datasource_type} errorMessage={this.renderErrorMessage()}
/> datasourceType={this.props.datasource_type}
/>
<div>
<Hotkeys
header="Keyboard shortcuts"
hotkeys={getHotKeys()}
placement="right"
/>
</div>
</div>
<br /> <br />
<ControlPanelsContainer <ControlPanelsContainer
actions={this.props.actions} actions={this.props.actions}