diff --git a/package-lock.json b/package-lock.json index 6528d9095..38bddca99 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,7 +26,7 @@ "@tensorflow/tfjs-core": "3.21.0", "bowser": "2.11.0", "classnames": "2.5.1", - "core-js": "3.38.0", + "core-js": "3.38.1", "font-awesome": "4.7.0", "form-urlencoded": "6.1.5", "formdata-polyfill": "4.0.10", @@ -66,7 +66,7 @@ "devDependencies": { "@edx/browserslist-config": "1.2.0", "@edx/reactifex": "1.1.0", - "@openedx/frontend-build": "14.1.2", + "@openedx/frontend-build": "14.1.4", "@testing-library/jest-dom": "6.4.8", "@testing-library/react": "12.1.5", "react-test-renderer": "17.0.2", @@ -3086,9 +3086,9 @@ } }, "node_modules/@openedx/frontend-build": { - "version": "14.1.2", - "resolved": "https://registry.npmjs.org/@openedx/frontend-build/-/frontend-build-14.1.2.tgz", - "integrity": "sha512-pLTcY/BLjCFn2qsBmUY0on2qB4PNShlg8scTYjrsz5fCASuSAJk000jOF5ys6bg6i8krSOIJlcZXPgrq0ywsUg==", + "version": "14.1.4", + "resolved": "https://registry.npmjs.org/@openedx/frontend-build/-/frontend-build-14.1.4.tgz", + "integrity": "sha512-DMzkitHqemtqwxmDsF8y7zRVAJcW8URPfWcLKtFvXffqJ3WW7fJXXMmiZWKra/vGBw3SRyYRqvdzQG1d2giPAw==", "license": "AGPL-3.0", "dependencies": { "@babel/cli": "7.24.8", @@ -3109,7 +3109,7 @@ "@types/jest": "29.5.12", "@typescript-eslint/eslint-plugin": "^5.58.0", "@typescript-eslint/parser": "^5.58.0", - "autoprefixer": "10.4.19", + "autoprefixer": "10.4.20", "babel-jest": "29.6.1", "babel-loader": "9.1.3", "babel-plugin-formatjs": "^10.4.0", @@ -3138,7 +3138,7 @@ "jest-environment-jsdom": "29.6.1", "mini-css-extract-plugin": "1.6.2", "parse5": "7.1.2", - "postcss": "8.4.39", + "postcss": "8.4.47", "postcss-custom-media": "10.0.8", "postcss-loader": "7.3.4", "postcss-rtlcss": "5.1.2", @@ -3310,9 +3310,9 @@ } }, "node_modules/@openedx/frontend-slot-footer": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@openedx/frontend-slot-footer/-/frontend-slot-footer-1.0.4.tgz", - "integrity": "sha512-ywMAYpS6mBP1LIuPgqHKEwWtVgYihKSZjDxEZE8yl7PrYFmJ/ZmlSAVEiZPvwyj55MP5G+JMXFRrKH3YMuRELw==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@openedx/frontend-slot-footer/-/frontend-slot-footer-1.0.5.tgz", + "integrity": "sha512-hlKj2p7zgAHfPTbmW4rAMUCCj35uCbm9VfRkZYPEIX2bdhkPjc4OIGTE5CKGkyWG5+zL+aap1ywwcKEjEgOMOQ==", "license": "AGPL-3.0", "dependencies": { "@openedx/frontend-plugin-framework": "^1.1.2" @@ -3520,7 +3520,9 @@ "license": "MIT" }, "node_modules/@remix-run/router": { - "version": "1.19.0", + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.19.2.tgz", + "integrity": "sha512-baiMx18+IMuD1yyvOGaHM9QrVUPGGG0jC+z+IPHnRJWUAUvaKuWKyE8gjDj2rzv3sz9zOGoRSPgeBVHRhZnBlA==", "license": "MIT", "engines": { "node": ">=14.0.0" @@ -5084,7 +5086,9 @@ } }, "node_modules/autoprefixer": { - "version": "10.4.19", + "version": "10.4.20", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", + "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==", "funding": [ { "type": "opencollective", @@ -5101,11 +5105,11 @@ ], "license": "MIT", "dependencies": { - "browserslist": "^4.23.0", - "caniuse-lite": "^1.0.30001599", + "browserslist": "^4.23.3", + "caniuse-lite": "^1.0.30001646", "fraction.js": "^4.3.7", "normalize-range": "^0.1.2", - "picocolors": "^1.0.0", + "picocolors": "^1.0.1", "postcss-value-parser": "^4.2.0" }, "bin": { @@ -6102,10 +6106,11 @@ "license": "MIT" }, "node_modules/core-js": { - "version": "3.38.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.38.0.tgz", - "integrity": "sha512-XPpwqEodRljce9KswjZShh95qJ1URisBeKCjUdq27YdenkslVe7OO0ZJhlYXAChW7OhXaRLl8AAba7IBfoIHug==", + "version": "3.38.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.38.1.tgz", + "integrity": "sha512-OP35aUorbU3Zvlx7pjsFdu1rGNnD4pgw/CWoYzRY3t2EzoVT7shKHY1dlAy3f41cGIO7ZDPQimhGFTlEYkG/Hw==", "hasInstallScript": true, + "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/core-js" @@ -12059,7 +12064,9 @@ } }, "node_modules/picocolors": { - "version": "1.0.1", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", "license": "ISC" }, "node_modules/picomatch": { @@ -12264,7 +12271,9 @@ } }, "node_modules/postcss": { - "version": "8.4.39", + "version": "8.4.47", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", + "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", "funding": [ { "type": "opencollective", @@ -12282,8 +12291,8 @@ "license": "MIT", "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.0.1", - "source-map-js": "^1.2.0" + "picocolors": "^1.1.0", + "source-map-js": "^1.2.1" }, "engines": { "node": "^10 || ^12 || >=14" @@ -13550,10 +13559,12 @@ } }, "node_modules/react-router": { - "version": "6.26.0", + "version": "6.26.2", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.26.2.tgz", + "integrity": "sha512-tvN1iuT03kHgOFnLPfLJ8V95eijteveqdOSk+srqfePtQvqCExB8eHOYnlilbOcyJyKnYkr1vJvf7YqotAJu1A==", "license": "MIT", "dependencies": { - "@remix-run/router": "1.19.0" + "@remix-run/router": "1.19.2" }, "engines": { "node": ">=14.0.0" @@ -13563,11 +13574,13 @@ } }, "node_modules/react-router-dom": { - "version": "6.26.0", + "version": "6.26.2", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.26.2.tgz", + "integrity": "sha512-z7YkaEW0Dy35T3/QKPYB1LjMK2R1fxnHO8kWpUMTBdfVzZrWOiY9a7CtN8HqdWtDUWd5FY6Dl8HFsqVwH4uOtQ==", "license": "MIT", "dependencies": { - "@remix-run/router": "1.19.0", - "react-router": "6.26.0" + "@remix-run/router": "1.19.2", + "react-router": "6.26.2" }, "engines": { "node": ">=14.0.0" @@ -14599,7 +14612,9 @@ } }, "node_modules/source-map-js": { - "version": "1.2.0", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" diff --git a/package.json b/package.json index 8e318ce9e..8f00fb4fe 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "@tensorflow/tfjs-core": "3.21.0", "bowser": "2.11.0", "classnames": "2.5.1", - "core-js": "3.38.0", + "core-js": "3.38.1", "font-awesome": "4.7.0", "form-urlencoded": "6.1.5", "formdata-polyfill": "4.0.10", @@ -85,7 +85,7 @@ "devDependencies": { "@edx/browserslist-config": "1.2.0", "@edx/reactifex": "1.1.0", - "@openedx/frontend-build": "14.1.2", + "@openedx/frontend-build": "14.1.4", "@testing-library/jest-dom": "6.4.8", "@testing-library/react": "12.1.5", "react-test-renderer": "17.0.2", diff --git a/src/account-settings/AccountSettingsPage.jsx b/src/account-settings/AccountSettingsPage.jsx index 6c2e336d8..f67e71762 100644 --- a/src/account-settings/AccountSettingsPage.jsx +++ b/src/account-settings/AccountSettingsPage.jsx @@ -120,7 +120,15 @@ class AccountSettingsPage extends React.Component { countryOptions: [{ value: '', label: this.props.intl.formatMessage(messages['account.settings.field.country.options.empty']), - }].concat(getCountryList(locale).map(({ code, name }) => ({ value: code, label: name }))), + }].concat( + this.removeDisabledCountries( + getCountryList(locale).map(({ code, name }) => ({ + value: code, + label: name, + disabled: this.isDisabledCountry(code), + })), + ), + ), stateOptions: [{ value: '', label: this.props.intl.formatMessage(messages['account.settings.field.state.options.empty']), @@ -147,11 +155,28 @@ class AccountSettingsPage extends React.Component { })), })); + removeDisabledCountries = (countryList) => { + const { disabledCountries, committedValues } = this.props; + + if (!disabledCountries.length) { + return countryList; + } + + return countryList.filter(({ value, disabled }) => { + const isUserCountry = value === committedValues.country; + return !disabled || isUserCountry; + }); + }; + handleEditableFieldChange = (name, value) => { this.props.updateDraft(name, value); }; handleSubmit = (formId, values) => { + if (formId === 'country' && this.isDisabledCountry(values)) { + return; + } + const { formValues } = this.props; let extendedProfileObject = {}; @@ -193,6 +218,11 @@ class AccountSettingsPage extends React.Component { } }; + isDisabledCountry = (country) => { + const { disabledCountries } = this.props; + return disabledCountries.includes(country); + }; + isEditable(fieldName) { return !this.props.staticFields.includes(fieldName); } @@ -476,7 +506,8 @@ class AccountSettingsPage extends React.Component { } = this.getLocalizedOptions(this.context.locale, this.props.formValues.country); // Show State field only if the country is US (could include Canada later) - const showState = this.props.formValues.country === COUNTRY_WITH_STATES; + const { country } = this.props.formValues; + const showState = country === COUNTRY_WITH_STATES && !this.isDisabledCountry(country); const { verifiedName } = this.props; const hasWorkExperience = !!this.props.formValues?.extended_profile?.find(field => field.field_name === 'work_experience'); @@ -880,6 +911,7 @@ AccountSettingsPage.propTypes = { name: PropTypes.string, useVerifiedNameForCerts: PropTypes.bool, verified_name: PropTypes.string, + country: PropTypes.string, }), drafts: PropTypes.shape({}), formErrors: PropTypes.shape({ @@ -938,6 +970,7 @@ AccountSettingsPage.propTypes = { ), navigate: PropTypes.func.isRequired, location: PropTypes.string.isRequired, + disabledCountries: PropTypes.arrayOf(PropTypes.string), }; AccountSettingsPage.defaultProps = { @@ -947,6 +980,7 @@ AccountSettingsPage.defaultProps = { committedValues: { useVerifiedNameForCerts: false, verified_name: null, + country: '', }, drafts: {}, formErrors: {}, @@ -963,6 +997,7 @@ AccountSettingsPage.defaultProps = { verifiedName: null, mostRecentVerifiedName: {}, verifiedNameHistory: [], + disabledCountries: [], }; export default withLocation(withNavigate(connect(accountSettingsPageSelector, { diff --git a/src/account-settings/EditableSelectField.jsx b/src/account-settings/EditableSelectField.jsx index 63a1f7d1c..bc1757e07 100644 --- a/src/account-settings/EditableSelectField.jsx +++ b/src/account-settings/EditableSelectField.jsx @@ -107,6 +107,7 @@ const EditableSelectField = (props) => { @@ -115,7 +116,7 @@ const EditableSelectField = (props) => { ); } return ( - ); diff --git a/src/account-settings/data/reducers.js b/src/account-settings/data/reducers.js index 7edb53a4e..35de9effc 100644 --- a/src/account-settings/data/reducers.js +++ b/src/account-settings/data/reducers.js @@ -39,6 +39,7 @@ export const defaultState = { verifiedName: null, mostRecentVerifiedName: {}, verifiedNameHistory: {}, + disabledCountries: ['RU'], }; const reducer = (state = defaultState, action = {}) => { diff --git a/src/account-settings/data/selectors.js b/src/account-settings/data/selectors.js index 1e6eb2497..99480a7f9 100644 --- a/src/account-settings/data/selectors.js +++ b/src/account-settings/data/selectors.js @@ -206,6 +206,11 @@ const activeAccountSelector = createSelector( accountSettings => accountSettings.values.is_active, ); +const disabledCountriesSelector = createSelector( + accountSettingsSelector, + accountSettings => accountSettings.disabledCountries, +); + export const siteLanguageSelector = createSelector( previousSiteLanguageSelector, draftsSelector, @@ -237,6 +242,7 @@ export const accountSettingsPageSelector = createSelector( mostRecentApprovedVerifiedNameValueSelector, mostRecentVerifiedNameSelector, sortedVerifiedNameHistorySelector, + disabledCountriesSelector, ( accountSettings, siteLanguageOptions, @@ -254,6 +260,7 @@ export const accountSettingsPageSelector = createSelector( verifiedName, mostRecentVerifiedName, verifiedNameHistory, + disabledCountries, ) => ({ siteLanguageOptions, siteLanguage, @@ -274,6 +281,7 @@ export const accountSettingsPageSelector = createSelector( verifiedName, mostRecentVerifiedName, verifiedNameHistory, + disabledCountries, }), ); diff --git a/src/notification-preferences/messages.js b/src/notification-preferences/messages.js index b99aca6bd..d8035452d 100644 --- a/src/notification-preferences/messages.js +++ b/src/notification-preferences/messages.js @@ -28,6 +28,7 @@ const messages = defineMessages({ contentReported {Reported content} courseUpdates {Course updates} oraStaffNotification {ORA new submissions} + oraGradeAssigned {ORA grade received} other {{text}} }`, description: 'Display text for Notification Types',