mirror of
https://github.com/weaveworks/scope.git
synced 2026-03-04 18:51:17 +00:00
Adds a shortcut panel!
This commit is contained in:
@@ -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')
|
||||
|
||||
@@ -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} />}
|
||||
|
||||
43
client/app/scripts/components/help-panel.js
Normal file
43
client/app/scripts/components/help-panel.js
Normal 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>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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!
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user