diff --git a/common/app/routes/challenges/components/classic/Tool-Panel.jsx b/common/app/routes/challenges/components/classic/Tool-Panel.jsx index 3dbbe05b54..ebfe66fdb7 100644 --- a/common/app/routes/challenges/components/classic/Tool-Panel.jsx +++ b/common/app/routes/challenges/components/classic/Tool-Panel.jsx @@ -6,6 +6,7 @@ export default class ToolPanel extends PureComponent { constructor(...props) { super(...props); this.makeHint = this.makeHint.bind(this); + this.makeReset = this.makeReset.bind(this); } static displayName = 'ToolPanel'; @@ -22,6 +23,14 @@ export default class ToolPanel extends PureComponent { 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) { if (!hint) { return null; @@ -33,7 +42,7 @@ export default class ToolPanel extends PureComponent { className='btn-big' onClick={ makeHint } > - Hint + Hint ); } @@ -60,6 +69,7 @@ export default class ToolPanel extends PureComponent { bsSize='large' bsStyle='primary' componentClass='label' + onClick={ this.makeReset } > Reset diff --git a/common/app/routes/challenges/redux/actions.js b/common/app/routes/challenges/redux/actions.js index d4f6a158ef..de3ddb5530 100644 --- a/common/app/routes/challenges/redux/actions.js +++ b/common/app/routes/challenges/redux/actions.js @@ -33,6 +33,7 @@ export const fetchChallengesCompleted = createAction( export const updateCurrentChallenge = createAction( types.updateCurrentChallenge ); +export const resetChallenge = createAction(types.resetChallenge); // replaceChallenge(dashedname) => Action export const replaceChallenge = createAction(types.replaceChallenge); diff --git a/common/app/routes/challenges/redux/index.js b/common/app/routes/challenges/redux/index.js index ffb98e4e47..1f33c002e9 100644 --- a/common/app/routes/challenges/redux/index.js +++ b/common/app/routes/challenges/redux/index.js @@ -2,6 +2,7 @@ import fetchChallengesSaga from './fetch-challenges-saga'; import completionSaga from './completion-saga'; import nextChallengeSaga from './next-challenge-saga'; import answerSaga from './answer-saga'; +import resetChallengeSaga from './reset-challenge-saga'; export * as actions from './actions'; export reducer from './reducer'; @@ -13,5 +14,6 @@ export const sagas = [ fetchChallengesSaga, completionSaga, nextChallengeSaga, - answerSaga + answerSaga, + resetChallengeSaga ]; diff --git a/common/app/routes/challenges/redux/reset-challenge-saga.js b/common/app/routes/challenges/redux/reset-challenge-saga.js new file mode 100644 index 0000000000..1ee4b2b9b8 --- /dev/null +++ b/common/app/routes/challenges/redux/reset-challenge-saga.js @@ -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); + }); +} diff --git a/common/app/routes/challenges/redux/types.js b/common/app/routes/challenges/redux/types.js index 3a17532170..e36b2e89a2 100644 --- a/common/app/routes/challenges/redux/types.js +++ b/common/app/routes/challenges/redux/types.js @@ -13,6 +13,7 @@ export default createTypes([ 'fetchChallengeCompleted', 'fetchChallengesCompleted', 'updateCurrentChallenge', + 'resetChallenge', 'replaceChallenge', 'resetUi', 'updateHint', diff --git a/common/app/toasts/Toasts.jsx b/common/app/toasts/Toasts.jsx index eee7b08be9..f0ba561e5f 100644 --- a/common/app/toasts/Toasts.jsx +++ b/common/app/toasts/Toasts.jsx @@ -4,9 +4,15 @@ import { createSelector } from 'reselect'; import { NotificationStack } from 'react-notification'; 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 }); // we use styles here to overwrite those built into the library // but there are some styles applied using