diff --git a/src/locales/cs.json b/src/locales/cs.json index 31aa94e4c..1504ba2a2 100644 --- a/src/locales/cs.json +++ b/src/locales/cs.json @@ -175,6 +175,8 @@ "app.assignments.hideAllButton": "Skrýt studentům", "app.assignments.hidePastAssignments": "Celkem {count} {count, plural, one {zadaná úloha má} =2 {zadané úlohy mají} =3 {zadané úlohy mají} =4 {zadané úlohy mají} other {zadaných úloh má}} termín v minulosti. Skrýt staré úlohy.", "app.assignments.invertSelection": "Invertovat", + "app.assignments.lockedSubmissions.reason": "Důvod", + "app.assignments.lockedSubmissions.title": "Odevzdávání řešení je v tuto chvíli zablokováno", "app.assignments.maxPoints": "Maximum bodů", "app.assignments.maxPointsShort": "Max. bodů", "app.assignments.name": "Název zadání", diff --git a/src/locales/en.json b/src/locales/en.json index ac988db2a..7aef8fc60 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -175,6 +175,8 @@ "app.assignments.hideAllButton": "Set Hidden", "app.assignments.hidePastAssignments": "Total {count} {count, plural, one {assignment} other {assignments}} {count, plural, one {is past its} other {are past their}} deadline. Hide old assignments.", "app.assignments.invertSelection": "Invert", + "app.assignments.lockedSubmissions.reason": "Reason", + "app.assignments.lockedSubmissions.title": "Submissions are currently locked out", "app.assignments.maxPoints": "Max. Points", "app.assignments.maxPointsShort": "Max. points", "app.assignments.name": "Assignment name", diff --git a/src/pages/Assignment/Assignment.js b/src/pages/Assignment/Assignment.js index 956aa3624..7b7bc2708 100644 --- a/src/pages/Assignment/Assignment.js +++ b/src/pages/Assignment/Assignment.js @@ -2,11 +2,12 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import ImmutablePropTypes from 'react-immutable-proptypes'; import { connect } from 'react-redux'; -import { FormattedMessage } from 'react-intl'; +import { FormattedMessage, injectIntl } from 'react-intl'; import { Col, Row } from 'react-bootstrap'; import Box from '../../components/widgets/Box'; import Callout from '../../components/widgets/Callout'; +import OptionalPopoverWrapper from '../../components/widgets/OptionalPopoverWrapper'; import { fetchAssignmentIfNeeded, syncWithExercise } from '../../redux/modules/assignments'; import { canSubmit } from '../../redux/modules/canSubmit'; @@ -54,6 +55,11 @@ import LoadingSolutionsTable from '../../components/Assignments/SolutionsTable/L import FailedLoadingSolutionsTable from '../../components/Assignments/SolutionsTable/FailedLoadingSolutionsTable'; import { hasPermissions } from '../../helpers/common'; +const getReason = ({ lockedReason }, locale) => + typeof lockedReason === 'object' + ? lockedReason[locale] || lockedReason.en || Object.values(lockedReason)[0] || 'Reason unknown.' + : lockedReason; + class Assignment extends Component { static loadAsync = ({ assignmentId }, dispatch, { userId }) => Promise.all([ @@ -99,6 +105,7 @@ class Assignment extends Component { fetchManyStatus, assignmentSolversLoading, assignmentSolverSelector, + intl: { locale }, } = this.props; return ( @@ -179,21 +186,50 @@ class Assignment extends Component {

} resource={canSubmit}> {canSubmitObj => ( - + + } + contents={ + <> + + + : + {' '} + {getReason(canSubmitObj, locale)} + + }> + + )}

- + {canSubmitObj.canSubmit && ( + + )} )} @@ -272,30 +308,33 @@ Assignment.propTypes = { assignmentSolverSelector: PropTypes.func.isRequired, reloadCanSubmit: PropTypes.func.isRequired, reloadSolvers: PropTypes.func.isRequired, + intl: PropTypes.object.isRequired, }; -export default connect( - (state, { params: { assignmentId, userId = null } }) => { - const loggedInUserId = loggedInUserIdSelector(state); - return { - assignment: getAssignment(state, assignmentId), - submitting: isSubmitting(state), - runtimeEnvironments: assignmentEnvironmentsSelector(state)(assignmentId), - userId, - loggedInUserId, - isStudentOf: loggedUserIsStudentOfSelector(state), - canSubmit: canSubmitSolution(assignmentId)(state), - solutions: getUserSolutionsSortedData(state)(userId || loggedInUserId, assignmentId), - fetchManyStatus: fetchManyUserSolutionsStatus(state)(userId || loggedInUserId, assignmentId), - assignmentSolversLoading: isAssignmentSolversLoading(state), - assignmentSolverSelector: getAssignmentSolverSelector(state), - }; - }, - (dispatch, { params: { assignmentId } }) => ({ - init: userId => () => dispatch(init(userId, assignmentId)), - loadAsync: userId => Assignment.loadAsync({ assignmentId }, dispatch, { userId }), - exerciseSync: () => dispatch(syncWithExercise(assignmentId)), - reloadCanSubmit: () => dispatch(canSubmit(assignmentId)), - reloadSolvers: (assignmentId, userId) => dispatch(fetchAssignmentSolvers({ assignmentId, userId })), - }) -)(Assignment); +export default injectIntl( + connect( + (state, { params: { assignmentId, userId = null } }) => { + const loggedInUserId = loggedInUserIdSelector(state); + return { + assignment: getAssignment(state, assignmentId), + submitting: isSubmitting(state), + runtimeEnvironments: assignmentEnvironmentsSelector(state)(assignmentId), + userId, + loggedInUserId, + isStudentOf: loggedUserIsStudentOfSelector(state), + canSubmit: canSubmitSolution(assignmentId)(state), + solutions: getUserSolutionsSortedData(state)(userId || loggedInUserId, assignmentId), + fetchManyStatus: fetchManyUserSolutionsStatus(state)(userId || loggedInUserId, assignmentId), + assignmentSolversLoading: isAssignmentSolversLoading(state), + assignmentSolverSelector: getAssignmentSolverSelector(state), + }; + }, + (dispatch, { params: { assignmentId } }) => ({ + init: userId => () => dispatch(init(userId, assignmentId)), + loadAsync: userId => Assignment.loadAsync({ assignmentId }, dispatch, { userId }), + exerciseSync: () => dispatch(syncWithExercise(assignmentId)), + reloadCanSubmit: () => dispatch(canSubmit(assignmentId)), + reloadSolvers: (assignmentId, userId) => dispatch(fetchAssignmentSolvers({ assignmentId, userId })), + }) + )(Assignment) +); diff --git a/src/pages/Solution/Solution.js b/src/pages/Solution/Solution.js index c8e04a70f..478b8be31 100644 --- a/src/pages/Solution/Solution.js +++ b/src/pages/Solution/Solution.js @@ -206,29 +206,28 @@ class Solution extends Component { )} {isStudent && ( - - - } resource={canSubmit}> - {canSubmitObj => ( - - )} - - - - + + {canSubmitObj => + canSubmitObj.canSubmit && ( + + + + + + + ) + } + )} {hasPermissions(solution, 'review') &&