mirror of
https://github.com/reduxjs/redux-devtools.git
synced 2024-11-28 20:43:56 +03:00
Import-Export States to your DevTools
This commit is contained in:
parent
0a1458cdbd
commit
38158191ce
|
@ -3,6 +3,8 @@ const ActionTypes = {
|
|||
RESET: 'RESET',
|
||||
ROLLBACK: 'ROLLBACK',
|
||||
COMMIT: 'COMMIT',
|
||||
EXPORT: 'EXPORT',
|
||||
IMPORT: 'IMPORT',
|
||||
SWEEP: 'SWEEP',
|
||||
TOGGLE_ACTION: 'TOGGLE_ACTION',
|
||||
JUMP_TO_STATE: 'JUMP_TO_STATE',
|
||||
|
@ -86,7 +88,8 @@ function liftReducer(reducer, initialState) {
|
|||
skippedActions: {},
|
||||
currentStateIndex: 0,
|
||||
monitorState: {
|
||||
isVisible: true
|
||||
isVisible: true,
|
||||
exportMode: false
|
||||
},
|
||||
timestamps: [Date.now()]
|
||||
};
|
||||
|
@ -121,6 +124,25 @@ function liftReducer(reducer, initialState) {
|
|||
currentStateIndex = 0;
|
||||
timestamps = [liftedAction.timestamp];
|
||||
break;
|
||||
case ActionTypes.EXPORT:
|
||||
monitorState = Object.assign(
|
||||
{},
|
||||
monitorState,
|
||||
{ exportMode: !monitorState.exportMode }
|
||||
);
|
||||
break;
|
||||
case ActionTypes.IMPORT:
|
||||
(
|
||||
{
|
||||
stagedActions,
|
||||
skippedActions,
|
||||
computedStates,
|
||||
currentStateIndex,
|
||||
monitorState,
|
||||
timestamps
|
||||
} = liftedAction.newState
|
||||
);
|
||||
break;
|
||||
case ActionTypes.ROLLBACK:
|
||||
stagedActions = [INIT_ACTION];
|
||||
skippedActions = {};
|
||||
|
@ -258,6 +280,12 @@ export const ActionCreators = {
|
|||
commit() {
|
||||
return { type: ActionTypes.COMMIT, timestamp: Date.now() };
|
||||
},
|
||||
export() {
|
||||
return { type: ActionTypes.EXPORT };
|
||||
},
|
||||
import(newState) {
|
||||
return { type: ActionTypes.IMPORT, newState };
|
||||
},
|
||||
sweep() {
|
||||
return { type: ActionTypes.SWEEP };
|
||||
},
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
import React, { PropTypes, findDOMNode, Component } from 'react';
|
||||
import LogMonitorEntry from './LogMonitorEntry';
|
||||
import LogMonitorButton from './LogMonitorButton';
|
||||
import LogMonitorTextarea from './LogMonitorTextarea';
|
||||
import * as themes from './themes';
|
||||
|
||||
const EXPORT_CONTAINER_HEIGHT = 150;
|
||||
const ELEMENTS_CONTAINER_TOP = 38;
|
||||
|
||||
const styles = {
|
||||
container: {
|
||||
fontFamily: 'monaco, Consolas, Lucida Console, monospace',
|
||||
|
@ -25,7 +29,7 @@ const styles = {
|
|||
position: 'absolute',
|
||||
left: 0,
|
||||
right: 0,
|
||||
top: 38,
|
||||
top: ELEMENTS_CONTAINER_TOP,
|
||||
bottom: 0,
|
||||
overflowX: 'hidden',
|
||||
overflowY: 'auto'
|
||||
|
@ -118,6 +122,14 @@ export default class LogMonitor extends Component {
|
|||
this.props.commit();
|
||||
}
|
||||
|
||||
handleExport() {
|
||||
this.props.export();
|
||||
}
|
||||
|
||||
handleImport(newState) {
|
||||
this.props.import(newState);
|
||||
}
|
||||
|
||||
handleToggleAction(index) {
|
||||
this.props.toggleAction(index);
|
||||
}
|
||||
|
@ -184,8 +196,10 @@ export default class LogMonitor extends Component {
|
|||
<LogMonitorButton theme={theme} onClick={::this.handleRollback} enabled={computedStates.length}>Revert</LogMonitorButton>
|
||||
<LogMonitorButton theme={theme} onClick={::this.handleSweep} enabled={Object.keys(skippedActions).some(key => skippedActions[key])}>Sweep</LogMonitorButton>
|
||||
<LogMonitorButton theme={theme} onClick={::this.handleCommit} enabled={computedStates.length > 1}>Commit</LogMonitorButton>
|
||||
<LogMonitorButton theme={theme} onClick={::this.handleExport} enabled={computedStates.length}>Export</LogMonitorButton>
|
||||
</div>
|
||||
<div style={styles.elements} ref="elements">
|
||||
<LogMonitorTextarea theme={theme} handleImport={::this.handleImport} currentState={this.props.store.getState()} />
|
||||
<div style={{...styles.elements, top: monitorState.exportMode ? EXPORT_CONTAINER_HEIGHT : ELEMENTS_CONTAINER_TOP }} ref="elements">
|
||||
{elements}
|
||||
</div>
|
||||
</div>
|
||||
|
|
42
src/react/LogMonitorTextarea.js
Normal file
42
src/react/LogMonitorTextarea.js
Normal file
|
@ -0,0 +1,42 @@
|
|||
import React, { PropTypes, findDOMNode, Component } from 'react';
|
||||
|
||||
const EXPORT_CONTAINER_HEIGHT = 150;
|
||||
const ELEMENTS_CONTAINER_TOP = 38;
|
||||
|
||||
var styles = {
|
||||
exportContainer: {
|
||||
width: '100%',
|
||||
height: EXPORT_CONTAINER_HEIGHT
|
||||
},
|
||||
exportArea: {
|
||||
position: 'relative',
|
||||
resize: 'none',
|
||||
width: '100%',
|
||||
height: 112,
|
||||
backgroundColor: '#4F5A66',
|
||||
color: 'white'
|
||||
}
|
||||
};
|
||||
|
||||
export default class LogMonitorTextarea extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
parseInput(event) {
|
||||
try {
|
||||
this.props.handleImport(JSON.parse(event.target.value))
|
||||
} catch(err) {
|
||||
console.warn('There was an error parsing the new state. Please enter a valid schema.');
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
let { handleImport, currentState, theme } = this.props;
|
||||
return currentState.monitorState.exportMode ? (
|
||||
<div style={{...styles.exportContainer, backgroundColor: theme.base00}}>
|
||||
<textarea style={styles.exportArea} value={JSON.stringify(currentState)} onChange={::this.parseInput} />
|
||||
</div>
|
||||
) : null;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user