Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/ReCodEx/web-app into simp…
Browse files Browse the repository at this point in the history
…le_exercise_form
  • Loading branch information
Martin Krulis committed Nov 29, 2017
2 parents 36c1653 + d537017 commit d63ba8e
Show file tree
Hide file tree
Showing 23 changed files with 190 additions and 91 deletions.
1 change: 1 addition & 0 deletions .env-sample
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ NODE_ENV=production
API_BASE=https://recodex.projekty.ms.mff.cuni.cz:4000/v1
PORT=443
# WEBPACK_DEV_SERVER_PORT=8081 # might be usefull for dev environment, if port 8081 is necessary for something
# If the REDUX_DEV_SERVER_PORT is not defined, the server will not be started.
# REDUX_DEV_SERVER_PORT=8082

TITLE=ReCodEx
Expand Down
22 changes: 16 additions & 6 deletions bin/dev.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import React from 'react';
import Express from 'express';
import webpack from 'webpack';
import WebpackDevServer from 'webpack-dev-server';
Expand All @@ -9,7 +8,7 @@ import remotedev from 'remotedev-server';

const PORT = process.env.PORT || 8080;
const WEBPACK_DEV_SERVER_PORT = process.env.WEBPACK_DEV_SERVER_PORT || 8081;
const REDUX_DEV_SERVER_PORT = process.env.REDUX_DEV_SERVER_PORT || 8082;
const REDUX_DEV_SERVER_PORT = process.env.REDUX_DEV_SERVER_PORT || null;

let app = new Express();
app.set('view engine', 'ejs');
Expand Down Expand Up @@ -39,10 +38,21 @@ var server = new WebpackDevServer(webpack(config), {
stats: { colors: true }
});

remotedev({
hostname: '127.0.0.1',
port: REDUX_DEV_SERVER_PORT
});
if (REDUX_DEV_SERVER_PORT) {
console.log(
`${colors.yellow('ReduxDevServer')} is running on ${colors.underline(
`http://localhost:${REDUX_DEV_SERVER_PORT}`
)}`
);
remotedev({
hostname: '127.0.0.1',
port: REDUX_DEV_SERVER_PORT
});
} else {
console.log(
'No ReduxDevServer port defined, using embeded redux dev tools instead.'
);
}

server.listen(WEBPACK_DEV_SERVER_PORT, 'localhost', () => {
console.log(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,20 @@ const AssignmentStatusIcon = ({ id, status, accepted = false }) => {
/>
);

case 'missing-submission':
return (
<Status
id={id}
icon={<Icon name="exclamation-triangle" className="text-red" />}
message={
<FormattedMessage
id="app.assignemntStatusIcon.solutionMissingSubmission"
defaultMessage="The solution was not submitted for evaluation probably due to an error. You may need to resubmit it."
/>
}
/>
);

default:
return (
<Status
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,15 @@ import AssignmentStatusIcon from '../Assignment/AssignmentStatusIcon';
const NotEvaluatedSubmissionTableRow = ({
link,
note,
solution: { createdAt }
solution: { createdAt },
lastSubmission
}) =>
<tr>
<td>
<AssignmentStatusIcon id={link} status="work-in-progress" />
<AssignmentStatusIcon
id={link}
status={lastSubmission ? 'work-in-progress' : 'missing-submission'}
/>
</td>
<td>
<FormattedDate value={createdAt * 1000} />
Expand All @@ -26,8 +30,8 @@ const NotEvaluatedSubmissionTableRow = ({
<td className="text-right">
<Link to={link} className="btn btn-flat btn-default btn-xs">
<FormattedMessage
id="app.submissionsTable.findOutResult"
defaultMessage="Find out results of evaluation"
id="app.submissionsTable.showDetails"
defaultMessage="Show details"
/>
</Link>
</td>
Expand All @@ -38,7 +42,8 @@ NotEvaluatedSubmissionTableRow.propTypes = {
note: PropTypes.string.isRequired,
solution: PropTypes.shape({
createdAt: PropTypes.number.isRequired
}).isRequired
}).isRequired,
lastSubmission: PropTypes.object
};

export default NotEvaluatedSubmissionTableRow;
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@ const SubmissionsTable = ({
const id = data.id;
const link = SUBMISSION_DETAIL_URI_FACTORY(assignmentId, id);

switch (data.lastSubmission.evaluationStatus) {
switch (data.lastSubmission
? data.lastSubmission.evaluationStatus
: null) {
case 'done':
return (
<SuccessfulSubmissionTableRow
Expand All @@ -79,12 +81,14 @@ const SubmissionsTable = ({
return (
<FailedSubmissionTableRow {...data} key={id} link={link} />
);
case null:
case 'work-in-progress':
return (
<NotEvaluatedSubmissionTableRow
{...data}
key={id}
link={link}
lastSubmission={data.lastSubmission}
/>
);
case 'evaluation-failed':
Expand Down
26 changes: 15 additions & 11 deletions src/components/Submissions/SubmissionDetail/SubmissionDetail.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ class SubmissionDetail extends Component {

componentWillMount() {
this.setState({
activeSubmissionId: this.props.submission.lastSubmission.id
activeSubmissionId: this.props.submission.lastSubmission
? this.props.submission.lastSubmission.id
: null
});
}

Expand All @@ -42,14 +44,16 @@ class SubmissionDetail extends Component {
evaluations
} = this.props;
const { openFileId, activeSubmissionId } = this.state;
const {
submittedBy,
evaluation,
isCorrect,
evaluationStatus,
...restSub
} = evaluations.toJS()[activeSubmissionId].data;

if (activeSubmissionId) {
var {
submittedBy,
evaluation,
isCorrect,
evaluationStatus,
...restSub
} = evaluations.toJS()[activeSubmissionId].data;
} else evaluationStatus = 'missing-submission';
return (
<div>
<Row>
Expand Down Expand Up @@ -118,7 +122,8 @@ class SubmissionDetail extends Component {
<DownloadResultArchiveContainer submissionId={restSub.id} />
</Col>
</Row>}
{isSupervisor &&
{activeSubmissionId &&
isSupervisor &&
<Row>
<Col lg={12}>
<ResourceRenderer resource={evaluations.toArray()}>
Expand Down Expand Up @@ -151,8 +156,7 @@ SubmissionDetail.propTypes = {
submission: PropTypes.shape({
id: PropTypes.string.isRequired,
note: PropTypes.string,
lastSubmission: PropTypes.shape({ id: PropTypes.string.isRequired })
.isRequired,
lastSubmission: PropTypes.shape({ id: PropTypes.string.isRequired }),
solution: PropTypes.shape({
createdAt: PropTypes.number.isRequired,
userId: PropTypes.string.isRequired,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,8 @@ const SubmissionStatus = ({
</td>
<th>
<FormattedMessage
id="app.submission.isCorrect"
defaultMessage="Solution is correct:"
id="app.submission.evaluationStatus"
defaultMessage="Evaluation Status:"
/>
</th>
<td>
Expand All @@ -128,6 +128,11 @@ const SubmissionStatus = ({
id="app.submission.evaluation.status.systemFailiure"
defaultMessage="Evaluation process had failed and your submission could not have been evaluated. Please submit the solution once more. If you keep receiving errors please contact the administrator of this project."
/>}
{evaluationStatus === 'missing-submission' &&
<FormattedMessage
id="app.submission.evaluation.status.solutionMissingSubmission"
defaultMessage="Solution was not submitted for evaluation. This was probably caused by an error in the assignment configuration."
/>}
</strong>
</td>
</tr>
Expand Down
6 changes: 1 addition & 5 deletions src/components/buttons/DeleteButton/DeleteButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,7 @@ import {
} from '../../../redux/helpers/resourceManager';

const DeleteButton = ({ resource, deleteResource, disabled, ...props }) => {
if (!resource) {
return null;
}

if (isDeleted(resource)) {
if (!resource || isDeleted(resource)) {
return <DeletedButton {...props} disabled={disabled} />;
}

Expand Down
10 changes: 4 additions & 6 deletions src/components/buttons/DeleteButton/DeletingFailedButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,20 @@ import { FormattedMessage } from 'react-intl';
import Button from '../../widgets/FlatButton';
import { FailedIcon } from '../../icons';

const DeletingFailedButton = ({ onClick, ...props }) => (
const DeletingFailedButton = ({ onClick, ...props }) =>
<Button
bsStyle="default"
bsSize="sm"
className="btn-flat"
onClick={onClick}
{...props}
>
<FailedIcon />
{' '}
<FailedIcon />{' '}
<FormattedMessage
id="app.deleteButton.deleting"
id="app.deleteButton.deletingFailed"
defaultMessage="Deleting failed"
/>
</Button>
);
</Button>;

DeletingFailedButton.propTypes = {
onClick: PropTypes.func
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,12 @@ const DeleteExerciseButtonContainer = ({
deleteExercise,
onDeleted,
...props
}) => (
}) =>
<DeleteButton
{...props}
resource={exercise}
deleteResource={deleteExercise}
/>
);
/>;

DeleteExerciseButtonContainer.propTypes = {
id: PropTypes.string.isRequired,
Expand All @@ -32,8 +31,11 @@ export default connect(
}),
(dispatch, { id, onDeleted }) => ({
deleteExercise: () => {
onDeleted && onDeleted();
return dispatch(deleteExercise(id));
const promise = dispatch(deleteExercise(id));
if (onDeleted) {
promise.then(onDeleted);
}
return promise;
}
})
)(DeleteExerciseButtonContainer);
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import Button from '../../components/widgets/FlatButton';
import { LinkContainer } from 'react-router-bootstrap';
import Icon from 'react-fontawesome';

import { fetchGroupsIfNeeded } from '../../redux/modules/groups';
import { fetchPublicGroupsIfNeeded } from '../../redux/modules/publicGroups';
import { fetchSisStatusIfNeeded } from '../../redux/modules/sisStatus';
import {
fetchSisSupervisedCourses,
Expand All @@ -21,7 +21,7 @@ import { sisPossibleParentsSelector } from '../../redux/selectors/sisPossiblePar
import { sisStateSelector } from '../../redux/selectors/sisStatus';
import { sisSupervisedCoursesSelector } from '../../redux/selectors/sisSupervisedCourses';
import { loggedInUserIdSelector } from '../../redux/selectors/auth';
import { groupDataAccessorSelector } from '../../redux/selectors/groups';
import { publicGroupDataAccessorSelector } from '../../redux/selectors/publicGroups';

import UsersNameContainer from '../UsersNameContainer';
import ResourceRenderer from '../../components/helpers/ResourceRenderer';
Expand Down Expand Up @@ -72,7 +72,12 @@ class SisSupervisorGroupsContainer extends Component {
.then(res => res.value)
.then(parents =>
parents.map(parent =>
dispatch(fetchGroupsIfNeeded(...parent.parentGroupsIds))
dispatch(
fetchPublicGroupsIfNeeded(
parent.id,
...parent.parentGroupsIds
)
)
)
)
)
Expand Down Expand Up @@ -341,7 +346,7 @@ export default injectIntl(
currentUserId,
sisCourses: sisSupervisedCoursesSelector(state),
sisPossibleParents: sisPossibleParentsSelector(state),
groupsAccessor: groupDataAccessorSelector(state)
groupsAccessor: publicGroupDataAccessorSelector(state)
};
},
dispatch => ({
Expand Down
17 changes: 10 additions & 7 deletions src/locales/cs.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
"app.assignemntStatusIcon.inProgress": "Řešení úlohy je právě vyhodnocováno.",
"app.assignemntStatusIcon.none": "Zatím nebyla odevzdána žádná řešení.",
"app.assignemntStatusIcon.ok": "Úloha byla úspěšně splněna.",
"app.assignemntStatusIcon.solutionMissingSubmission": "The solution was not submitted for evaluation probably due to an error. You may need to resubmit it.",
"app.assignment.alreadySubmitted": "Already submitted:",
"app.assignment.canSubmit": "Můžete odevzdat více řešení:",
"app.assignment.deadline": "Termín odevzdání",
"app.assignment.editSettings": "Upravit nastavení zadané úlohy",
Expand Down Expand Up @@ -141,7 +143,8 @@
"app.deleteButton.confirm": "Opravdu toto chcete smazat? Tato operace nemůže být vrácena.",
"app.deleteButton.delete": "Smazat",
"app.deleteButton.deleted": "Smazáno.",
"app.deleteButton.deleting": "Mazání selhalo",
"app.deleteButton.deleting": "Mazání ...",
"app.deleteButton.deletingFailed": "Mazání selhalo",
"app.editAssignment.deleteAssignment": "Smazat zadání úlohy",
"app.editAssignment.deleteAssignmentWarning": "Smazání zadané úlohy odstraní všechna studentská řešní. Pro případné obnovení těchto dat prosím kontaktujte správce ReCodExu.",
"app.editAssignment.description": "Změnit nastavení zadání úlohy včetně jejích limitů",
Expand Down Expand Up @@ -276,7 +279,6 @@
"app.editGroupForm.successNew": "Create group",
"app.editGroupForm.titleEdit": "Edit group",
"app.editGroupForm.titleNew": "Create new group",
"app.editGroupForm.validation.description": "Please fill the description of the group.",
"app.editGroupForm.validation.emptyName": "Please fill the name of the group.",
"app.editGroupForm.validation.localizedText": "Please fill localized information.",
"app.editGroupForm.validation.localizedText.locale": "Please select the language.",
Expand Down Expand Up @@ -777,6 +779,7 @@
"app.resourceDependendBreadcrumbItem.loading": "Načítání ...",
"app.resourceRenderer.loading": "Načítání ...",
"app.resourceRenderer.loadingFailed": "Načítání se nezdařilo.",
"app.resubmitSolution.confirm": "Are you sure you want to resubmit this solution?",
"app.resubmitSolution.resubmitAll": "Znovu vyhodnotit všechna řešení této zadané úlohy",
"app.resubmitSolution.resubmitAllConfirm": "Opravdu chcete vyhodnotit všechna řešení všech studentů tohoto zadání úlohy? Tato akce může trvat velmi dlouho.",
"app.resubmitSolution.resubmitDebug": "Resubmit (debug mode)",
Expand Down Expand Up @@ -836,18 +839,18 @@
"app.submission.evaluation.bonusPoints": "Bonusové body:",
"app.submission.evaluation.status.failed": "Řešení nesplňuje zadaná kritéria.",
"app.submission.evaluation.status.isCorrect": "Řešení splňuje zadaná kritérii.",
"app.submission.evaluation.status.solutionMissingSubmission": "Solution was not submitted for evaluation. This was probably caused by an error in the assignment configuration.",
"app.submission.evaluation.status.systemFailiure": "Vyhodnocení selhalo a Řešení nebylo ohodnoceno. Prosíme odešlete Řešení ještě jednou. Pokud problém přetrvává, obraťte se na správce systému.",
"app.submission.evaluation.status.workInProgress": "Vyhodnocování řešení ještě nebylo dokončeno.",
"app.submission.evaluation.title": "Vyhodnocení řešení",
"app.submission.evaluation.title.testResults": "Výsledky testů",
"app.submission.isCorrect": "Řešení je správné:",
"app.submission.evaluationStatus": "Evaluation Status:",
"app.submission.note": "Poznámka:",
"app.submission.originalSubmission": "Původní řešení:",
"app.submission.reevaluatedBy": "Reevaluated by:",
"app.submission.submittedAt": "Odevzdáno:",
"app.submission.submittedBy": "Odevzdáno cvičícím:",
"app.submission.title": "Řešení",
"app.submissionEvaluation.active": "Active",
"app.submissionEvaluation.select": "Select",
"app.submissionEvaluation.selected": "Selected",
"app.submissionEvaluation.title": "Other submissions of this solution",
"app.submissionStatus.accepted": "Toto řešení bylo připnuto cvičícím.",
"app.submissions.testResultsTable.exitCode": "Exit code",
Expand All @@ -860,7 +863,6 @@
"app.submissions.testResultsTable.testName": "Název testu",
"app.submissions.testResultsTable.timeExceeded": "Časový limit",
"app.submissionsTable.failedLoading": "Nebylo možné načíst odevzdaná řešení.",
"app.submissionsTable.findOutResult": "Zjistit výsledky vyhodnocení",
"app.submissionsTable.loading": "Načítají se odezvdaná řešení ...",
"app.submissionsTable.noSolutionsFound": "Zatím nebyla odevzdána žádná řešení.",
"app.submissionsTable.note": "Poznámka",
Expand All @@ -869,6 +871,7 @@
"app.submissionsTable.solutionValidity": "Správnost řešení",
"app.submissionsTable.submissionDate": "Datum odevzdání",
"app.submissionsTable.submitNewSolution": "Odevzdat nové řešení",
"app.submissionsTable.title": "Submitted solutions",
"app.submissionsTableContainer.title": "Odevzdaná řešení",
"app.submistSolution.instructions": "Musíte připojit alespoň jeden soubor se zdrojovým kódem a počkat, než jsou všechny soubory nahrány na server. Pokud nastane problém při uploadu některých soborů, nahrajte je znovu nebo soubory odeberte. Jméno souboru NESMÍ OBSAHOVAT žádné nestandardní znaky (například v kódování UTF-8).",
"app.submistSolution.submitFailed": "Odevzdané řešení bylo aktivně odmítnuto. Toto je obvykle způsobeno nahráním souborů se jménem obsahujícím nestandardní znaky nebo špatnou koncovkou. Pokud nemůžete odevzdat řešení bez zjevného důvodu, kontaktujte prosím svého cvičícího.",
Expand Down
Loading

0 comments on commit d63ba8e

Please sign in to comment.