From 6bbe102e07a7f15ff4369f46f8d23f6d2a2b777b Mon Sep 17 00:00:00 2001 From: Tristan WAGNER Date: Fri, 22 Nov 2024 12:39:49 +0100 Subject: [PATCH] fix(manager-react-components): useNotifications prevent early clears Signed-off-by: Florian Renaut Signed-off-by: Tristan WAGNER --- .../notifications/notifications.spec.tsx | 22 +++++++++++++------ .../notifications/useNotifications.ts | 16 ++++++++++++-- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/packages/manager-react-components/src/components/notifications/notifications.spec.tsx b/packages/manager-react-components/src/components/notifications/notifications.spec.tsx index 38442b356419..94421d24dbe4 100644 --- a/packages/manager-react-components/src/components/notifications/notifications.spec.tsx +++ b/packages/manager-react-components/src/components/notifications/notifications.spec.tsx @@ -1,4 +1,4 @@ -import { vitest } from 'vitest'; +import { vi, vitest } from 'vitest'; import React, { useEffect } from 'react'; import { render } from '@testing-library/react'; import { useNotifications, NotificationType } from './useNotifications'; @@ -29,17 +29,25 @@ function ClearNotifications() { } describe('notifications component', () => { - it('should list notifications', async () => { + it('should render and clear notifications only after 1000ms', async () => { + vi.useFakeTimers(); let { container } = render(); + expect(container.children.length).toBe(0); render(); - container = await render().container; expect(container.children.length).toBe(2); - }); - it('should clear notifications', async () => { - let { container } = render(); - expect(container.children.length).not.toBe(0); + + vi.advanceTimersByTime(999); + + render(); + container = render().container; + expect(container.children.length).toBe(2); + + vi.advanceTimersByTime(1); + render(); container = render().container; expect(container.children.length).toBe(0); + + vi.restoreAllMocks(); }); }); diff --git a/packages/manager-react-components/src/components/notifications/useNotifications.ts b/packages/manager-react-components/src/components/notifications/useNotifications.ts index 8829fdb65c9d..e428fdca65f0 100644 --- a/packages/manager-react-components/src/components/notifications/useNotifications.ts +++ b/packages/manager-react-components/src/components/notifications/useNotifications.ts @@ -14,6 +14,7 @@ export interface Notification { content: ReactNode; type: NotificationType; dismissable?: boolean; + creationTimestamp?: number; } export interface NotificationState { @@ -44,7 +45,13 @@ export const useNotifications = create((set, get) => ({ uid: state.uid + 1, notifications: [ ...state.notifications, - { uid: state.uid, content, type, dismissable }, + { + uid: state.uid, + content, + type, + dismissable, + creationTimestamp: Date.now(), + }, ], })), addSuccess: (content: ReactNode, dismissable = false) => @@ -61,7 +68,12 @@ export const useNotifications = create((set, get) => ({ ({ uid }) => uid !== toRemoveUid, ), })), - clearNotifications: () => set(() => ({ notifications: [] })), + clearNotifications: () => + set((state) => ({ + notifications: state.notifications.filter( + (notification) => Date.now() - notification.creationTimestamp < 1000, + ), + })), })); export default useNotifications;