From 4298b963cb783d61c036ab643793dfb149e2c66d Mon Sep 17 00:00:00 2001 From: Petr Stefan Date: Tue, 24 Oct 2017 19:17:33 +0200 Subject: [PATCH] Unaccept solution --- .../buttons/AcceptSolution/AcceptSolution.js | 17 +++++---- .../AcceptedSolutionContainer.js | 17 ++++++--- src/locales/cs.json | 2 +- src/locales/en.json | 2 +- src/redux/modules/submissions.js | 35 ++++++++++++++++++- 5 files changed, 56 insertions(+), 17 deletions(-) diff --git a/src/components/buttons/AcceptSolution/AcceptSolution.js b/src/components/buttons/AcceptSolution/AcceptSolution.js index 4ce3f75b2..2c79fd744 100644 --- a/src/components/buttons/AcceptSolution/AcceptSolution.js +++ b/src/components/buttons/AcceptSolution/AcceptSolution.js @@ -4,28 +4,27 @@ import { FormattedMessage } from 'react-intl'; import Icon from 'react-fontawesome'; import Button from '../../widgets/FlatButton'; -const AcceptSolution = ({ accepted, accept }) => +const AcceptSolution = ({ accepted, accept, unaccept }) => accepted === true - ? : ; AcceptSolution.propTypes = { accepted: PropTypes.bool.isRequired, - accept: PropTypes.func.isRequired + accept: PropTypes.func.isRequired, + unaccept: PropTypes.func.isRequired }; export default AcceptSolution; diff --git a/src/containers/AcceptSolutionContainer/AcceptedSolutionContainer.js b/src/containers/AcceptSolutionContainer/AcceptedSolutionContainer.js index b0b5b53ba..d9c0ab1f0 100644 --- a/src/containers/AcceptSolutionContainer/AcceptedSolutionContainer.js +++ b/src/containers/AcceptSolutionContainer/AcceptedSolutionContainer.js @@ -3,17 +3,23 @@ import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import AcceptSolution from '../../components/buttons/AcceptSolution'; -import { acceptSubmission } from '../../redux/modules/submissions'; +import { + acceptSubmission, + unacceptSubmission +} from '../../redux/modules/submissions'; import { isAccepted } from '../../redux/selectors/submissions'; -const AcceptSolutionContainer = ({ accepted, accept }) => { - return ; +const AcceptSolutionContainer = ({ accepted, accept, unaccept }) => { + return ( + + ); }; AcceptSolutionContainer.propTypes = { id: PropTypes.string.isRequired, accepted: PropTypes.bool.isRequired, - accept: PropTypes.func.isRequired + accept: PropTypes.func.isRequired, + unaccept: PropTypes.func.isRequired }; const mapStateToProps = (state, { id }) => ({ @@ -21,7 +27,8 @@ const mapStateToProps = (state, { id }) => ({ }); const mapDispatchToProps = (dispatch, { id }) => ({ - accept: () => dispatch(acceptSubmission(id)) + accept: () => dispatch(acceptSubmission(id)), + unaccept: () => dispatch(unacceptSubmission(id)) }); export default connect(mapStateToProps, mapDispatchToProps)( diff --git a/src/locales/cs.json b/src/locales/cs.json index db9151316..a49962d11 100644 --- a/src/locales/cs.json +++ b/src/locales/cs.json @@ -1,6 +1,6 @@ { "app.EditEnvironmentLimitsForm.cloneAll.yesNoQuestion": "Do you really want to use these limits for all the tests of all runtime environments?", - "app.acceptSolution.accepted": "Označeno pro hodnocení", + "app.acceptSolution.accepted": "Odebrat označení pro hodnocení", "app.acceptSolution.notAccepted": "Označit pro hodnocení", "app.addLicence.addLicenceTitle": "Přidat novou licenci", "app.addLicence.failed": "Přidávání licence selhalo.", diff --git a/src/locales/en.json b/src/locales/en.json index 0dd7aeb3a..a5a5084dd 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -1,6 +1,6 @@ { "app.EditEnvironmentLimitsForm.cloneAll.yesNoQuestion": "Do you really want to use these limits for all the tests of all runtime environments?", - "app.acceptSolution.accepted": "Marked for grading", + "app.acceptSolution.accepted": "Remove grading mark", "app.acceptSolution.notAccepted": "Mark for grading", "app.addLicence.addLicenceTitle": "Add new licence", "app.addLicence.failed": "Cannot add the licence.", diff --git a/src/redux/modules/submissions.js b/src/redux/modules/submissions.js index d42a0868a..61c2a7408 100644 --- a/src/redux/modules/submissions.js +++ b/src/redux/modules/submissions.js @@ -38,6 +38,10 @@ export const additionalActionTypes = { ACCEPT_PENDING: 'recodex/submissions/ACCEPT_PENDING', ACCEPT_FULFILLED: 'recodex/submissions/ACCEPT_FULFILLED', ACCEPT_FAILED: 'recodex/submissions/ACCEPT_FAILED', + UNACCEPT: 'recodex/submissions/UNACCEPT', + UNACCEPT_PENDING: 'recodex/submissions/UNACCEPT_PENDING', + UNACCEPT_FULFILLED: 'recodex/submissions/UNACCEPT_FULFILLED', + UNACCEPT_FAILED: 'recodex/submissions/UNACCEPT_FAILED', RESUBMIT_ALL: 'recodex/submissions/RESUBMIT_ALL', DOWNLOAD_RESULT_ARCHIVE: 'recodex/files/DOWNLOAD_RESULT_ARCHIVE' }; @@ -58,11 +62,19 @@ export const setPoints = (submissionId, bonusPoints) => export const acceptSubmission = id => createApiAction({ type: additionalActionTypes.ACCEPT, - method: 'GET', + method: 'POST', endpoint: `/submissions/${id}/set-accepted`, meta: { id } }); +export const unacceptSubmission = id => + createApiAction({ + type: additionalActionTypes.UNACCEPT, + method: 'DELETE', + endpoint: `/submissions/${id}/unset-accepted`, + meta: { id } + }); + export const resubmitSubmission = (id, isPrivate, isDebug = true) => createApiAction({ type: submissionActionTypes.SUBMIT, @@ -136,6 +148,27 @@ const reducer = handleActions( ) : item ) + ), + [additionalActionTypes.UNACCEPT_PENDING]: (state, { meta: { id } }) => + state.setIn(['resources', id, 'data', 'accepted'], false), + + [additionalActionTypes.UNACCEPT_FAILED]: (state, { meta: { id } }) => + state.setIn(['resources', id, 'data', 'accepted'], true), + + [additionalActionTypes.UNACCEPT_FULFILLED]: (state, { meta: { id } }) => + state.update('resources', resources => + resources.map( + (item, itemId) => + item.get('data') !== null + ? item.update( + 'data', + data => + itemId === id + ? data.set('accepted', false) + : data.set('accepted', true) + ) + : item + ) ) }), initialState