Feature(challenges): add reset logic
This commit is contained in:
@ -6,6 +6,7 @@ export default class ToolPanel extends PureComponent {
|
|||||||
constructor(...props) {
|
constructor(...props) {
|
||||||
super(...props);
|
super(...props);
|
||||||
this.makeHint = this.makeHint.bind(this);
|
this.makeHint = this.makeHint.bind(this);
|
||||||
|
this.makeReset = this.makeReset.bind(this);
|
||||||
}
|
}
|
||||||
static displayName = 'ToolPanel';
|
static displayName = 'ToolPanel';
|
||||||
|
|
||||||
@ -22,6 +23,14 @@ export default class ToolPanel extends PureComponent {
|
|||||||
this.props.updateHint();
|
this.props.updateHint();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
makeReset() {
|
||||||
|
this.props.makeToast({
|
||||||
|
message: 'This will restore your code editor to its original state.',
|
||||||
|
action: 'clear my code',
|
||||||
|
actionCreator: 'resetChallenge'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
renderHint(hint, makeHint) {
|
renderHint(hint, makeHint) {
|
||||||
if (!hint) {
|
if (!hint) {
|
||||||
return null;
|
return null;
|
||||||
@ -33,7 +42,7 @@ export default class ToolPanel extends PureComponent {
|
|||||||
className='btn-big'
|
className='btn-big'
|
||||||
onClick={ makeHint }
|
onClick={ makeHint }
|
||||||
>
|
>
|
||||||
Hint
|
Hint
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -60,6 +69,7 @@ export default class ToolPanel extends PureComponent {
|
|||||||
bsSize='large'
|
bsSize='large'
|
||||||
bsStyle='primary'
|
bsStyle='primary'
|
||||||
componentClass='label'
|
componentClass='label'
|
||||||
|
onClick={ this.makeReset }
|
||||||
>
|
>
|
||||||
Reset
|
Reset
|
||||||
</Button>
|
</Button>
|
||||||
|
@ -33,6 +33,7 @@ export const fetchChallengesCompleted = createAction(
|
|||||||
export const updateCurrentChallenge = createAction(
|
export const updateCurrentChallenge = createAction(
|
||||||
types.updateCurrentChallenge
|
types.updateCurrentChallenge
|
||||||
);
|
);
|
||||||
|
export const resetChallenge = createAction(types.resetChallenge);
|
||||||
// replaceChallenge(dashedname) => Action
|
// replaceChallenge(dashedname) => Action
|
||||||
export const replaceChallenge = createAction(types.replaceChallenge);
|
export const replaceChallenge = createAction(types.replaceChallenge);
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ import fetchChallengesSaga from './fetch-challenges-saga';
|
|||||||
import completionSaga from './completion-saga';
|
import completionSaga from './completion-saga';
|
||||||
import nextChallengeSaga from './next-challenge-saga';
|
import nextChallengeSaga from './next-challenge-saga';
|
||||||
import answerSaga from './answer-saga';
|
import answerSaga from './answer-saga';
|
||||||
|
import resetChallengeSaga from './reset-challenge-saga';
|
||||||
|
|
||||||
export * as actions from './actions';
|
export * as actions from './actions';
|
||||||
export reducer from './reducer';
|
export reducer from './reducer';
|
||||||
@ -13,5 +14,6 @@ export const sagas = [
|
|||||||
fetchChallengesSaga,
|
fetchChallengesSaga,
|
||||||
completionSaga,
|
completionSaga,
|
||||||
nextChallengeSaga,
|
nextChallengeSaga,
|
||||||
answerSaga
|
answerSaga,
|
||||||
|
resetChallengeSaga
|
||||||
];
|
];
|
||||||
|
15
common/app/routes/challenges/redux/reset-challenge-saga.js
Normal file
15
common/app/routes/challenges/redux/reset-challenge-saga.js
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import types from './types';
|
||||||
|
import { updateCurrentChallenge } from './actions';
|
||||||
|
|
||||||
|
export default function resetChallengeSaga(actions$, getState) {
|
||||||
|
return actions$
|
||||||
|
.filter(({ type }) => type === types.resetChallenge)
|
||||||
|
.map(() => {
|
||||||
|
const {
|
||||||
|
challengesApp: { challenge: dashedName },
|
||||||
|
entities: { challenge: challengeMap }
|
||||||
|
} = getState();
|
||||||
|
const currentChallenge = challengeMap[dashedName];
|
||||||
|
return updateCurrentChallenge(currentChallenge);
|
||||||
|
});
|
||||||
|
}
|
@ -13,6 +13,7 @@ export default createTypes([
|
|||||||
'fetchChallengeCompleted',
|
'fetchChallengeCompleted',
|
||||||
'fetchChallengesCompleted',
|
'fetchChallengesCompleted',
|
||||||
'updateCurrentChallenge',
|
'updateCurrentChallenge',
|
||||||
|
'resetChallenge',
|
||||||
'replaceChallenge',
|
'replaceChallenge',
|
||||||
'resetUi',
|
'resetUi',
|
||||||
'updateHint',
|
'updateHint',
|
||||||
|
@ -4,9 +4,15 @@ import { createSelector } from 'reselect';
|
|||||||
import { NotificationStack } from 'react-notification';
|
import { NotificationStack } from 'react-notification';
|
||||||
|
|
||||||
import { removeToast } from './redux/actions';
|
import { removeToast } from './redux/actions';
|
||||||
import { submitChallenge } from '../routes/challenges/redux/actions';
|
import {
|
||||||
|
submitChallenge,
|
||||||
|
resetChallenge
|
||||||
|
} from '../routes/challenges/redux/actions';
|
||||||
|
|
||||||
const registeredActions = { submitChallenge };
|
const registeredActions = {
|
||||||
|
submitChallenge,
|
||||||
|
resetChallenge
|
||||||
|
};
|
||||||
const mapStateToProps = state => ({ toasts: state.toasts });
|
const mapStateToProps = state => ({ toasts: state.toasts });
|
||||||
// we use styles here to overwrite those built into the library
|
// we use styles here to overwrite those built into the library
|
||||||
// but there are some styles applied using
|
// but there are some styles applied using
|
||||||
|
Reference in New Issue
Block a user