From 3d671a6381bb0c0a97c26cf9583f34dc3d3deb68 Mon Sep 17 00:00:00 2001 From: Martin Krulis Date: Fri, 26 Jan 2018 01:23:40 +0100 Subject: [PATCH] Reflect exercise.isBroken flag in the UI. --- .../ExercisesListItem/ExercisesListItem.js | 13 ++- .../Exercises/ExercisesName/ExercisesName.js | 13 ++- .../ExercisesSimpleListItem.js | 15 +++- .../Groups/SupervisorsView/SupervisorsView.js | 3 +- .../AssignExerciseButton.js | 26 ++++-- src/components/icons/ExercisePrefixIcons.js | 51 ++++++++++++ .../icons/MaybeLockedExerciseIcon.js | 32 -------- src/components/icons/index.js | 2 +- src/locales/cs.json | 3 + src/locales/en.json | 3 + src/pages/EditExercise/EditExercise.js | 16 ++++ .../EditExerciseSimpleConfig.js | 16 ++++ src/pages/Exercise/Exercise.js | 82 ++++++++++++------- 13 files changed, 196 insertions(+), 79 deletions(-) create mode 100644 src/components/icons/ExercisePrefixIcons.js delete mode 100644 src/components/icons/MaybeLockedExerciseIcon.js diff --git a/src/components/Exercises/ExercisesListItem/ExercisesListItem.js b/src/components/Exercises/ExercisesListItem/ExercisesListItem.js index b675d24a2..1734600db 100644 --- a/src/components/Exercises/ExercisesListItem/ExercisesListItem.js +++ b/src/components/Exercises/ExercisesListItem/ExercisesListItem.js @@ -9,7 +9,7 @@ import { Link } from 'react-router'; import withLinks from '../../../hoc/withLinks'; import { LocalizedExerciseName } from '../../helpers/LocalizedNames'; -import { MaybeLockedExerciseIcon } from '../../icons'; +import { ExercisePrefixIcons } from '../../icons'; const ExercisesListItem = ({ id, @@ -20,6 +20,8 @@ const ExercisesListItem = ({ localizedTexts, createdAt, isLocked, + isBroken, + validationError, createActions, locale, links: { EXERCISE_URI_FACTORY } @@ -29,7 +31,12 @@ const ExercisesListItem = ({ - + @@ -74,6 +81,8 @@ ExercisesListItem.propTypes = { difficulty: PropTypes.string.isRequired, createdAt: PropTypes.number.isRequired, isLocked: PropTypes.bool.isRequired, + isBroken: PropTypes.bool.isRequired, + validationError: PropTypes.string, localizedTexts: PropTypes.array.isRequired, createActions: PropTypes.func, locale: PropTypes.string.isRequired, diff --git a/src/components/Exercises/ExercisesName/ExercisesName.js b/src/components/Exercises/ExercisesName/ExercisesName.js index 19b00a590..8a740cbdb 100644 --- a/src/components/Exercises/ExercisesName/ExercisesName.js +++ b/src/components/Exercises/ExercisesName/ExercisesName.js @@ -5,18 +5,25 @@ import { Link } from 'react-router'; import withLinks from '../../../hoc/withLinks'; import { LocalizedExerciseName } from '../../helpers/LocalizedNames'; -import { MaybeLockedExerciseIcon } from '../../icons'; +import { ExercisePrefixIcons } from '../../icons'; const ExercisesName = ({ id, name, localizedTexts, isLocked, + isBroken, + validationError, noLink, links: { EXERCISE_URI_FACTORY } }) => - + {noLink ? @@ -31,6 +38,8 @@ ExercisesName.propTypes = { name: PropTypes.string.isRequired, localizedTexts: PropTypes.array.isRequired, isLocked: PropTypes.bool.isRequired, + isBroken: PropTypes.bool.isRequired, + validationError: PropTypes.string, noLink: PropTypes.bool, links: PropTypes.object }; diff --git a/src/components/Exercises/ExercisesSimpleListItem/ExercisesSimpleListItem.js b/src/components/Exercises/ExercisesSimpleListItem/ExercisesSimpleListItem.js index 294c6a32f..1a14fa2cf 100644 --- a/src/components/Exercises/ExercisesSimpleListItem/ExercisesSimpleListItem.js +++ b/src/components/Exercises/ExercisesSimpleListItem/ExercisesSimpleListItem.js @@ -6,7 +6,7 @@ import { Link } from 'react-router'; import withLinks from '../../../hoc/withLinks'; import { LocalizedExerciseName } from '../../helpers/LocalizedNames'; -import { MaybeLockedExerciseIcon } from '../../icons'; +import { ExercisePrefixIcons } from '../../icons'; const ExercisesSimpleListItem = ({ id, @@ -14,6 +14,8 @@ const ExercisesSimpleListItem = ({ difficulty, authorId, isLocked, + isBroken, + validationError, localizedTexts, createActions, locale, @@ -21,7 +23,12 @@ const ExercisesSimpleListItem = ({ }) => - + @@ -36,7 +43,7 @@ const ExercisesSimpleListItem = ({ {createActions && - {createActions(id, isLocked)} + {createActions(id, isLocked, isBroken)} } ; @@ -46,6 +53,8 @@ ExercisesSimpleListItem.propTypes = { name: PropTypes.string.isRequired, difficulty: PropTypes.string.isRequired, isLocked: PropTypes.bool.isRequired, + isBroken: PropTypes.bool.isRequired, + validationError: PropTypes.string, localizedTexts: PropTypes.array.isRequired, createActions: PropTypes.func, locale: PropTypes.string.isRequired, diff --git a/src/components/Groups/SupervisorsView/SupervisorsView.js b/src/components/Groups/SupervisorsView/SupervisorsView.js index 7e492a435..b99fabc77 100644 --- a/src/components/Groups/SupervisorsView/SupervisorsView.js +++ b/src/components/Groups/SupervisorsView/SupervisorsView.js @@ -140,10 +140,11 @@ const SupervisorsView = ({ {(...exercises) => + createActions={(exerciseId, isLocked, isBroken) =>
assignExercise(exerciseId)} /> diff --git a/src/components/buttons/AssignExerciseButton/AssignExerciseButton.js b/src/components/buttons/AssignExerciseButton/AssignExerciseButton.js index 91c73b280..25c5cb36a 100644 --- a/src/components/buttons/AssignExerciseButton/AssignExerciseButton.js +++ b/src/components/buttons/AssignExerciseButton/AssignExerciseButton.js @@ -1,19 +1,30 @@ import React from 'react'; import PropTypes from 'prop-types'; import { FormattedMessage } from 'react-intl'; +import Icon from 'react-fontawesome'; import Button from '../../widgets/FlatButton'; import { SendIcon, InfoIcon } from '../../../components/icons'; -const AssignExerciseButton = ({ isLocked, assignExercise, ...props }) => { - if (isLocked) { +const AssignExerciseButton = ({ + isLocked, + isBroken, + assignExercise, + ...props +}) => { + if (isLocked || isBroken) { return ( ); } else { @@ -32,6 +43,7 @@ const AssignExerciseButton = ({ isLocked, assignExercise, ...props }) => { AssignExerciseButton.propTypes = { isLocked: PropTypes.bool.isRequired, + isBroken: PropTypes.bool.isRequired, assignExercise: PropTypes.func.isRequired }; diff --git a/src/components/icons/ExercisePrefixIcons.js b/src/components/icons/ExercisePrefixIcons.js new file mode 100644 index 000000000..a1904b1dd --- /dev/null +++ b/src/components/icons/ExercisePrefixIcons.js @@ -0,0 +1,51 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { FormattedMessage } from 'react-intl'; +import Icon from 'react-fontawesome'; +import { OverlayTrigger, Tooltip } from 'react-bootstrap'; + +const ExercisePrefixIcons = ({ id, isLocked, isBroken, ...props }) => + + {isLocked && + + + + + } + > + + +    + } + {isBroken && + + + + + } + > + + +    + } + ; + +ExercisePrefixIcons.propTypes = { + id: PropTypes.any.isRequired, + isLocked: PropTypes.bool.isRequired, + isBroken: PropTypes.bool.isRequired +}; + +export default ExercisePrefixIcons; diff --git a/src/components/icons/MaybeLockedExerciseIcon.js b/src/components/icons/MaybeLockedExerciseIcon.js deleted file mode 100644 index 48b666bd7..000000000 --- a/src/components/icons/MaybeLockedExerciseIcon.js +++ /dev/null @@ -1,32 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import { FormattedMessage } from 'react-intl'; -import Icon from 'react-fontawesome'; -import { OverlayTrigger, Tooltip } from 'react-bootstrap'; - -const MaybeLockedExerciseIcon = ({ id, isLocked, ...props }) => - isLocked && ( - - - - - } - > - - - {' '} - - ); - -MaybeLockedExerciseIcon.propTypes = { - id: PropTypes.any.isRequired, - isLocked: PropTypes.bool.isRequired -}; - -export default MaybeLockedExerciseIcon; diff --git a/src/components/icons/index.js b/src/components/icons/index.js index d8b1e699a..8ad560be5 100644 --- a/src/components/icons/index.js +++ b/src/components/icons/index.js @@ -20,6 +20,6 @@ export { default as SettingsIcon } from './SettingsIcon'; export { default as MaybeBonusAssignmentIcon } from './MaybeBonusAssignmentIcon'; -export { default as MaybeLockedExerciseIcon } from './MaybeLockedExerciseIcon'; +export { default as ExercisePrefixIcons } from './ExercisePrefixIcons'; export { default as CopyIcon } from './CopyIcon'; export { default as LocalIcon } from './LocalIcon'; diff --git a/src/locales/cs.json b/src/locales/cs.json index d91ca9912..7b83ba6f2 100644 --- a/src/locales/cs.json +++ b/src/locales/cs.json @@ -5,6 +5,7 @@ "app.EditSimpleLimitsForm.validation.NaN": "Given value is not a number.", "app.EditSimpleLimitsForm.validation.tooHigh": "Given value exceeds the recommended maximum ({max}).", "app.EditSimpleLimitsForm.validation.tooLow": "Given value is below the recommended minimum ({min}).", + "app.ExercisePrefixIcons.isLocked": "Exercise is locked by author and cannot be assigned", "app.acceptSolution.accepted": "Zrušit jako finální", "app.acceptSolution.notAccepted": "Akceptovat jako finální", "app.addLicence.addLicenceTitle": "Přidat novou licenci", @@ -32,6 +33,7 @@ "app.adminAssignmentsTable.noAssignments": "Nejsou dostupné žádné úlohy.", "app.adminAssignmentsTableRow.edit": "Upravit", "app.adminAssignmentsTableRow.loading": "Načítají se zadané úlohy ...", + "app.assignExerciseButton.isBroken": "Broken", "app.assignExerciseButton.isLocked": "Locked", "app.assignemntStatusIcon.evaluationFailed": "Žádné řesení nebylo správně vyhodnoceno.", "app.assignemntStatusIcon.failed": "Žádné správné řešení nebylo zatím odevzdáno.", @@ -486,6 +488,7 @@ "app.exercise.forked": "Duplikováno z:", "app.exercise.groups": "Groups:", "app.exercise.groupsBox": "Skupiny", + "app.exercise.isBroken": "Exercise configuration is incorrect and needs fixing", "app.exercise.isLocked": "Is locked:", "app.exercise.isPublic": "Is public:", "app.exercise.noReferenceSolutions": "Nyní zde nejsou žádná referenční řešení pro tuto úlohu.", diff --git a/src/locales/en.json b/src/locales/en.json index 64e8e3082..ecad5041e 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -5,6 +5,7 @@ "app.EditSimpleLimitsForm.validation.NaN": "Given value is not a number.", "app.EditSimpleLimitsForm.validation.tooHigh": "Given value exceeds the recommended maximum ({max}).", "app.EditSimpleLimitsForm.validation.tooLow": "Given value is below the recommended minimum ({min}).", + "app.ExercisePrefixIcons.isLocked": "Exercise is locked by author and cannot be assigned", "app.acceptSolution.accepted": "Revoke as Final", "app.acceptSolution.notAccepted": "Accept as Final", "app.addLicence.addLicenceTitle": "Add new licence", @@ -32,6 +33,7 @@ "app.adminAssignmentsTable.noAssignments": "There are no assignments.", "app.adminAssignmentsTableRow.edit": "Edit", "app.adminAssignmentsTableRow.loading": "Loading assignments ...", + "app.assignExerciseButton.isBroken": "Broken", "app.assignExerciseButton.isLocked": "Locked", "app.assignemntStatusIcon.evaluationFailed": "No solution was evaluated correctly by ReCodEx.", "app.assignemntStatusIcon.failed": "No correct solution was submitted yet.", @@ -486,6 +488,7 @@ "app.exercise.forked": "Forked from:", "app.exercise.groups": "Groups:", "app.exercise.groupsBox": "Groups", + "app.exercise.isBroken": "Exercise configuration is incorrect and needs fixing", "app.exercise.isLocked": "Is locked:", "app.exercise.isPublic": "Is public:", "app.exercise.noReferenceSolutions": "There are no reference solutions for this exercise yet.", diff --git a/src/pages/EditExercise/EditExercise.js b/src/pages/EditExercise/EditExercise.js index 912c73caa..90a198d39 100644 --- a/src/pages/EditExercise/EditExercise.js +++ b/src/pages/EditExercise/EditExercise.js @@ -6,6 +6,7 @@ import { Row, Col } from 'react-bootstrap'; import { connect } from 'react-redux'; import { push } from 'react-router-redux'; import { reset, getFormValues } from 'redux-form'; +import Icon from 'react-fontawesome'; import Page from '../../components/layout/Page'; import Box from '../../components/widgets/Box'; @@ -88,6 +89,21 @@ class EditExercise extends Component { > {exercise =>
+ {exercise.isBroken && + + +
+

+    + +

+ {exercise.validationError} +
+ +
}
+ {exercise.isBroken && + + +
+

+    + +

+ {exercise.validationError} +
+ +
} {exercise =>
+ {exercise.isBroken && + + +
+

+    + +

+ {exercise.validationError} +
+ +
} {canEditExercise(exercise.id) && @@ -239,33 +255,36 @@ class Exercise extends Component { {exercise.localizedTexts.length > 0 && }
- - -

- } - noPadding - > - + +

+ } + noPadding > - {() => - - this.assignExercise(groupId)} - />} - />} -
-
+ + {() => + + + this.assignExercise(groupId)} + />} + />} + +
} - - {(...pipelines) => + + {pipelines => @@ -419,8 +441,6 @@ class Exercise extends Component {

}
- -