diff --git a/.eslintignore b/.eslintignore deleted file mode 100755 index 9c46e7b475..0000000000 --- a/.eslintignore +++ /dev/null @@ -1,6 +0,0 @@ -coverage/* -dist/ -node_modules/ -jest.config.js -env.config.jsx -example.env.config.jsx diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index e3a4764294..0000000000 --- a/.eslintrc.js +++ /dev/null @@ -1,44 +0,0 @@ -const path = require('path'); -// eslint-disable-next-line import/no-extraneous-dependencies -const { createConfig } = require('@openedx/frontend-build'); - -module.exports = createConfig( - 'eslint', - { - rules: { - 'jsx-a11y/label-has-associated-control': [2, { - controlComponents: ['Input'], - }], - 'template-curly-spacing': 'off', - 'react-hooks/exhaustive-deps': 'off', - '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 - 'import/resolver': { - webpack: { - config: path.resolve(__dirname, 'webpack.dev.config.js'), - }, - }, - }, - overrides: [ - { - files: ['plugins/**/*.test.jsx'], - rules: { - 'import/no-extraneous-dependencies': 'off', - }, - }, - ], - }, -); diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 5c58eb3c34..0d03424ff8 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -5,8 +5,9 @@ Design decisions and their rationales should be documented in the repo (docstrin [OEP-19](https://open-edx-proposals.readthedocs.io/en/latest/oep-0019-bp-developer-documentation.html), and can be linked here. Useful information to include: + - Which user roles will this change impact? Common user roles are "Learner", "Course Author", -"Developer", and "Operator". + "Developer", and "Operator". - Include screenshots for changes to the UI (ideally, both "before" and "after" screenshots, if applicable). ## Supporting information @@ -21,6 +22,7 @@ Please provide detailed step-by-step instructions for manually testing this chan ## Other information Include anything else that will help reviewers and consumers understand the change. + - Does this change depend on other changes elsewhere? - Any special concerns or limitations? For example: deprecations, migrations, security, or accessibility. diff --git a/.oxlintrc.json b/.oxlintrc.json index 7aa558b4d9..9b11fe5569 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -7,7 +7,7 @@ "rules": { "eslint/no-unused-vars": ["warn", { // Allow using {ignoredProp, ...keepTheRest} to omit a prop like 'ignoredProp' from an object. - "ignoreRestSiblings": true, + "ignoreRestSiblings": true }], // We disable exhaustive-deps because: it's noisy, and we often include extra deps when we want a memoized thing to // re-calculate after some change, even if we're not using that thing in the calculation. @@ -21,11 +21,11 @@ // complete, but we rarely if ever want that; we usually want to // continue invalidating more things immediately. So we don't usually // want to await this. - "invalidateQueries", + "invalidateQueries" ] }] }, "ignorePatterns": [ - "webpack.dev-tutor.config.js", + "webpack.dev-tutor.config.js" ] -} \ No newline at end of file +} diff --git a/Makefile b/Makefile index c0fcdbdb66..66878b437d 100644 --- a/Makefile +++ b/Makefile @@ -51,9 +51,7 @@ validate-no-uncommitted-package-lock-changes: validate: make validate-no-uncommitted-package-lock-changes npm run i18n_extract -# We are trying out oxlint. Now that it's been working well for a while with both oxlint and eslint, we have disabled -# eslint, and after a few weeks we'll evaluate whether any problems are slipping through if only oxlint is used. - npm run oxlint + npm run lint npm run types npm run test:ci npm run build diff --git a/dprint.json b/dprint.json new file mode 100644 index 0000000000..17e17d9b14 --- /dev/null +++ b/dprint.json @@ -0,0 +1,38 @@ +{ + "lineWidth": 120, + "indentWidth": 2, + "useTabs": false, + "typescript": { + "quoteStyle": "alwaysSingle", + "jsx.quoteStyle": "preferDouble", + "semiColons": "always", + "trailingCommas": "onlyMultiLine", + "useBraces": "always", + "operatorPosition": "maintain", + "arrowFunction.useParentheses": "maintain", + "module.sortImportDeclarations": "maintain", + "importDeclaration.sortNamedImports": "maintain", + "importDeclaration.preferSingleLine": false, + "exportDeclaration.sortNamedExports": "maintain" + }, + "json": { + }, + "markdown": { + }, + "excludes": [ + "**/node_modules", + "**/*-lock.json", + "**/dist", + "**/coverage", + "jest.config.js", + "env.config.*", + "example.env.config.*", + "module.config.js", + "**/messages.{ts,js}" + ], + "plugins": [ + "https://plugins.dprint.dev/typescript-0.95.15.wasm", + "https://plugins.dprint.dev/json-0.21.3.wasm", + "https://plugins.dprint.dev/markdown-0.21.1.wasm" + ] +} diff --git a/dprint.messages.json b/dprint.messages.json new file mode 100644 index 0000000000..aaf431c60e --- /dev/null +++ b/dprint.messages.json @@ -0,0 +1,10 @@ +{ + // For messages files, we allow unlimited line length, to keep the file format consistent. + // For now a separate file is required, but this could be simplified when + // https://github.com/dprint/dprint/issues/996 is implemented or if we change to a different formatter. + "extends": "dprint.json", + "lineWidth": 10000, + "includes": ["src/**/messages.{ts,js}"] + // Because this inherits "excludes" from "dprint.json", it's necessary to use "--excludes-override none" + // to run this on the command line. +} diff --git a/package-lock.json b/package-lock.json index fb0dba2d4f..f60f8dfbda 100644 --- a/package-lock.json +++ b/package-lock.json @@ -91,6 +91,7 @@ "@types/react": "^18", "@types/react-dom": "^18", "axios-mock-adapter": "2.1.0", + "dprint": "^0.54.0", "eslint-import-resolver-webpack": "^0.13.8", "fetch-mock-jest": "^1.5.1", "jest-canvas-mock": "^2.5.2", @@ -2543,6 +2544,181 @@ "react": ">=16.8.0" } }, + "node_modules/@dprint/darwin-arm64": { + "version": "0.54.0", + "resolved": "https://registry.npmjs.org/@dprint/darwin-arm64/-/darwin-arm64-0.54.0.tgz", + "integrity": "sha512-yqRI4enH+BDp+4+ZsPVdZM5h873JK1lN7li9l9A5u4C4cvh1oEsiBWAzEPccRkJ2ctF8LgaizBSxO38sqEVYbw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@dprint/darwin-x64": { + "version": "0.54.0", + "resolved": "https://registry.npmjs.org/@dprint/darwin-x64/-/darwin-x64-0.54.0.tgz", + "integrity": "sha512-W9BARpgHypcQwatg5mnHaCpX6pLX5dBxxiv+tZKruhOmq8MKYOrAYDXlceMuHSowmWREfUF5yL4SRgXDGI6WQw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@dprint/linux-arm64-glibc": { + "version": "0.54.0", + "resolved": "https://registry.npmjs.org/@dprint/linux-arm64-glibc/-/linux-arm64-glibc-0.54.0.tgz", + "integrity": "sha512-VhM7p70VFuNqxZMdiv1e+nMboPj/hMFlTIBWrRaX7+6VThs9mJr9+94wrUeXgfnfsyaEKSbRFa/dru1PINoSNw==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@dprint/linux-arm64-musl": { + "version": "0.54.0", + "resolved": "https://registry.npmjs.org/@dprint/linux-arm64-musl/-/linux-arm64-musl-0.54.0.tgz", + "integrity": "sha512-QS1A74Lv60/L9oemHCzbHgOLbV2smSJG5IxS5fjf8ZWetyUt918WDzIHBilz/+uiB+OlW2UVTsm952UG0YOrLw==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@dprint/linux-loong64-glibc": { + "version": "0.54.0", + "resolved": "https://registry.npmjs.org/@dprint/linux-loong64-glibc/-/linux-loong64-glibc-0.54.0.tgz", + "integrity": "sha512-8Myka2/0KbhuZnEKL6jagPXTgDKVpd/tfXDRa0oibUBgaqOSku6iRMzHGa/PhqHL+s14Gcp+/cIHz0zU3Tkgug==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@dprint/linux-loong64-musl": { + "version": "0.54.0", + "resolved": "https://registry.npmjs.org/@dprint/linux-loong64-musl/-/linux-loong64-musl-0.54.0.tgz", + "integrity": "sha512-/AN3xCuMhC4PK7Pbj7/4zBuhFGr4m0OHV/5uGTfzpkKX/3+AXoyKl7PbT2VlNMGXAK0kuRThfjtx23gIwlWk7Q==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@dprint/linux-riscv64-glibc": { + "version": "0.54.0", + "resolved": "https://registry.npmjs.org/@dprint/linux-riscv64-glibc/-/linux-riscv64-glibc-0.54.0.tgz", + "integrity": "sha512-Aw2vXzzwFDpPbXh6ajsSabVCkCc66C3hCyMKprR/IxYvFtjYX80nh1ox0c7iaw6c4HacHMRLGw7FUSXvomPaEQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@dprint/linux-x64-glibc": { + "version": "0.54.0", + "resolved": "https://registry.npmjs.org/@dprint/linux-x64-glibc/-/linux-x64-glibc-0.54.0.tgz", + "integrity": "sha512-zZqj3wQELOX8n6QfT2uuWoMf64Wv0lMXNyam3btm+PKkg0P6a54TPL09Bs9XsViOdxgTcamsiQ7HlErt/LEjIA==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@dprint/linux-x64-musl": { + "version": "0.54.0", + "resolved": "https://registry.npmjs.org/@dprint/linux-x64-musl/-/linux-x64-musl-0.54.0.tgz", + "integrity": "sha512-it6Qdt06dyW2adbAXpOCb7/KQLxlm4i1UphUAWqWsZk4t3EYetyAza9J0g3Vu9itIWSEIo9MnccgANckQJ6+qw==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@dprint/win32-arm64": { + "version": "0.54.0", + "resolved": "https://registry.npmjs.org/@dprint/win32-arm64/-/win32-arm64-0.54.0.tgz", + "integrity": "sha512-F5kjV/6I9YtNOTDWHUpTqM2HHHS510BPL7z4NJuU0nDnaVeks7GwNEltGr56CcsG8XQYhkiAsqZytPu6AhA2hQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@dprint/win32-x64": { + "version": "0.54.0", + "resolved": "https://registry.npmjs.org/@dprint/win32-x64/-/win32-x64-0.54.0.tgz", + "integrity": "sha512-AAr2ye/DtgYXDplRoPS+5U++x7T6W4a3I9FvTFWFxziFmUptvAg5G2c4FcXoAduSruhYZJvjDZrLseR2c3IwXg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@edx/brand": { "name": "@openedx/brand-openedx", "version": "1.2.3", @@ -11333,6 +11509,30 @@ "webpack": "^4 || ^5" } }, + "node_modules/dprint": { + "version": "0.54.0", + "resolved": "https://registry.npmjs.org/dprint/-/dprint-0.54.0.tgz", + "integrity": "sha512-sIy25poR2gRP/tWPTgP0MPeJoJcpv0xzYDcsboapvthbEt1Qw3Al252CA0xFyIh2cYEGGKyBJtKokryv4ERlJw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "dprint": "bin.cjs" + }, + "optionalDependencies": { + "@dprint/darwin-arm64": "0.54.0", + "@dprint/darwin-x64": "0.54.0", + "@dprint/linux-arm64-glibc": "0.54.0", + "@dprint/linux-arm64-musl": "0.54.0", + "@dprint/linux-loong64-glibc": "0.54.0", + "@dprint/linux-loong64-musl": "0.54.0", + "@dprint/linux-riscv64-glibc": "0.54.0", + "@dprint/linux-x64-glibc": "0.54.0", + "@dprint/linux-x64-musl": "0.54.0", + "@dprint/win32-arm64": "0.54.0", + "@dprint/win32-x64": "0.54.0" + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", diff --git a/package.json b/package.json index b3e8472959..0c7ccbc2f9 100644 --- a/package.json +++ b/package.json @@ -13,9 +13,8 @@ "build": "fedx-scripts webpack", "i18n_extract": "fedx-scripts formatjs extract --include=plugins", "stylelint": "stylelint \"plugins/**/*.scss\" \"src/**/*.scss\" \"scss/**/*.scss\" --config .stylelintrc.json", - "lint": "npm run stylelint && fedx-scripts eslint --ext .js --ext .jsx --ext .ts --ext .tsx .", - "oxlint": "oxlint --type-aware --deny-warnings", - "lint:fix": "npm run stylelint -- --fix && fedx-scripts eslint --fix --ext .js --ext .jsx --ext .ts --ext .tsx .", + "lint": "dprint check && dprint --config dprint.messages.json check --excludes-override none && oxlint --type-aware --deny-warnings && npm run stylelint", + "lint:fix": "dprint fmt && dprint --config dprint.messages.json fmt --excludes-override none && oxlint --type-aware --fix", "start": "fedx-scripts webpack-dev-server --progress", "start:with-theme": "paragon install-theme && npm start && npm install", "dev": "PUBLIC_PATH=/authoring/ MFE_CONFIG_API_URL='http://localhost:8000/api/mfe_config/v1' fedx-scripts webpack-dev-server --progress --host apps.local.openedx.io", @@ -116,7 +115,7 @@ "@types/react": "^18", "@types/react-dom": "^18", "axios-mock-adapter": "2.1.0", - "eslint-import-resolver-webpack": "^0.13.8", + "dprint": "^0.54.0", "fetch-mock-jest": "^1.5.1", "jest-canvas-mock": "^2.5.2", "jest-expect-message": "^1.1.3", diff --git a/plugins/course-apps/calculator/package.json b/plugins/course-apps/calculator/package.json index dec9813433..7c1784273f 100644 --- a/plugins/course-apps/calculator/package.json +++ b/plugins/course-apps/calculator/package.json @@ -1,17 +1,17 @@ { - "name": "@openedx-plugins/course-app-calculator", - "version": "0.1.0", - "description": "Calculator configuration for courses using it", - "peerDependencies": { - "@edx/frontend-app-authoring": "*", - "@edx/frontend-platform": "*", - "@openedx/paragon": "*", - "prop-types": "*", - "react": "*" - }, - "peerDependenciesMeta": { - "@edx/frontend-app-authoring": { - "optional": true - } + "name": "@openedx-plugins/course-app-calculator", + "version": "0.1.0", + "description": "Calculator configuration for courses using it", + "peerDependencies": { + "@edx/frontend-app-authoring": "*", + "@edx/frontend-platform": "*", + "@openedx/paragon": "*", + "prop-types": "*", + "react": "*" + }, + "peerDependenciesMeta": { + "@edx/frontend-app-authoring": { + "optional": true } + } } diff --git a/plugins/course-apps/dates/package.json b/plugins/course-apps/dates/package.json index f3678afe18..3e944a64a2 100644 --- a/plugins/course-apps/dates/package.json +++ b/plugins/course-apps/dates/package.json @@ -1,17 +1,17 @@ { - "name": "@openedx-plugins/course-app-dates", - "version": "0.1.0", - "description": "Dates configuration for courses using it", - "peerDependencies": { - "@edx/frontend-app-authoring": "*", - "@edx/frontend-platform": "*", - "@openedx/paragon": "*", - "prop-types": "*", - "react": "*" - }, - "peerDependenciesMeta": { - "@edx/frontend-app-authoring": { - "optional": true - } + "name": "@openedx-plugins/course-app-dates", + "version": "0.1.0", + "description": "Dates configuration for courses using it", + "peerDependencies": { + "@edx/frontend-app-authoring": "*", + "@edx/frontend-platform": "*", + "@openedx/paragon": "*", + "prop-types": "*", + "react": "*" + }, + "peerDependenciesMeta": { + "@edx/frontend-app-authoring": { + "optional": true } + } } diff --git a/plugins/course-apps/edxnotes/package.json b/plugins/course-apps/edxnotes/package.json index 39c643d015..d15c7852fe 100644 --- a/plugins/course-apps/edxnotes/package.json +++ b/plugins/course-apps/edxnotes/package.json @@ -1,17 +1,17 @@ { - "name": "@openedx-plugins/course-app-edxnotes", - "version": "0.1.0", - "description": "edxnotes configuration for courses using it", - "peerDependencies": { - "@edx/frontend-app-authoring": "*", - "@edx/frontend-platform": "*", - "@openedx/paragon": "*", - "prop-types": "*", - "react": "*" - }, - "peerDependenciesMeta": { - "@edx/frontend-app-authoring": { - "optional": true - } + "name": "@openedx-plugins/course-app-edxnotes", + "version": "0.1.0", + "description": "edxnotes configuration for courses using it", + "peerDependencies": { + "@edx/frontend-app-authoring": "*", + "@edx/frontend-platform": "*", + "@openedx/paragon": "*", + "prop-types": "*", + "react": "*" + }, + "peerDependenciesMeta": { + "@edx/frontend-app-authoring": { + "optional": true } + } } diff --git a/plugins/course-apps/learning_assistant/Settings.jsx b/plugins/course-apps/learning_assistant/Settings.jsx index 7b9bb916b3..6aba6ab2da 100644 --- a/plugins/course-apps/learning_assistant/Settings.jsx +++ b/plugins/course-apps/learning_assistant/Settings.jsx @@ -15,7 +15,7 @@ const LearningAssistantSettings = ({ onClose }) => { const intl = useIntl(); // We need to render more than one link, so we use the bodyChildren prop. - const bodyChildren = ( + const bodyChildren = appInfo?.documentationLinks?.learnMoreOpenaiDataPrivacy && appInfo?.documentationLinks?.learnMoreOpenai ? (
@@ -41,8 +41,7 @@ const LearningAssistantSettings = ({ onClose }) => { )}
) - : null - ); + : null; return ( { }; +const onClose = () => {}; describe('Learning Assistant Settings', () => { it('renders', async () => { const initialState = { models: { courseApps: { - learning_assistant: - { + learning_assistant: { id: 'learning_assistant', enabled: true, name: 'Learning Assistant', @@ -38,10 +37,12 @@ describe('Learning Assistant Settings', () => { render(); const toggleDescription = 'Reinforce learning concepts by sharing text-based course content ' - + 'with OpenAI (via API) to power an in-course Learning Assistant. Learners can leave feedback about the quality ' - + 'of the AI-powered experience for use by edX to improve the performance of the tool.'; + + 'with OpenAI (via API) to power an in-course Learning Assistant. Learners can leave feedback about the quality ' + + 'of the AI-powered experience for use by edX to improve the performance of the tool.'; - await waitFor(() => expect(screen.getByRole('heading', { name: 'Configure Learning Assistant' })).toBeInTheDocument()); + await waitFor(() => + expect(screen.getByRole('heading', { name: 'Configure Learning Assistant' })).toBeInTheDocument() + ); await waitFor(() => expect(screen.getByText(toggleDescription)).toBeInTheDocument()); await waitFor(() => expect(screen.getByText('Learn more about how OpenAI handles data')).toBeInTheDocument()); await waitFor(() => expect(screen.getByText('Learn more about OpenAI API data privacy')).toBeInTheDocument()); diff --git a/plugins/course-apps/learning_assistant/package.json b/plugins/course-apps/learning_assistant/package.json index 1ad1a000a9..07d90b0b3b 100644 --- a/plugins/course-apps/learning_assistant/package.json +++ b/plugins/course-apps/learning_assistant/package.json @@ -1,19 +1,18 @@ { - "name": "@openedx-plugins/course-app-learning_assistant", - "version": "0.1.0", - "description": "Learning Assistant configuration for courses using it", - "peerDependencies": { - "@edx/frontend-app-authoring": "*", - "@edx/frontend-platform": "*", - "@openedx/paragon": "*", - "prop-types": "*", - "react": "*", - "yup": "*" - }, - "peerDependenciesMeta": { - "@edx/frontend-app-authoring": { - "optional": true - } + "name": "@openedx-plugins/course-app-learning_assistant", + "version": "0.1.0", + "description": "Learning Assistant configuration for courses using it", + "peerDependencies": { + "@edx/frontend-app-authoring": "*", + "@edx/frontend-platform": "*", + "@openedx/paragon": "*", + "prop-types": "*", + "react": "*", + "yup": "*" + }, + "peerDependenciesMeta": { + "@edx/frontend-app-authoring": { + "optional": true } + } } - \ No newline at end of file diff --git a/plugins/course-apps/live/BBBSettings.jsx b/plugins/course-apps/live/BBBSettings.jsx index e81e3aa03c..c5cc14fe9b 100644 --- a/plugins/course-apps/live/BBBSettings.jsx +++ b/plugins/course-apps/live/BBBSettings.jsx @@ -42,15 +42,17 @@ const BbbSettings = ({ }; return ( <> - {isPiiDisabled ? ( -

- {intl.formatMessage(messages.requestPiiSharingEnableForBbb, { provider: providerNames[values.provider] })} -

- ) : ( -

- {intl.formatMessage(messages.providerHelperText, { providerName: providerNames[values.provider] })} -

- )} + {isPiiDisabled ? + ( +

+ {intl.formatMessage(messages.requestPiiSharingEnableForBbb, { provider: providerNames[values.provider] })} +

+ ) : + ( +

+ {intl.formatMessage(messages.providerHelperText, { providerName: providerNames[values.provider] })} +

+ )} @@ -78,33 +80,35 @@ const BbbSettings = ({ showLaunchIcon className="text-primary-500 pt-2" > - { intl.formatMessage(messages.learnMore, { providerName: 'plans' }) } + {intl.formatMessage(messages.learnMore, { providerName: 'plans' })} <> - {isPiiDisabled ? ( -

- {intl.formatMessage(messages.piiSharingEnableHelpTextBbb)} -

- ) : ( - <> - {bbbPlan === bbbPlanTypes.commercial && } - {bbbPlan === bbbPlanTypes.free && ( - - {intl.formatMessage(messages.freePlanMessage)} - - {intl.formatMessage(messages.privacyPolicy)} - - - )} - - )} + {isPiiDisabled ? + ( +

+ {intl.formatMessage(messages.piiSharingEnableHelpTextBbb)} +

+ ) : + ( + <> + {bbbPlan === bbbPlanTypes.commercial && } + {bbbPlan === bbbPlanTypes.free && ( + + {intl.formatMessage(messages.freePlanMessage)} + + {intl.formatMessage(messages.privacyPolicy)} + + + )} + + )} ); diff --git a/plugins/course-apps/live/BbbSettings.test.jsx b/plugins/course-apps/live/BbbSettings.test.jsx index 1336513139..91ae0e439c 100644 --- a/plugins/course-apps/live/BbbSettings.test.jsx +++ b/plugins/course-apps/live/BbbSettings.test.jsx @@ -63,8 +63,14 @@ const mockStore = async ({ const fetchProviderConfigUrl = `${providersApiUrl}/${courseId}/`; const fetchLiveConfigUrl = `${providerConfigurationApiUrl}/${courseId}/`; - axiosMock.onGet(fetchProviderConfigUrl).reply(200, configurationProviders(emailSharing, usernameSharing, 'big_blue_button', isFreeTier)); - axiosMock.onGet(fetchLiveConfigUrl).reply(200, generateLiveConfigurationApiResponse(enabled, piiSharingAllowed, 'bigBlueButton', isFreeTier)); + axiosMock.onGet(fetchProviderConfigUrl).reply( + 200, + configurationProviders(emailSharing, usernameSharing, 'big_blue_button', isFreeTier), + ); + axiosMock.onGet(fetchLiveConfigUrl).reply( + 200, + generateLiveConfigurationApiResponse(enabled, piiSharingAllowed, 'bigBlueButton', isFreeTier), + ); await executeThunk(fetchLiveProviders(courseId), store.dispatch); await executeThunk(fetchLiveConfiguration(courseId), store.dispatch); @@ -88,14 +94,17 @@ describe('BBB Settings', () => { expect(container.querySelector('select[name="tierType"]')).not.toBeDisabled(); }); - test.each([[true, 3], [false, 2]])('Plan dropdown should display correct number of options', async (isFreeTier, noOfOptions) => { - await mockStore({ emailSharing: true, isFreeTier }); - renderComponent(); - const spinner = getByRole(container, 'status'); - await waitForElementToBeRemoved(spinner); - const dropDown = queryByTestId(container, 'plansDropDown'); - expect(getAllByRole(dropDown, 'option').length).toBe(noOfOptions); - }); + test.each([[true, 3], [false, 2]])( + 'Plan dropdown should display correct number of options', + async (isFreeTier, noOfOptions) => { + await mockStore({ emailSharing: true, isFreeTier }); + renderComponent(); + const spinner = getByRole(container, 'status'); + await waitForElementToBeRemoved(spinner); + const dropDown = queryByTestId(container, 'plansDropDown'); + expect(getAllByRole(dropDown, 'option').length).toBe(noOfOptions); + }, + ); test( 'Connect to support and PII sharing message is visible and plans selection is disabled, When pii sharing is disabled, ', diff --git a/plugins/course-apps/live/Settings.jsx b/plugins/course-apps/live/Settings.jsx index 5295d1b420..06ebe67bfd 100644 --- a/plugins/course-apps/live/Settings.jsx +++ b/plugins/course-apps/live/Settings.jsx @@ -30,7 +30,10 @@ const LiveSettings = ({ const { courseId } = useCourseAuthoringContext(); const availableProviders = useSelector((state) => state.live.appIds); const { - piiSharingAllowed, selectedAppId, enabled, status, + piiSharingAllowed, + selectedAppId, + enabled, + status, } = useSelector(state => state.live); const appConfig = useModel('liveAppConfigs', selectedAppId); @@ -52,15 +55,18 @@ const LiveSettings = ({ const validationSchema = { enabled: Yup.boolean(), consumerKey: Yup.string().when(['provider', 'tierType'], { - is: (provider, tier) => provider === 'zoom' || (provider === 'big_blue_button' && tier === bbbPlanTypes.commercial), + is: (provider, tier) => + provider === 'zoom' || (provider === 'big_blue_button' && tier === bbbPlanTypes.commercial), then: Yup.string().required(intl.formatMessage(messages.consumerKeyRequired)), }), consumerSecret: Yup.string().when(['provider', 'tierType'], { - is: (provider, tier) => provider === 'zoom' || (provider === 'big_blue_button' && tier === bbbPlanTypes.commercial), + is: (provider, tier) => + provider === 'zoom' || (provider === 'big_blue_button' && tier === bbbPlanTypes.commercial), then: Yup.string().notRequired(intl.formatMessage(messages.consumerSecretRequired)), }), launchUrl: Yup.string().when(['provider', 'tierType'], { - is: (provider, tier) => provider === 'zoom' || (provider === 'big_blue_button' && tier === bbbPlanTypes.commercial), + is: (provider, tier) => + provider === 'zoom' || (provider === 'big_blue_button' && tier === bbbPlanTypes.commercial), then: Yup.string().required(intl.formatMessage(messages.launchUrlRequired)), }), launchEmail: Yup.string(), @@ -96,9 +102,7 @@ const LiveSettings = ({ enableReinitialize > {({ values, setFieldValue }) => ( - (status === RequestStatus.IN_PROGRESS) ? ( - - ) : ( + (status === RequestStatus.IN_PROGRESS) ? : ( <>

{intl.formatMessage(messages.selectProvider)}

))} - {values.provider === 'zoom' ? + {values.provider === 'zoom' ? + : ( - {!values.piiSharingEnable ? ( -

- {intl.formatMessage(messages.requestPiiSharingEnable, { provider: providerNames[values.provider] })} -

- ) : ( - <> - {(values.piiSharingEmail || values.piiSharingUsername) - && ( -

- {intl.formatMessage(messages.providerHelperText, { providerName: providerNames[values.provider] })} -

- )} - - - - )} + {!values.piiSharingEnable ? + ( +

+ {intl.formatMessage(messages.requestPiiSharingEnable, { provider: providerNames[values.provider] })} +

+ ) : + ( + <> + {(values.piiSharingEmail || values.piiSharingUsername) + && ( +

+ {intl.formatMessage(messages.providerHelperText, { providerName: providerNames[values.provider] })} +

+ )} + + + + )} ); }; diff --git a/plugins/course-apps/live/constants.js b/plugins/course-apps/live/constants.js index 3a1294eb65..3b012a244a 100644 --- a/plugins/course-apps/live/constants.js +++ b/plugins/course-apps/live/constants.js @@ -1,5 +1,8 @@ import { - GoogleMeet, MicrosoftTeams, Zoom, Bbb, + GoogleMeet, + MicrosoftTeams, + Zoom, + Bbb, } from '@openedx/paragon/icons'; export const iconsSrc = { diff --git a/plugins/course-apps/live/package.json b/plugins/course-apps/live/package.json index ac9485ea7e..35a3f33ad4 100644 --- a/plugins/course-apps/live/package.json +++ b/plugins/course-apps/live/package.json @@ -1,22 +1,22 @@ { - "name": "@openedx-plugins/course-app-live", - "version": "0.1.0", - "description": "Live course configuration for courses using it", - "peerDependencies": { - "@edx/frontend-app-authoring": "*", - "@edx/frontend-platform": "*", - "@openedx/paragon": "*", - "@reduxjs/toolkit": "*", - "lodash": "*", - "prop-types": "*", - "react": "*", - "react-redux": "*", - "react-router-dom": "*", - "yup": "*" - }, - "peerDependenciesMeta": { - "@edx/frontend-app-authoring": { - "optional": true - } + "name": "@openedx-plugins/course-app-live", + "version": "0.1.0", + "description": "Live course configuration for courses using it", + "peerDependencies": { + "@edx/frontend-app-authoring": "*", + "@edx/frontend-platform": "*", + "@openedx/paragon": "*", + "@reduxjs/toolkit": "*", + "lodash": "*", + "prop-types": "*", + "react": "*", + "react-redux": "*", + "react-router-dom": "*", + "yup": "*" + }, + "peerDependenciesMeta": { + "@edx/frontend-app-authoring": { + "optional": true } + } } diff --git a/plugins/course-apps/ora_settings/Settings.jsx b/plugins/course-apps/ora_settings/Settings.jsx index 386f3d7420..0ea271817d 100644 --- a/plugins/course-apps/ora_settings/Settings.jsx +++ b/plugins/course-apps/ora_settings/Settings.jsx @@ -5,7 +5,13 @@ import { useIntl } from '@edx/frontend-platform/i18n'; import { useDispatch, useSelector } from 'react-redux'; import { - ActionRow, Alert, Badge, Form, Hyperlink, ModalDialog, StatefulButton, + ActionRow, + Alert, + Badge, + Form, + Hyperlink, + ModalDialog, + StatefulButton, } from '@openedx/paragon'; import { Info } from '@openedx/paragon/icons'; import { updateModel, useModel } from 'CourseAuthoring/generic/model-store'; @@ -54,7 +60,8 @@ const ORASettings = ({ onClose }) => { success = await dispatch(updateModel({ modelType: 'courseApps', model: { - id: appId, enabled: formValues.enableFlexiblePeerGrade, + id: appId, + enabled: formValues.enableFlexiblePeerGrade, }, })); } @@ -88,7 +95,7 @@ const ORASettings = ({ onClose }) => { {formatMessage(messages.enableFlexPeerGradeLabel)} {formValues.enableFlexiblePeerGrade && ( @@ -97,8 +104,8 @@ const ORASettings = ({ onClose }) => { )} - )} - helpText={( + } + helpText={

{formatMessage(messages.enableFlexPeerGradeHelp)}

@@ -112,7 +119,7 @@ const ORASettings = ({ onClose }) => {
- )} + } onChange={handleChange} checked={formValues.enableFlexiblePeerGrade} /> diff --git a/plugins/course-apps/ora_settings/Settings.test.jsx b/plugins/course-apps/ora_settings/Settings.test.jsx index 787042f527..82c7f7b497 100644 --- a/plugins/course-apps/ora_settings/Settings.test.jsx +++ b/plugins/course-apps/ora_settings/Settings.test.jsx @@ -38,7 +38,14 @@ const renderComponent = () => ( - } /> + + + + } + /> @@ -113,7 +120,8 @@ describe('ORASettings', () => { renderComponent(); const errorAlert = screen.getByRole('alert'); - expect(within(errorAlert).getByText('We encountered a technical error when loading this page.', { exact: false })).toBeVisible(); + expect(within(errorAlert).getByText('We encountered a technical error when loading this page.', { exact: false })) + .toBeVisible(); }); it('Displays Permissions Error Alert', async () => { diff --git a/plugins/course-apps/ora_settings/package.json b/plugins/course-apps/ora_settings/package.json index 3f93dcb722..d9dee7e483 100644 --- a/plugins/course-apps/ora_settings/package.json +++ b/plugins/course-apps/ora_settings/package.json @@ -1,20 +1,19 @@ { - "name": "@openedx-plugins/course-app-ora_settings", - "version": "0.1.0", - "description": "Open Response Assessment configuration for courses using it", - "peerDependencies": { - "@edx/frontend-app-authoring": "*", - "@edx/frontend-platform": "*", - "@openedx/paragon": "*", - "prop-types": "*", - "react": "*", - "react-redux": "*", - "yup": "*" - }, - "peerDependenciesMeta": { - "@edx/frontend-app-authoring": { - "optional": true - } + "name": "@openedx-plugins/course-app-ora_settings", + "version": "0.1.0", + "description": "Open Response Assessment configuration for courses using it", + "peerDependencies": { + "@edx/frontend-app-authoring": "*", + "@edx/frontend-platform": "*", + "@openedx/paragon": "*", + "prop-types": "*", + "react": "*", + "react-redux": "*", + "yup": "*" + }, + "peerDependenciesMeta": { + "@edx/frontend-app-authoring": { + "optional": true } + } } - \ No newline at end of file diff --git a/plugins/course-apps/proctoring/Settings.jsx b/plugins/course-apps/proctoring/Settings.jsx index fd1369f4e8..3a8bcda11c 100644 --- a/plugins/course-apps/proctoring/Settings.jsx +++ b/plugins/course-apps/proctoring/Settings.jsx @@ -1,5 +1,8 @@ import React, { - useContext, useEffect, useRef, useState, + useContext, + useEffect, + useRef, + useState, } from 'react'; import classNames from 'classnames'; import EmailValidator from 'email-validator'; @@ -10,7 +13,13 @@ import { getConfig } from '@edx/frontend-platform'; import { getAuthenticatedUser } from '@edx/frontend-platform/auth'; import { useIntl, FormattedMessage } from '@edx/frontend-platform/i18n'; import { - ActionRow, Alert, Badge, Form, Hyperlink, ModalDialog, StatefulButton, + ActionRow, + Alert, + Badge, + Form, + Hyperlink, + ModalDialog, + StatefulButton, } from '@openedx/paragon'; import ExamsApiService from 'CourseAuthoring/data/services/ExamsApiService'; @@ -120,7 +129,9 @@ const ProctoringSettings = ({ onClose }) => { } if (requiresEscalationEmailProviders.includes(formValues.proctoringProvider)) { - studioDataToPostBack.proctored_exam_settings.proctoring_escalation_email = formValues.escalationEmail === '' ? null : formValues.escalationEmail; + studioDataToPostBack.proctored_exam_settings.proctoring_escalation_email = formValues.escalationEmail === '' + ? null + : formValues.escalationEmail; } // only save back to exam service if necessary @@ -161,14 +172,20 @@ const ProctoringSettings = ({ onClose }) => { && !(formValues.escalationEmail === '' && !formValues.enableProctoredExams) ) { if (formValues.escalationEmail === '') { - const errorMessage = intl.formatMessage(messages['authoring.proctoring.escalationemail.error.blank'], { proctoringProviderName: getProviderDisplayLabel(formValues.proctoringProvider) }); + const errorMessage = intl.formatMessage(messages['authoring.proctoring.escalationemail.error.blank'], { + proctoringProviderName: getProviderDisplayLabel(formValues.proctoringProvider), + }); setFormStatus({ isValid: false, errors: { formEscalationEmail: { dialogErrorMessage: ( - + {errorMessage} ), @@ -183,7 +200,15 @@ const ProctoringSettings = ({ onClose }) => { isValid: false, errors: { formEscalationEmail: { - dialogErrorMessage: ({errorMessage}), + dialogErrorMessage: ( + + {errorMessage} + + ), inputErrorMessage: errorMessage, }, }, @@ -280,30 +305,28 @@ const ProctoringSettings = ({ onClose }) => { name="enableProctoredExams" onChange={handleChange} checked={formValues.enableProctoredExams} - label={( + label={
{intl.formatMessage(messages['authoring.proctoring.enableproctoredexams.label'])} - { - formValues.enableProctoredExams && ( - - {intl.formatMessage(messages['authoring.proctoring.enabled'])} - - ) - } + {formValues.enableProctoredExams && ( + + {intl.formatMessage(messages['authoring.proctoring.enabled'])} + + )}
- )} - helpText={( + } + helpText={

{intl.formatMessage(messages['authoring.proctoring.enableproctoredexams.help'])}

{learnMoreLink}
- )} + } /> {/* PROCTORING PROVIDER */} - { formValues.enableProctoredExams && ( + {formValues.enableProctoredExams && ( <>
@@ -320,11 +343,9 @@ const ProctoringSettings = ({ onClose }) => { {getProctoringProviderOptions(availableProctoringProviders)} - { - cannotEditProctoringProvider() - ? intl.formatMessage(messages['authoring.proctoring.provider.help.aftercoursestart']) - : intl.formatMessage(messages['authoring.proctoring.provider.help']) - } + {cannotEditProctoringProvider() + ? intl.formatMessage(messages['authoring.proctoring.provider.help.aftercoursestart']) + : intl.formatMessage(messages['authoring.proctoring.provider.help'])} @@ -351,17 +372,15 @@ const ProctoringSettings = ({ onClose }) => { {Object.prototype.hasOwnProperty.call(formStatus.errors, 'formEscalationEmail') && ( - { - formStatus.errors.formEscalationEmail - && formStatus.errors.formEscalationEmail.inputErrorMessage - } + {formStatus.errors.formEscalationEmail + && formStatus.errors.formEscalationEmail.inputErrorMessage} )}
)} {/* ALLOW OPTING OUT OF PROCTORED EXAMS */} - { isEdxStaff && formValues.enableProctoredExams && !isLtiProviderSelected && ( + {isEdxStaff && formValues.enableProctoredExams && !isLtiProviderSelected && (
@@ -388,21 +407,15 @@ const ProctoringSettings = ({ onClose }) => { } function renderLoading() { - return ( - - ); + return ; } function renderConnectionError() { - return ( - - ); + return ; } function renderPermissionError() { - return ( - - ); + return ; } function renderSaveSuccess() { diff --git a/plugins/course-apps/proctoring/Settings.test.jsx b/plugins/course-apps/proctoring/Settings.test.jsx index 793d983cd3..a2148e89e2 100644 --- a/plugins/course-apps/proctoring/Settings.test.jsx +++ b/plugins/course-apps/proctoring/Settings.test.jsx @@ -1,5 +1,10 @@ import { - render, screen, cleanup, waitFor, fireEvent, act, + render, + screen, + cleanup, + waitFor, + fireEvent, + act, initializeMocks, } from 'CourseAuthoring/testUtils'; diff --git a/plugins/course-apps/proctoring/package.json b/plugins/course-apps/proctoring/package.json index 55e973ed20..3e8dbb4d40 100644 --- a/plugins/course-apps/proctoring/package.json +++ b/plugins/course-apps/proctoring/package.json @@ -1,20 +1,20 @@ { - "name": "@openedx-plugins/course-app-proctoring", - "version": "0.1.0", - "description": "Proctoring configuration for courses using it", - "peerDependencies": { - "@edx/frontend-app-authoring": "*", - "@edx/frontend-platform": "*", - "@openedx/paragon": "*", - "classnames": "*", - "email-validator": "*", - "react": "*", - "prop-types": "*", - "moment": "*" - }, - "peerDependenciesMeta": { - "@edx/frontend-app-authoring": { - "optional": true - } + "name": "@openedx-plugins/course-app-proctoring", + "version": "0.1.0", + "description": "Proctoring configuration for courses using it", + "peerDependencies": { + "@edx/frontend-app-authoring": "*", + "@edx/frontend-platform": "*", + "@openedx/paragon": "*", + "classnames": "*", + "email-validator": "*", + "react": "*", + "prop-types": "*", + "moment": "*" + }, + "peerDependenciesMeta": { + "@edx/frontend-app-authoring": { + "optional": true } + } } diff --git a/plugins/course-apps/progress/Settings.jsx b/plugins/course-apps/progress/Settings.jsx index 04da126bab..1f01c56c79 100644 --- a/plugins/course-apps/progress/Settings.jsx +++ b/plugins/course-apps/progress/Settings.jsx @@ -29,21 +29,19 @@ const ProgressSettings = ({ onClose }) => { validationSchema={{ enableProgressGraph: Yup.boolean() }} onSettingsSave={handleSettingsSave} > - { - ({ handleChange, handleBlur, values }) => ( - showProgressGraphSetting && ( - - ) + {({ handleChange, handleBlur, values }) => ( + showProgressGraphSetting && ( + ) - } + )} ); }; diff --git a/plugins/course-apps/progress/package.json b/plugins/course-apps/progress/package.json index 678de578b9..ea74a0b0c5 100644 --- a/plugins/course-apps/progress/package.json +++ b/plugins/course-apps/progress/package.json @@ -1,18 +1,18 @@ { - "name": "@openedx-plugins/course-app-progress", - "version": "0.1.0", - "description": "Progress configuration for courses using it", - "peerDependencies": { - "@edx/frontend-app-authoring": "*", - "@edx/frontend-platform": "*", - "@openedx/paragon": "*", - "prop-types": "*", - "react": "*", - "yup": "*" - }, - "peerDependenciesMeta": { - "@edx/frontend-app-authoring": { - "optional": true - } + "name": "@openedx-plugins/course-app-progress", + "version": "0.1.0", + "description": "Progress configuration for courses using it", + "peerDependencies": { + "@edx/frontend-app-authoring": "*", + "@edx/frontend-platform": "*", + "@openedx/paragon": "*", + "prop-types": "*", + "react": "*", + "yup": "*" + }, + "peerDependenciesMeta": { + "@edx/frontend-app-authoring": { + "optional": true } + } } diff --git a/plugins/course-apps/teams/GroupEditor.jsx b/plugins/course-apps/teams/GroupEditor.jsx index 5d4d457b5c..bdf942cc91 100644 --- a/plugins/course-apps/teams/GroupEditor.jsx +++ b/plugins/course-apps/teams/GroupEditor.jsx @@ -30,7 +30,12 @@ const TeamTypeNameMessage = { }; const GroupEditor = ({ - group, onDelete, onChange, onBlur, fieldNameCommonBase, errors, + group, + onDelete, + onChange, + onBlur, + fieldNameCommonBase, + errors, }) => { const intl = useIntl(); const [isDeleting, setDeleting] = useState(false); @@ -69,20 +74,21 @@ const GroupEditor = ({ deleteAlt={intl.formatMessage(messages.deleteAlt)} expandAlt={intl.formatMessage(messages.expandAlt)} collapseAlt={intl.formatMessage(messages.collapseAlt)} - title={ - isOpen - ? ( -
- {intl.formatMessage(messages.configureGroup)} + title={isOpen + ? ( +
+ {intl.formatMessage(messages.configureGroup)} +
+ ) : + ( +
+
+ {intl.formatMessage(TeamTypeNameMessage[group.type ? group.type : GroupTypes.OPEN].label)}
- ) : ( -
-
{intl.formatMessage(TeamTypeNameMessage[group.type ? group.type : GroupTypes.OPEN].label)}
-
{group.name}
-
{group.description}
-
- ) - } +
{group.name}
+
{group.description}
+
+ )} > - {Object.values(GroupTypes).map(groupType => isGroupTypeEnabled(groupType) && ( - - {intl.formatMessage(TeamTypeNameMessage[groupType].label)} - - ))} + {Object.values(GroupTypes).map(groupType => + isGroupTypeEnabled(groupType) && ( + + {intl.formatMessage(TeamTypeNameMessage[groupType].label)} + + ) + )} { errors: {}, }; - const renderComponent = (overrideProps = {}) => render( - - - , - ); + const renderComponent = (overrideProps = {}) => + render( + + + , + ); beforeEach(() => { useFormikContext.mockReturnValue({ diff --git a/plugins/course-apps/teams/Settings.jsx b/plugins/course-apps/teams/Settings.jsx index a81a19a64f..038cf6fb7b 100644 --- a/plugins/course-apps/teams/Settings.jsx +++ b/plugins/course-apps/teams/Settings.jsx @@ -116,52 +116,53 @@ const TeamSettings = ({ onSettingsSave={handleSettingsSave} configureBeforeEnable > - { - ({ - handleChange, handleBlur, values, errors, - }) => ( - <> -

{intl.formatMessage(messages.teamSize)}

- -
-

{intl.formatMessage(messages.groups)}

- {intl.formatMessage(messages.groupsHelp)} - - {({ push, remove }) => ( - <> - {values.groups?.map((group, index) => ( - remove(index)} - onChange={handleChange} - onBlur={handleBlur} - /> - ))} - - - )} - -
- - ) - } + {({ + handleChange, + handleBlur, + values, + errors, + }) => ( + <> +

{intl.formatMessage(messages.teamSize)}

+ +
+

{intl.formatMessage(messages.groups)}

+ {intl.formatMessage(messages.groupsHelp)} + + {({ push, remove }) => ( + <> + {values.groups?.map((group, index) => ( + remove(index)} + onChange={handleChange} + onBlur={handleBlur} + /> + ))} + + + )} + +
+ + )} ); }; diff --git a/plugins/course-apps/teams/package.json b/plugins/course-apps/teams/package.json index 9b377a1763..9975cd8960 100644 --- a/plugins/course-apps/teams/package.json +++ b/plugins/course-apps/teams/package.json @@ -1,20 +1,20 @@ { - "name": "@openedx-plugins/course-app-teams", - "version": "0.1.0", - "description": "Teams configuration for courses using it", - "peerDependencies": { - "@edx/frontend-app-authoring": "*", - "@edx/frontend-platform": "*", - "@openedx/paragon": "*", - "formik": "*", - "prop-types": "*", - "react": "*", - "uuid": "*", - "yup": "*" - }, - "peerDependenciesMeta": { - "@edx/frontend-app-authoring": { - "optional": true - } + "name": "@openedx-plugins/course-app-teams", + "version": "0.1.0", + "description": "Teams configuration for courses using it", + "peerDependencies": { + "@edx/frontend-app-authoring": "*", + "@edx/frontend-platform": "*", + "@openedx/paragon": "*", + "formik": "*", + "prop-types": "*", + "react": "*", + "uuid": "*", + "yup": "*" + }, + "peerDependenciesMeta": { + "@edx/frontend-app-authoring": { + "optional": true } + } } diff --git a/plugins/course-apps/wiki/Settings.jsx b/plugins/course-apps/wiki/Settings.jsx index c1ede73440..ffd62cbf35 100644 --- a/plugins/course-apps/wiki/Settings.jsx +++ b/plugins/course-apps/wiki/Settings.jsx @@ -25,19 +25,17 @@ const WikiSettings = ({ onClose }) => { validationSchema={{ enablePublicWiki: Yup.boolean() }} onSettingsSave={handleSettingsSave} > - { - ({ values, handleChange, handleBlur }) => ( - - ) - } + {({ values, handleChange, handleBlur }) => ( + + )} ); }; diff --git a/plugins/course-apps/wiki/package.json b/plugins/course-apps/wiki/package.json index b7d92a69bb..856aa8598a 100644 --- a/plugins/course-apps/wiki/package.json +++ b/plugins/course-apps/wiki/package.json @@ -1,18 +1,18 @@ { - "name": "@openedx-plugins/course-app-wiki", - "version": "0.1.0", - "description": "Wiki configuration for courses using it", - "peerDependencies": { - "@edx/frontend-app-authoring": "*", - "@edx/frontend-platform": "*", - "@openedx/paragon": "*", - "prop-types": "*", - "react": "*", - "yup": "*" - }, - "peerDependenciesMeta": { - "@edx/frontend-app-authoring": { - "optional": true - } + "name": "@openedx-plugins/course-app-wiki", + "version": "0.1.0", + "description": "Wiki configuration for courses using it", + "peerDependencies": { + "@edx/frontend-app-authoring": "*", + "@edx/frontend-platform": "*", + "@openedx/paragon": "*", + "prop-types": "*", + "react": "*", + "yup": "*" + }, + "peerDependenciesMeta": { + "@edx/frontend-app-authoring": { + "optional": true } + } } diff --git a/plugins/course-apps/xpert_unit_summary/Settings.test.jsx b/plugins/course-apps/xpert_unit_summary/Settings.test.jsx index b831f5ba19..d8ff859913 100644 --- a/plugins/course-apps/xpert_unit_summary/Settings.test.jsx +++ b/plugins/course-apps/xpert_unit_summary/Settings.test.jsx @@ -2,12 +2,19 @@ import ReactDOM from 'react-dom'; import React from 'react'; import { MemoryRouter, Routes, Route } from 'react-router-dom'; import { - getConfig, initializeMockApp, setConfig, + getConfig, + initializeMockApp, + setConfig, } from '@edx/frontend-platform'; import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth'; import { AppProvider, PageWrap } from '@edx/frontend-platform/react'; import { - findByTestId, queryByTestId, render, waitFor, getByText, fireEvent, + findByTestId, + queryByTestId, + render, + waitFor, + getByText, + fireEvent, } from '@testing-library/react'; import MockAdapter from 'axios-mock-adapter'; import PagesAndResourcesProvider from 'CourseAuthoring/pages-and-resources/PagesAndResourcesProvider'; @@ -34,11 +41,19 @@ function renderComponent() { } + element={ + + + + } />
} + element={ + +
+ + } /> @@ -49,11 +64,13 @@ function renderComponent() { } function generateCourseLevelAPIResponse({ - success, enabled, + success, + enabled, }) { return { response: { - success, enabled, + success, + enabled, }, }; } @@ -97,10 +114,13 @@ describe('XpertUnitSummarySettings', () => { describe('with successful network connections', () => { beforeEach(() => { axiosMock.onGet(API.getXpertSettingsUrl(courseId)) - .reply(200, generateCourseLevelAPIResponse({ - success: true, - enabled: true, - })); + .reply( + 200, + generateCourseLevelAPIResponse({ + success: true, + enabled: true, + }), + ); renderComponent(); }); @@ -113,10 +133,13 @@ describe('XpertUnitSummarySettings', () => { test('Shows switch on if disabled from backend', async () => { axiosMock.onGet(API.getXpertSettingsUrl(courseId)) - .reply(200, generateCourseLevelAPIResponse({ - success: true, - enabled: false, - })); + .reply( + 200, + generateCourseLevelAPIResponse({ + success: true, + enabled: false, + }), + ); renderComponent(); await waitFor(() => expect(container.querySelector('#enable-xpert-unit-summary-toggle')).toBeTruthy()); @@ -131,10 +154,13 @@ describe('XpertUnitSummarySettings', () => { test('Shows disable radio selected if enabled from backend', async () => { axiosMock.onGet(API.getXpertSettingsUrl(courseId)) - .reply(200, generateCourseLevelAPIResponse({ - success: true, - enabled: false, - })); + .reply( + 200, + generateCourseLevelAPIResponse({ + success: true, + enabled: false, + }), + ); renderComponent(); await waitFor(() => expect(container.querySelector('#enable-xpert-unit-summary-toggle')).toBeTruthy()); @@ -145,10 +171,13 @@ describe('XpertUnitSummarySettings', () => { describe('first time course configuration', () => { beforeEach(() => { axiosMock.onGet(API.getXpertSettingsUrl(courseId)) - .reply(400, generateCourseLevelAPIResponse({ - success: false, - enabled: undefined, - })); + .reply( + 400, + generateCourseLevelAPIResponse({ + success: false, + enabled: undefined, + }), + ); renderComponent(); }); @@ -163,16 +192,22 @@ describe('XpertUnitSummarySettings', () => { describe('saving configuration changes', () => { beforeEach(() => { axiosMock.onGet(API.getXpertSettingsUrl(courseId)) - .reply(200, generateCourseLevelAPIResponse({ - success: true, - enabled: false, - })); + .reply( + 200, + generateCourseLevelAPIResponse({ + success: true, + enabled: false, + }), + ); axiosMock.onPost(API.getXpertSettingsUrl(courseId)) - .reply(200, generateCourseLevelAPIResponse({ - success: true, - enabled: true, - })); + .reply( + 200, + generateCourseLevelAPIResponse({ + success: true, + enabled: true, + }), + ); renderComponent(); }); @@ -192,10 +227,13 @@ describe('XpertUnitSummarySettings', () => { describe('testing configurable gating', () => { beforeEach(async () => { axiosMock.onGet(API.getXpertConfigurationStatusUrl(courseId)) - .reply(200, generateCourseLevelAPIResponse({ - success: true, - enabled: true, - })); + .reply( + 200, + generateCourseLevelAPIResponse({ + success: true, + enabled: true, + }), + ); jest.spyOn(API, 'getXpertPluginConfigurable'); await executeThunk(Thunks.fetchXpertPluginConfigurable(courseId), store.dispatch); renderComponent(); @@ -209,16 +247,22 @@ describe('XpertUnitSummarySettings', () => { describe('removing course configuration', () => { beforeEach(() => { axiosMock.onGet(API.getXpertSettingsUrl(courseId)) - .reply(200, generateCourseLevelAPIResponse({ - success: true, - enabled: true, - })); + .reply( + 200, + generateCourseLevelAPIResponse({ + success: true, + enabled: true, + }), + ); axiosMock.onDelete(API.getXpertSettingsUrl(courseId)) - .reply(200, generateCourseLevelAPIResponse({ - success: true, - enabled: undefined, - })); + .reply( + 200, + generateCourseLevelAPIResponse({ + success: true, + enabled: undefined, + }), + ); renderComponent(); }); @@ -237,16 +281,22 @@ describe('XpertUnitSummarySettings', () => { describe('resetting course units', () => { test('reset all units to be enabled', async () => { axiosMock.onGet(API.getXpertSettingsUrl(courseId)) - .reply(200, generateCourseLevelAPIResponse({ - success: true, - enabled: true, - })); + .reply( + 200, + generateCourseLevelAPIResponse({ + success: true, + enabled: true, + }), + ); axiosMock.onPost(API.getXpertSettingsUrl(courseId)) - .reply(200, generateCourseLevelAPIResponse({ - success: true, - enabled: true, - })); + .reply( + 200, + generateCourseLevelAPIResponse({ + success: true, + enabled: true, + }), + ); renderComponent(); @@ -259,16 +309,22 @@ describe('XpertUnitSummarySettings', () => { test('reset all units to be disabled', async () => { axiosMock.onGet(API.getXpertSettingsUrl(courseId)) - .reply(200, generateCourseLevelAPIResponse({ - success: true, - enabled: false, - })); + .reply( + 200, + generateCourseLevelAPIResponse({ + success: true, + enabled: false, + }), + ); axiosMock.onPost(API.getXpertSettingsUrl(courseId)) - .reply(200, generateCourseLevelAPIResponse({ - success: true, - enabled: false, - })); + .reply( + 200, + generateCourseLevelAPIResponse({ + success: true, + enabled: false, + }), + ); renderComponent(); diff --git a/plugins/course-apps/xpert_unit_summary/data/thunks.js b/plugins/course-apps/xpert_unit_summary/data/thunks.js index eeaa4ee0b1..ec0bd91ff5 100644 --- a/plugins/course-apps/xpert_unit_summary/data/thunks.js +++ b/plugins/course-apps/xpert_unit_summary/data/thunks.js @@ -1,9 +1,16 @@ -import { updateSavingStatus, updateLoadingStatus, updateResetStatus } from 'CourseAuthoring/pages-and-resources/data/slice'; +import { + updateSavingStatus, + updateLoadingStatus, + updateResetStatus, +} from 'CourseAuthoring/pages-and-resources/data/slice'; import { RequestStatus } from 'CourseAuthoring/data/constants'; import { addModel, updateModel } from 'CourseAuthoring/generic/model-store'; import { - getXpertSettings, postXpertSettings, getXpertPluginConfigurable, deleteXpertSettings, + getXpertSettings, + postXpertSettings, + getXpertPluginConfigurable, + deleteXpertSettings, } from './api'; export function updateXpertSettings(courseId, state) { @@ -13,7 +20,9 @@ export function updateXpertSettings(courseId, state) { const { response } = await postXpertSettings(courseId, state); const { success } = response; if (success) { - dispatch(updateModel({ modelType: 'XpertSettings', model: { id: 'xpert-unit-summary', enabled: state.enabled } })); + dispatch( + updateModel({ modelType: 'XpertSettings', model: { id: 'xpert-unit-summary', enabled: state.enabled } }), + ); dispatch(updateSavingStatus({ status: RequestStatus.SUCCESSFUL })); return true; } diff --git a/plugins/course-apps/xpert_unit_summary/package.json b/plugins/course-apps/xpert_unit_summary/package.json index 26c0c7d5b9..121c25e2e3 100644 --- a/plugins/course-apps/xpert_unit_summary/package.json +++ b/plugins/course-apps/xpert_unit_summary/package.json @@ -1,21 +1,21 @@ { - "name": "@openedx-plugins/course-app-xpert_unit_summary", - "version": "0.1.0", - "description": "Xpert Unit Summaries configuration for courses using it", - "peerDependencies": { - "@edx/frontend-app-authoring": "*", - "@edx/frontend-platform": "*", - "@openedx/paragon": "*", - "formik": "*", - "prop-types": "*", - "yup": "*", - "react": "*", - "react-redux": "*", - "react-router-dom": "*" - }, - "peerDependenciesMeta": { - "@edx/frontend-app-authoring": { - "optional": true - } + "name": "@openedx-plugins/course-app-xpert_unit_summary", + "version": "0.1.0", + "description": "Xpert Unit Summaries configuration for courses using it", + "peerDependencies": { + "@edx/frontend-app-authoring": "*", + "@edx/frontend-platform": "*", + "@openedx/paragon": "*", + "formik": "*", + "prop-types": "*", + "yup": "*", + "react": "*", + "react-redux": "*", + "react-router-dom": "*" + }, + "peerDependenciesMeta": { + "@edx/frontend-app-authoring": { + "optional": true } + } } diff --git a/plugins/course-apps/xpert_unit_summary/settings-modal/SettingsModal.jsx b/plugins/course-apps/xpert_unit_summary/settings-modal/SettingsModal.jsx index f4c016b044..e06846dd46 100644 --- a/plugins/course-apps/xpert_unit_summary/settings-modal/SettingsModal.jsx +++ b/plugins/course-apps/xpert_unit_summary/settings-modal/SettingsModal.jsx @@ -14,13 +14,18 @@ import { Hyperlink, } from '@openedx/paragon'; import { - Info, CheckCircleOutline, SpinnerSimple, + Info, + CheckCircleOutline, + SpinnerSimple, } from '@openedx/paragon/icons'; import { Formik } from 'formik'; import PropTypes from 'prop-types'; import React, { - useContext, useEffect, useRef, useState, + useContext, + useEffect, + useRef, + useState, } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import * as Yup from 'yup'; @@ -45,18 +50,21 @@ import ResetIcon from './ResetIcon'; import './SettingsModal.scss'; const AppSettingsForm = ({ - formikProps, children, showForm, -}) => children && ( - - {showForm ? ( - - {children(formikProps)} - - ) : ( - - )} - -); + formikProps, + children, + showForm, +}) => + children && ( + + {showForm ? + ( + + {children(formikProps)} + + ) : + } + + ); AppSettingsForm.propTypes = { // Ignore the warning here since we're just passing along the props as-is and the child component should validate @@ -71,7 +79,12 @@ AppSettingsForm.defaultProps = { }; const SettingsModalBase = ({ - title, onClose, variant, isMobile, children, footer, + title, + onClose, + variant, + isMobile, + children, + footer, }) => { const intl = useIntl(); return ( @@ -156,14 +169,14 @@ const ResetUnitsButton = ({ return ( {intl.formatMessage(messages[messageKey])} - )} + } > @@ -317,7 +328,7 @@ const SettingsModal = ({ isMobile={isMobile} isFullscreenOnMobile intl={intl} - footer={( + footer={ - )} + } > {saveError && ( @@ -344,7 +355,7 @@ const SettingsModal = ({ onChange={formikProps.handleChange} onBlur={formikProps.handleBlur} checked={formikProps.values.enabled} - label={( + label={
{enableAppLabel} {formikProps.values.enabled && ( @@ -353,14 +364,14 @@ const SettingsModal = ({ )}
- )} - helpText={( + } + helpText={

{enableAppHelp}

{helpPrivacyLink} {learnMoreLink}
- )} + } /> {(formikProps.values.enabled || configureBeforeEnable) && ( (undefined); @@ -122,7 +123,9 @@ export function useCourseAuthoringContext(): CourseAuthoringContextData { const ctx = useContext(CourseAuthoringContext); if (ctx === undefined) { /* istanbul ignore next */ - throw new Error('useCourseAuthoringContext() was used in a component without a ancestor.'); + throw new Error( + 'useCourseAuthoringContext() was used in a component without a ancestor.', + ); } return ctx; } diff --git a/src/CourseAuthoringPage.test.tsx b/src/CourseAuthoringPage.test.tsx index a4ef4fc7ed..d7339a283f 100644 --- a/src/CourseAuthoringPage.test.tsx +++ b/src/CourseAuthoringPage.test.tsx @@ -19,11 +19,12 @@ jest.mock('react-router-dom', () => ({ let axiosMock; let store; -const renderComponent = children => render( - - {children} - , -); +const renderComponent = children => + render( + + {children} + , + ); beforeEach(async () => { const mocks = initializeMocks(); @@ -48,8 +49,7 @@ describe('Editor Pages Load no header', () => { const wrapper = renderComponent( - - , + , ); expect(wrapper.queryByRole('status')).not.toBeInTheDocument(); }); @@ -59,8 +59,7 @@ describe('Editor Pages Load no header', () => { const wrapper = renderComponent( - - , + , ); expect(wrapper.queryByRole('status')).toBeInTheDocument(); }); @@ -98,8 +97,7 @@ describe('Course authoring page', () => { const wrapper = renderComponent(
- - , + , ); expect(await wrapper.findByTestId(contentTestId)).toBeInTheDocument(); expect(wrapper.queryByTestId('notFoundAlert')).not.toBeInTheDocument(); diff --git a/src/CourseAuthoringPage.tsx b/src/CourseAuthoringPage.tsx index e8b328d483..7e6d4055bd 100644 --- a/src/CourseAuthoringPage.tsx +++ b/src/CourseAuthoringPage.tsx @@ -35,22 +35,21 @@ const CourseAuthoringPage = ({ children }: Props) => { const isEditor = pathname.includes('/editor'); if (courseDetailStatus === RequestStatus.NOT_FOUND && !isEditor) { - return ( - - ); + return ; } if (courseAppsApiStatus === RequestStatus.DENIED) { - return ( - - ); + return ; } return (
- {/* While V2 Editors are temporarily served from their own pages + { + /* While V2 Editors are temporarily served from their own pages using url pattern containing /editor/, we shouldn't have the header and footer on these pages. - This functionality will be removed in TNL-9591 */} - {inProgress ? !isEditor && + This functionality will be removed in TNL-9591 */ + } + {inProgress ? + !isEditor && : (!isEditor && (
{ size: 'fluid', }} /> - ) - )} + ))} {children} {!inProgress && !isEditor && }
diff --git a/src/CourseAuthoringRoutes.test.tsx b/src/CourseAuthoringRoutes.test.tsx index f7aabc829f..cece487f07 100644 --- a/src/CourseAuthoringRoutes.test.tsx +++ b/src/CourseAuthoringRoutes.test.tsx @@ -1,7 +1,10 @@ import CourseAuthoringRoutes from './CourseAuthoringRoutes'; import { getApiWaffleFlagsUrl } from './data/api'; import { - screen, initializeMocks, render, waitFor, + screen, + initializeMocks, + render, + waitFor, } from './testUtils'; const courseId = 'course-v1:edX+TestX+Test_Course'; diff --git a/src/CourseAuthoringRoutes.tsx b/src/CourseAuthoringRoutes.tsx index 6ca81f930d..d4b9eb3bbd 100644 --- a/src/CourseAuthoringRoutes.tsx +++ b/src/CourseAuthoringRoutes.tsx @@ -1,5 +1,8 @@ import { - Navigate, Routes, Route, useParams, + Navigate, + Routes, + Route, + useParams, } from 'react-router-dom'; import { getConfig } from '@edx/frontend-platform'; import { PageWrap } from '@edx/frontend-platform/react'; @@ -65,7 +68,7 @@ const CourseAuthoringRoutes = () => { @@ -75,27 +78,49 @@ const CourseAuthoringRoutes = () => { - )} + } /> } + element={ + + + + } /> } + element={ + + + + } /> } + element={ + + + + } /> : null} + element={getConfig().ENABLE_VIDEO_UPLOAD_PAGE_LINK_IN_CONTENT_DROPDOWN === 'true' + ? ( + + + + ) + : null} /> } + element={ + + + + } /> { /> } + element={ + + + + } /> } + element={ + + + + } /> {DECODED_ROUTES.COURSE_UNIT.map((path) => ( } + element={ + + + + + + } /> ))} } + element={ + + + + } /> } + element={ + + + + } /> } + element={ + + + + } /> } + element={ + + + + } /> } + element={ + + + + } /> } + element={ + + + + } /> } + element={ + + + + } /> - )} + } /> - )} + } /> } + element={ + + + + } /> } + element={ + + + + } /> : null} + element={getConfig().ENABLE_CERTIFICATE_PAGE === 'true' + ? ( + + + + ) + : null} /> } + element={ + + + + } /> diff --git a/src/__mocks__/clipboardSection.ts b/src/__mocks__/clipboardSection.ts index b6a1da4ea1..ba9d8cc0f2 100644 --- a/src/__mocks__/clipboardSection.ts +++ b/src/__mocks__/clipboardSection.ts @@ -12,5 +12,6 @@ export default { }, sourceUsageKey: 'block-v1:edX+DemoX+Demo_Course+type@chapter+block@chapter_0270f6de40fc', sourceContextTitle: 'Demonstration Course', - sourceEditUrl: 'http://localhost:18010/container/block-v1:edX+DemoX+Demo_Course+type@chapter+block@chapter_0270f6de40fc', + sourceEditUrl: + 'http://localhost:18010/container/block-v1:edX+DemoX+Demo_Course+type@chapter+block@chapter_0270f6de40fc', }; diff --git a/src/__mocks__/clipboardSubsection.ts b/src/__mocks__/clipboardSubsection.ts index 541e95f979..49fca1495a 100644 --- a/src/__mocks__/clipboardSubsection.ts +++ b/src/__mocks__/clipboardSubsection.ts @@ -12,5 +12,6 @@ export default { }, sourceUsageKey: 'block-v1:edX+DemoX+Demo_Course+type@sequential+block@sequential_0270f6de40fc', sourceContextTitle: 'Demonstration Course', - sourceEditUrl: 'http://localhost:18010/container/block-v1:edX+DemoX+Demo_Course+type@sequential+block@sequential_0270f6de40fc', + sourceEditUrl: + 'http://localhost:18010/container/block-v1:edX+DemoX+Demo_Course+type@sequential+block@sequential_0270f6de40fc', }; diff --git a/src/__mocks__/clipboardUnit.ts b/src/__mocks__/clipboardUnit.ts index fb20bde413..e71f4a1cf1 100644 --- a/src/__mocks__/clipboardUnit.ts +++ b/src/__mocks__/clipboardUnit.ts @@ -12,5 +12,6 @@ export default { }, sourceUsageKey: 'block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical_0270f6de40fc', sourceContextTitle: 'Demonstration Course', - sourceEditUrl: 'http://localhost:18010/container/block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical_0270f6de40fc', + sourceEditUrl: + 'http://localhost:18010/container/block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical_0270f6de40fc', }; diff --git a/src/__mocks__/index.ts b/src/__mocks__/index.ts index 14c73faa93..44e19f2e6d 100644 --- a/src/__mocks__/index.ts +++ b/src/__mocks__/index.ts @@ -1,4 +1,4 @@ -export { default as clipboardUnit } from './clipboardUnit'; +export { default as clipboardSection } from './clipboardSection'; export { default as clipboardSubsection } from './clipboardSubsection'; +export { default as clipboardUnit } from './clipboardUnit'; export { default as clipboardXBlock } from './clipboardXBlock'; -export { default as clipboardSection } from './clipboardSection'; diff --git a/src/accessibility-page/AccessibilityBody/AccessibilityBody.tsx b/src/accessibility-page/AccessibilityBody/AccessibilityBody.tsx index 4991a8b387..1277807e08 100644 --- a/src/accessibility-page/AccessibilityBody/AccessibilityBody.tsx +++ b/src/accessibility-page/AccessibilityBody/AccessibilityBody.tsx @@ -7,8 +7,8 @@ const AccessibilityBody = ({ communityAccessibilityLink, email, }: { - communityAccessibilityLink: string, - email: string, + communityAccessibilityLink: string; + email: string; }) => (
diff --git a/src/accessibility-page/AccessibilityForm/AccessibilityForm.test.tsx b/src/accessibility-page/AccessibilityForm/AccessibilityForm.test.tsx index e20efedae8..2afae32a84 100644 --- a/src/accessibility-page/AccessibilityForm/AccessibilityForm.test.tsx +++ b/src/accessibility-page/AccessibilityForm/AccessibilityForm.test.tsx @@ -63,9 +63,10 @@ describe('', () => { it('renders in progress state', async () => { axiosMock.onPost(getZendeskrUrl()).reply( - () => new Promise(() => { - // always in pending - }), + () => + new Promise(() => { + // always in pending + }), ); await user.click(submitButton); diff --git a/src/accessibility-page/AccessibilityForm/AccessibilityForm.tsx b/src/accessibility-page/AccessibilityForm/AccessibilityForm.tsx index f12502d7ba..7053f3cfa2 100644 --- a/src/accessibility-page/AccessibilityForm/AccessibilityForm.tsx +++ b/src/accessibility-page/AccessibilityForm/AccessibilityForm.tsx @@ -1,15 +1,22 @@ import { - FormattedMessage, FormattedDate, FormattedTime, useIntl, + FormattedMessage, + FormattedDate, + FormattedTime, + useIntl, } from '@edx/frontend-platform/i18n'; import { - ActionRow, Alert, Form, Stack, StatefulButton, + ActionRow, + Alert, + Form, + Stack, + StatefulButton, } from '@openedx/paragon'; import { STATEFUL_BUTTON_STATES } from '@src/constants'; import useAccessibility from './hooks'; import messages from './messages'; -const AccessibilityForm = ({ accessibilityEmail }: { accessibilityEmail: string }) => { +const AccessibilityForm = ({ accessibilityEmail }: { accessibilityEmail: string; }) => { const intl = useIntl(); const { errors, @@ -70,10 +77,10 @@ const AccessibilityForm = ({ accessibilityEmail }: { accessibilityEmail: string ), - time_start: (), - day_end: (), - time_end: (), + day_start: , + time_start: , + day_end: , + time_end: , }} />
@@ -118,11 +125,9 @@ const AccessibilityForm = ({ accessibilityEmail }: { accessibilityEmail: string key="save-button" onClick={handleSubmit} disabled={!isFormFilled} - state={ - savingStatus === 'pending' - ? STATEFUL_BUTTON_STATES.pending - : STATEFUL_BUTTON_STATES.default - } + state={savingStatus === 'pending' + ? STATEFUL_BUTTON_STATES.pending + : STATEFUL_BUTTON_STATES.default} {...createButtonState} /> diff --git a/src/accessibility-page/AccessibilityForm/hooks.ts b/src/accessibility-page/AccessibilityForm/hooks.ts index 6d9855a1e2..7b6281dc6d 100644 --- a/src/accessibility-page/AccessibilityForm/hooks.ts +++ b/src/accessibility-page/AccessibilityForm/hooks.ts @@ -23,7 +23,12 @@ const useAccessibility = (initialValues: AccessibilityFormData) => { }); const { - values, errors, touched, handleChange, handleBlur, handleReset, + values, + errors, + touched, + handleChange, + handleBlur, + handleReset, } = useFormik({ initialValues, enableReinitialize: true, diff --git a/src/advanced-settings/AdvancedSettings.test.tsx b/src/advanced-settings/AdvancedSettings.test.tsx index 2d24fb2b7a..8b9d73aa70 100644 --- a/src/advanced-settings/AdvancedSettings.test.tsx +++ b/src/advanced-settings/AdvancedSettings.test.tsx @@ -18,23 +18,25 @@ const mockPathname = '/foo-bar'; const courseId = '123'; // Mock the TextareaAutosize component -jest.mock('react-textarea-autosize', () => jest.fn((props) => ( -