Skip to content

Commit

Permalink
Showing the lockedReason from can-submit endpoint if the submissions …
Browse files Browse the repository at this point in the history
…are locked out.
  • Loading branch information
krulis-martin committed Oct 29, 2023
1 parent 73b474d commit f233473
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 61 deletions.
2 changes: 2 additions & 0 deletions src/locales/cs.json
Original file line number Diff line number Diff line change
Expand Up @@ -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. <a>Skrýt staré úlohy.</a>",
"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í",
Expand Down
2 changes: 2 additions & 0 deletions src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -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. <a>Hide old assignments.</a>",
"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",
Expand Down
115 changes: 77 additions & 38 deletions src/pages/Assignment/Assignment.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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([
Expand Down Expand Up @@ -99,6 +105,7 @@ class Assignment extends Component {
fetchManyStatus,
assignmentSolversLoading,
assignmentSolverSelector,
intl: { locale },
} = this.props;

return (
Expand Down Expand Up @@ -179,21 +186,50 @@ class Assignment extends Component {
<p className="text-center">
<ResourceRenderer loading={<SubmitSolutionButton disabled={true} />} resource={canSubmit}>
{canSubmitObj => (
<SubmitSolutionButton onClick={init(assignment.id)} disabled={!canSubmitObj.canSubmit} />
<OptionalPopoverWrapper
container={this}
popoverId={`submit-locked-${assignment.id}`}
placement="bottom"
hide={!canSubmitObj.lockedReason}
title={
<FormattedMessage
id="app.assignments.lockedSubmissions.title"
defaultMessage="Submissions are currently locked out"
/>
}
contents={
<>
<strong>
<FormattedMessage
id="app.assignments.lockedSubmissions.reason"
defaultMessage="Reason"
/>
:
</strong>{' '}
{getReason(canSubmitObj, locale)}
</>
}>
<SubmitSolutionButton
onClick={init(assignment.id)}
disabled={!canSubmitObj.canSubmit}
/>
</OptionalPopoverWrapper>
)}
</ResourceRenderer>
</p>
<SubmitSolutionContainer
userId={loggedInUserId}
id={assignment.id}
onSubmit={submitSolution}
presubmitValidation={presubmitSolution}
afterEvaluationStarts={this.reloadAfterSubmit}
onReset={init}
isOpen={submitting}
solutionFilesLimit={assignment.solutionFilesLimit}
solutionSizeLimit={assignment.solutionSizeLimit}
/>
{canSubmitObj.canSubmit && (
<SubmitSolutionContainer
userId={loggedInUserId}
id={assignment.id}
onSubmit={submitSolution}
presubmitValidation={presubmitSolution}
afterEvaluationStarts={this.reloadAfterSubmit}
onReset={init}
isOpen={submitting}
solutionFilesLimit={assignment.solutionFilesLimit}
solutionSizeLimit={assignment.solutionSizeLimit}
/>
)}
</div>
)}

Expand Down Expand Up @@ -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)
);
45 changes: 22 additions & 23 deletions src/pages/Solution/Solution.js
Original file line number Diff line number Diff line change
Expand Up @@ -206,29 +206,28 @@ class Solution extends Component {
)}

{isStudent && (
<Row>
<Col xs={12} className="mb-3 text-right">
<ResourceRenderer loading={<SubmitSolutionButton disabled={true} />} resource={canSubmit}>
{canSubmitObj => (
<SubmitSolutionButton
onClick={initCanSubmit(assignment.id)}
disabled={!canSubmitObj.canSubmit}
/>
)}
</ResourceRenderer>
<SubmitSolutionContainer
userId={loggedInUserId}
id={assignment.id}
onSubmit={submitSolution}
presubmitValidation={presubmitSolution}
afterEvaluationStarts={reloadCanSubmit}
onReset={initCanSubmit}
isOpen={submitting}
solutionFilesLimit={assignment.solutionFilesLimit}
solutionSizeLimit={assignment.solutionSizeLimit}
/>
</Col>
</Row>
<ResourceRenderer resource={canSubmit}>
{canSubmitObj =>
canSubmitObj.canSubmit && (
<Row>
<Col xs={12} className="mb-3 text-right">
<SubmitSolutionButton onClick={initCanSubmit(assignment.id)} />
<SubmitSolutionContainer
userId={loggedInUserId}
id={assignment.id}
onSubmit={submitSolution}
presubmitValidation={presubmitSolution}
afterEvaluationStarts={reloadCanSubmit}
onReset={initCanSubmit}
isOpen={submitting}
solutionFilesLimit={assignment.solutionFilesLimit}
solutionSizeLimit={assignment.solutionSizeLimit}
/>
</Col>
</Row>
)
}
</ResourceRenderer>
)}

{hasPermissions(solution, 'review') &&
Expand Down

0 comments on commit f233473

Please sign in to comment.