diff --git a/src/containers/CriterionContainer/CriterionFeedback.jsx b/src/containers/CriterionContainer/CriterionFeedback.jsx index 811f5f9..7b65693 100644 --- a/src/containers/CriterionContainer/CriterionFeedback.jsx +++ b/src/containers/CriterionContainer/CriterionFeedback.jsx @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import { Form } from '@openedx/paragon'; -import { injectIntl, intlShape } from '@edx/frontend-platform/i18n'; +import { useIntl } from '@edx/frontend-platform/i18n'; import { feedbackRequirement } from 'data/services/lms/constants'; import { actions, selectors } from 'data/redux'; @@ -12,60 +12,56 @@ import messages from './messages'; /** * */ -export class CriterionFeedback extends React.Component { - constructor(props) { - super(props); - this.onChange = this.onChange.bind(this); - } +export const CriterionFeedback = ({ + orderNum, + isGrading, + config, + setValue, + value, + isInvalid, +}) => { + const intl = useIntl(); - onChange(event) { - this.props.setValue({ + const onChange = (event) => { + setValue({ value: event.target.value, - orderNum: this.props.orderNum, + orderNum, }); - } + }; - get commentMessage() { - const { config, isGrading } = this.props; - let commentMessage = this.translate(isGrading ? messages.addComments : messages.comments); + const translate = (msg) => intl.formatMessage(msg); + + const getCommentMessage = () => { + let commentMessage = translate(isGrading ? messages.addComments : messages.comments); if (config === feedbackRequirement.optional) { - commentMessage += ` ${this.translate(messages.optional)}`; + commentMessage += ` ${translate(messages.optional)}`; } return commentMessage; + }; + + if (config === feedbackRequirement.disabled) { + return null; } - translate = (msg) => this.props.intl.formatMessage(msg); - - render() { - const { - config, - isGrading, - value, - isInvalid, - } = this.props; - if (config === feedbackRequirement.disabled) { - return null; - } - return ( - - - {isInvalid && ( - - {this.translate(messages.criterionFeedbackError)} - - )} - - ); - } -} + return ( + + + {isInvalid && ( + + {translate(messages.criterionFeedbackError)} + + )} + + ); +}; CriterionFeedback.defaultProps = { value: '', @@ -74,8 +70,6 @@ CriterionFeedback.defaultProps = { CriterionFeedback.propTypes = { orderNum: PropTypes.number.isRequired, isGrading: PropTypes.bool.isRequired, - // injected - intl: intlShape.isRequired, // redux config: PropTypes.string.isRequired, setValue: PropTypes.func.isRequired, @@ -93,6 +87,4 @@ export const mapDispatchToProps = { setValue: actions.grading.setCriterionFeedback, }; -export default injectIntl( - connect(mapStateToProps, mapDispatchToProps)(CriterionFeedback), -); +export default connect(mapStateToProps, mapDispatchToProps)(CriterionFeedback); diff --git a/src/containers/CriterionContainer/CriterionFeedback.test.jsx b/src/containers/CriterionContainer/CriterionFeedback.test.jsx index 34f0130..ac4ab11 100644 --- a/src/containers/CriterionContainer/CriterionFeedback.test.jsx +++ b/src/containers/CriterionContainer/CriterionFeedback.test.jsx @@ -6,7 +6,6 @@ import { feedbackRequirement, gradeStatuses, } from 'data/services/lms/constants'; -import { formatMessage } from 'testUtils'; import { CriterionFeedback, mapStateToProps, @@ -38,7 +37,6 @@ jest.unmock('react'); describe('Criterion Feedback', () => { const props = { - intl: { formatMessage }, orderNum: 1, config: 'config string', isGrading: true, diff --git a/src/containers/CriterionContainer/RadioCriterion.jsx b/src/containers/CriterionContainer/RadioCriterion.jsx index 7b5d67f..88e79ee 100644 --- a/src/containers/CriterionContainer/RadioCriterion.jsx +++ b/src/containers/CriterionContainer/RadioCriterion.jsx @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import { Form } from '@openedx/paragon'; -import { injectIntl, intlShape } from '@edx/frontend-platform/i18n'; +import { useIntl } from '@edx/frontend-platform/i18n'; import { actions, selectors } from 'data/redux'; import messages from './messages'; @@ -11,51 +11,46 @@ import messages from './messages'; /** * */ -export class RadioCriterion extends React.Component { - constructor(props) { - super(props); - this.onChange = this.onChange.bind(this); - } +export const RadioCriterion = ({ + orderNum, + isGrading, + config, + data, + setCriterionOption, + isInvalid, +}) => { + const intl = useIntl(); - onChange(event) { - this.props.setCriterionOption({ - orderNum: this.props.orderNum, + const onChange = (event) => { + setCriterionOption({ + orderNum, value: event.target.value, }); - } + }; - render() { - const { - config, - data, - intl, - isGrading, - isInvalid, - } = this.props; - return ( - - {config.options.map((option) => ( - - {option.label} - - ))} - {isInvalid && ( - - {intl.formatMessage(messages.rubricSelectedError)} - - )} - - ); - } -} + return ( + + {config.options.map((option) => ( + + {option.label} + + ))} + {isInvalid && ( + + {intl.formatMessage(messages.rubricSelectedError)} + + )} + + ); +}; RadioCriterion.defaultProps = { data: { @@ -67,8 +62,6 @@ RadioCriterion.defaultProps = { RadioCriterion.propTypes = { orderNum: PropTypes.number.isRequired, isGrading: PropTypes.bool.isRequired, - // injected - intl: intlShape.isRequired, // redux config: PropTypes.shape({ prompt: PropTypes.string, @@ -99,4 +92,4 @@ export const mapDispatchToProps = { setCriterionOption: actions.grading.setCriterionOption, }; -export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(RadioCriterion)); +export default connect(mapStateToProps, mapDispatchToProps)(RadioCriterion); diff --git a/src/containers/CriterionContainer/RadioCriterion.test.jsx b/src/containers/CriterionContainer/RadioCriterion.test.jsx index e0a07c4..7b55063 100644 --- a/src/containers/CriterionContainer/RadioCriterion.test.jsx +++ b/src/containers/CriterionContainer/RadioCriterion.test.jsx @@ -1,7 +1,6 @@ import { render } from '@testing-library/react'; import { actions, selectors } from 'data/redux'; -import { formatMessage } from 'testUtils'; import { RadioCriterion, mapDispatchToProps, @@ -33,7 +32,6 @@ jest.unmock('react'); describe('Radio Criterion Container', () => { const props = { - intl: { formatMessage }, orderNum: 1, isGrading: true, config: { diff --git a/src/containers/ResponseDisplay/SubmissionFiles.jsx b/src/containers/ResponseDisplay/SubmissionFiles.jsx index d255128..3e21f32 100644 --- a/src/containers/ResponseDisplay/SubmissionFiles.jsx +++ b/src/containers/ResponseDisplay/SubmissionFiles.jsx @@ -5,7 +5,7 @@ import { Card, Collapsible, Icon, DataTable, Button, } from '@openedx/paragon'; import { ArrowDropDown, ArrowDropUp, WarningFilled } from '@openedx/paragon/icons'; -import { injectIntl, intlShape } from '@edx/frontend-platform/i18n'; +import { useIntl } from '@edx/frontend-platform/i18n'; import { downloadAllLimit, downloadSingleLimit } from 'data/constants/files'; @@ -19,93 +19,91 @@ import messages from './messages'; /** * */ -export class SubmissionFiles extends React.Component { - get title() { - return `${this.props.intl.formatMessage(messages.submissionFiles)} (${this.props.files.length})`; - } +export const SubmissionFiles = ({ files }) => { + const intl = useIntl(); - get canDownload() { + const getTitle = () => `${intl.formatMessage(messages.submissionFiles)} (${files.length})`; + + const getCanDownload = () => { let totalFileSize = 0; - const exceedFileSize = this.props.files.some(file => { + const exceedFileSize = files.some(file => { totalFileSize += file.size; return file.size > downloadSingleLimit; }); return !exceedFileSize && totalFileSize < downloadAllLimit; - } + }; - render() { - const { files, intl } = this.props; - return ( - - {files.length ? ( - <> - - -

{this.title}

- - - - - - -
- -
- - - + return ( + + {files.length ? ( + <> + + +

{getTitle()}

+ + + + + + +
+ +
+ + + +
+
+
+ + { + getCanDownload() ? : ( +
+ + {intl.formatMessage(messages.exceedFileSize)} +
- - - - { - this.canDownload ? : ( -
- - {intl.formatMessage(messages.exceedFileSize)} - -
- ) - } -
- - ) : ( -
-

{this.title}

-
- )} -
- ); - } -} + ) + } + + + ) : ( +
+

{getTitle()}

+
+ )} + + ); +}; SubmissionFiles.defaultProps = { files: [], }; + SubmissionFiles.propTypes = { files: PropTypes.arrayOf( PropTypes.shape({ @@ -114,7 +112,6 @@ SubmissionFiles.propTypes = { downloadURL: PropTypes.string, }), ), - intl: intlShape.isRequired, }; -export default injectIntl(SubmissionFiles); +export default SubmissionFiles; diff --git a/src/containers/ResponseDisplay/SubmissionFiles.test.jsx b/src/containers/ResponseDisplay/SubmissionFiles.test.jsx index 9bf088c..0025520 100644 --- a/src/containers/ResponseDisplay/SubmissionFiles.test.jsx +++ b/src/containers/ResponseDisplay/SubmissionFiles.test.jsx @@ -32,7 +32,7 @@ describe('SubmissionFiles', () => { }; let el; beforeEach(() => { - el = shallow(); + el = shallow(); }); describe('snapshot', () => { @@ -41,13 +41,13 @@ describe('SubmissionFiles', () => { }); test('files does not exist', () => { - el = shallow(); + el = shallow(); expect(el.snapshot).toMatchSnapshot(); }); test('files size exceed', () => { const files = props.files.map(file => ({ ...file, size: downloadSingleLimit + 1 })); - el = shallow(); + el = shallow(); expect(el.snapshot).toMatchSnapshot(); }); }); @@ -70,7 +70,7 @@ describe('SubmissionFiles', () => { oneFileExceed.forEach(file => expect(file.size < downloadAllLimit).toEqual(true)); - el = shallow(); + el = shallow(); expect(el.instance.findByTestId('file-download')).toHaveLength(0); const warningEl = el.instance.findByTestId('exceed-download-text')[0]; @@ -90,7 +90,7 @@ describe('SubmissionFiles', () => { expect(file.size < downloadSingleLimit).toEqual(true); }); - el = shallow(); + el = shallow(); expect(el.instance.findByTestId('file-download')).toHaveLength(0); }); }); diff --git a/src/containers/ReviewActions/components/OverrideGradeConfirmModal.jsx b/src/containers/ReviewActions/components/OverrideGradeConfirmModal.jsx index 27cbd52..42b40b2 100644 --- a/src/containers/ReviewActions/components/OverrideGradeConfirmModal.jsx +++ b/src/containers/ReviewActions/components/OverrideGradeConfirmModal.jsx @@ -1,33 +1,36 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { injectIntl, intlShape } from '@edx/frontend-platform/i18n'; +import { useIntl } from '@edx/frontend-platform/i18n'; import ConfirmModal from 'components/ConfirmModal'; import messages from './messages'; -export const OverrideGradeConfirmModal = ({ - intl, - isOpen, - onCancel, - onConfirm, -}) => ( - -); +export const OverrideGradeConfirmModal = ( + { + isOpen, + onCancel, + onConfirm, + }, +) => { + const intl = useIntl(); + + return ( + + ); +}; OverrideGradeConfirmModal.propTypes = { isOpen: PropTypes.bool.isRequired, onCancel: PropTypes.func.isRequired, onConfirm: PropTypes.func.isRequired, - // injected - intl: intlShape.isRequired, }; -export default injectIntl(OverrideGradeConfirmModal); +export default OverrideGradeConfirmModal; diff --git a/src/containers/ReviewActions/components/OverrideGradeConfirmModal.test.jsx b/src/containers/ReviewActions/components/OverrideGradeConfirmModal.test.jsx index a6d50ee..7f48882 100644 --- a/src/containers/ReviewActions/components/OverrideGradeConfirmModal.test.jsx +++ b/src/containers/ReviewActions/components/OverrideGradeConfirmModal.test.jsx @@ -1,13 +1,11 @@ import { shallow } from '@edx/react-unit-test-utils'; -import { formatMessage } from 'testUtils'; import { OverrideGradeConfirmModal } from './OverrideGradeConfirmModal'; jest.mock('components/ConfirmModal', () => 'ConfirmModal'); describe('OverrideGradeConfirmModal', () => { const props = { - intl: { formatMessage }, isOpen: false, onCancel: jest.fn().mockName('this.props.onCancel'), onConfirm: jest.fn().mockName('this.props.onConfirm'), diff --git a/src/containers/ReviewModal/components/CloseReviewConfirmModal.jsx b/src/containers/ReviewModal/components/CloseReviewConfirmModal.jsx index 4e5cb06..33862b9 100644 --- a/src/containers/ReviewModal/components/CloseReviewConfirmModal.jsx +++ b/src/containers/ReviewModal/components/CloseReviewConfirmModal.jsx @@ -1,33 +1,36 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { injectIntl, intlShape } from '@edx/frontend-platform/i18n'; +import { useIntl } from '@edx/frontend-platform/i18n'; import ConfirmModal from 'components/ConfirmModal'; import messages from './messages'; -export const CloseReviewConfirmModal = ({ - intl, - isOpen, - onCancel, - onConfirm, -}) => ( - -); +export const CloseReviewConfirmModal = ( + { + isOpen, + onCancel, + onConfirm, + }, +) => { + const intl = useIntl(); + + return ( + + ); +}; CloseReviewConfirmModal.propTypes = { isOpen: PropTypes.bool.isRequired, onCancel: PropTypes.func.isRequired, onConfirm: PropTypes.func.isRequired, - // injected - intl: intlShape.isRequired, }; -export default injectIntl(CloseReviewConfirmModal); +export default CloseReviewConfirmModal; diff --git a/src/containers/ReviewModal/components/CloseReviewConfirmModal.test.jsx b/src/containers/ReviewModal/components/CloseReviewConfirmModal.test.jsx index 5c11d74..e1016eb 100644 --- a/src/containers/ReviewModal/components/CloseReviewConfirmModal.test.jsx +++ b/src/containers/ReviewModal/components/CloseReviewConfirmModal.test.jsx @@ -1,13 +1,11 @@ import { shallow } from '@edx/react-unit-test-utils'; -import { formatMessage } from 'testUtils'; import { CloseReviewConfirmModal } from './CloseReviewConfirmModal'; jest.mock('components/ConfirmModal', () => 'ConfirmModal'); describe('CloseReviewConfirmModal', () => { const props = { - intl: { formatMessage }, isOpen: false, onCancel: jest.fn().mockName('this.props.onCancel'), onConfirm: jest.fn().mockName('this.props.onConfirm'),