Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 14 additions & 10 deletions src/components/forms/MultiAssignForm/MultiAssignForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import SubmitButton from '../SubmitButton';
import { getGroupCanonicalLocalizedName } from '../../../helpers/getLocalizedData';

const MultiAssignForm = ({
anyTouched,
dirty,
submitting,
handleSubmit,
submitFailed: hasFailed,
Expand Down Expand Up @@ -41,8 +41,8 @@ const MultiAssignForm = ({
)
.map((group, i) =>
<Field
key={i}
name={`groups.${group.id}`}
key={group.id}
name={`groups.id${group.id}`}
component={CheckboxField}
onOff
label={getGroupCanonicalLocalizedName(group, groupsAccessor, locale)}
Expand Down Expand Up @@ -172,21 +172,21 @@ const MultiAssignForm = ({
id="multiAssignForm"
invalid={invalid}
submitting={submitting}
dirty={anyTouched}
dirty={dirty}
hasSucceeded={hasSucceeded}
hasFailed={hasFailed}
handleSubmit={data => handleSubmit(data).then(() => reset())}
messages={{
submit: (
<FormattedMessage
id="app.multiAssignForm.submit"
defaultMessage="Assign exercise"
defaultMessage="Assign Exercise"
/>
),
submitting: (
<FormattedMessage
id="app.multiAssignForm.submitting"
defaultMessage="Assigning exercise ..."
defaultMessage="Assigning Exercise ..."
/>
),
success: (
Expand All @@ -204,14 +204,18 @@ MultiAssignForm.propTypes = {
initialValues: PropTypes.object,
values: PropTypes.object,
handleSubmit: PropTypes.func.isRequired,
anyTouched: PropTypes.bool,
dirty: PropTypes.bool,
submitting: PropTypes.bool,
submitFailed: PropTypes.bool,
submitSucceeded: PropTypes.bool,
invalid: PropTypes.bool,
reset: PropTypes.func.isRequired,
firstDeadline: PropTypes.oneOfType([PropTypes.number, PropTypes.object]), // object == moment.js instance
allowSecondDeadline: PropTypes.oneOfType([PropTypes.bool, PropTypes.string]),
firstDeadline: PropTypes.oneOfType([
PropTypes.number,
PropTypes.string,
PropTypes.object
]), // object == moment.js instance
allowSecondDeadline: PropTypes.bool,
groups: PropTypes.array.isRequired,
groupsAccessor: PropTypes.func.isRequired,
locale: PropTypes.string.isRequired
Expand All @@ -238,7 +242,6 @@ const validate = ({
groups
}) => {
const errors = {};

if (
!groups ||
Object.keys(groups).length === 0 ||
Expand Down Expand Up @@ -344,5 +347,6 @@ const validate = ({
export default reduxForm({
form: 'multiAssign',
enableReinitialize: true,
keepDirtyOnReinitialize: false,
validate
})(MultiAssignForm);
13 changes: 11 additions & 2 deletions src/components/helpers/ResourceRenderer/ResourceRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ class ResourceRenderer extends Component {
this.oldData = null;
};

componentWillUpdate = () => {
// Reset caching variables ...
this.oldResources = null;
this.oldData = null;
};

// Perform rendering of the childs whilst keeping resource data cached ...
renderReady = resources => {
const { children: ready, returnAsArray = false } = this.props;
Expand All @@ -81,7 +87,9 @@ class ResourceRenderer extends Component {
.map(
(res, idx) =>
// If a particular resource did not change, re-use its old data
this.oldResources && this.oldResources[idx] === res
this.oldResources &&
this.oldResources[idx] === res &&
this.oldResources[idx].get('data') === res.get('data')
? this.oldData[idx]
: getJsData(res)
);
Expand Down Expand Up @@ -129,7 +137,8 @@ ResourceRenderer.propTypes = {
hiddenUntilReady: PropTypes.bool,
forceLoading: PropTypes.bool,
noIcons: PropTypes.bool,
returnAsArray: PropTypes.bool
returnAsArray: PropTypes.bool,
debug: PropTypes.bool
};

export default ResourceRenderer;
12 changes: 6 additions & 6 deletions src/locales/cs.json
Original file line number Diff line number Diff line change
Expand Up @@ -785,20 +785,20 @@
"app.maybeBonusAssignmentIcon.isBonus": "Je bonusová",
"app.maybePublicIcon.isNotPublic": "Není veřejné",
"app.maybePublicIcon.isPublic": "Je veřejné",
"app.multiAssignForm.allowSecondDeadline": "Allow second deadline.",
"app.multiAssignForm.allowSecondDeadline": "Povolit druhý deadline.",
"app.multiAssignForm.canViewLimitRatios": "Visibility of memory and time ratios",
"app.multiAssignForm.chooseFirstDeadlineBeforeSecondDeadline": "You must select the date of the first deadline before selecting the date of the second deadline.",
"app.multiAssignForm.failed": "Saving failed. Please try again later.",
"app.multiAssignForm.firstDeadline": "First deadline:",
"app.multiAssignForm.firstDeadline": "První deadline:",
"app.multiAssignForm.isBonus": "Assignment is bonus one and points from it are not included in students overall score",
"app.multiAssignForm.maxPointsBeforeFirstDeadline": "Maximum amount of points received when submitted before the deadline:",
"app.multiAssignForm.maxPointsBeforeSecondDeadline": "Maximum amount of points received when submitted before the second deadline:",
"app.multiAssignForm.pointsPercentualThreshold": "Minimum percentage of points which submissions have to gain:",
"app.multiAssignForm.secondDeadline": "Second deadline:",
"app.multiAssignForm.secondDeadline": "Druhý deadline:",
"app.multiAssignForm.submissionsCountLimit": "Submissions count limit:",
"app.multiAssignForm.submit": "Assign exercise",
"app.multiAssignForm.submitting": "Assigning exercise ...",
"app.multiAssignForm.success": "Exercise was assigned.",
"app.multiAssignForm.submit": "Zadat úlohu",
"app.multiAssignForm.submitting": "Zadávám úlohu ...",
"app.multiAssignForm.success": "Úloha byla zadána.",
"app.multiAssignForm.validation.emptyDeadline": "Please fill the date and time of the deadline.",
"app.multiAssignForm.validation.emptyGroups": "Please select one or more groups to assign exercise.",
"app.multiAssignForm.validation.maxPointsBeforeFirstDeadline": "Please fill the maximum number of points received when submitted before the deadline with a nonnegative integer.",
Expand Down
4 changes: 2 additions & 2 deletions src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -796,8 +796,8 @@
"app.multiAssignForm.pointsPercentualThreshold": "Minimum percentage of points which submissions have to gain:",
"app.multiAssignForm.secondDeadline": "Second deadline:",
"app.multiAssignForm.submissionsCountLimit": "Submissions count limit:",
"app.multiAssignForm.submit": "Assign exercise",
"app.multiAssignForm.submitting": "Assigning exercise ...",
"app.multiAssignForm.submit": "Assign Exercise",
"app.multiAssignForm.submitting": "Assigning Exercise ...",
"app.multiAssignForm.success": "Exercise was assigned.",
"app.multiAssignForm.validation.emptyDeadline": "Please fill the date and time of the deadline.",
"app.multiAssignForm.validation.emptyGroups": "Please select one or more groups to assign exercise.",
Expand Down
45 changes: 40 additions & 5 deletions src/pages/Exercise/Exercise.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { LinkContainer } from 'react-router-bootstrap';
import Icon from 'react-fontawesome';
import { formValueSelector } from 'redux-form';
import moment from 'moment';
import { defaultMemoize } from 'reselect';

import SupplementaryFilesTableContainer from '../../containers/SupplementaryFilesTableContainer/SupplementaryFilesTableContainer';
import Button from '../../components/widgets/FlatButton';
Expand Down Expand Up @@ -124,6 +125,26 @@ class Exercise extends Component {
this.setState({ forkId: Math.random().toString() });
}

multiAssignFormInitialValues = defaultMemoize(visibleGroups => {
const groups = {};
visibleGroups.forEach(g => {
groups[`id${g.id}`] = false;
});

return {
groups,
submissionsCountLimit: '',
firstDeadline: '',
secondDeadline: '',
allowSecondDeadline: false,
maxPointsBeforeFirstDeadline: '',
maxPointsBeforeSecondDeadline: '',
canViewLimitRatios: false,
pointsPercentualThreshold: 0,
isBonus: false
};
});

assignExercise = formData => {
const { assignExercise, editAssignment } = this.props;

Expand All @@ -134,14 +155,22 @@ class Exercise extends Component {

let actions = [];

for (const groupId of groups) {
for (const groupIdMangled of groups) {
const groupId = groupIdMangled.replace(/^id/, '');
const groupPromise = assignExercise(
groupId
).then(({ value: assigment }) => {
let assignmentData = Object.assign({}, assigment, formData, {
firstDeadline: moment(formData.firstDeadline).unix(),
secondDeadline: moment(formData.secondDeadline).unix(),
submissionsCountLimit: Number(formData.submissionsCountLimit),
pointsPercentualThreshold: Number(formData.pointsPercentualThreshold),
maxPointsBeforeFirstDeadline: Number(
formData.maxPointsBeforeFirstDeadline
),
maxPointsBeforeSecondDeadline: Number(
formData.maxPointsBeforeSecondDeadline
),
isPublic: true
});
if (!assignmentData.allowSecondDeadline) {
Expand Down Expand Up @@ -270,8 +299,7 @@ class Exercise extends Component {
{exercise.localizedTexts.length > 0 &&
<LocalizedTexts locales={exercise.localizedTexts} />}
</div>
{isSuperAdmin &&
!exercise.isBroken &&
{!exercise.isBroken &&
!exercise.isLocked &&
<Box
title={formatMessage(messages.groupsBox)}
Expand All @@ -288,6 +316,9 @@ class Exercise extends Component {
<ResourceRenderer resource={groups.toArray()} returnAsArray>
{visibleGroups =>
<MultiAssignForm
initialValues={this.multiAssignFormInitialValues(
visibleGroups
)}
groups={visibleGroups}
onSubmit={this.assignExercise}
firstDeadline={firstDeadline}
Expand Down Expand Up @@ -504,8 +535,12 @@ Exercise.propTypes = {
groups: ImmutablePropTypes.map,
isSuperAdmin: PropTypes.bool,
groupsAccessor: PropTypes.func.isRequired,
firstDeadline: PropTypes.oneOfType([PropTypes.number, PropTypes.object]),
allowSecondDeadline: PropTypes.oneOfType([PropTypes.bool, PropTypes.string])
firstDeadline: PropTypes.oneOfType([
PropTypes.number,
PropTypes.string,
PropTypes.object
]),
allowSecondDeadline: PropTypes.bool
};

const editMultiAssignFormSelector = formValueSelector('multiAssign');
Expand Down