import { createAction , createSelector , createSlice , PayloadAction } from '@reduxjs/toolkit' ; import { all , put , select , takeLatest } from 'redux-saga/effects' ; import { notificationsConfigs } from '@features/NotificationsPanel/constants' ; import { ExtendedNotification , LSKeys } from '@types' ; import { generateUUID } from '@utils' ; import { findIndex , propEq } from '@vendor' ; import { getAppState } from './selectors' ; export const initialState = [ ] as ExtendedNotification [ ] ; const slice = createSlice ( { name : LSKeys . NOTIFICATIONS , initialState , reducers : { create ( state , action ) { state . push ( action . payload ) ; } , update ( state , action ) { const idx = findIndex ( propEq ( 'uuid' , action . payload . uuid ) , state ) ; state [ idx ] = action . payload ; } } } ) ; export const { create : createNotification , update : updateNotification } = slice . actions ; export const selectNotifications = createSelector ( getAppState , ( s ) => s . notifications . filter ( ( n ) => n . template in notificationsConfigs ) ) ; export default slice ; export const displayNotification = createAction < { templateName : string ; templateData ? : TObject ; } > ( `${ slice . name }/displayNotification` ) ; export const dismissNotification = createAction < ExtendedNotification > ( `${ slice . name }/dismissNotification` ) ; /**
 * Sagas
 */ export function * notificationSaga ( ) { yield all ( [ takeLatest ( displayNotification . type , displayNotificationWorker ) , takeLatest ( dismissNotification . type , dismissNotificationWorker ) ] ) ; } export function * displayNotificationWorker ( { payload : { templateName , templateData } } ) { const notifications = yield select ( selectNotifications ) ; if ( ! notificationsConfigs [ templateName ] ?. preventDismisExisting ) { const dismissableNotifications = notifications . filter ( ( x ) => notificationsConfigs [ x . template ] . dismissOnOverwrite && ! x . dismissed ) ; for ( const notif of dismissableNotifications ) { yield put ( dismissNotification ( notif ) ) ; } } const notification = { uuid : generateUUID ( ) , template : templateName , templateData , dateDisplayed : new Date ( ) , dismissed : false , dateDismissed : undefined } ; const existingNotification = notifications . find ( ( x ) => x . template === notification . template ) ; if ( existingNotification ) { if ( notificationsConfigs [ templateName ] ?. repeatInterval || notificationsConfigs [ templateName ] ?. dismissForever ) { notification . dismissed = existingNotification . dismissed ; notification . dateDismissed = existingNotification . dateDismissed ; } yield put ( updateNotification ( notification ) ) ; } else { yield put ( createNotification ( notification ) ) ; } } export function * dismissNotificationWorker ( { payload } ) { yield put ( updateNotification ( { ... payload , dismissed : true , dateDismissed : new Date ( ) } ) ) ; }