diff --git a/Makefile b/Makefile index f7cf268af..9e34fc928 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ transifex_resource = frontend-app-course-authoring export TRANSIFEX_RESOURCE = ${transifex_resource} -transifex_langs = "ar,fr,es_419,zh_CN,pt,it,de,uk,ru,hi,fr_CA,it_IT,pt_PT,de_DE" +transifex_langs = "ar,de,de_DE,es_419,fa_IR,fr,fr_CA,hi,it,it_IT,pt,pt_PT,ru,uk,zh_CN" intl_imports = ./node_modules/.bin/intl-imports.js transifex_utils = ./node_modules/.bin/transifex-utils.js diff --git a/src/advanced-settings/AdvancedSettings.jsx b/src/advanced-settings/AdvancedSettings.jsx index 654a33441..7611593a9 100644 --- a/src/advanced-settings/AdvancedSettings.jsx +++ b/src/advanced-settings/AdvancedSettings.jsx @@ -85,7 +85,7 @@ const AdvancedSettings = ({ intl, courseId }) => { } if (loadingSettingsStatus === RequestStatus.DENIED) { return ( -
+
); diff --git a/src/custom-pages/CustomPageCard.jsx b/src/custom-pages/CustomPageCard.jsx index 2d0133545..e0aeed548 100644 --- a/src/custom-pages/CustomPageCard.jsx +++ b/src/custom-pages/CustomPageCard.jsx @@ -41,7 +41,7 @@ const CustomPageCard = ({ })); }; - const toggleVisibilty = () => { + const toggleVisibility = () => { dispatch(updateCustomPageVisibility({ blockId: page.id, metadata: { course_staff_only: !page.courseStaffOnly }, @@ -87,7 +87,7 @@ const CustomPageCard = ({ src={page.courseStaffOnly ? VisibilityOff : Visibility} iconAs={Icon} alt={intl.formatMessage(messages.visibilityTooltipContent)} - onClick={toggleVisibilty} + onClick={toggleVisibility} data-testid="visibility-toggle-icon" /> +
); diff --git a/src/custom-pages/factories/mockApiResponses.jsx b/src/custom-pages/factories/mockApiResponses.jsx index 15f3882f6..83fc9581b 100644 --- a/src/custom-pages/factories/mockApiResponses.jsx +++ b/src/custom-pages/factories/mockApiResponses.jsx @@ -52,7 +52,7 @@ export const generateXblockData = ( data: '

test

', }); -export const generateUpdateVisiblityApiResponse = ( +export const generateUpdateVisibilityApiResponse = ( blockId, visibility, ) => ({ diff --git a/src/files-and-videos/files-page/data/thunks.js b/src/files-and-videos/files-page/data/thunks.js index 490520431..6e5bad6a6 100644 --- a/src/files-and-videos/files-page/data/thunks.js +++ b/src/files-and-videos/files-page/data/thunks.js @@ -33,8 +33,8 @@ export function fetchAssets(courseId) { try { const { totalCount } = await getAssets(courseId); const { assets } = await getAssets(courseId, totalCount); - const parsedAssests = updateFileValues(assets); - dispatch(addModels({ modelType: 'assets', models: parsedAssests })); + const parsedAssets = updateFileValues(assets); + dispatch(addModels({ modelType: 'assets', models: parsedAssets })); dispatch(setAssetIds({ assetIds: assets.map(asset => asset.id), })); @@ -79,10 +79,10 @@ export function addAssetFile(courseId, file) { try { const { asset } = await addAsset(courseId, file); - const [parsedAssest] = updateFileValues([asset]); + const [parsedAssets] = updateFileValues([asset]); dispatch(addModel({ modelType: 'assets', - model: { ...parsedAssest }, + model: { ...parsedAssets }, })); dispatch(addAssetSuccess({ assetId: asset.id, diff --git a/src/header/messages.js b/src/header/messages.js index 81b5d96f1..f9877c75e 100644 --- a/src/header/messages.js +++ b/src/header/messages.js @@ -144,7 +144,7 @@ const messages = defineMessages({ 'header.label.secondary.nav': { id: 'header.label.secondary.nav', defaultMessage: 'Secondary', - description: 'The aria label for the seconary nav', + description: 'The aria label for the secondary nav', }, 'header.label.courseOutline': { id: 'header.label.courseOutline', diff --git a/src/i18n/index.js b/src/i18n/index.js index 2abb2b7cf..ec971823c 100644 --- a/src/i18n/index.js +++ b/src/i18n/index.js @@ -1,36 +1,38 @@ import { messages as footerMessages } from '@edx/frontend-component-footer'; import { messages as paragonMessages } from '@edx/paragon'; import arMessages from './messages/ar.json'; -import frMessages from './messages/fr.json'; -import es419Messages from './messages/es_419.json'; -import zhcnMessages from './messages/zh_CN.json'; -import ptMessages from './messages/pt.json'; -import itMessages from './messages/it.json'; -import ukMessages from './messages/uk.json'; import deMessages from './messages/de.json'; -import ruMessages from './messages/ru.json'; -import hiMessages from './messages/hi.json'; +import deDEMessages from './messages/de_DE.json'; +import es419Messages from './messages/es_419.json'; +import faIRMessages from './messages/fa_IR.json'; +import frMessages from './messages/fr.json'; import frCAMessages from './messages/fr_CA.json'; -import dedeMessages from './messages/de_DE.json'; -import ititMessages from './messages/it_IT.json'; -import ptptMessages from './messages/pt_PT.json'; +import hiMessages from './messages/hi.json'; +import itMessages from './messages/it.json'; +import itITMessages from './messages/it_IT.json'; +import ptMessages from './messages/pt.json'; +import ptPTMessages from './messages/pt_PT.json'; +import ruMessages from './messages/ru.json'; +import ukMessages from './messages/uk.json'; +import zhCNMessages from './messages/zh_CN.json'; // no need to import en messages-- they are in the defaultMessage field const appMessages = { ar: arMessages, - 'es-419': es419Messages, - fr: frMessages, - 'zh-cn': zhcnMessages, - pt: ptMessages, - it: itMessages, de: deMessages, - hi: hiMessages, + 'de-de': deDEMessages, + 'es-419': es419Messages, + 'fa-ir': faIRMessages, + fr: frMessages, 'fr-ca': frCAMessages, + hi: hiMessages, + it: itMessages, + 'it-it': itITMessages, ru: ruMessages, + pt: ptMessages, + 'pt-pt': ptPTMessages, uk: ukMessages, - 'de-de': dedeMessages, - 'it-it': ititMessages, - 'pt-pt': ptptMessages, + 'zh-cn': zhCNMessages, }; export default [ diff --git a/src/i18n/messages/fa_IR.json b/src/i18n/messages/fa_IR.json new file mode 100644 index 000000000..9e26dfeeb --- /dev/null +++ b/src/i18n/messages/fa_IR.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/src/pages-and-resources/discussions/app-config-form/apps/shared/discussion-restrictions/RestrictDatesInput.jsx b/src/pages-and-resources/discussions/app-config-form/apps/shared/discussion-restrictions/RestrictDatesInput.jsx index b48f6daf6..aa367075b 100644 --- a/src/pages-and-resources/discussions/app-config-form/apps/shared/discussion-restrictions/RestrictDatesInput.jsx +++ b/src/pages-and-resources/discussions/app-config-form/apps/shared/discussion-restrictions/RestrictDatesInput.jsx @@ -5,7 +5,7 @@ import PropTypes from 'prop-types'; import FieldFeedback from '../../../../../../generic/FieldFeedback'; -const RestictDatesInput = ({ +const RestrictDatesInput = ({ value, type, label, @@ -64,7 +64,7 @@ const RestictDatesInput = ({ ); }; -RestictDatesInput.propTypes = { +RestrictDatesInput.propTypes = { value: PropTypes.string.isRequired, fieldName: PropTypes.string.isRequired, label: PropTypes.string.isRequired, @@ -77,7 +77,7 @@ RestictDatesInput.propTypes = { dataTestId: PropTypes.string, }; -RestictDatesInput.defaultProps = { +RestrictDatesInput.defaultProps = { fieldClasses: '', helpText: '', feedbackClasses: '', @@ -85,4 +85,4 @@ RestictDatesInput.defaultProps = { dataTestId: null, }; -export default React.memo(RestictDatesInput); +export default React.memo(RestrictDatesInput); diff --git a/src/pages-and-resources/discussions/app-list/AppList.jsx b/src/pages-and-resources/discussions/app-list/AppList.jsx index 9db10b700..0cd8efc1f 100644 --- a/src/pages-and-resources/discussions/app-list/AppList.jsx +++ b/src/pages-and-resources/discussions/app-list/AppList.jsx @@ -33,7 +33,7 @@ const AppList = ({ intl }) => { const features = useModels('features', featureIds); const isGlobalStaff = getAuthenticatedUser().administrator; const ltiProvider = !['openedx', 'legacy'].includes(activeAppId); - const isOnSmallcreen = useIsOnSmallScreen(); + const isOnSmallScreen = useIsOnSmallScreen(); const showOneEdxProvider = useMemo(() => apps.filter(app => ( activeAppId === 'openedx' ? app.id !== 'legacy' : app.id !== 'openedx' @@ -122,8 +122,8 @@ const AppList = ({ intl }) => { return (
-
-

+
+

{intl.formatMessage(messages.heading)}

{ lg: 4, xl: 4, }} - className={!isOnSmallcreen && 'mt-5'} + className={!isOnSmallScreen && 'mt-5'} > {(isGlobalStaff || ltiProvider) ? showAppCard(apps) : showAppCard(showOneEdxProvider)} diff --git a/src/pages-and-resources/xpert-unit-summary/XpertUnitSummarySettings.test.jsx b/src/pages-and-resources/xpert-unit-summary/XpertUnitSummarySettings.test.jsx index 6c7828624..000b09999 100644 --- a/src/pages-and-resources/xpert-unit-summary/XpertUnitSummarySettings.test.jsx +++ b/src/pages-and-resources/xpert-unit-summary/XpertUnitSummarySettings.test.jsx @@ -47,7 +47,7 @@ function renderComponent() { container = wrapper.container; } -function generateCourseLevelAPIRepsonse({ +function generateCourseLevelAPIResponse({ success, enabled, }) { return { @@ -96,7 +96,7 @@ describe('XpertUnitSummarySettings', () => { describe('with successful network connections', () => { beforeEach(() => { axiosMock.onGet(API.getXpertSettingsUrl(courseId)) - .reply(200, generateCourseLevelAPIRepsonse({ + .reply(200, generateCourseLevelAPIResponse({ success: true, enabled: true, })); @@ -111,7 +111,7 @@ describe('XpertUnitSummarySettings', () => { test('Shows switch on if disabled from backend', async () => { axiosMock.onGet(API.getXpertSettingsUrl(courseId)) - .reply(200, generateCourseLevelAPIRepsonse({ + .reply(200, generateCourseLevelAPIResponse({ success: true, enabled: false, })); @@ -129,7 +129,7 @@ describe('XpertUnitSummarySettings', () => { test('Shows disable radio selected if enabled from backend', async () => { axiosMock.onGet(API.getXpertSettingsUrl(courseId)) - .reply(200, generateCourseLevelAPIRepsonse({ + .reply(200, generateCourseLevelAPIResponse({ success: true, enabled: false, })); @@ -143,7 +143,7 @@ describe('XpertUnitSummarySettings', () => { describe('first time course configuration', () => { beforeEach(() => { axiosMock.onGet(API.getXpertSettingsUrl(courseId)) - .reply(400, generateCourseLevelAPIRepsonse({ + .reply(400, generateCourseLevelAPIResponse({ success: false, enabled: undefined, })); @@ -151,7 +151,7 @@ describe('XpertUnitSummarySettings', () => { renderComponent(); }); - test('Does not show as enabled if configuation does not exist', async () => { + test('Does not show as enabled if configuration does not exist', async () => { await waitFor(() => expect(container.querySelector('#enable-xpert-unit-summary-toggle')).toBeTruthy()); expect(container.querySelector('#enable-xpert-unit-summary-toggle').checked).not.toBeTruthy(); expect(queryByTestId(container, 'enable-badge')).not.toBeTruthy(); @@ -161,13 +161,13 @@ describe('XpertUnitSummarySettings', () => { describe('saving configuration changes', () => { beforeEach(() => { axiosMock.onGet(API.getXpertSettingsUrl(courseId)) - .reply(200, generateCourseLevelAPIRepsonse({ + .reply(200, generateCourseLevelAPIResponse({ success: true, enabled: false, })); axiosMock.onPost(API.getXpertSettingsUrl(courseId)) - .reply(200, generateCourseLevelAPIRepsonse({ + .reply(200, generateCourseLevelAPIResponse({ success: true, enabled: true, })); @@ -190,7 +190,7 @@ describe('XpertUnitSummarySettings', () => { describe('testing configurable gating', () => { beforeEach(async () => { axiosMock.onGet(API.getXpertConfigurationStatusUrl(courseId)) - .reply(200, generateCourseLevelAPIRepsonse({ + .reply(200, generateCourseLevelAPIResponse({ success: true, enabled: true, })); @@ -207,13 +207,13 @@ describe('XpertUnitSummarySettings', () => { describe('removing course configuration', () => { beforeEach(() => { axiosMock.onGet(API.getXpertSettingsUrl(courseId)) - .reply(200, generateCourseLevelAPIRepsonse({ + .reply(200, generateCourseLevelAPIResponse({ success: true, enabled: true, })); axiosMock.onDelete(API.getXpertSettingsUrl(courseId)) - .reply(200, generateCourseLevelAPIRepsonse({ + .reply(200, generateCourseLevelAPIResponse({ success: true, enabled: undefined, })); @@ -235,13 +235,13 @@ describe('XpertUnitSummarySettings', () => { describe('resetting course units', () => { test('reset all units to be enabled', async () => { axiosMock.onGet(API.getXpertSettingsUrl(courseId)) - .reply(200, generateCourseLevelAPIRepsonse({ + .reply(200, generateCourseLevelAPIResponse({ success: true, enabled: true, })); axiosMock.onPost(API.getXpertSettingsUrl(courseId)) - .reply(200, generateCourseLevelAPIRepsonse({ + .reply(200, generateCourseLevelAPIResponse({ success: true, enabled: true, })); @@ -257,13 +257,13 @@ describe('XpertUnitSummarySettings', () => { test('reset all units to be disabled', async () => { axiosMock.onGet(API.getXpertSettingsUrl(courseId)) - .reply(200, generateCourseLevelAPIRepsonse({ + .reply(200, generateCourseLevelAPIResponse({ success: true, enabled: false, })); axiosMock.onPost(API.getXpertSettingsUrl(courseId)) - .reply(200, generateCourseLevelAPIRepsonse({ + .reply(200, generateCourseLevelAPIResponse({ success: true, enabled: false, })); diff --git a/src/utils.js b/src/utils.js index 67a37e6db..6e5edcee7 100644 --- a/src/utils.js +++ b/src/utils.js @@ -181,8 +181,8 @@ export function setupYupExtensions() { Yup.addMethod(Yup.string, 'compare', function compare(message, type) { return this.test('isGreater', message, function isGreater() { // This function compare 2 dates or 2 times. It return no error if dateInstance/timeInstance is empty - // of if startTime or endTime is not present for time comparesion - // or startDate or endDate is not present for date comparesion + // of if startTime or endTime is not present for time comparison + // or startDate or endDate is not present for date comparison if (!this.parent || (!(this.parent.startTime && this.parent.endTime) && type === 'time')