diff --git a/.eslintrc.js b/.eslintrc.js index 6fc94024b..e3a476429 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -14,6 +14,15 @@ module.exports = createConfig( 'no-restricted-exports': 'off', // There is no reason to disallow this syntax anymore; we don't use regenerator-runtime in new browsers 'no-restricted-syntax': 'off', + 'no-restricted-imports': ['error', { + patterns: [ + { + group: ['@edx/frontend-platform/i18n'], + importNames: ['injectIntl'], + message: "Use 'useIntl' hook instead of injectIntl.", + }, + ], + }], }, settings: { // Import URLs should be resolved using aliases diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 01c7ba382..5c58eb3c3 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -30,9 +30,9 @@ We're trying to move away from some deprecated patterns in this codebase. Please check if your PR meets these recommendations before asking for a review: - [ ] Any _new_ files are using TypeScript (`.ts`, `.tsx`). -- [ ] Deprecated `propTypes`, `defaultProps`, and `injectIntl` patterns are not used in any new or modified code. +- [ ] Avoid `propTypes` and `defaultProps` in any new or modified code. - [ ] Tests should use the helpers in `src/testUtils.tsx` (specifically `initializeMocks`) - [ ] Do not add new fields to the Redux state/store. Use React Context to share state among multiple components. - [ ] Use React Query to load data from REST APIs. See any `apiHooks.ts` in this repo for examples. - [ ] All new i18n messages in `messages.ts` files have a `description` for translators to use. -- [ ] Imports avoid using `../`. To import from parent folders, use `@src`, e.g. `import { initializeMocks } from '@src/testUtils';` instead of `from '../../../../testUtils'` +- [ ] Avoid using `../` in import paths. To import from parent folders, use `@src`, e.g. `import { initializeMocks } from '@src/testUtils';` instead of `from '../../../../testUtils'` diff --git a/plugins/course-apps/proctoring/Settings.test.jsx b/plugins/course-apps/proctoring/Settings.test.jsx index 6cdd33aa1..65c6ca7b7 100644 --- a/plugins/course-apps/proctoring/Settings.test.jsx +++ b/plugins/course-apps/proctoring/Settings.test.jsx @@ -6,7 +6,7 @@ import MockAdapter from 'axios-mock-adapter'; import { initializeMockApp, mergeConfig } from '@edx/frontend-platform'; import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth'; -import { IntlProvider, injectIntl } from '@edx/frontend-platform/i18n'; +import { IntlProvider } from '@edx/frontend-platform/i18n'; import { AppProvider } from '@edx/frontend-platform/react'; import StudioApiService from 'CourseAuthoring/data/services/StudioApiService'; @@ -20,7 +20,6 @@ const defaultProps = { courseId, onClose: () => {}, }; -const IntlProctoredExamSettings = injectIntl(ProctoredExamSettings); let store; const intlWrapper = children => ( @@ -102,7 +101,7 @@ describe('ProctoredExamSettings', () => { describe('Field dependencies', () => { beforeEach(async () => { - await act(async () => render(intlWrapper())); + await act(async () => render(intlWrapper())); }); it('Updates Zendesk ticket field if proctortrack is provider', async () => { @@ -152,7 +151,7 @@ describe('ProctoredExamSettings', () => { course_start_date: '2070-01-01T00:00:00Z', }); - await act(async () => render(intlWrapper())); + await act(async () => render(intlWrapper())); await waitFor(() => { screen.getByText('Proctored exams'); }); @@ -225,7 +224,7 @@ describe('ProctoredExamSettings', () => { StudioApiService.getProctoredExamSettingsUrl(defaultProps.courseId), ).reply(200, {}); - await act(async () => render(intlWrapper())); + await act(async () => render(intlWrapper())); }); proctoringProvidersRequiringEscalationEmail.forEach(provider => { @@ -409,7 +408,7 @@ describe('ProctoredExamSettings', () => { const isAdmin = false; setupApp(isAdmin); mockCourseData(mockGetPastCourseData); - await act(async () => render(intlWrapper())); + await act(async () => render(intlWrapper())); const providerOption = screen.getByTestId('proctortrack'); expect(providerOption.hasAttribute('disabled')).toEqual(true); }); @@ -418,7 +417,7 @@ describe('ProctoredExamSettings', () => { const isAdmin = false; setupApp(isAdmin); mockCourseData(mockGetFutureCourseData); - await act(async () => render(intlWrapper())); + await act(async () => render(intlWrapper())); const providerOption = screen.getByTestId('proctortrack'); expect(providerOption.hasAttribute('disabled')).toEqual(false); }); @@ -428,7 +427,7 @@ describe('ProctoredExamSettings', () => { const org = 'test-org'; setupApp(isAdmin, org); mockCourseData(mockGetFutureCourseData); - await act(async () => render(intlWrapper())); + await act(async () => render(intlWrapper())); const providerOption = screen.getByTestId('proctortrack'); expect(providerOption.hasAttribute('disabled')).toEqual(false); }); @@ -437,7 +436,7 @@ describe('ProctoredExamSettings', () => { const isAdmin = true; setupApp(isAdmin); mockCourseData(mockGetPastCourseData); - await act(async () => render(intlWrapper())); + await act(async () => render(intlWrapper())); const providerOption = screen.getByTestId('proctortrack'); expect(providerOption.hasAttribute('disabled')).toEqual(false); }); @@ -446,7 +445,7 @@ describe('ProctoredExamSettings', () => { const isAdmin = true; setupApp(isAdmin); mockCourseData(mockGetFutureCourseData); - await act(async () => render(intlWrapper())); + await act(async () => render(intlWrapper())); const providerOption = screen.getByTestId('proctortrack'); expect(providerOption.hasAttribute('disabled')).toEqual(false); }); @@ -457,7 +456,7 @@ describe('ProctoredExamSettings', () => { available_proctoring_providers: ['lti_external', 'proctortrack', 'mockproc'], }; mockCourseData(courseData); - await act(async () => render(intlWrapper())); + await act(async () => render(intlWrapper())); await waitFor(() => { screen.getByDisplayValue('mockproc'); }); @@ -470,7 +469,7 @@ describe('ProctoredExamSettings', () => { available_proctoring_providers: ['lti_external', 'proctortrack', 'mockproc'], }; mockCourseData(courseData); - await act(async () => render(intlWrapper())); + await act(async () => render(intlWrapper())); await waitFor(() => { screen.getByDisplayValue('mockproc'); }); @@ -483,7 +482,7 @@ describe('ProctoredExamSettings', () => { const isAdmin = true; setupApp(isAdmin); mockCourseData(mockGetFutureCourseData); - await act(async () => render(intlWrapper())); + await act(async () => render(intlWrapper())); await waitFor(() => { screen.getByDisplayValue('mockproc'); }); @@ -497,7 +496,7 @@ describe('ProctoredExamSettings', () => { EXAMS_BASE_URL: null, }, 'CourseAuthoringConfig'); - await act(async () => render(intlWrapper())); + await act(async () => render(intlWrapper())); await waitFor(() => { screen.getByDisplayValue('mockproc'); }); @@ -516,7 +515,7 @@ describe('ProctoredExamSettings', () => { ).reply(200, { provider: 'test_lti', }); - await act(async () => render(intlWrapper())); + await act(async () => render(intlWrapper())); await waitFor(() => { screen.getByText('Proctoring provider'); }); @@ -529,14 +528,14 @@ describe('ProctoredExamSettings', () => { describe('Toggles field visibility based on user permissions', () => { it('Hides opting out and zendesk tickets for non edX staff', async () => { setupApp(false); - await act(async () => render(intlWrapper())); + await act(async () => render(intlWrapper())); expect(screen.queryByTestId('allowOptingOutYes')).toBeNull(); expect(screen.queryByTestId('createZendeskTicketsYes')).toBeNull(); }); it('Shows opting out and zendesk tickets for edX staff', async () => { setupApp(true); - await act(async () => render(intlWrapper())); + await act(async () => render(intlWrapper())); expect(screen.queryByTestId('allowOptingOutYes')).not.toBeNull(); expect(screen.queryByTestId('createZendeskTicketsYes')).not.toBeNull(); }); @@ -544,7 +543,7 @@ describe('ProctoredExamSettings', () => { describe('Connection states', () => { it('Shows the spinner before the connection is complete', async () => { - render(intlWrapper()); + render(intlWrapper()); const spinner = await screen.findByRole('status'); expect(spinner.textContent).toEqual('Loading...'); }); @@ -554,7 +553,7 @@ describe('ProctoredExamSettings', () => { StudioApiService.getProctoredExamSettingsUrl(defaultProps.courseId), ).reply(500); - await act(async () => render(intlWrapper())); + await act(async () => render(intlWrapper())); const connectionError = screen.getByTestId('connectionErrorAlert'); expect(connectionError.textContent).toEqual( expect.stringContaining('We encountered a technical error when loading this page.'), @@ -566,7 +565,7 @@ describe('ProctoredExamSettings', () => { `${ExamsApiService.getExamsBaseUrl()}/api/v1/providers`, ).reply(500); - await act(async () => render(intlWrapper())); + await act(async () => render(intlWrapper())); const connectionError = screen.getByTestId('connectionErrorAlert'); expect(connectionError.textContent).toEqual( expect.stringContaining('We encountered a technical error when loading this page.'), @@ -578,7 +577,7 @@ describe('ProctoredExamSettings', () => { StudioApiService.getProctoredExamSettingsUrl(defaultProps.courseId), ).reply(403); - await act(async () => render(intlWrapper())); + await act(async () => render(intlWrapper())); const permissionError = screen.getByTestId('permissionDeniedAlert'); expect(permissionError.textContent).toEqual( expect.stringContaining('You are not authorized to view this page'), @@ -597,7 +596,7 @@ describe('ProctoredExamSettings', () => { }); it('Disable button while submitting', async () => { - await act(async () => render(intlWrapper())); + await act(async () => render(intlWrapper())); let submitButton = screen.getByTestId('submissionButton'); expect(screen.queryByTestId('saveInProgress')).toBeFalsy(); fireEvent.click(submitButton); @@ -607,7 +606,7 @@ describe('ProctoredExamSettings', () => { }); it('Makes API call successfully with proctoring_escalation_email if proctortrack', async () => { - await act(async () => render(intlWrapper())); + await act(async () => render(intlWrapper())); // Make a change to the provider to proctortrack and set the email const selectElement = screen.getByDisplayValue('mockproc'); fireEvent.change(selectElement, { target: { value: 'proctortrack' } }); @@ -638,7 +637,7 @@ describe('ProctoredExamSettings', () => { }); it('Makes API call successfully without proctoring_escalation_email if not proctortrack', async () => { - await act(async () => render(intlWrapper())); + await act(async () => render(intlWrapper())); // make sure we have not selected proctortrack as the proctoring provider expect(screen.getByDisplayValue('mockproc')).toBeDefined(); @@ -665,7 +664,7 @@ describe('ProctoredExamSettings', () => { }); it('Successfully updates exam configuration and studio provider is set to "lti_external" for lti providers', async () => { - await act(async () => render(intlWrapper())); + await act(async () => render(intlWrapper())); // Make a change to the provider to test_lti and set the email const selectElement = screen.getByDisplayValue('mockproc'); fireEvent.change(selectElement, { target: { value: 'test_lti' } }); @@ -706,7 +705,7 @@ describe('ProctoredExamSettings', () => { }); it('Sets exam service provider to null if a non-lti provider is selected', async () => { - await act(async () => render(intlWrapper())); + await act(async () => render(intlWrapper())); const submitButton = screen.getByTestId('submissionButton'); fireEvent.click(submitButton); // update exam service config @@ -750,7 +749,7 @@ describe('ProctoredExamSettings', () => { course_start_date: '2070-01-01T00:00:00Z', }); - await act(async () => render(intlWrapper())); + await act(async () => render(intlWrapper())); const submitButton = screen.getByTestId('submissionButton'); fireEvent.click(submitButton); // does not update exam service config @@ -780,7 +779,7 @@ describe('ProctoredExamSettings', () => { StudioApiService.getProctoredExamSettingsUrl(defaultProps.courseId), ).reply(500); - await act(async () => render(intlWrapper())); + await act(async () => render(intlWrapper())); const submitButton = screen.getByTestId('submissionButton'); fireEvent.click(submitButton); expect(axiosMock.history.post.length).toBe(1); @@ -798,7 +797,7 @@ describe('ProctoredExamSettings', () => { `${ExamsApiService.getExamsBaseUrl()}/api/v1/configs/course_id/${defaultProps.courseId}`, ).reply(500, 'error'); - await act(async () => render(intlWrapper())); + await act(async () => render(intlWrapper())); const submitButton = screen.getByTestId('submissionButton'); fireEvent.click(submitButton); expect(axiosMock.history.post.length).toBe(1); @@ -816,7 +815,7 @@ describe('ProctoredExamSettings', () => { `${ExamsApiService.getExamsBaseUrl()}/api/v1/configs/course_id/${defaultProps.courseId}`, ).reply(403, 'error'); - await act(async () => render(intlWrapper())); + await act(async () => render(intlWrapper())); const submitButton = screen.getByTestId('submissionButton'); fireEvent.click(submitButton); expect(axiosMock.history.post.length).toBe(1); @@ -835,7 +834,7 @@ describe('ProctoredExamSettings', () => { StudioApiService.getProctoredExamSettingsUrl(defaultProps.courseId), ).reply(500); - await act(async () => render(intlWrapper())); + await act(async () => render(intlWrapper())); const submitButton = screen.getByTestId('submissionButton'); fireEvent.click(submitButton); expect(axiosMock.history.post.length).toBe(1); @@ -868,7 +867,7 @@ describe('ProctoredExamSettings', () => { const isAdmin = false; setupApp(isAdmin); - await act(async () => render(intlWrapper())); + await act(async () => render(intlWrapper())); // Make a change to the proctoring provider const selectElement = screen.getByDisplayValue('mockproc'); fireEvent.change(selectElement, { target: { value: 'proctortrack' } }); diff --git a/src/course-checklist/ChecklistSection/ChecklistItemComment.jsx b/src/course-checklist/ChecklistSection/ChecklistItemComment.jsx index 1fda16188..d6903f66d 100644 --- a/src/course-checklist/ChecklistSection/ChecklistItemComment.jsx +++ b/src/course-checklist/ChecklistSection/ChecklistItemComment.jsx @@ -1,5 +1,5 @@ import PropTypes from 'prop-types'; -import { injectIntl, FormattedMessage, FormattedNumber } from '@edx/frontend-platform/i18n'; +import { FormattedMessage, FormattedNumber } from '@edx/frontend-platform/i18n'; import { Icon } from '@openedx/paragon'; import { Link } from 'react-router-dom'; import { ModeComment } from '@openedx/paragon/icons'; @@ -127,4 +127,4 @@ ChecklistItemComment.propTypes = { ]).isRequired, }; -export default injectIntl(ChecklistItemComment); +export default ChecklistItemComment; diff --git a/src/editors/containers/GameEditor/index.jsx b/src/editors/containers/GameEditor/index.jsx index e14c3bad0..c4f580d42 100644 --- a/src/editors/containers/GameEditor/index.jsx +++ b/src/editors/containers/GameEditor/index.jsx @@ -1,3 +1,4 @@ +/* istanbul ignore file */ /* eslint-disable @typescript-eslint/no-unused-vars */ /* eslint-disable no-unused-vars */ /* eslint-disable import/extensions */ @@ -13,7 +14,7 @@ import { connect } from 'react-redux'; import PropTypes from 'prop-types'; import { Spinner } from '@openedx/paragon'; -import { injectIntl, intlShape } from '@edx/frontend-platform/i18n'; +import { useIntl } from '@edx/frontend-platform/i18n'; import EditorContainer from '../EditorContainer'; // This 'module' self-import hack enables mocking during tests. @@ -30,7 +31,7 @@ export const hooks = { }), }; -export const thumbEditor = ({ +export const ThumbEditor = ({ onClose, // redux blockValue, @@ -38,44 +39,46 @@ export const thumbEditor = ({ blockFailed, blockFinished, initializeEditor, + // eslint-disable-next-line react/prop-types exampleValue, - // inject - intl, -}) => ( - -
- {exampleValue} -
-
- {!blockFinished - ? ( -
- -
- ) - : ( -

- Your Editor Goes here. - You can get at the xblock data with the blockValue field. - here is what is in your xblock: {JSON.stringify(blockValue)} -

- )} -
-
-); -thumbEditor.defaultProps = { +}) => { + const intl = useIntl(); + return ( + +
+ {exampleValue} +
+
+ {!blockFinished + ? ( +
+ +
+ ) + : ( +

+ Your Editor Goes here. + You can get at the xblock data with the blockValue field. + here is what is in your xblock: {JSON.stringify(blockValue)} +

+ )} +
+
+ ); +}; +ThumbEditor.defaultProps = { blockValue: null, lmsEndpointUrl: null, }; -thumbEditor.propTypes = { +ThumbEditor.propTypes = { onClose: PropTypes.func.isRequired, // redux blockValue: PropTypes.shape({ @@ -85,8 +88,6 @@ thumbEditor.propTypes = { blockFailed: PropTypes.bool.isRequired, blockFinished: PropTypes.bool.isRequired, initializeEditor: PropTypes.func.isRequired, - // inject - intl: intlShape.isRequired, }; export const mapStateToProps = (state) => ({ @@ -103,4 +104,4 @@ export const mapDispatchToProps = { // TODO fill with dispatches here if needed }; -export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(thumbEditor)); +export default connect(mapStateToProps, mapDispatchToProps)(ThumbEditor); diff --git a/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/index.jsx b/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/index.jsx index 4dddd02d4..fd2d40b6e 100644 --- a/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/index.jsx +++ b/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/index.jsx @@ -13,7 +13,7 @@ import HintsCard from './settingsComponents/HintsCard'; import ResetCard from './settingsComponents/ResetCard'; import TimerCard from './settingsComponents/TimerCard'; import TypeCard from './settingsComponents/TypeCard'; -import ToleranceCard from './settingsComponents/Tolerance'; +import { ToleranceCard } from './settingsComponents/Tolerance'; import GroupFeedbackCard from './settingsComponents/GroupFeedback/index'; import SwitchEditorCard from './settingsComponents/SwitchEditorCard'; import messages from './messages'; diff --git a/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/settingsComponents/Tolerance/index.jsx b/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/settingsComponents/Tolerance/index.jsx index 6ad6709d4..ab587a3ab 100644 --- a/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/settingsComponents/Tolerance/index.jsx +++ b/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/settingsComponents/Tolerance/index.jsx @@ -1,5 +1,5 @@ import React, { useEffect } from 'react'; -import { injectIntl, FormattedMessage, intlShape } from '@edx/frontend-platform/i18n'; +import { FormattedMessage, useIntl } from '@edx/frontend-platform/i18n'; import { Alert, Form } from '@openedx/paragon'; import PropTypes from 'prop-types'; import SettingsOption from '../../SettingsOption'; @@ -46,14 +46,13 @@ export const getSummary = ({ tolerance, intl }) => { } }; -const ToleranceCard = ({ +export const ToleranceCard = ({ tolerance, answers, updateSettings, correctAnswerCount, - // inject - intl, }) => { + const intl = useIntl(); const isAnswerRange = isAnswerRangeSet({ answers }); const hasMultipleCorrectAnswers = correctAnswerCount > 1; let summary = getSummary({ tolerance, intl }); @@ -141,8 +140,4 @@ ToleranceCard.propTypes = { unselectedFeedback: PropTypes.string, })).isRequired, updateSettings: PropTypes.func.isRequired, - intl: intlShape.isRequired, }; - -export const ToleranceCardInternal = ToleranceCard; // For testing only -export default injectIntl(ToleranceCard); diff --git a/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/settingsComponents/Tolerance/index.test.jsx b/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/settingsComponents/Tolerance/index.test.jsx index e784751e3..c9e921270 100644 --- a/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/settingsComponents/Tolerance/index.test.jsx +++ b/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/settingsComponents/Tolerance/index.test.jsx @@ -4,7 +4,7 @@ import { import React from 'react'; import messages from './messages'; import { ToleranceTypes } from './constants'; -import { ToleranceCardInternal as ToleranceCard } from './index'; +import { ToleranceCard } from './index'; import { formatMessage } from '../../../../../../../testUtils'; jest.mock('@edx/frontend-platform/i18n', () => ({ @@ -13,6 +13,9 @@ jest.mock('@edx/frontend-platform/i18n', () => ({ FormattedMessage: jest.fn(({ defaultMessage }) => (
{ defaultMessage }
)), + useIntl: () => ({ + formatMessage: (message) => message.defaultMessage, + }), })); // eslint-disable-next-line react/prop-types diff --git a/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/ThumbnailWidget/index.jsx b/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/ThumbnailWidget/index.jsx index 47e66306c..7f9464e72 100644 --- a/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/ThumbnailWidget/index.jsx +++ b/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/ThumbnailWidget/index.jsx @@ -3,8 +3,7 @@ import { connect, useDispatch } from 'react-redux'; import PropTypes from 'prop-types'; import { FormattedMessage, - injectIntl, - intlShape, + useIntl, } from '@edx/frontend-platform/i18n'; import { Image, @@ -32,14 +31,13 @@ import { ErrorContext } from '../../../../hooks'; * Collapsible Form widget controlling video thumbnail */ const ThumbnailWidget = ({ - // injected - intl, // redux isLibrary, allowThumbnailUpload, thumbnail, videoId, }) => { + const intl = useIntl(); const dispatch = useDispatch(); const [error] = React.useContext(ErrorContext).thumbnail; const imgRef = React.useRef(); @@ -126,8 +124,6 @@ const ThumbnailWidget = ({ }; ThumbnailWidget.propTypes = { - // injected - intl: intlShape.isRequired, // redux isLibrary: PropTypes.bool.isRequired, allowThumbnailUpload: PropTypes.bool.isRequired, @@ -144,4 +140,4 @@ export const mapStateToProps = (state) => ({ export const mapDispatchToProps = {}; export const ThumbnailWidgetInternal = ThumbnailWidget; // For testing only -export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(ThumbnailWidget)); +export default connect(mapStateToProps, mapDispatchToProps)(ThumbnailWidget); diff --git a/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/TranscriptWidget/TranscriptActionMenu.jsx b/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/TranscriptWidget/TranscriptActionMenu.jsx index 46f51180b..8e9bea77b 100644 --- a/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/TranscriptWidget/TranscriptActionMenu.jsx +++ b/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/TranscriptWidget/TranscriptActionMenu.jsx @@ -2,7 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { connect, useDispatch } from 'react-redux'; -import { FormattedMessage, injectIntl } from '@edx/frontend-platform/i18n'; +import { FormattedMessage } from '@edx/frontend-platform/i18n'; import { Dropdown, Icon, IconButton } from '@openedx/paragon'; import { MoreHoriz } from '@openedx/paragon/icons'; @@ -90,4 +90,4 @@ export const mapDispatchToProps = { }; export const TranscriptActionMenuInternal = TranscriptActionMenu; // For testing only -export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(TranscriptActionMenu)); +export default connect(mapStateToProps, mapDispatchToProps)(TranscriptActionMenu); diff --git a/src/editors/setupEditorTest.js b/src/editors/setupEditorTest.js index 4ccd927f8..efccc0bc1 100644 --- a/src/editors/setupEditorTest.js +++ b/src/editors/setupEditorTest.js @@ -15,13 +15,9 @@ import 'jest-canvas-mock'; jest.mock('@edx/frontend-platform/i18n', () => { const i18n = jest.requireActual('@edx/frontend-platform/i18n'); - const PropTypes = jest.requireActual('prop-types'); return { ...i18n, useIntl: () => ({ formatMessage: mockFormatMessage }), - intlShape: PropTypes.shape({ - formatMessage: PropTypes.func, - }), defineMessages: m => m, getLocale: () => 'getLocale', FormattedDate: () => 'FormattedDate', diff --git a/src/files-and-videos/videos-page/info-sidebar/transcript-item/Transcript.jsx b/src/files-and-videos/videos-page/info-sidebar/transcript-item/Transcript.jsx index 88e435f98..ad5566df9 100644 --- a/src/files-and-videos/videos-page/info-sidebar/transcript-item/Transcript.jsx +++ b/src/files-and-videos/videos-page/info-sidebar/transcript-item/Transcript.jsx @@ -8,7 +8,7 @@ import { useToggle, } from '@openedx/paragon'; import { DeleteOutline } from '@openedx/paragon/icons'; -import { injectIntl, FormattedMessage, intlShape } from '@edx/frontend-platform/i18n'; +import { FormattedMessage, useIntl } from '@edx/frontend-platform/i18n'; import { isEmpty } from 'lodash'; import LanguageSelect from './LanguageSelect'; import TranscriptMenu from './TranscriptMenu'; @@ -20,9 +20,8 @@ const Transcript = ({ transcript, previousSelection, handleTranscript, - // injected - intl, }) => { + const intl = useIntl(); const [isConfirmationOpen, openConfirmation, closeConfirmation] = useToggle(); const [newLanguage, setNewLanguage] = useState(transcript); const language = transcript; @@ -122,8 +121,6 @@ Transcript.propTypes = { transcript: PropTypes.string.isRequired, previousSelection: PropTypes.arrayOf(PropTypes.string).isRequired, handleTranscript: PropTypes.func.isRequired, - // injected - intl: intlShape.isRequired, }; -export default injectIntl(Transcript); +export default Transcript; diff --git a/src/files-and-videos/videos-page/transcript-settings/ThreePlayMediaForm.jsx b/src/files-and-videos/videos-page/transcript-settings/ThreePlayMediaForm.jsx index b9c3e7b71..dda5ba5f8 100644 --- a/src/files-and-videos/videos-page/transcript-settings/ThreePlayMediaForm.jsx +++ b/src/files-and-videos/videos-page/transcript-settings/ThreePlayMediaForm.jsx @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { isEmpty } from 'lodash'; -import { injectIntl, FormattedMessage, intlShape } from '@edx/frontend-platform/i18n'; +import { FormattedMessage, useIntl } from '@edx/frontend-platform/i18n'; import { Form, Icon, @@ -18,9 +18,8 @@ const ThreePlayMediaForm = ({ data, setData, transcriptionPlan, - // injected - intl, }) => { + const intl = useIntl(); if (hasTranscriptCredentials) { const selectedLanguages = data.preferredLanguages ? data.preferredLanguages : []; const turnaroundOptions = transcriptionPlan.turnaround; @@ -133,8 +132,6 @@ ThreePlayMediaForm.propTypes = { translations: PropTypes.shape({}), languages: PropTypes.shape({}), }).isRequired, - // injected - intl: intlShape.isRequired, }; -export default injectIntl(ThreePlayMediaForm); +export default ThreePlayMediaForm; diff --git a/src/frontend-platform.d.ts b/src/frontend-platform.d.ts index d9b2f7f91..d728a4fcc 100644 --- a/src/frontend-platform.d.ts +++ b/src/frontend-platform.d.ts @@ -3,12 +3,6 @@ // (whichever comes first). declare module '@edx/frontend-platform/i18n' { - // eslint-disable-next-line import/no-extraneous-dependencies - import { injectIntl as _injectIntl } from 'react-intl'; - /** @deprecated Use useIntl() hook instead. */ - export const injectIntl: typeof _injectIntl; - /** @deprecated Use useIntl() hook instead. */ - export const intlShape: any; // eslint-disable-next-line import/no-extraneous-dependencies export { diff --git a/src/grading-settings/GradingSettings.test.jsx b/src/grading-settings/GradingSettings.test.jsx index 686cf9acd..02e0dfb8b 100644 --- a/src/grading-settings/GradingSettings.test.jsx +++ b/src/grading-settings/GradingSettings.test.jsx @@ -1,6 +1,6 @@ import { initializeMockApp } from '@edx/frontend-platform'; import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth'; -import { injectIntl, IntlProvider } from '@edx/frontend-platform/i18n'; +import { IntlProvider } from '@edx/frontend-platform/i18n'; import { AppProvider } from '@edx/frontend-platform/react'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { @@ -25,7 +25,7 @@ const RootWrapper = () => ( - + diff --git a/src/grading-settings/grading-scale/GradingScale.test.jsx b/src/grading-settings/grading-scale/GradingScale.test.jsx index 276ad07ec..d4b1db186 100644 --- a/src/grading-settings/grading-scale/GradingScale.test.jsx +++ b/src/grading-settings/grading-scale/GradingScale.test.jsx @@ -1,5 +1,5 @@ import React from 'react'; -import { IntlProvider, injectIntl } from '@edx/frontend-platform/i18n'; +import { IntlProvider } from '@edx/frontend-platform/i18n'; import { initializeMockApp } from '@edx/frontend-platform'; import { render, waitFor, fireEvent } from '@testing-library/react'; @@ -19,7 +19,6 @@ const sortedGrades = [ const RootWrapper = () => ( ', () => { const { getAllByTestId } = render( ', () => { const { getAllByTestId } = render( ', () => { }); it('renders sidebar text content correctly', async () => { - render(); + render(); expect(await screen.findByText(messages.gradingSidebarTitle.defaultMessage)).toBeInTheDocument(); expect(screen.getByText(messages.gradingSidebarAbout1.defaultMessage)).toBeInTheDocument(); expect(screen.getByText(messages.gradingSidebarAbout2.defaultMessage)).toBeInTheDocument(); diff --git a/src/import-page/file-section/FileSection.test.jsx b/src/import-page/file-section/FileSection.test.jsx index 6d6bfb2d2..d5b27dc45 100644 --- a/src/import-page/file-section/FileSection.test.jsx +++ b/src/import-page/file-section/FileSection.test.jsx @@ -1,6 +1,6 @@ import React from 'react'; import { initializeMockApp } from '@edx/frontend-platform'; -import { IntlProvider, injectIntl } from '@edx/frontend-platform/i18n'; +import { IntlProvider } from '@edx/frontend-platform/i18n'; import { AppProvider } from '@edx/frontend-platform/react'; import { fireEvent, render, waitFor } from '@testing-library/react'; @@ -14,7 +14,7 @@ const courseId = '123'; const RootWrapper = () => ( - + );