mirror of
https://github.com/reduxjs/redux-devtools.git
synced 2025-07-27 00:19:55 +03:00
Merge 4e3b362a9c
into c13a911a0f
This commit is contained in:
commit
ad54a58a2c
|
@ -3,6 +3,7 @@ const ActionTypes = {
|
||||||
RESET: 'RESET',
|
RESET: 'RESET',
|
||||||
ROLLBACK: 'ROLLBACK',
|
ROLLBACK: 'ROLLBACK',
|
||||||
COMMIT: 'COMMIT',
|
COMMIT: 'COMMIT',
|
||||||
|
IMPORT_STATE: 'IMPORT_STATE',
|
||||||
SWEEP: 'SWEEP',
|
SWEEP: 'SWEEP',
|
||||||
TOGGLE_ACTION: 'TOGGLE_ACTION',
|
TOGGLE_ACTION: 'TOGGLE_ACTION',
|
||||||
JUMP_TO_STATE: 'JUMP_TO_STATE',
|
JUMP_TO_STATE: 'JUMP_TO_STATE',
|
||||||
|
@ -121,6 +122,16 @@ function liftReducer(reducer, initialState) {
|
||||||
currentStateIndex = 0;
|
currentStateIndex = 0;
|
||||||
timestamps = [liftedAction.timestamp];
|
timestamps = [liftedAction.timestamp];
|
||||||
break;
|
break;
|
||||||
|
case ActionTypes.IMPORT_STATE:
|
||||||
|
({
|
||||||
|
stagedActions,
|
||||||
|
skippedActions,
|
||||||
|
computedStates,
|
||||||
|
currentStateIndex,
|
||||||
|
monitorState,
|
||||||
|
timestamps
|
||||||
|
} = liftedAction.nextLiftedState);
|
||||||
|
break;
|
||||||
case ActionTypes.ROLLBACK:
|
case ActionTypes.ROLLBACK:
|
||||||
stagedActions = [INIT_ACTION];
|
stagedActions = [INIT_ACTION];
|
||||||
skippedActions = {};
|
skippedActions = {};
|
||||||
|
@ -258,6 +269,9 @@ export const ActionCreators = {
|
||||||
commit() {
|
commit() {
|
||||||
return { type: ActionTypes.COMMIT, timestamp: Date.now() };
|
return { type: ActionTypes.COMMIT, timestamp: Date.now() };
|
||||||
},
|
},
|
||||||
|
importState(nextLiftedState) {
|
||||||
|
return { type: ActionTypes.IMPORT_STATE, nextLiftedState };
|
||||||
|
},
|
||||||
sweep() {
|
sweep() {
|
||||||
return { type: ActionTypes.SWEEP };
|
return { type: ActionTypes.SWEEP };
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
/* eslint-disable no-alert */
|
||||||
import React, { PropTypes, findDOMNode, Component } from 'react';
|
import React, { PropTypes, findDOMNode, Component } from 'react';
|
||||||
import LogMonitorEntry from './LogMonitorEntry';
|
import LogMonitorEntry from './LogMonitorEntry';
|
||||||
import LogMonitorButton from './LogMonitorButton';
|
import LogMonitorButton from './LogMonitorButton';
|
||||||
|
@ -118,6 +119,21 @@ export default class LogMonitor extends Component {
|
||||||
this.props.commit();
|
this.props.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleExport() {
|
||||||
|
window.prompt('Current state\'s schema', JSON.stringify(this.props.store.getState()));
|
||||||
|
}
|
||||||
|
|
||||||
|
handleImport() {
|
||||||
|
try {
|
||||||
|
let nextLiftedState = window.prompt('Please paste a valid action log');
|
||||||
|
if (nextLiftedState) {
|
||||||
|
this.props.importState(JSON.parse(nextLiftedState));
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.warn('There was an error parsing the new state. Please enter a valid schema.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
handleToggleAction(index) {
|
handleToggleAction(index) {
|
||||||
this.props.toggleAction(index);
|
this.props.toggleAction(index);
|
||||||
}
|
}
|
||||||
|
@ -184,6 +200,8 @@ export default class LogMonitor extends Component {
|
||||||
<LogMonitorButton theme={theme} onClick={::this.handleRollback} enabled={computedStates.length}>Revert</LogMonitorButton>
|
<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.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.handleCommit} enabled={computedStates.length > 1}>Commit</LogMonitorButton>
|
||||||
|
<LogMonitorButton theme={theme} onClick={::this.handleImport} enabled={true}>Import</LogMonitorButton>
|
||||||
|
<LogMonitorButton theme={theme} onClick={::this.handleExport} enabled={computedStates.length}>Export</LogMonitorButton>
|
||||||
</div>
|
</div>
|
||||||
<div style={styles.elements} ref="elements">
|
<div style={styles.elements} ref="elements">
|
||||||
{elements}
|
{elements}
|
||||||
|
@ -192,3 +210,4 @@ export default class LogMonitor extends Component {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* eslint-enable no-alert */
|
||||||
|
|
|
@ -243,4 +243,42 @@ describe('devTools', () => {
|
||||||
monitoredDevToolsStore.dispatch(ActionCreators.jumpToState(3));
|
monitoredDevToolsStore.dispatch(ActionCreators.jumpToState(3));
|
||||||
expect(reducerCalls).toBe(4);
|
expect(reducerCalls).toBe(4);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('Import State', () => {
|
||||||
|
let monitoredStore;
|
||||||
|
let monitoredDevToolsStore;
|
||||||
|
let exportedState;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
monitoredStore = devTools()(createStore)(counter);
|
||||||
|
monitoredDevToolsStore = monitoredStore.devToolsStore;
|
||||||
|
// Set up state to export
|
||||||
|
monitoredStore.dispatch({ type: 'INCREMENT' });
|
||||||
|
monitoredStore.dispatch({ type: 'INCREMENT' });
|
||||||
|
monitoredStore.dispatch({ type: 'INCREMENT' });
|
||||||
|
|
||||||
|
exportedState = monitoredDevToolsStore.getState();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should replay all the steps when a state is imported', () => {
|
||||||
|
let importMonitoredStore = devTools()(createStore)(counter);
|
||||||
|
let importMonitoredDevToolsStore = importMonitoredStore.devToolsStore;
|
||||||
|
// Import exported state
|
||||||
|
importMonitoredDevToolsStore.dispatch(ActionCreators.importState(exportedState));
|
||||||
|
expect(importMonitoredDevToolsStore.getState()).toEqual(exportedState);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should replace the existing action log with the one imported', () => {
|
||||||
|
let importMonitoredStore = devTools()(createStore)(counter);
|
||||||
|
let importMonitoredDevToolsStore = importMonitoredStore.devToolsStore;
|
||||||
|
|
||||||
|
importMonitoredStore.dispatch({ type: 'DECREMENT' });
|
||||||
|
importMonitoredStore.dispatch({ type: 'DECREMENT' });
|
||||||
|
|
||||||
|
// Import exported state
|
||||||
|
importMonitoredDevToolsStore.dispatch(ActionCreators.importState(exportedState));
|
||||||
|
|
||||||
|
expect(importMonitoredDevToolsStore.getState()).toEqual(exportedState);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue
Block a user