From 235dd9c462ac355741355aba2785e32dfb84c748 Mon Sep 17 00:00:00 2001 From: sundasnoreen12 Date: Wed, 20 Nov 2024 23:36:14 +0500 Subject: [PATCH] feat: added api for account notification type --- .../NotificationPreferenceApp.jsx | 7 +-- .../NotificationSettings.jsx | 2 +- src/notification-preferences/data/actions.js | 6 +- src/notification-preferences/data/reducers.js | 14 ++++- src/notification-preferences/data/service.js | 17 ++++++ src/notification-preferences/data/thunks.js | 58 +++++++++++++++---- 6 files changed, 80 insertions(+), 24 deletions(-) diff --git a/src/notification-preferences/NotificationPreferenceApp.jsx b/src/notification-preferences/NotificationPreferenceApp.jsx index 216ab420f..52d7d217a 100644 --- a/src/notification-preferences/NotificationPreferenceApp.jsx +++ b/src/notification-preferences/NotificationPreferenceApp.jsx @@ -11,21 +11,16 @@ import { useIsOnMobile } from '../hooks'; import NotificationTypes from './NotificationTypes'; import { notificationChannels, shouldHideAppPreferences } from './data/utils'; import NotificationPreferenceColumn from './NotificationPreferenceColumn'; -import { selectPreferenceAppToggleValue, selectSelectedCourseId, selectAppPreferences } from './data/selectors'; +import { selectPreferenceAppToggleValue, selectAppPreferences } from './data/selectors'; const NotificationPreferenceApp = ({ appId }) => { const intl = useIntl(); - const courseId = useSelector(selectSelectedCourseId()); const appToggle = useSelector(selectPreferenceAppToggleValue(appId)); const appPreferences = useSelector(selectAppPreferences(appId)); const mobileView = useIsOnMobile(); const NOTIFICATION_CHANNELS = notificationChannels(); const hideAppPreferences = shouldHideAppPreferences(appPreferences, appId) || false; - if (!courseId) { - return null; - } - return ( !hideAppPreferences && ( { - {courseId && } + ) ); diff --git a/src/notification-preferences/data/actions.js b/src/notification-preferences/data/actions.js index a8e5420ff..e9f900d78 100644 --- a/src/notification-preferences/data/actions.js +++ b/src/notification-preferences/data/actions.js @@ -10,8 +10,10 @@ export const Actions = { UPDATE_APP_PREFERENCE: 'updateAppValue', }; -export const fetchNotificationPreferenceSuccess = (courseId, payload) => dispatch => ( - dispatch({ type: Actions.FETCHED_PREFERENCES, courseId, payload }) +export const fetchNotificationPreferenceSuccess = (courseId, payload, isAccountPreference) => dispatch => ( + dispatch({ + type: Actions.FETCHED_PREFERENCES, courseId, payload, isAccountPreference, + }) ); export const fetchNotificationPreferenceFetching = () => dispatch => ( diff --git a/src/notification-preferences/data/reducers.js b/src/notification-preferences/data/reducers.js index 83e5cfe31..1683b2009 100644 --- a/src/notification-preferences/data/reducers.js +++ b/src/notification-preferences/data/reducers.js @@ -5,18 +5,19 @@ import { SUCCESS_STATUS, FAILURE_STATUS, } from '../../constants'; +import { normalizeAccountPreferences } from './thunks'; export const defaultState = { showPreferences: false, courses: { status: IDLE_STATUS, - courses: [{ id: 'account', name: 'Account' }], + courses: [{ id: '', name: 'Account' }], pagination: {}, }, preferences: { status: IDLE_STATUS, updatePreferenceStatus: IDLE_STATUS, - selectedCourse: 'account', + selectedCourse: '', preferences: [], apps: [], nonEditable: {}, @@ -66,15 +67,22 @@ const notificationPreferencesReducer = (state = defaultState, action = {}) => { }, }; case Actions.FETCHED_PREFERENCES: + { + const { preferences } = state; + if (action.isAccountPreference) { + normalizeAccountPreferences(preferences, action.payload); + } + return { ...state, preferences: { - ...state.preferences, + ...preferences, status: SUCCESS_STATUS, updatePreferenceStatus: SUCCESS_STATUS, ...action.payload, }, }; + } case Actions.FAILED_PREFERENCES: return { ...state, diff --git a/src/notification-preferences/data/service.js b/src/notification-preferences/data/service.js index 4296bbea7..67380c3d9 100644 --- a/src/notification-preferences/data/service.js +++ b/src/notification-preferences/data/service.js @@ -32,3 +32,20 @@ export const patchPreferenceToggle = async ( const { data } = await getAuthenticatedHttpClient().patch(url, patchData); return data; }; + +export const postPreferenceToggle = async ( + notificationApp, + notificationType, + notificationChannel, + value, +) => { + const patchData = snakeCaseObject({ + notificationApp, + notificationType: snakeCase(notificationType), + notificationChannel, + value, + }); + const url = `${getConfig().LMS_BASE_URL}/api/notifications/preferences/update-all/`; + const { data } = await getAuthenticatedHttpClient().post(url, patchData); + return data; +}; diff --git a/src/notification-preferences/data/thunks.js b/src/notification-preferences/data/thunks.js index 1c6022321..62a802cac 100644 --- a/src/notification-preferences/data/thunks.js +++ b/src/notification-preferences/data/thunks.js @@ -1,4 +1,5 @@ import { camelCaseObject } from '@edx/frontend-platform'; +import camelCase from 'lodash.camelcase'; import EMAIL_CADENCE from './constants'; import { fetchCourseListSuccess, @@ -14,6 +15,7 @@ import { getCourseList, getCourseNotificationPreferences, patchPreferenceToggle, + postPreferenceToggle, } from './service'; const normalizeCourses = (responseData) => { @@ -36,8 +38,29 @@ const normalizeCourses = (responseData) => { }; }; -const normalizePreferences = (responseData) => { - const preferences = responseData.notificationPreferenceConfig; +export const normalizeAccountPreferences = (originalData, updateInfo) => { + const { + app, notificationType, channel, updatedValue, + } = updateInfo.data; + + const preferenceToUpdate = originalData.preferences.find( + (preference) => preference.appId === app && preference.id === camelCase(notificationType), + ); + + if (preferenceToUpdate) { + preferenceToUpdate[channel] = updatedValue; + } + + return originalData; +}; + +const normalizePreferences = (responseData, courseId) => { + let preferences; + if (courseId) { + preferences = responseData.notificationPreferenceConfig; + } else { + preferences = responseData.data; + } const appKeys = Object.keys(preferences); const apps = appKeys.map((appId) => ({ @@ -92,7 +115,7 @@ export const fetchCourseNotificationPreferences = (courseId) => ( dispatch(updateSelectedCourse(courseId)); dispatch(fetchNotificationPreferenceFetching()); const data = await getCourseNotificationPreferences(courseId); - const normalizedData = normalizePreferences(camelCaseObject(data)); + const normalizedData = normalizePreferences(camelCaseObject(data), courseId); dispatch(fetchNotificationPreferenceSuccess(courseId, normalizedData)); } catch (errors) { dispatch(fetchNotificationPreferenceFailed()); @@ -121,15 +144,26 @@ export const updatePreferenceToggle = ( notificationChannel, !value, )); - const data = await patchPreferenceToggle( - courseId, - notificationApp, - notificationType, - notificationChannel, - value, - ); - const normalizedData = normalizePreferences(camelCaseObject(data)); - dispatch(fetchNotificationPreferenceSuccess(courseId, normalizedData)); + let data = null; + if (courseId) { + data = await patchPreferenceToggle( + courseId, + notificationApp, + notificationType, + notificationChannel, + value, + ); + const normalizedData = normalizePreferences(camelCaseObject(data), courseId); + dispatch(fetchNotificationPreferenceSuccess(courseId, normalizedData)); + } else { + data = await postPreferenceToggle( + notificationApp, + notificationType, + notificationChannel, + value, + ); + dispatch(fetchNotificationPreferenceSuccess(courseId, camelCaseObject(data), true)); + } } catch (errors) { dispatch(updatePreferenceValue( notificationApp,