Adds a shortcut panel!

This commit is contained in:
Simon Howe
2016-04-07 18:33:34 +02:00
parent c452b68200
commit 0a9f26bb60
6 changed files with 146 additions and 3 deletions

View File

@@ -13,6 +13,22 @@ import AppStore from '../stores/app-store';
const log = debug('scope:app-actions');
export function showHelp() {
AppDispatcher.dispatch({type: ActionTypes.SHOW_HELP});
}
export function hideHelp() {
AppDispatcher.dispatch({type: ActionTypes.HIDE_HELP});
}
export function toggleHelp() {
if (AppStore.getShowingHelp()) {
hideHelp();
} else {
showHelp();
}
}
export function selectMetric(metricId) {
AppDispatcher.dispatch({
type: ActionTypes.SELECT_METRIC,
@@ -219,7 +235,9 @@ export function enterNode(nodeId) {
export function hitEsc() {
const controlPipe = AppStore.getControlPipe();
if (controlPipe && controlPipe.get('status') === 'PIPE_DELETED') {
if (AppStore.getShowingHelp()) {
hideHelp();
} else if (controlPipe && controlPipe.get('status') === 'PIPE_DELETED') {
AppDispatcher.dispatch({
type: ActionTypes.CLICK_CLOSE_TERMINAL,
pipeId: controlPipe.get('id')

View File

@@ -7,12 +7,13 @@ import Logo from './logo';
import AppStore from '../stores/app-store';
import Footer from './footer.js';
import Sidebar from './sidebar.js';
import HelpPanel from './help-panel';
import Status from './status.js';
import Topologies from './topologies.js';
import TopologyOptions from './topology-options.js';
import { getApiDetails, getTopologies } from '../utils/web-api-utils';
import { pinNextMetric, hitEsc, unpinMetric,
selectMetric } from '../actions/app-actions';
selectMetric, toggleHelp } from '../actions/app-actions';
import Details from './details';
import Nodes from './nodes';
import MetricSelector from './metric-selector';
@@ -43,6 +44,7 @@ function getStateFromStores() {
availableCanvasMetrics: AppStore.getAvailableCanvasMetrics(),
nodeDetails: AppStore.getNodeDetails(),
nodes: AppStore.getNodes(),
showingHelp: AppStore.getShowingHelp(),
selectedNodeId: AppStore.getSelectedNodeId(),
selectedMetric: AppStore.getSelectedMetric(),
topologies: AppStore.getTopologies(),
@@ -113,6 +115,8 @@ export default class App extends React.Component {
} else if (char === 'd') {
toggleDebugToolbar();
this.forceUpdate();
} else if (char === '?') {
toggleHelp();
}
}
@@ -127,6 +131,9 @@ export default class App extends React.Component {
return (
<div className="app">
{showingDebugToolbar() && <DebugToolbar />}
{this.state.showingHelp && <HelpPanel />}
{showingDetails && <Details nodes={this.state.nodes}
controlStatus={this.state.controlStatus}
details={this.state.nodeDetails} />}

View File

@@ -0,0 +1,43 @@
import React from 'react';
const GENERAL_SHORTCUTS = [
{key: 'esc', label: 'Close panel'},
];
const CANVAS_METRIC_SHORTCUTS = [
{key: '<', label: 'Pin previous metric'},
{key: '>', label: 'Pin next metric'},
{key: 'q', label: 'Unpin current metric'},
];
function renderShortcuts(cuts) {
return (
<div>
{cuts.map(({key, label}) => (
<div key={key} className="help-panel-shortcut">
<div className="key"><kbd>{key}</kbd></div>
<div className="label">{label}</div>
</div>
))}
</div>
);
}
export default class HelpPanel extends React.Component {
render() {
return (
<div className="help-panel">
<div className="help-panel-header">
<h2>Keyboard Shortcuts</h2>
</div>
<div className="help-panel-main">
<h3>General</h3>
{renderShortcuts(GENERAL_SHORTCUTS)}
<h3>Canvas Metrics</h3>
{renderShortcuts(CANVAS_METRIC_SHORTCUTS)}
</div>
</div>
);
}
}

View File

@@ -21,6 +21,7 @@ const ACTION_TYPES = [
'DO_CONTROL_SUCCESS',
'ENTER_EDGE',
'ENTER_NODE',
'HIDE_HELP',
'LEAVE_EDGE',
'LEAVE_NODE',
'PIN_METRIC',
@@ -36,7 +37,8 @@ const ACTION_TYPES = [
'RECEIVE_API_DETAILS',
'RECEIVE_ERROR',
'ROUTE_TOPOLOGY',
'SELECT_METRIC'
'SELECT_METRIC',
'SHOW_HELP'
];
export default _.zipObject(ACTION_TYPES, ACTION_TYPES);

View File

@@ -58,6 +58,7 @@ let routeSet = false;
let controlPipes = makeOrderedMap(); // pipeId -> controlPipe
let updatePausedAt = null; // Date
let websocketClosed = true;
let showingHelp = false;
let selectedMetric = null;
let pinnedMetric = selectedMetric;
@@ -149,6 +150,10 @@ export class AppStore extends Store {
};
}
getShowingHelp() {
return showingHelp;
}
getActiveTopologyOptions() {
// options for current topology, sub-topologies share options with parent
if (currentTopology && currentTopology.get('parentId')) {
@@ -449,6 +454,16 @@ export class AppStore extends Store {
this.__emitChange();
break;
}
case ActionTypes.SHOW_HELP: {
showingHelp = true;
this.__emitChange();
break;
}
case ActionTypes.HIDE_HELP: {
showingHelp = false;
this.__emitChange();
break;
}
case ActionTypes.DESELECT_NODE: {
closeNodeDetails();
this.__emitChange();

View File

@@ -1080,6 +1080,64 @@ h2 {
}
}
//
// Help panel!
//
.help-panel {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 2048;
.shadow-2;
&-header {
background-color: @weave-blue;
padding: 36px;
color: white;
h2 {
margin: 0;
}
}
&-main {
padding: 12px 36px 36px;
background-color: white;
}
h3 {
text-transform: uppercase;
font-size: 90%;
color: #8383ac;
padding: 4px 0;
}
&-shortcut {
kbd {
display: inline-block;
padding: 3px 5px;
font-size: 11px;
line-height: 10px;
color: #555;
vertical-align: middle;
background-color: #fcfcfc;
border: solid 1px #ccc;
border-bottom-color: #bbb;
border-radius: 3px;
box-shadow: inset 0 -1px 0 #bbb;
}
div.key {
width: 100px;
display: inline-block;
}
div.label {
display: inline-block;
}
}
}
//
// Debug panel!
//