diff --git a/package.json b/package.json
index 1c283d1c..11643109 100644
--- a/package.json
+++ b/package.json
@@ -47,6 +47,7 @@
"redux": "^2.0.0"
},
"dependencies": {
+ "react-dock": "0.0.2",
"react-json-tree": "^0.1.8",
"react-mixin": "^1.7.0",
"react-redux": "^2.0.0",
diff --git a/src/createDevTools.js b/src/createDevTools.js
index b5eecadd..e1849699 100644
--- a/src/createDevTools.js
+++ b/src/createDevTools.js
@@ -1,5 +1,6 @@
import createAll from 'react-redux/lib/components/createAll';
import { ActionCreators } from './devTools';
+import DebugPanel from './react/DebugPanel';
export default function createDevTools(React) {
const { PropTypes, Component } = React;
@@ -11,8 +12,13 @@ export default function createDevTools(React) {
)
class DevTools extends Component {
render() {
- const { monitor: Monitor } = this.props;
- return ;
+ const { monitor: Monitor, panelState, setPanelState,
+ visibleOnLoad, position, ...props } = this.props;
+ return (
+
+
+
+ );
}
}
@@ -37,9 +43,9 @@ export default function createDevTools(React) {
}
render() {
+ const { store: { devToolsStore }, ...props } = this.props;
return (
-
+
);
}
};
diff --git a/src/devTools.js b/src/devTools.js
index f57e9bc1..471de44e 100644
--- a/src/devTools.js
+++ b/src/devTools.js
@@ -6,7 +6,7 @@ const ActionTypes = {
SWEEP: 'SWEEP',
TOGGLE_ACTION: 'TOGGLE_ACTION',
JUMP_TO_STATE: 'JUMP_TO_STATE',
- SET_MONITOR_STATE: 'SET_MONITOR_STATE',
+ SET_PANEL_STATE: 'SET_PANEL_STATE',
RECOMPUTE_STATES: 'RECOMPUTE_STATES'
};
@@ -85,7 +85,8 @@ function liftReducer(reducer, initialState) {
stagedActions: [INIT_ACTION],
skippedActions: {},
currentStateIndex: 0,
- monitorState: {
+ panelState: {
+ position: 'right',
isVisible: true
},
timestamps: [Date.now()]
@@ -101,7 +102,7 @@ function liftReducer(reducer, initialState) {
skippedActions,
computedStates,
currentStateIndex,
- monitorState,
+ panelState,
timestamps
} = liftedState;
@@ -145,8 +146,8 @@ function liftReducer(reducer, initialState) {
stagedActions = [...stagedActions, liftedAction.action];
timestamps = [...timestamps, liftedAction.timestamp];
break;
- case ActionTypes.SET_MONITOR_STATE:
- monitorState = liftedAction.monitorState;
+ case ActionTypes.SET_PANEL_STATE:
+ panelState = liftedAction.panelState;
break;
case ActionTypes.RECOMPUTE_STATES:
stagedActions = liftedAction.stagedActions;
@@ -172,7 +173,7 @@ function liftReducer(reducer, initialState) {
skippedActions,
computedStates,
currentStateIndex,
- monitorState,
+ panelState,
timestamps
};
};
@@ -244,8 +245,8 @@ export const ActionCreators = {
jumpToState(index) {
return { type: ActionTypes.JUMP_TO_STATE, index };
},
- setMonitorState(monitorState) {
- return { type: ActionTypes.SET_MONITOR_STATE, monitorState };
+ setPanelState(panelState) {
+ return { type: ActionTypes.SET_PANEL_STATE, panelState };
},
recomputeStates(committedState, stagedActions) {
return {
diff --git a/src/react/DebugPanel.js b/src/react/DebugPanel.js
index d58dc3b4..bc0aff38 100644
--- a/src/react/DebugPanel.js
+++ b/src/react/DebugPanel.js
@@ -1,51 +1,71 @@
import React, { PropTypes, Component } from 'react';
+import Dock from 'react-dock';
-export function getDefaultStyle(props) {
- let { left, right, bottom, top } = props;
- if (typeof left === 'undefined' && typeof right === 'undefined') {
- right = true;
- }
- if (typeof top === 'undefined' && typeof bottom === 'undefined') {
- bottom = true;
- }
-
- return {
- position: 'fixed',
- zIndex: 10000,
- fontSize: 17,
- overflow: 'hidden',
- opacity: 1,
- color: 'white',
- left: left ? 0 : undefined,
- right: right ? 0 : undefined,
- top: top ? 0 : undefined,
- bottom: bottom ? 0 : undefined,
- maxHeight: (bottom && top) ? '100%' : '30%',
- maxWidth: (left && right) ? '100%' : '30%',
- wordWrap: 'break-word',
- boxSizing: 'border-box',
- boxShadow: '-2px 0 7px 0 rgba(0, 0, 0, 0.5)'
- };
-}
+const POSITIONS = ['left', 'top', 'right', 'bottom'];
export default class DebugPanel extends Component {
static propTypes = {
- left: PropTypes.bool,
- right: PropTypes.bool,
- bottom: PropTypes.bool,
- top: PropTypes.bool,
getStyle: PropTypes.func.isRequired
};
static defaultProps = {
- getStyle: getDefaultStyle
+ getStyle: () => ({}),
+ panelState: {
+ position: 'right',
+ isVisible: true
+ },
+ visibleOnLoad: true,
+ position: 'right',
+ dimMode: 'none'
};
+ componentWillMount() {
+ const { panelState, visibleOnLoad, position } = this.props;
+
+ this.props.setPanelState({
+ ...panelState,
+ isVisible: visibleOnLoad,
+ position: position
+ });
+ }
+
+ componentDidMount() {
+ if (typeof window !== 'undefined') {
+ window.addEventListener('keydown', this.handleKeyPress);
+ }
+ }
+
+ componentWillUnmount() {
+ if (typeof window !== 'undefined') {
+ window.removeEventListener('keydown', this.handleKeyPress);
+ }
+ }
+
render() {
+ const { getStyle, dimMode, panelState: { position, isVisible } } = this.props;
return (
-
+
{this.props.children}
-
+
);
}
+
+ handleKeyPress = event => {
+ const { panelState } = this.props;
+ if (event.ctrlKey && event.keyCode === 72) { // Ctrl+H
+ event.preventDefault();
+ this.props.setPanelState({
+ ...panelState,
+ isVisible: !panelState.isVisible
+ });
+ } else if (event.ctrlKey && event.keyCode === 68) { // Ctrl+D
+ event.preventDefault();
+ const positionIdx = POSITIONS.indexOf(panelState.position);
+ this.props.setPanelState({
+ ...panelState,
+ position: POSITIONS[(positionIdx + 1) % POSITIONS.length]
+ });
+ }
+ }
}
diff --git a/src/react/LogMonitor.js b/src/react/LogMonitor.js
index d960f460..17b818e2 100644
--- a/src/react/LogMonitor.js
+++ b/src/react/LogMonitor.js
@@ -33,17 +33,9 @@ const styles = {
};
export default class LogMonitor extends Component {
- constructor(props) {
- super(props);
- if (typeof window !== 'undefined') {
- window.addEventListener('keydown', ::this.handleKeyPress);
- }
- }
-
static propTypes = {
computedStates: PropTypes.array.isRequired,
currentStateIndex: PropTypes.number.isRequired,
- monitorState: PropTypes.object.isRequired,
stagedActions: PropTypes.array.isRequired,
skippedActions: PropTypes.object.isRequired,
reset: PropTypes.func.isRequired,
@@ -52,16 +44,12 @@ export default class LogMonitor extends Component {
sweep: PropTypes.func.isRequired,
toggleAction: PropTypes.func.isRequired,
jumpToState: PropTypes.func.isRequired,
- setMonitorState: PropTypes.func.isRequired,
- select: PropTypes.func.isRequired,
- visibleOnLoad: PropTypes.bool
+ select: PropTypes.func.isRequired
};
static defaultProps = {
select: (state) => state,
- monitorState: { isVisible: true },
- theme: 'nicinabox',
- visibleOnLoad: true
+ theme: 'nicinabox'
};
componentWillReceiveProps(nextProps) {
@@ -93,15 +81,6 @@ export default class LogMonitor extends Component {
}
}
- componentWillMount() {
- let visibleOnLoad = this.props.visibleOnLoad;
- const { monitorState } = this.props;
- this.props.setMonitorState({
- ...monitorState,
- isVisible: visibleOnLoad
- });
- }
-
handleRollback() {
this.props.rollback();
}
@@ -122,21 +101,9 @@ export default class LogMonitor extends Component {
this.props.reset();
}
- handleKeyPress(event) {
- const { monitorState } = this.props;
-
- if (event.ctrlKey && event.keyCode === 72) { // Ctrl+H
- event.preventDefault();
- this.props.setMonitorState({
- ...monitorState,
- isVisible: !monitorState.isVisible
- });
- }
- }
-
render() {
const elements = [];
- const { monitorState, skippedActions, stagedActions, computedStates, select } = this.props;
+ const { skippedActions, stagedActions, computedStates, select } = this.props;
let theme;
if (typeof this.props.theme === 'string') {
if (typeof themes[this.props.theme] !== 'undefined') {
@@ -148,10 +115,6 @@ export default class LogMonitor extends Component {
} else {
theme = this.props.theme;
}
- if (!monitorState.isVisible) {
- return null;
- }
-
for (let i = 0; i < stagedActions.length; i++) {
const action = stagedActions[i];
const { state, error } = computedStates[i];
diff --git a/src/react/index.js b/src/react/index.js
index cce0e96d..d3e831d2 100644
--- a/src/react/index.js
+++ b/src/react/index.js
@@ -3,4 +3,3 @@ import createDevTools from '../createDevTools';
export const DevTools = createDevTools(React);
export { default as LogMonitor } from './LogMonitor';
-export { default as DebugPanel } from './DebugPanel';