Skip to content

Commit 87c35d7

Browse files
committed
Adding buttons for selective partial assignment sync with the exercise.
1 parent d94b5d7 commit 87c35d7

File tree

7 files changed

+66
-11
lines changed

7 files changed

+66
-11
lines changed

src/components/Assignments/Assignment/AssignmentSync/AssignmentSync.js

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@ import PropTypes from 'prop-types';
33
import { FormattedMessage } from 'react-intl';
44
import { Row, Col } from 'react-bootstrap';
55

6-
import Button from '../../../widgets/TheButton';
6+
import Button, { TheButtonGroup } from '../../../widgets/TheButton';
77
import Callout from '../../../widgets/Callout';
88
import DateTime from '../../../widgets/DateTime';
99
import { getSyncMessages } from '../../../helpers/assignments.js';
10+
import { SYNC_OPTIONS_ALL, SYNC_OPTIONS_TEXTS, SYNC_OPTIONS_CONFIG } from '../../../../redux/modules/assignments.js';
1011

1112
const AssignmentSync = ({ syncInfo, exerciseSync }) => {
1213
const messages = getSyncMessages(syncInfo);
@@ -39,9 +40,41 @@ const AssignmentSync = ({ syncInfo, exerciseSync }) => {
3940
<ul>{messages}</ul>
4041
</div>
4142
<p>
42-
<Button variant="primary" onClick={exerciseSync} disabled={!syncInfo.isSynchronizationPossible}>
43-
<FormattedMessage id="app.assignment.syncButton" defaultMessage="Update Assignment" />
44-
</Button>
43+
<TheButtonGroup>
44+
{(syncInfo.localizedTexts?.upToDate === false || syncInfo.fileLinks?.upToDate === false) && (
45+
<Button
46+
variant="primary"
47+
onClick={() => exerciseSync(SYNC_OPTIONS_TEXTS)}
48+
disabled={!syncInfo.isSynchronizationPossible}>
49+
<FormattedMessage id="app.assignment.syncTextsButton" defaultMessage="Update Texts" />
50+
</Button>
51+
)}
52+
53+
{(syncInfo.files?.upToDate === false ||
54+
syncInfo.exerciseTests?.upToDate === false ||
55+
syncInfo.configurationType?.upToDate === false ||
56+
syncInfo.scoreConfig?.upToDate === false ||
57+
syncInfo.exerciseConfig?.upToDate === false ||
58+
syncInfo.runtimeEnvironments?.upToDate === false ||
59+
syncInfo.exerciseEnvironmentConfigs?.upToDate === false ||
60+
syncInfo.hardwareGroups?.upToDate === false ||
61+
syncInfo.limits?.upToDate === false ||
62+
syncInfo.mergeJudgeLogs?.upToDate === false) && (
63+
<Button
64+
variant="primary"
65+
onClick={() => exerciseSync(SYNC_OPTIONS_CONFIG)}
66+
disabled={!syncInfo.isSynchronizationPossible}>
67+
<FormattedMessage id="app.assignment.syncConfigButton" defaultMessage="Update Configuration" />
68+
</Button>
69+
)}
70+
71+
<Button
72+
variant="primary"
73+
onClick={() => exerciseSync(SYNC_OPTIONS_ALL)}
74+
disabled={!syncInfo.isSynchronizationPossible}>
75+
<FormattedMessage id="app.assignment.syncAllButton" defaultMessage="Update Whole Assignment" />
76+
</Button>
77+
</TheButtonGroup>
4578

4679
{!syncInfo.isSynchronizationPossible && (
4780
<span style={{ marginLeft: '2em' }} className="text-body-secondary">

src/locales/cs.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,9 @@
126126
"app.assignment.submissionCounterDecreasedByNotEvaluated": "Řešení, která nebyla vyhodnocena nebo jejich vyhodnocení selhalo, se nepočítají do limitu odevzdaných řešení.",
127127
"app.assignment.submissionsCountLimit": "Počet pokusů",
128128
"app.assignment.submissionsCountLimitExplanation": "Maximální počet odevzdaných řešení této úlohy od jednoho studenta. Vyučující můž udělit další pokusy tak, že smaže starší odevzdaná řešení.",
129-
"app.assignment.syncButton": "Aktualizovat zadání",
129+
"app.assignment.syncAllButton": "Aktualizovat celou úlohu",
130130
"app.assignment.syncButton.exerciseBroken": "Aktualizační tlačítko je zakázané, protože konfigurace úlohy je rozbitá. Nejprve musíte úlohu opravit.",
131+
"app.assignment.syncConfigButton": "Aktualizovat konfiguraci",
131132
"app.assignment.syncConfigurationType": "Konfigurace byla přepnuta do pokročilého módu",
132133
"app.assignment.syncDescription": "Aktualizovány byly následující položky:",
133134
"app.assignment.syncExerciseConfig": "Konfigurace úlohy",
@@ -144,6 +145,7 @@
144145
"app.assignment.syncRequiredTitle": "Data úlohy jsou novější než data zadané úlohy",
145146
"app.assignment.syncRuntimeEnvironments": "Výběr běhového prostředí",
146147
"app.assignment.syncScoreConfig": "Konfigurace skóre",
148+
"app.assignment.syncTextsButton": "Aktualizovat texty",
147149
"app.assignment.title": "Podrobnosti zadané úlohy",
148150
"app.assignment.visible": "Viditelná studentům",
149151
"app.assignment.visibleFrom": "Viditelná od",

src/locales/en.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,9 @@
126126
"app.assignment.submissionCounterDecreasedByNotEvaluated": "Failed and not evaluated submissions are not counted when restricting submission attempts.",
127127
"app.assignment.submissionsCountLimit": "Submission attempts",
128128
"app.assignment.submissionsCountLimitExplanation": "Maximal number of solutions logged by one student for this assignment. The teacher may choose to grant additional attempts by deleting old solutions.",
129-
"app.assignment.syncButton": "Update Assignment",
129+
"app.assignment.syncAllButton": "Update Whole Assignment",
130130
"app.assignment.syncButton.exerciseBroken": "The update button is disabled since the exercise is broken. The exercise configuration must be mended first.",
131+
"app.assignment.syncConfigButton": "Update Configuration",
131132
"app.assignment.syncConfigurationType": "Configuration was switched to advanced mode",
132133
"app.assignment.syncDescription": "The following sections were updated:",
133134
"app.assignment.syncExerciseConfig": "Exercise configuration",
@@ -144,6 +145,7 @@
144145
"app.assignment.syncRequiredTitle": "The exercise data are newer than assignment data",
145146
"app.assignment.syncRuntimeEnvironments": "Selection of runtime environments",
146147
"app.assignment.syncScoreConfig": "Score configuration",
148+
"app.assignment.syncTextsButton": "Update Texts",
147149
"app.assignment.title": "Assignment Detail",
148150
"app.assignment.visible": "Visible to students",
149151
"app.assignment.visibleFrom": "Visible from",

src/pages/Assignment/Assignment.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import Box from '../../components/widgets/Box';
99
import Callout from '../../components/widgets/Callout';
1010
import OptionalPopoverWrapper from '../../components/widgets/OptionalPopoverWrapper';
1111

12-
import { fetchAssignmentIfNeeded, syncWithExercise } from '../../redux/modules/assignments.js';
12+
import { fetchAssignmentIfNeeded, syncWithExercise, SYNC_OPTIONS_ALL } from '../../redux/modules/assignments.js';
1313
import { canSubmit } from '../../redux/modules/canSubmit.js';
1414
import {
1515
init,
@@ -342,7 +342,7 @@ export default injectIntl(
342342
(dispatch, { params: { assignmentId } }) => ({
343343
init: userId => () => dispatch(init(userId, assignmentId)),
344344
loadAsync: userId => Assignment.loadAsync({ assignmentId }, dispatch, { userId }),
345-
exerciseSync: () => dispatch(syncWithExercise(assignmentId)),
345+
exerciseSync: (syncOptions = SYNC_OPTIONS_ALL) => dispatch(syncWithExercise(assignmentId, syncOptions)),
346346
reloadCanSubmit: () => dispatch(canSubmit(assignmentId)),
347347
reloadSolvers: (assignmentId, userId) => dispatch(fetchAssignmentSolvers({ assignmentId, userId })),
348348
})

src/pages/EditAssignment/EditAssignment.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import {
2727
editAssignment,
2828
editAssignmentLocalizedTexts,
2929
syncWithExercise,
30+
SYNC_OPTIONS_ALL,
3031
validateAssignment,
3132
fetchAssignmentAsyncJobs,
3233
} from '../../redux/modules/assignments.js';
@@ -227,6 +228,7 @@ class EditAssignment extends Component {
227228
form="editAssignmentLocalizedTexts"
228229
initialValues={assignment ? prepareEditLocalizedTextsInitialValues(assignment) : {}}
229230
onSubmit={this.editLocalizedTextsSubmitHandler}
231+
localizedTextsLinks={assignment.localizedTextsLinks}
230232
/>
231233
)}
232234
</ResourceRenderer>
@@ -314,7 +316,7 @@ export default withLinks(
314316
dispatch(editAssignmentLocalizedTexts(assignmentId, data)).then(() =>
315317
dispatch(fetchAssignmentAsyncJobs(assignmentId))
316318
),
317-
exerciseSync: () => dispatch(syncWithExercise(assignmentId)),
319+
exerciseSync: (syncOptions = SYNC_OPTIONS_ALL) => dispatch(syncWithExercise(assignmentId, syncOptions)),
318320
validateAssignment: version => dispatch(validateAssignment(assignmentId, version)),
319321
})
320322
)(EditAssignment)

src/pages/ExerciseAssignments/ExerciseAssignments.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import {
2727
editAssignment,
2828
deleteAssignment,
2929
syncWithExercise,
30+
SYNC_OPTIONS_ALL,
3031
fetchExerciseAssignments,
3132
} from '../../redux/modules/assignments.js';
3233
import { exerciseSelector } from '../../redux/selectors/exercises.js';
@@ -296,7 +297,7 @@ export default connect(
296297
(dispatch, { params: { exerciseId } }) => ({
297298
loadAsync: () => ExerciseAssignments.loadAsync({ exerciseId }, dispatch),
298299
assignExercise: groupId => dispatch(assignExercise(groupId, exerciseId)),
299-
syncAssignment: id => dispatch(syncWithExercise(id)),
300+
syncAssignment: (id, syncOptions = SYNC_OPTIONS_ALL) => dispatch(syncWithExercise(id, syncOptions)),
300301
editAssignment: (id, body) => dispatch(editAssignment(id, body)),
301302
deleteAssignment: id => dispatch(deleteAssignment(id)),
302303
sendNotification: message => dispatch(sendNotification(exerciseId, message)),

src/redux/modules/assignments.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,26 @@ export const validateAssignment = (id, version) =>
6363
body: { version },
6464
});
6565

66-
export const syncWithExercise = assignmentId =>
66+
export const SYNC_OPTIONS_ALL = [];
67+
export const SYNC_OPTIONS_TEXTS = ['localizedTexts', 'fileLinks'];
68+
export const SYNC_OPTIONS_CONFIG = [
69+
'configurationType',
70+
'exerciseConfig',
71+
'exerciseEnvironmentConfigs',
72+
'exerciseTests',
73+
'files',
74+
'hardwareGroups',
75+
'limits',
76+
'mergeJudgeLogs',
77+
'runtimeEnvironments',
78+
'scoreConfig',
79+
];
80+
export const syncWithExercise = (assignmentId, syncOptions = SYNC_OPTIONS_ALL) =>
6781
createApiAction({
6882
type: additionalActionTypes.SYNC_ASSIGNMENT,
6983
endpoint: `/exercise-assignments/${assignmentId}/sync-exercise`,
7084
method: 'POST',
85+
body: { syncOptions },
7186
meta: { assignmentId },
7287
});
7388

0 commit comments

Comments
 (0)