diff --git a/public/app/core/reducers/appNotification.test.ts b/public/app/core/reducers/appNotification.test.ts index c868e3910ed..cc072562838 100644 --- a/public/app/core/reducers/appNotification.test.ts +++ b/public/app/core/reducers/appNotification.test.ts @@ -116,4 +116,46 @@ describe('notify', () => { expect(result).toEqual(expectedResult); }); + + it('Dedupe identical alerts', () => { + const initialState = { + appNotifications: [ + { + id: 'id1', + severity: AppNotificationSeverity.Success, + icon: 'success', + title: 'test', + text: 'test alert', + timeout: AppNotificationTimeout.Success, + }, + ], + }; + + const result = appNotificationsReducer( + initialState, + notifyApp({ + id: 'id2', + severity: AppNotificationSeverity.Success, + icon: 'success', + title: 'test', + text: 'test alert', + timeout: AppNotificationTimeout.Success, + }) + ); + + const expectedResult = { + appNotifications: [ + { + id: 'id1', + severity: AppNotificationSeverity.Success, + icon: 'success', + title: 'test', + text: 'test alert', + timeout: AppNotificationTimeout.Success, + }, + ], + }; + + expect(result).toEqual(expectedResult); + }); }); diff --git a/public/app/core/reducers/appNotification.ts b/public/app/core/reducers/appNotification.ts index 6c77b8d4a38..a61782ee730 100644 --- a/public/app/core/reducers/appNotification.ts +++ b/public/app/core/reducers/appNotification.ts @@ -15,10 +15,23 @@ const appNotificationsSlice = createSlice({ name: 'appNotifications', initialState, reducers: { - notifyApp: (state, action: PayloadAction): AppNotificationsState => ({ - ...state, - appNotifications: state.appNotifications.concat([action.payload]), - }), + notifyApp: (state, action: PayloadAction) => { + const newAlert = action.payload; + + for (const existingAlert of state.appNotifications) { + if ( + newAlert.icon === existingAlert.icon && + newAlert.severity === existingAlert.severity && + newAlert.text === existingAlert.text && + newAlert.title === existingAlert.title && + newAlert.component === existingAlert.component + ) { + return; + } + } + + state.appNotifications.push(newAlert); + }, clearAppNotification: (state, action: PayloadAction): AppNotificationsState => ({ ...state, appNotifications: state.appNotifications.filter((appNotification) => appNotification.id !== action.payload),