@@ -3,7 +3,13 @@ import React, { useEffect, useState, useMemo } from 'react';
33import { useDispatch , useSelector } from 'react-redux' ;
44import { NotificationBadgeVariant as BadgeVariant } from '@patternfly/react-core' ;
55import { groupBy } from 'lodash' ;
6- import { startNotificationsPolling } from '../../redux/actions/notifications' ;
6+ import { subscribeToNotifications } from '../../common/channels/notificationChannel' ;
7+ import {
8+ fetchNotifications ,
9+ startNotificationsPolling ,
10+ } from '../../redux/actions/notifications' ;
11+ import { NOTIFICATIONS } from '../../redux/consts' ;
12+ import { actionTypeGenerator } from '../../redux/API/APIActionTypeGenerator' ;
713import forceSingleton from '../../common/forceSingleton' ;
814
915export const NotificationsContext = forceSingleton ( 'NotificationsContext' , ( ) =>
@@ -19,6 +25,7 @@ export const NotificationsContextWrapper = ({ children }) => {
1925
2026 const notificationsState = useSelector ( state => state . notifications ) ;
2127 const notifications = groupBy ( notificationsState . notifications , n => n . group ) ;
28+ const { SUCCESS } = actionTypeGenerator ( NOTIFICATIONS ) ;
2229
2330 const [ expandedNotifications , setExpandedNotifications ] = useState ( [ ] ) ;
2431 const [ expandedKebab , setExpandedKebab ] = useState ( '' ) ;
@@ -45,8 +52,35 @@ export const NotificationsContextWrapper = ({ children }) => {
4552 } ;
4653
4754 useEffect ( ( ) => {
55+ // Initial fetch of notifications
56+ dispatch ( fetchNotifications ( ) ) ;
57+
58+ // Subscribe to real-time updates via Action Cable
59+ const subscription = subscribeToNotifications ( {
60+ received : data => {
61+ try {
62+ const payload = JSON . parse ( data . payload ) ;
63+ dispatch ( {
64+ type : SUCCESS ,
65+ response : payload ,
66+ } ) ;
67+ } catch ( error ) {
68+ console . error ( 'Failed to parse notification payload:' , error ) ;
69+ }
70+ } ,
71+ } ) ;
72+
73+ // Start polling as fallback (in case WebSocket connection fails)
74+ // Action Cable handles real-time updates, polling runs every 5 minutes as a safety net
4875 dispatch ( startNotificationsPolling ( ) ) ;
49- } , [ dispatch ] ) ;
76+
77+ // Cleanup: unsubscribe when component unmounts
78+ return ( ) => {
79+ if ( subscription && subscription . unsubscribe ) {
80+ subscription . unsubscribe ( ) ;
81+ }
82+ } ;
83+ } , [ dispatch , SUCCESS ] ) ;
5084
5185 const countUnreadMessages = useMemo ( ( ) => {
5286 if ( notificationsState . notifications ) {
0 commit comments