diff --git a/src/account-settings/AccountSettingsPage.jsx b/src/account-settings/AccountSettingsPage.jsx index c606ce5..ddb56ce 100644 --- a/src/account-settings/AccountSettingsPage.jsx +++ b/src/account-settings/AccountSettingsPage.jsx @@ -47,6 +47,7 @@ import { COPPA_COMPLIANCE_YEAR, WORK_EXPERIENCE_OPTIONS, getStatesList, + FIELD_LABELS, } from './data/constants'; import { fetchSiteLanguages } from './site-language'; import { fetchCourseList } from '../notification-preferences/data/thunks'; @@ -163,16 +164,13 @@ class AccountSettingsPage extends React.Component { }; removeDisabledCountries = (countryList) => { - const { disabledCountries, committedValues } = this.props; + const { countriesCodesList, committedValues } = this.props; + const committedCountry = committedValues?.country; - if (!disabledCountries.length) { + if (!countriesCodesList.length) { return countryList; } - - return countryList.filter(({ value, disabled }) => { - const isUserCountry = value === committedValues.country; - return !disabled || isUserCountry; - }); + return countryList.filter(({ value }) => value === committedCountry || countriesCodesList.find(x => x === value)); }; handleEditableFieldChange = (name, value) => { @@ -180,7 +178,7 @@ class AccountSettingsPage extends React.Component { }; handleSubmit = (formId, values) => { - if (formId === 'country' && this.isDisabledCountry(values)) { + if (formId === FIELD_LABELS.COUNTRY && this.isDisabledCountry(values)) { return; } @@ -226,8 +224,9 @@ class AccountSettingsPage extends React.Component { }; isDisabledCountry = (country) => { - const { disabledCountries } = this.props; - return disabledCountries.includes(country); + const { countriesCodesList } = this.props; + + return countriesCodesList.length > 0 && !countriesCodesList.find(x => x === country); }; isEditable(fieldName) { @@ -974,7 +973,12 @@ AccountSettingsPage.propTypes = { ), navigate: PropTypes.func.isRequired, location: PropTypes.string.isRequired, - disabledCountries: PropTypes.arrayOf(PropTypes.string), + countriesCodesList: PropTypes.arrayOf( + PropTypes.shape({ + value: PropTypes.string.isRequired, + label: PropTypes.string.isRequired, + }), + ), }; AccountSettingsPage.defaultProps = { @@ -1001,7 +1005,7 @@ AccountSettingsPage.defaultProps = { verifiedName: null, mostRecentVerifiedName: {}, verifiedNameHistory: [], - disabledCountries: [], + countriesCodesList: [], }; export default withLocation(withNavigate(connect(accountSettingsPageSelector, { diff --git a/src/account-settings/data/actions.js b/src/account-settings/data/actions.js index 27d8f76..0e85a1e 100644 --- a/src/account-settings/data/actions.js +++ b/src/account-settings/data/actions.js @@ -27,6 +27,7 @@ export const fetchSettingsSuccess = ({ profileDataManager, timeZones, verifiedNameHistory, + countriesCodesList, }) => ({ type: FETCH_SETTINGS.SUCCESS, payload: { @@ -35,6 +36,7 @@ export const fetchSettingsSuccess = ({ profileDataManager, timeZones, verifiedNameHistory, + countriesCodesList, }, }); diff --git a/src/account-settings/data/constants.js b/src/account-settings/data/constants.js index 6ba4f6f..d10746a 100644 --- a/src/account-settings/data/constants.js +++ b/src/account-settings/data/constants.js @@ -132,6 +132,10 @@ export function getStatesList(country) { return country && COUNTRY_STATES_MAP[country.toUpperCase()]; } +export const FIELD_LABELS = { + COUNTRY: 'country', +}; + export const DECLINED = 'declined'; export const SELF_DESCRIBE = 'self-describe'; export const OTHER = 'other'; diff --git a/src/account-settings/data/reducers.js b/src/account-settings/data/reducers.js index 35de9ef..b5f853b 100644 --- a/src/account-settings/data/reducers.js +++ b/src/account-settings/data/reducers.js @@ -39,7 +39,7 @@ export const defaultState = { verifiedName: null, mostRecentVerifiedName: {}, verifiedNameHistory: {}, - disabledCountries: ['RU'], + countries: [], }; const reducer = (state = defaultState, action = {}) => { @@ -65,6 +65,7 @@ const reducer = (state = defaultState, action = {}) => { loaded: true, loadingError: null, verifiedNameHistory: action.payload.verifiedNameHistory, + countriesCodesList: action.payload.countriesCodesList, }; case FETCH_SETTINGS.FAILURE: return { diff --git a/src/account-settings/data/sagas.js b/src/account-settings/data/sagas.js index c27cbe9..f7cede7 100644 --- a/src/account-settings/data/sagas.js +++ b/src/account-settings/data/sagas.js @@ -53,7 +53,7 @@ export function* handleFetchSettings() { const { username, userId, roles: userRoles } = getAuthenticatedUser(); const { - thirdPartyAuthProviders, profileDataManager, timeZones, ...values + thirdPartyAuthProviders, profileDataManager, timeZones, countries, ...values } = yield call( getSettings, username, @@ -71,6 +71,7 @@ export function* handleFetchSettings() { profileDataManager, timeZones, verifiedNameHistory, + countriesCodesList: countries, })); } catch (e) { yield put(fetchSettingsFailure(e.message)); diff --git a/src/account-settings/data/selectors.js b/src/account-settings/data/selectors.js index 27e7e7b..fc69830 100644 --- a/src/account-settings/data/selectors.js +++ b/src/account-settings/data/selectors.js @@ -88,6 +88,11 @@ const previousSiteLanguageSelector = createSelector( accountSettings => accountSettings.previousSiteLanguage, ); +const countriesSelector = createSelector( + accountSettingsSelector, + accountSettings => accountSettings.countriesCodesList, +); + const editableFieldErrorSelector = createSelector( editableFieldNameSelector, accountSettingsSelector, @@ -237,7 +242,7 @@ export const accountSettingsPageSelector = createSelector( mostRecentApprovedVerifiedNameValueSelector, mostRecentVerifiedNameSelector, sortedVerifiedNameHistorySelector, - disabledCountriesSelector, + countriesSelector, ( accountSettings, siteLanguageOptions, @@ -255,7 +260,7 @@ export const accountSettingsPageSelector = createSelector( verifiedName, mostRecentVerifiedName, verifiedNameHistory, - disabledCountries, + countriesCodesList, ) => ({ siteLanguageOptions, siteLanguage, @@ -276,7 +281,7 @@ export const accountSettingsPageSelector = createSelector( verifiedName, mostRecentVerifiedName, verifiedNameHistory, - disabledCountries, + countriesCodesList, }), ); diff --git a/src/account-settings/data/service.js b/src/account-settings/data/service.js index 10152c8..14c66f8 100644 --- a/src/account-settings/data/service.js +++ b/src/account-settings/data/service.js @@ -1,5 +1,6 @@ import { getConfig } from '@edx/frontend-platform'; import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth'; +import { logError } from '@edx/frontend-platform/logging'; import pick from 'lodash.pick'; import omit from 'lodash.omit'; import isEmpty from 'lodash.isempty'; @@ -7,6 +8,7 @@ import isEmpty from 'lodash.isempty'; import { handleRequestError, unpackFieldErrors } from './utils'; import { getThirdPartyAuthProviders } from '../third-party-auth'; import { postVerifiedNameConfig } from '../certificate-preference/data/service'; +import { FIELD_LABELS } from './constants'; const SOCIAL_PLATFORMS = [ { id: 'twitter', key: 'social_link_twitter' }, @@ -186,6 +188,24 @@ export async function postVerifiedName(data) { .catch(error => handleRequestError(error)); } +function extractCountryList(data) { + return data?.fields + .find(({ name }) => name === FIELD_LABELS.COUNTRY) + ?.options?.map(({ value }) => (value)) || []; +} + +export async function getCountryList() { + const url = `${getConfig().LMS_BASE_URL}/user_api/v1/account/registration/`; + + try { + const { data } = await getAuthenticatedHttpClient().get(url); + return extractCountryList(data); + } catch (e) { + logError(e); + return []; + } +} + /** * A single function to GET everything considered a setting. Currently encapsulates Account, Preferences, and * ThirdPartyAuth. @@ -197,12 +217,14 @@ export async function getSettings(username, userRoles) { thirdPartyAuthProviders, profileDataManager, timeZones, + countries, ] = await Promise.all([ getAccount(username), getPreferences(username), getThirdPartyAuthProviders(), getProfileDataManager(username, userRoles), getTimeZones(), + getCountryList(), ]); return { @@ -211,6 +233,7 @@ export async function getSettings(username, userRoles) { thirdPartyAuthProviders, profileDataManager, timeZones, + countries, }; }