@@ -2,18 +2,21 @@ import React, { useCallback, useMemo } from 'react';
22import PropTypes from 'prop-types' ;
33import { useDispatch , useSelector } from 'react-redux' ;
44import { useIntl } from '@edx/frontend-platform/i18n' ;
5- import { Collapsible } from '@openedx/paragon' ;
5+ import { Collapsible , NavItem } from '@openedx/paragon' ;
6+ import classNames from 'classnames' ;
67import messages from './messages' ;
78import ToggleSwitch from './ToggleSwitch' ;
89import {
910 selectPreferenceAppToggleValue ,
11+ selectNonEditablePreferences ,
1012 selectPreferencesOfApp ,
1113 selectSelectedCourseId ,
1214 selectUpdatePreferencesStatus ,
1315} from './data/selectors' ;
1416import NotificationPreferenceRow from './NotificationPreferenceRow' ;
15- import { updateAppPreferenceToggle } from './data/thunks' ;
17+ import { updateAppPreferenceToggle , updateChannelPreferenceToggle } from './data/thunks' ;
1618import { LOADING_STATUS } from '../constants' ;
19+ import NOTIFICATION_CHANNELS from './data/constants' ;
1720
1821const NotificationPreferenceApp = ( { appId } ) => {
1922 const dispatch = useDispatch ( ) ;
@@ -22,6 +25,18 @@ const NotificationPreferenceApp = ({ appId }) => {
2225 const appPreferences = useSelector ( selectPreferencesOfApp ( appId ) ) ;
2326 const appToggle = useSelector ( selectPreferenceAppToggleValue ( appId ) ) ;
2427 const updatePreferencesStatus = useSelector ( selectUpdatePreferencesStatus ( ) ) ;
28+ const nonEditable = useSelector ( selectNonEditablePreferences ( appId ) ) ;
29+
30+ const onChannelToggle = useCallback ( ( event ) => {
31+ const { id : notificationChannel } = event . target ;
32+ const isPreferenceNonEditable = ( preference ) => nonEditable ?. [ preference . id ] ?. includes ( notificationChannel ) ;
33+
34+ const hasActivePreferences = appPreferences . some (
35+ ( preference ) => preference [ notificationChannel ] && ! isPreferenceNonEditable ( preference ) ,
36+ ) ;
37+
38+ dispatch ( updateChannelPreferenceToggle ( courseId , appId , notificationChannel , ! hasActivePreferences ) ) ;
39+ } , [ appId , appPreferences , courseId , dispatch , nonEditable ] ) ;
2540
2641 const preferences = useMemo ( ( ) => (
2742 appPreferences . map ( preference => (
@@ -36,10 +51,10 @@ const NotificationPreferenceApp = ({ appId }) => {
3651 dispatch ( updateAppPreferenceToggle ( courseId , appId , event . target . checked ) ) ;
3752 // eslint-disable-next-line react-hooks/exhaustive-deps
3853 } , [ appId ] ) ;
39-
4054 if ( ! courseId ) {
4155 return null ;
4256 }
57+
4358 return (
4459 < Collapsible . Advanced open = { appToggle } data-testid = { `${ appId } -app` } className = "mb-5" >
4560 < Collapsible . Trigger >
@@ -62,7 +77,22 @@ const NotificationPreferenceApp = ({ appId }) => {
6277 < div className = "d-flex flex-row header-label" >
6378 < span className = "col-8 px-0" > { intl . formatMessage ( messages . typeLabel ) } </ span >
6479 < span className = "d-flex col-4 px-0" >
65- < span className = "ml-auto" > { intl . formatMessage ( messages . webLabel ) } </ span >
80+ { NOTIFICATION_CHANNELS . map ( ( channel ) => (
81+ < NavItem
82+ id = { channel }
83+ key = { channel }
84+ className = { classNames (
85+ 'd-flex' ,
86+ { 'ml-auto' : channel === 'web' } ,
87+ { 'mx-auto' : channel === 'email' } ,
88+ { 'ml-auto mr-0' : channel === 'push' } ,
89+ ) }
90+ role = "button"
91+ onClick = { onChannelToggle }
92+ >
93+ { intl . formatMessage ( messages . notificationChannel , { text : channel } ) }
94+ </ NavItem >
95+ ) ) }
6696 </ span >
6797 </ div >
6898 < div className = "my-3" >
0 commit comments