diff --git a/.env b/.env
index e27becc..6d485f1 100644
--- a/.env
+++ b/.env
@@ -37,4 +37,3 @@ SUPPORT_URL_TO_UNLINK_SOCIAL_MEDIA_ACCOUNT='https://help.edx.org/edxlearner/s/ar
COUNTRIES_WITH_DELETE_ACCOUNT_DISABLED='[]'
# Fallback in local style files
PARAGON_THEME_URLS={}
-ENABLE_PREFERENCES_V2='false'
diff --git a/.env.development b/.env.development
index f013121..0a12856 100644
--- a/.env.development
+++ b/.env.development
@@ -38,4 +38,3 @@ SUPPORT_URL_TO_UNLINK_SOCIAL_MEDIA_ACCOUNT='https://help.edx.org/edxlearner/s/ar
COUNTRIES_WITH_DELETE_ACCOUNT_DISABLED='[]'
# Fallback in local style files
PARAGON_THEME_URLS={}
-ENABLE_PREFERENCES_V2='false'
diff --git a/.env.test b/.env.test
index 4c9fc47..1c7a3b3 100644
--- a/.env.test
+++ b/.env.test
@@ -34,4 +34,3 @@ LEARNER_FEEDBACK_URL=''
SUPPORT_URL_TO_UNLINK_SOCIAL_MEDIA_ACCOUNT='https://help.edx.org/edxlearner/s/article/How-do-I-link-or-unlink-my-edX-account-to-a-social-media-account'
COUNTRIES_WITH_DELETE_ACCOUNT_DISABLED='[]'
PARAGON_THEME_URLS={}
-ENABLE_PREFERENCES_V2='false'
diff --git a/src/account-settings/AccountSettingsPage.jsx b/src/account-settings/AccountSettingsPage.jsx
index 71c0e39..b74ee03 100644
--- a/src/account-settings/AccountSettingsPage.jsx
+++ b/src/account-settings/AccountSettingsPage.jsx
@@ -50,7 +50,7 @@ import {
FIELD_LABELS,
} from './data/constants';
import { fetchSiteLanguages } from './site-language';
-import { fetchCourseList } from '../notification-preferences/data/thunks';
+import { fetchNotificationPreferences } from '../notification-preferences/data/thunks';
import NotificationSettings from '../notification-preferences/NotificationSettings';
import { withLocation, withNavigate } from './hoc';
@@ -75,7 +75,7 @@ class AccountSettingsPage extends React.Component {
}
componentDidMount() {
- this.props.fetchCourseList();
+ this.props.fetchNotificationPreferences();
this.props.fetchSettings();
this.props.fetchSiteLanguages(this.props.navigate);
sendTrackingLogEvent('edx.user.settings.viewed', {
@@ -945,7 +945,7 @@ AccountSettingsPage.propTypes = {
saveSettings: PropTypes.func.isRequired,
fetchSettings: PropTypes.func.isRequired,
beginNameChange: PropTypes.func.isRequired,
- fetchCourseList: PropTypes.func.isRequired,
+ fetchNotificationPreferences: PropTypes.func.isRequired,
tpaProviders: PropTypes.arrayOf(PropTypes.shape({
connected: PropTypes.bool,
})),
@@ -1010,7 +1010,7 @@ AccountSettingsPage.defaultProps = {
};
export default withLocation(withNavigate(connect(accountSettingsPageSelector, {
- fetchCourseList,
+ fetchNotificationPreferences,
fetchSettings,
saveSettings,
saveMultipleSettings,
diff --git a/src/index.jsx b/src/index.jsx
index 0b50016..d15b9da 100755
--- a/src/index.jsx
+++ b/src/index.jsx
@@ -74,7 +74,6 @@ initialize({
MARKETING_EMAILS_OPT_IN: (process.env.MARKETING_EMAILS_OPT_IN || false),
PASSWORD_RESET_SUPPORT_LINK: process.env.PASSWORD_RESET_SUPPORT_LINK,
LEARNER_FEEDBACK_URL: process.env.LEARNER_FEEDBACK_URL,
- ENABLE_PREFERENCES_V2: process.env.ENABLE_PREFERENCES_V2 || false,
}, 'App loadConfig override handler');
},
},
diff --git a/src/notification-preferences/NotificationCoursesDropdown.jsx b/src/notification-preferences/NotificationCoursesDropdown.jsx
deleted file mode 100644
index 5432dbc..0000000
--- a/src/notification-preferences/NotificationCoursesDropdown.jsx
+++ /dev/null
@@ -1,74 +0,0 @@
-import React, { useCallback, useEffect, useMemo } from 'react';
-import { useDispatch, useSelector } from 'react-redux';
-
-import { useIntl } from '@edx/frontend-platform/i18n';
-import { Dropdown } from '@openedx/paragon';
-
-import { IDLE_STATUS, SUCCESS_STATUS } from '../constants';
-import { selectCourseList, selectCourseListStatus, selectSelectedCourseId } from './data/selectors';
-import { fetchCourseList, setSelectedCourse } from './data/thunks';
-import messages from './messages';
-
-const NotificationCoursesDropdown = () => {
- const intl = useIntl();
- const dispatch = useDispatch();
- const coursesList = useSelector(selectCourseList());
- const courseListStatus = useSelector(selectCourseListStatus());
- const selectedCourseId = useSelector(selectSelectedCourseId());
- const selectedCourse = useMemo(
- () => coursesList.find((course) => course.id === selectedCourseId),
- [coursesList, selectedCourseId],
- );
-
- const handleCourseSelection = useCallback((courseId) => {
- dispatch(setSelectedCourse(courseId));
- }, [dispatch]);
-
- const fetchCourses = useCallback((page = 1, pageSize = 99999) => {
- dispatch(fetchCourseList(page, pageSize));
- }, [dispatch]);
-
- useEffect(() => {
- if (courseListStatus === IDLE_STATUS) {
- fetchCourses();
- }
- }, [courseListStatus, fetchCourses]);
-
- return (
- courseListStatus === SUCCESS_STATUS && (
-
-
{intl.formatMessage(messages.notificationDropdownlabel)}
-
-
- {selectedCourse?.name}
-
-
- {coursesList.map((course) => (
-
- {course.name}
-
- ))}
-
-
-
- {selectedCourse?.name === 'Account'
- ? intl.formatMessage(messages.notificationDropdownApplies)
- : intl.formatMessage(messages.notificationCourseDropdownApplies)}
-
-
- )
- );
-};
-
-export default NotificationCoursesDropdown;
diff --git a/src/notification-preferences/NotificationPreferenceColumn.jsx b/src/notification-preferences/NotificationPreferenceColumn.jsx
index 2dbae1e..d6a0e32 100644
--- a/src/notification-preferences/NotificationPreferenceColumn.jsx
+++ b/src/notification-preferences/NotificationPreferenceColumn.jsx
@@ -15,7 +15,7 @@ import { LOADING_STATUS } from '../constants';
import { updatePreferenceToggle } from './data/thunks';
import {
selectAppNonEditableChannels, selectAppPreferences,
- selectSelectedCourseId, selectUpdatePreferencesStatus,
+ selectUpdatePreferencesStatus,
} from './data/selectors';
import { notificationChannels, shouldHideAppPreferences } from './data/utils';
import {
@@ -25,7 +25,6 @@ import {
const NotificationPreferenceColumn = ({ appId, channel, appPreference }) => {
const dispatch = useDispatch();
const intl = useIntl();
- const courseId = useSelector(selectSelectedCourseId());
const appPreferences = useSelector(selectAppPreferences(appId));
const updatePreferencesStatus = useSelector(selectUpdatePreferencesStatus());
const nonEditable = useSelector(selectAppNonEditableChannels(appId));
@@ -34,11 +33,11 @@ const NotificationPreferenceColumn = ({ appId, channel, appPreference }) => {
const hideAppPreferences = shouldHideAppPreferences(appPreferences, appId) || false;
const getValue = useCallback((notificationChannel, innerText, checked) => {
- if (notificationChannel === EMAIL_CADENCE && courseId) {
+ if (notificationChannel === EMAIL_CADENCE) {
return innerText;
}
return checked;
- }, [courseId]);
+ }, []);
const getEmailCadence = useCallback((notificationChannel, checked, innerText, emailCadence) => {
if (notificationChannel === EMAIL_CADENCE) {
@@ -63,14 +62,13 @@ const NotificationPreferenceColumn = ({ appId, channel, appPreference }) => {
);
dispatch(updatePreferenceToggle(
- courseId,
appId,
notificationType,
notificationChannel,
value,
emailCadence !== MIXED ? emailCadence : undefined,
));
- }, [appPreferences, getValue, getEmailCadence, dispatch, courseId, appId]);
+ }, [appPreferences, getValue, getEmailCadence, dispatch, appId]);
const renderPreference = (preference) => (
(preference?.coreNotificationTypes?.length > 0 || preference.id !== 'core') && (
diff --git a/src/notification-preferences/NotificationPreferences.jsx b/src/notification-preferences/NotificationPreferences.jsx
index 46cbc87..a510f72 100644
--- a/src/notification-preferences/NotificationPreferences.jsx
+++ b/src/notification-preferences/NotificationPreferences.jsx
@@ -9,23 +9,21 @@ import { Spinner, NavItem } from '@openedx/paragon';
import { useIsOnMobile } from '../hooks';
import messages from './messages';
import NotificationPreferenceApp from './NotificationPreferenceApp';
-import { fetchCourseNotificationPreferences } from './data/thunks';
+import { fetchNotificationPreferences } from './data/thunks';
import { LOADING_STATUS } from '../constants';
import {
- selectCourseListStatus, selectNotificationPreferencesStatus, selectPreferenceAppsId, selectSelectedCourseId,
+ selectNotificationPreferencesStatus, selectPreferenceAppsId,
} from './data/selectors';
import { notificationChannels } from './data/utils';
const NotificationPreferences = () => {
const dispatch = useDispatch();
const intl = useIntl();
- const courseStatus = useSelector(selectCourseListStatus());
- const courseId = useSelector(selectSelectedCourseId());
const notificationStatus = useSelector(selectNotificationPreferencesStatus());
const preferenceAppsIds = useSelector(selectPreferenceAppsId());
const mobileView = useIsOnMobile();
const NOTIFICATION_CHANNELS = notificationChannels();
- const isLoading = notificationStatus === LOADING_STATUS || courseStatus === LOADING_STATUS;
+ const isLoading = notificationStatus === LOADING_STATUS;
const preferencesList = useMemo(() => (
preferenceAppsIds.map(appId => (
@@ -34,8 +32,8 @@ const NotificationPreferences = () => {
), [preferenceAppsIds]);
useEffect(() => {
- dispatch(fetchCourseNotificationPreferences(courseId));
- }, [courseId, dispatch]);
+ dispatch(fetchNotificationPreferences());
+ }, [dispatch]);
if (preferenceAppsIds.length === 0) {
return null;
diff --git a/src/notification-preferences/NotificationPreferences.test.jsx b/src/notification-preferences/NotificationPreferences.test.jsx
index dc237ac..dcf364d 100644
--- a/src/notification-preferences/NotificationPreferences.test.jsx
+++ b/src/notification-preferences/NotificationPreferences.test.jsx
@@ -12,7 +12,7 @@ import { defaultState } from './data/reducers';
import NotificationPreferences from './NotificationPreferences';
import { LOADING_STATUS, SUCCESS_STATUS } from '../constants';
import {
- getCourseNotificationPreferences,
+ getNotificationPreferences,
postPreferenceToggle,
} from './data/service';
@@ -117,7 +117,6 @@ describe('Notification Preferences', () => {
store = setupStore({
...defaultPreferences,
status: SUCCESS_STATUS,
- selectedCourse: courseId,
});
auth.getAuthenticatedHttpClient = jest.fn(() => ({
@@ -148,19 +147,10 @@ describe('Notification Preferences', () => {
expect(screen.queryAllByTestId('notification-preference')).toHaveLength(4);
});
- it('update preference on click', async () => {
- const wrapper = await render(notificationPreferences(store));
- const element = wrapper.container.querySelector('#core-web');
- expect(element).not.toBeChecked();
- await fireEvent.click(element);
- expect(mockDispatch).toHaveBeenCalled();
- });
-
it('update account preference on click', async () => {
store = setupStore({
...defaultPreferences,
status: SUCCESS_STATUS,
- selectedCourse: '',
});
await render(notificationPreferences(store));
const element = screen.getByTestId('toggle-core-web');
@@ -203,22 +193,11 @@ describe('Notification Preferences API v2 Logic', () => {
setConfig({ LMS_BASE_URL });
});
- describe('getCourseNotificationPreferences', () => {
- it('should call the v2 configurations URL when ENABLE_PREFERENCES_V2 is true', async () => {
- setConfig({ LMS_BASE_URL, ENABLE_PREFERENCES_V2: 'true' });
+ describe('getNotificationPreferences', () => {
+ it('should call the v2 configurations URL', async () => {
const expectedUrl = `${LMS_BASE_URL}/api/notifications/v2/configurations/`;
- await getCourseNotificationPreferences('any-course-id');
-
- expect(mockHttpClient.get).toHaveBeenCalledWith(expectedUrl);
- expect(mockHttpClient.get).toHaveBeenCalledTimes(1);
- });
-
- it('should call the original (v1) configurations URL when ENABLE_PREFERENCES_V2 is not true', async () => {
- setConfig({ LMS_BASE_URL, ENABLE_PREFERENCES_V2: 'false' });
- const expectedUrl = `${LMS_BASE_URL}/api/notifications/configurations/${courseId}`;
-
- await getCourseNotificationPreferences(courseId);
+ await getNotificationPreferences();
expect(mockHttpClient.get).toHaveBeenCalledWith(expectedUrl);
expect(mockHttpClient.get).toHaveBeenCalledTimes(1);
@@ -226,8 +205,7 @@ describe('Notification Preferences API v2 Logic', () => {
});
describe('postPreferenceToggle', () => {
- it('should call the v2 configurations URL with PUT method when ENABLE_PREFERENCES_V2 is true', async () => {
- setConfig({ LMS_BASE_URL, ENABLE_PREFERENCES_V2: 'true' });
+ it('should call the v2 configurations URL with PUT method', async () => {
const expectedUrl = `${LMS_BASE_URL}/api/notifications/v2/configurations/`;
const testArgs = ['app_name', 'notification_type', 'web', true, 'daily'];
@@ -237,17 +215,5 @@ describe('Notification Preferences API v2 Logic', () => {
expect(mockHttpClient.put).toHaveBeenCalledTimes(1);
expect(mockHttpClient.post).not.toHaveBeenCalled();
});
-
- it('should call the original (v1) update-all URL with POST method when ENABLE_PREFERENCES_V2 is not true', async () => {
- setConfig({ LMS_BASE_URL, ENABLE_PREFERENCES_V2: 'false' });
- const expectedUrl = `${LMS_BASE_URL}/api/notifications/preferences/update-all/`;
- const testArgs = ['app_name', 'notification_type', 'web', true, 'daily'];
-
- await postPreferenceToggle(...testArgs);
-
- expect(mockHttpClient.post).toHaveBeenCalledWith(expectedUrl, expect.any(Object));
- expect(mockHttpClient.post).toHaveBeenCalledTimes(1);
- expect(mockHttpClient.put).not.toHaveBeenCalled();
- });
});
});
diff --git a/src/notification-preferences/NotificationSettings.jsx b/src/notification-preferences/NotificationSettings.jsx
index d437f89..1c30c7d 100644
--- a/src/notification-preferences/NotificationSettings.jsx
+++ b/src/notification-preferences/NotificationSettings.jsx
@@ -4,9 +4,8 @@ import { useSelector } from 'react-redux';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Container, Hyperlink } from '@openedx/paragon';
-import { selectSelectedCourseId, selectShowPreferences } from './data/selectors';
+import { selectShowPreferences } from './data/selectors';
import messages from './messages';
-import NotificationCoursesDropdown from './NotificationCoursesDropdown';
import NotificationPreferences from './NotificationPreferences';
import { useFeedbackWrapper } from '../hooks';
@@ -14,7 +13,6 @@ const NotificationSettings = () => {
useFeedbackWrapper();
const intl = useIntl();
const showPreferences = useSelector(selectShowPreferences());
- const courseId = useSelector(selectSelectedCourseId());
return (
showPreferences && (
@@ -42,8 +40,7 @@ const NotificationSettings = () => {
{intl.formatMessage(messages.notificationPreferenceGuideLink)}
-
-
+
)
diff --git a/src/notification-preferences/data/actions.js b/src/notification-preferences/data/actions.js
index e9f900d..e0f0a5d 100644
--- a/src/notification-preferences/data/actions.js
+++ b/src/notification-preferences/data/actions.js
@@ -2,19 +2,15 @@ export const Actions = {
FETCHED_PREFERENCES: 'fetchedPreferences',
FETCHING_PREFERENCES: 'fetchingPreferences',
FAILED_PREFERENCES: 'failedPreferences',
- FETCHING_COURSE_LIST: 'fetchingCourseList',
- FETCHED_COURSE_LIST: 'fetchedCourseList',
- FAILED_COURSE_LIST: 'failedCourseList',
- UPDATE_SELECTED_COURSE: 'updateSelectedCourse',
UPDATE_PREFERENCE: 'updatePreference',
UPDATE_APP_PREFERENCE: 'updateAppValue',
};
-export const fetchNotificationPreferenceSuccess = (courseId, payload, isAccountPreference) => dispatch => (
+export const fetchNotificationPreferenceSuccess = (payload, showPreferences, isPreferenceUpdate) => dispatch => {
dispatch({
- type: Actions.FETCHED_PREFERENCES, courseId, payload, isAccountPreference,
- })
-);
+ type: Actions.FETCHED_PREFERENCES, payload, showPreferences, isPreferenceUpdate,
+ });
+};
export const fetchNotificationPreferenceFetching = () => dispatch => (
dispatch({ type: Actions.FETCHING_PREFERENCES })
@@ -24,22 +20,6 @@ export const fetchNotificationPreferenceFailed = () => dispatch => (
dispatch({ type: Actions.FAILED_PREFERENCES })
);
-export const fetchCourseListSuccess = payload => dispatch => (
- dispatch({ type: Actions.FETCHED_COURSE_LIST, payload })
-);
-
-export const fetchCourseListFetching = () => dispatch => (
- dispatch({ type: Actions.FETCHING_COURSE_LIST })
-);
-
-export const fetchCourseListFailed = () => dispatch => (
- dispatch({ type: Actions.FAILED_COURSE_LIST })
-);
-
-export const updateSelectedCourse = courseId => dispatch => (
- dispatch({ type: Actions.UPDATE_SELECTED_COURSE, courseId })
-);
-
export const updatePreferenceValue = (appId, preferenceName, notificationChannel, value) => dispatch => (
dispatch({
type: Actions.UPDATE_PREFERENCE,
diff --git a/src/notification-preferences/data/reducers.js b/src/notification-preferences/data/reducers.js
index 1683b20..a9aacd2 100644
--- a/src/notification-preferences/data/reducers.js
+++ b/src/notification-preferences/data/reducers.js
@@ -9,15 +9,9 @@ import { normalizeAccountPreferences } from './thunks';
export const defaultState = {
showPreferences: false,
- courses: {
- status: IDLE_STATUS,
- courses: [{ id: '', name: 'Account' }],
- pagination: {},
- },
preferences: {
status: IDLE_STATUS,
updatePreferenceStatus: IDLE_STATUS,
- selectedCourse: '',
preferences: [],
apps: [],
nonEditable: {},
@@ -26,35 +20,9 @@ export const defaultState = {
const notificationPreferencesReducer = (state = defaultState, action = {}) => {
const {
- courseId, appId, notificationChannel, preferenceName, value,
+ appId, notificationChannel, preferenceName, value,
} = action;
switch (action.type) {
- case Actions.FETCHING_COURSE_LIST:
- return {
- ...state,
- courses: {
- ...state.courses,
- status: LOADING_STATUS,
- },
- };
- case Actions.FETCHED_COURSE_LIST:
- return {
- ...state,
- courses: {
- status: SUCCESS_STATUS,
- courses: [...state.courses.courses, ...action.payload.courseList],
- pagination: action.payload.pagination,
- },
- showPreferences: action.payload.showPreferences,
- };
- case Actions.FAILED_COURSE_LIST:
- return {
- ...state,
- courses: {
- ...state.courses,
- status: FAILURE_STATUS,
- },
- };
case Actions.FETCHING_PREFERENCES:
return {
...state,
@@ -69,7 +37,7 @@ const notificationPreferencesReducer = (state = defaultState, action = {}) => {
case Actions.FETCHED_PREFERENCES:
{
const { preferences } = state;
- if (action.isAccountPreference) {
+ if (action.isPreferenceUpdate) {
normalizeAccountPreferences(preferences, action.payload);
}
@@ -81,6 +49,7 @@ const notificationPreferencesReducer = (state = defaultState, action = {}) => {
updatePreferenceStatus: SUCCESS_STATUS,
...action.payload,
},
+ showPreferences: action.showPreferences,
};
}
case Actions.FAILED_PREFERENCES:
@@ -95,14 +64,6 @@ const notificationPreferencesReducer = (state = defaultState, action = {}) => {
nonEditable: {},
},
};
- case Actions.UPDATE_SELECTED_COURSE:
- return {
- ...state,
- preferences: {
- ...state.preferences,
- selectedCourse: courseId,
- },
- };
case Actions.UPDATE_PREFERENCE:
return {
...state,
diff --git a/src/notification-preferences/data/reducers.test.js b/src/notification-preferences/data/reducers.test.js
index 697b7fe..79a5ee4 100644
--- a/src/notification-preferences/data/reducers.test.js
+++ b/src/notification-preferences/data/reducers.test.js
@@ -10,7 +10,6 @@ import {
describe('notification-preferences reducer', () => {
let state = null;
- const selectedCourseId = 'selected-course-id';
const preferenceData = {
apps: [{ id: 'discussion', enabled: true }],
@@ -28,53 +27,6 @@ describe('notification-preferences reducer', () => {
state = reducer();
});
- it('updates course list when api call is successful', () => {
- const data = {
- pagination: {
- count: 1,
- currentPage: 1,
- hasMore: false,
- totalPages: 1,
- },
- courseList: [],
- };
- const result = reducer(
- state,
- { type: Actions.FETCHED_COURSE_LIST, payload: data },
- );
- expect(result.courses).toEqual({
- status: SUCCESS_STATUS,
- courses: [{ id: '', name: 'Account' }],
- pagination: data.pagination,
- });
- });
-
- test.each([
- { action: Actions.FETCHING_COURSE_LIST, status: LOADING_STATUS },
- { action: Actions.FAILED_COURSE_LIST, status: FAILURE_STATUS },
- ])('course list is empty when api call is %s', ({ action, status }) => {
- const result = reducer(
- state,
- { type: action },
- );
- expect(result.courses).toEqual({
- status,
- courses: [{
- id: '',
- name: 'Account',
- }],
- pagination: {},
- });
- });
-
- it('updates selected course id', () => {
- const result = reducer(
- state,
- { type: Actions.UPDATE_SELECTED_COURSE, courseId: selectedCourseId },
- );
- expect(result.preferences.selectedCourse).toEqual(selectedCourseId);
- });
-
it('updates preferences when api call is successful', () => {
const result = reducer(
state,
@@ -83,7 +35,6 @@ describe('notification-preferences reducer', () => {
expect(result.preferences).toEqual({
status: SUCCESS_STATUS,
updatePreferenceStatus: SUCCESS_STATUS,
- selectedCourse: '',
...preferenceData,
});
});
@@ -98,7 +49,6 @@ describe('notification-preferences reducer', () => {
);
expect(result.preferences).toEqual({
status,
- selectedCourse: '',
preferences: [],
apps: [],
nonEditable: {},
diff --git a/src/notification-preferences/data/selectors.js b/src/notification-preferences/data/selectors.js
index 3dbe375..3850e72 100644
--- a/src/notification-preferences/data/selectors.js
+++ b/src/notification-preferences/data/selectors.js
@@ -13,20 +13,6 @@ export const selectPreferences = () => state => (
state.notificationPreferences.preferences?.preferences
);
-export const selectCourseListStatus = () => state => (
- state.notificationPreferences.courses.status
-);
-
-export const selectCourseList = () => state => (
- state.notificationPreferences.courses.courses
-);
-
-export const selectCourse = courseId => state => (
- selectCourseList()(state).find(
- course => course.id === courseId,
- )
-);
-
export const selectPreferenceAppsId = () => state => (
state.notificationPreferences.preferences.apps.map(app => app.id)
);
@@ -57,14 +43,6 @@ export const selectPreferenceNonEditableChannels = (appId, name) => state => (
state?.notificationPreferences.preferences.nonEditable[appId]?.[name] || []
);
-export const selectSelectedCourseId = () => state => (
- state.notificationPreferences.preferences.selectedCourse
-);
-
-export const selectPagination = () => state => (
- state.notificationPreferences.courses.pagination
-);
-
export const selectShowPreferences = () => state => (
state.notificationPreferences.showPreferences
);
diff --git a/src/notification-preferences/data/service.js b/src/notification-preferences/data/service.js
index d9dbc88..332f90d 100644
--- a/src/notification-preferences/data/service.js
+++ b/src/notification-preferences/data/service.js
@@ -2,40 +2,12 @@ import { getConfig, snakeCaseObject } from '@edx/frontend-platform';
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
import snakeCase from 'lodash.snakecase';
-export const getCourseNotificationPreferences = async (courseId) => {
- let url = `${getConfig().LMS_BASE_URL}/api/notifications/configurations/${courseId}`;
- if (getConfig().ENABLE_PREFERENCES_V2 === 'true') {
- url = `${getConfig().LMS_BASE_URL}/api/notifications/v2/configurations/`;
- }
+export const getNotificationPreferences = async () => {
+ const url = `${getConfig().LMS_BASE_URL}/api/notifications/v2/configurations/`;
const { data } = await getAuthenticatedHttpClient().get(url);
return data;
};
-export const getCourseList = async (page, pageSize) => {
- const params = snakeCaseObject({ page, pageSize });
- const url = `${getConfig().LMS_BASE_URL}/api/notifications/enrollments/`;
- const { data } = await getAuthenticatedHttpClient().get(url, { params });
- return data;
-};
-
-export const patchPreferenceToggle = async (
- courseId,
- notificationApp,
- notificationType,
- notificationChannel,
- value,
-) => {
- const patchData = snakeCaseObject({
- notificationApp,
- notificationType: snakeCase(notificationType),
- notificationChannel,
- value,
- });
- const url = `${getConfig().LMS_BASE_URL}/api/notifications/configurations/${courseId}`;
- const { data } = await getAuthenticatedHttpClient().patch(url, patchData);
- return data;
-};
-
export const postPreferenceToggle = async (
notificationApp,
notificationType,
@@ -50,13 +22,7 @@ export const postPreferenceToggle = async (
value,
emailCadence,
});
- if (getConfig().ENABLE_PREFERENCES_V2 === 'true') {
- const url = `${getConfig().LMS_BASE_URL}/api/notifications/v2/configurations/`;
- const { data } = await getAuthenticatedHttpClient().put(url, patchData);
- return data;
- }
-
- const url = `${getConfig().LMS_BASE_URL}/api/notifications/preferences/update-all/`;
- const { data } = await getAuthenticatedHttpClient().post(url, patchData);
+ const url = `${getConfig().LMS_BASE_URL}/api/notifications/v2/configurations/`;
+ const { data } = await getAuthenticatedHttpClient().put(url, patchData);
return data;
};
diff --git a/src/notification-preferences/data/thunk.test.js b/src/notification-preferences/data/thunk.test.js
index 2b23e40..6aa4e66 100644
--- a/src/notification-preferences/data/thunk.test.js
+++ b/src/notification-preferences/data/thunk.test.js
@@ -4,7 +4,7 @@ import {
fetchNotificationPreferenceSuccess,
fetchNotificationPreferenceFailed,
} from './actions';
-import { patchPreferenceToggle, postPreferenceToggle } from './service';
+import { postPreferenceToggle } from './service';
import { EMAIL } from './constants';
jest.mock('./service', () => ({
@@ -60,37 +60,9 @@ describe('updatePreferenceToggle', () => {
jest.clearAllMocks();
});
- it('should update preference for a course-specific notification', async () => {
- patchPreferenceToggle.mockResolvedValue({ data: mockData });
- await updatePreferenceToggle(
- courseId,
- notificationApp,
- notificationType,
- notificationChannel,
- value,
- emailCadence,
- )(dispatch);
-
- expect(dispatch).toHaveBeenCalledWith(updatePreferenceValue(
- notificationApp,
- notificationType,
- notificationChannel,
- !value,
- ));
- expect(patchPreferenceToggle).toHaveBeenCalledWith(
- courseId,
- notificationApp,
- notificationType,
- notificationChannel,
- value,
- );
- expect(dispatch).toHaveBeenCalledWith(fetchNotificationPreferenceSuccess(courseId, { data: mockData }, false));
- });
-
- it('should update preference globally when courseId is not provided', async () => {
+ it('should update preference globally', async () => {
postPreferenceToggle.mockResolvedValue({ data: mockData });
await updatePreferenceToggle(
- null,
notificationApp,
notificationType,
notificationChannel,
@@ -115,23 +87,22 @@ describe('updatePreferenceToggle', () => {
});
it('should handle email preferences separately', async () => {
- patchPreferenceToggle.mockResolvedValue({ data: mockData });
- await updatePreferenceToggle(courseId, notificationApp, notificationType, EMAIL, value, emailCadence)(dispatch);
+ postPreferenceToggle.mockResolvedValue({ data: mockData });
+ await updatePreferenceToggle(notificationApp, notificationType, EMAIL, value, emailCadence)(dispatch);
- expect(patchPreferenceToggle).toHaveBeenCalledWith(
- courseId,
+ expect(postPreferenceToggle).toHaveBeenCalledWith(
notificationApp,
notificationType,
EMAIL,
true,
+ emailCadence,
);
expect(dispatch).toHaveBeenCalledWith(fetchNotificationPreferenceSuccess(courseId, { data: mockData }, false));
});
it('should dispatch fetchNotificationPreferenceFailed on error', async () => {
- patchPreferenceToggle.mockRejectedValue(new Error('Network Error'));
+ postPreferenceToggle.mockRejectedValue(new Error('Network Error'));
await updatePreferenceToggle(
- courseId,
notificationApp,
notificationType,
notificationChannel,
diff --git a/src/notification-preferences/data/thunks.js b/src/notification-preferences/data/thunks.js
index 0041b84..7798de9 100644
--- a/src/notification-preferences/data/thunks.js
+++ b/src/notification-preferences/data/thunks.js
@@ -2,42 +2,16 @@ import { camelCaseObject } from '@edx/frontend-platform';
import camelCase from 'lodash.camelcase';
import { EMAIL, EMAIL_CADENCE, EMAIL_CADENCE_PREFERENCES } from './constants';
import {
- fetchCourseListSuccess,
- fetchCourseListFetching,
- fetchCourseListFailed,
fetchNotificationPreferenceFailed,
fetchNotificationPreferenceFetching,
fetchNotificationPreferenceSuccess,
updatePreferenceValue,
- updateSelectedCourse,
} from './actions';
import {
- getCourseList,
- getCourseNotificationPreferences,
- patchPreferenceToggle,
+ getNotificationPreferences,
postPreferenceToggle,
} from './service';
-const normalizeCourses = (responseData) => {
- const courseList = responseData.results?.map((enrollment) => ({
- id: enrollment.course.id,
- name: enrollment.course.displayName,
- })) || [];
-
- const pagination = {
- count: responseData.count,
- currentPage: responseData.currentPage,
- hasMore: Boolean(responseData.next),
- totalPages: responseData.numPages,
- };
-
- return {
- courseList,
- pagination,
- showPreferences: responseData.showPreferences,
- };
-};
-
export const normalizeAccountPreferences = (originalData, updateInfo) => {
const {
app, notificationType, channel, updatedValue,
@@ -54,13 +28,8 @@ export const normalizeAccountPreferences = (originalData, updateInfo) => {
return originalData;
};
-const normalizePreferences = (responseData, courseId) => {
- let preferences;
- if (courseId) {
- preferences = responseData.notificationPreferenceConfig;
- } else {
- preferences = responseData.data;
- }
+const normalizePreferences = (responseData) => {
+ const preferences = responseData.data;
const appKeys = Object.keys(preferences);
const apps = appKeys.map((appId) => ({
@@ -97,41 +66,20 @@ const normalizePreferences = (responseData, courseId) => {
return normalizedPreferences;
};
-export const fetchCourseList = (page, pageSize) => (
+export const fetchNotificationPreferences = () => (
async (dispatch) => {
try {
- dispatch(fetchCourseListFetching());
- const data = await getCourseList(page, pageSize);
- const normalizedData = normalizeCourses(camelCaseObject(data));
- dispatch(fetchCourseListSuccess(normalizedData));
- } catch (errors) {
- dispatch(fetchCourseListFailed());
- }
- }
-);
-
-export const fetchCourseNotificationPreferences = (courseId) => (
- async (dispatch) => {
- try {
- dispatch(updateSelectedCourse(courseId));
dispatch(fetchNotificationPreferenceFetching());
- const data = await getCourseNotificationPreferences(courseId);
- const normalizedData = normalizePreferences(camelCaseObject(data), courseId);
- dispatch(fetchNotificationPreferenceSuccess(courseId, normalizedData));
+ const data = camelCaseObject(await getNotificationPreferences());
+ const normalizedData = normalizePreferences(data);
+ dispatch(fetchNotificationPreferenceSuccess(normalizedData, data.showPreferences));
} catch (errors) {
dispatch(fetchNotificationPreferenceFailed());
}
}
);
-export const setSelectedCourse = courseId => (
- async (dispatch) => {
- dispatch(updateSelectedCourse(courseId));
- }
-);
-
export const updatePreferenceToggle = (
- courseId,
notificationApp,
notificationType,
notificationChannel,
@@ -149,49 +97,35 @@ export const updatePreferenceToggle = (
));
// Function to handle data normalization and dispatching success
- const handleSuccessResponse = (data, isGlobal = false) => {
- const processedData = courseId
- ? normalizePreferences(camelCaseObject(data), courseId)
- : camelCaseObject(data);
+ const handleSuccessResponse = (data) => {
+ const processedData = camelCaseObject(data);
- dispatch(fetchNotificationPreferenceSuccess(courseId, processedData, isGlobal));
+ dispatch(fetchNotificationPreferenceSuccess(processedData, processedData.showPreferences, true));
return processedData;
};
- // Function to toggle preference based on context (course-specific or global)
- const togglePreference = async (channel, toggleValue, cadence) => {
- if (courseId) {
- return patchPreferenceToggle(
- courseId,
- notificationApp,
- notificationType,
- channel,
- channel === EMAIL_CADENCE ? cadence : toggleValue,
- );
- }
-
- return postPreferenceToggle(
- notificationApp,
- notificationType,
- channel,
- channel === EMAIL_CADENCE ? undefined : toggleValue,
- cadence,
- );
- };
+ // Function to toggle preference based on context
+ const togglePreference = async (channel, toggleValue, cadence) => postPreferenceToggle(
+ notificationApp,
+ notificationType,
+ channel,
+ channel === EMAIL_CADENCE ? undefined : toggleValue,
+ cadence,
+ );
// Execute the main preference toggle
const data = await togglePreference(notificationChannel, value, emailCadence);
- handleSuccessResponse(data, !courseId);
+ handleSuccessResponse(data);
// Handle special case for email notifications
if (notificationChannel === EMAIL && value) {
const emailCadenceData = await togglePreference(
EMAIL_CADENCE,
- courseId ? undefined : value,
+ value,
EMAIL_CADENCE_PREFERENCES.DAILY,
);
- handleSuccessResponse(emailCadenceData, !courseId);
+ handleSuccessResponse(emailCadenceData);
}
} catch (errors) {
dispatch(updatePreferenceValue(
diff --git a/src/notification-preferences/messages.js b/src/notification-preferences/messages.js
index fea8cd3..00c598b 100644
--- a/src/notification-preferences/messages.js
+++ b/src/notification-preferences/messages.js
@@ -93,7 +93,7 @@ const messages = defineMessages({
},
accountNotificationDescription: {
id: 'account.notification.description',
- defaultMessage: 'Account-level settings apply to all courses. Notifications for individual courses can be changed within each course and will override account-level settings.',
+ defaultMessage: 'Account-level settings apply to all courses.',
description: 'Account notification description',
},
notificationCadenceDescription: {