diff --git a/src/components/CollapsibleFeedback/CollapsibleFeedback.jsx b/src/components/CollapsibleFeedback/CollapsibleFeedback.jsx new file mode 100644 index 00000000..cd48b2ff --- /dev/null +++ b/src/components/CollapsibleFeedback/CollapsibleFeedback.jsx @@ -0,0 +1,40 @@ +import React from 'react'; +import PropTypes from 'prop-types'; + +import { Collapsible } from '@edx/paragon'; +import { useIntl } from '@edx/frontend-platform/i18n'; +import messages from './messages'; + +const CollapsibleFeedback = ({ children, stepScore, stepLabel, defaultOpen }) => { + const { formatMessage } = useIntl(); + const [open, setOpen] = React.useState(defaultOpen); + + const toggle = () => setOpen(!open); + + return ( + + {formatMessage(messages.grade, { stepLabel })} + {stepScore && formatMessage(messages.gradePoints, stepScore)} + + } + open={open} + onToggle={toggle} + > + {children} + + ); +}; +CollapsibleFeedback.defaultProps = {}; +CollapsibleFeedback.propTypes = { + stepLabel: PropTypes.string.isRequired, + stepScore: PropTypes.shape({ + earned: PropTypes.number, + possible: PropTypes.number, + }), + children: PropTypes.node.isRequired, + defaultOpen: PropTypes.bool, +}; + +export default CollapsibleFeedback; diff --git a/src/components/CollapsibleFeedback/MultipleAssessmentStep.jsx b/src/components/CollapsibleFeedback/MultipleAssessmentStep.jsx new file mode 100644 index 00000000..9f5c7d04 --- /dev/null +++ b/src/components/CollapsibleFeedback/MultipleAssessmentStep.jsx @@ -0,0 +1,48 @@ +import React, { Fragment } from 'react'; +import PropTypes from 'prop-types'; + +import CollapsibleFeedback from './CollapsibleFeedback'; +import AssessmentCriterion from './AssessmentCriterion'; + +const MultipleAssessmentStep = ({ + stepLabel, + step, + stepScore, + assessments, + defaultOpen, +}) => ( +
+ + {assessments?.map((assessment, index) => ( + +

+ {stepLabel} {index + 1}: +

+ +
+
+ ))} +
+
+); + +MultipleAssessmentStep.defaultProps = { + defaultOpen: false, +}; +MultipleAssessmentStep.propTypes = { + stepLabel: PropTypes.string.isRequired, + stepScore: PropTypes.shape({ + earned: PropTypes.number, + possible: PropTypes.number, + }), + assessments: PropTypes.arrayOf( + PropTypes.shape({ + selectedOption: PropTypes.number, + // selectedPoints: PropTypes.number, + feedback: PropTypes.string, + }) + ), + defaultOpen: PropTypes.bool, +}; + +export default MultipleAssessmentStep; diff --git a/src/components/CollapsibleFeedback/SingleAssessmentStep.jsx b/src/components/CollapsibleFeedback/SingleAssessmentStep.jsx new file mode 100644 index 00000000..ffb830ce --- /dev/null +++ b/src/components/CollapsibleFeedback/SingleAssessmentStep.jsx @@ -0,0 +1,40 @@ +import React from 'react'; +import PropTypes from 'prop-types'; + +import CollapsibleFeedback from './CollapsibleFeedback'; +import AssessmentCriterion from './AssessmentCriterion'; + +const SingleAssessmentStep = ({ + stepLabel, + step, + stepScore, + assessment, + defaultOpen, +}) => ( + + + +); + +SingleAssessmentStep.defaultProps = { + defaultOpen: false, +}; +SingleAssessmentStep.propTypes = { + stepLabel: PropTypes.string.isRequired, + stepScore: PropTypes.shape({ + earned: PropTypes.number, + possible: PropTypes.number, + }), + assessment: PropTypes.shape({ + selectedOption: PropTypes.number, + // selectedPoints: PropTypes.number, + feedback: PropTypes.string, + }), + defaultOpen: PropTypes.bool, +}; + +export default SingleAssessmentStep; diff --git a/src/components/CollapsibleFeedback/index.jsx b/src/components/CollapsibleFeedback/index.jsx index cd48b2ff..d84328df 100644 --- a/src/components/CollapsibleFeedback/index.jsx +++ b/src/components/CollapsibleFeedback/index.jsx @@ -1,40 +1,5 @@ -import React from 'react'; -import PropTypes from 'prop-types'; - -import { Collapsible } from '@edx/paragon'; -import { useIntl } from '@edx/frontend-platform/i18n'; -import messages from './messages'; - -const CollapsibleFeedback = ({ children, stepScore, stepLabel, defaultOpen }) => { - const { formatMessage } = useIntl(); - const [open, setOpen] = React.useState(defaultOpen); - - const toggle = () => setOpen(!open); - - return ( - - {formatMessage(messages.grade, { stepLabel })} - {stepScore && formatMessage(messages.gradePoints, stepScore)} - - } - open={open} - onToggle={toggle} - > - {children} - - ); -}; -CollapsibleFeedback.defaultProps = {}; -CollapsibleFeedback.propTypes = { - stepLabel: PropTypes.string.isRequired, - stepScore: PropTypes.shape({ - earned: PropTypes.number, - possible: PropTypes.number, - }), - children: PropTypes.node.isRequired, - defaultOpen: PropTypes.bool, -}; - -export default CollapsibleFeedback; +export { default as CollapsibleFeedback } from './CollapsibleFeedback'; +export { default as MultipleAssessmentStep } from './MultipleAssessmentStep'; +export { default as SingleAssessmentStep } from './SingleAssessmentStep'; +export { default as AssessmentCriterion } from './AssessmentCriterion'; +export { default as Feedback } from './Feedback'; \ No newline at end of file diff --git a/src/data/services/lms/fakeData/pageData/assessments.js b/src/data/services/lms/fakeData/pageData/assessments.js index 2449adf8..c64c3713 100644 --- a/src/data/services/lms/fakeData/pageData/assessments.js +++ b/src/data/services/lms/fakeData/pageData/assessments.js @@ -23,7 +23,7 @@ export const getAssessmentState = ({ progressKey, stepConfig }) => { return null; } const out = {}; - out.effectiveAssessmentType = 'staff'; + out.effectiveAssessmentType = 'peer'; if (stepConfig.includes(stepNames.staff)) { out.staff = { stepScore: { earned: 10, possible: 10 }, diff --git a/src/views/GradeView/FinalGrade.jsx b/src/views/GradeView/FinalGrade.jsx index 727c55d8..8b8bf5cc 100644 --- a/src/views/GradeView/FinalGrade.jsx +++ b/src/views/GradeView/FinalGrade.jsx @@ -1,94 +1,49 @@ -import React, { Fragment } from 'react'; +import React from 'react'; import { useIntl } from '@edx/frontend-platform/i18n'; -import CollapsibleFeedback from 'components/CollapsibleFeedback'; import { useAssessmentsData } from 'data/services/lms/hooks/selectors'; import messages from './messages'; -import AssessmentCriterion from 'components/CollapsibleFeedback/AssessmentCriterion'; import InfoPopover from 'components/InfoPopover'; +import { + SingleAssessmentStep, + MultipleAssessmentStep, +} from 'components/CollapsibleFeedback'; const FinalGrade = () => { const { formatMessage } = useIntl(); - const assessments = useAssessmentsData(); - const effectiveStep = assessments.effectiveAssessmentType; + const { effectiveAssessmentType, ...steps } = useAssessmentsData(); - const finalStepScore = assessments[effectiveStep]?.stepScore; + const finalStepScore = steps[effectiveAssessmentType]?.stepScore; - const result = []; - if (assessments.staff) { - const stepLabel = formatMessage(messages.staffStepLabel); - result.push( - - { + const stepLabel = formatMessage(messages[`${step}StepLabel`]); + const StepComponent = ['staff', 'self'].includes(step) + ? SingleAssessmentStep + : MultipleAssessmentStep; + if (step === effectiveAssessmentType) { + result = [ + - - ); - } - if (assessments.peer) { - const stepLabel = formatMessage(messages.peerStepLabel); - result.push( -
- - {assessments.peer.assessments?.map((peer, index) => ( - -

- {stepLabel} {index + 1}: -

- -
-
- ))} -
-
- ); - } - if (assessments.peerUnweighted) { - const stepLabel = formatMessage(messages.unweightedPeerStepLabel); - result.push( -
- - {assessments.peerUnweighted.assessments?.map((peer, index) => ( - -

- {stepLabel} {index + 1}: -

- -
-
- ))} -
-
- ); - } - if (assessments.self) { - const stepLabel = formatMessage(messages.selfStepLabel); - result.push( - - , + ...result, + ]; + } else { + result.push( + - - ); - } + ); + } + }); const [finalGrade, ...rest] = result; @@ -97,7 +52,13 @@ const FinalGrade = () => {

{formatMessage(messages.yourFinalGrade, finalStepScore)} {}}> -

{formatMessage(effectiveStep === 'peer' ? messages.peerAsFinalGradeInfo :messages.finalGradeInfo)}

+

+ {effectiveAssessmentType === 'peer' + ? formatMessage(messages.peerAsFinalGradeInfo) + : formatMessage(messages.finalGradeInfo, { + step: effectiveAssessmentType, + })} +

{finalGrade} diff --git a/src/views/GradeView/messages.js b/src/views/GradeView/messages.js index dca9c8e0..300c6df1 100644 --- a/src/views/GradeView/messages.js +++ b/src/views/GradeView/messages.js @@ -46,7 +46,7 @@ const messages = defineMessages({ defaultMessage: 'Staff', description: 'Staff step label', }, - unweightedPeerStepLabel: { + peerUnweightedStepLabel: { id: 'ora-grade-view.unweightedPeerStepLabel', defaultMessage: 'Unweighted Peer', description: 'Unweighted peer step label',