From 19238da56b3e8114aa8e21dfbb768a4a2816025f Mon Sep 17 00:00:00 2001 From: Ananya_Agarwal Date: Tue, 5 Mar 2024 19:23:44 +0530 Subject: [PATCH 1/5] [frontend] Dismiss info alert popup messages after 3 seconds --- .../AlertComponent/AlertComponent.tsx | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/desktop/core/src/desktop/js/reactComponents/AlertComponent/AlertComponent.tsx b/desktop/core/src/desktop/js/reactComponents/AlertComponent/AlertComponent.tsx index 7dbdd7a5491..2eda41bcc06 100644 --- a/desktop/core/src/desktop/js/reactComponents/AlertComponent/AlertComponent.tsx +++ b/desktop/core/src/desktop/js/reactComponents/AlertComponent/AlertComponent.tsx @@ -25,15 +25,16 @@ interface HueAlert { message: string; } +type alertType = 'error' | 'info' | 'warning'; interface VisibleAlert { alert: HueAlert; - type: 'error' | 'info' | 'warning'; + type: alertType; } const AlertComponent: React.FC = () => { const [alert, setAlerts] = useState([]); - const updateAlerts = (alert, type) => { + const updateAlerts = (alert: HueAlert, type: alertType) => { if (!alert.message) { return; } @@ -43,7 +44,16 @@ const AlertComponent: React.FC = () => { if (activeAlerts.some(activeAlerts => activeAlerts.alert.message === alert.message)) { return activeAlerts; } - return [...activeAlerts, { alert, type }]; + + const newAlert:VisibleAlert = { alert, type }; + + if(type === 'info') { + setTimeout(() => { + handleClose(newAlert); + }, 3000); + } + + return [...activeAlerts, newAlert]; }); }; @@ -74,14 +84,14 @@ const AlertComponent: React.FC = () => { }; }, []); - const handleClose = (alertObjToClose: HueAlert) => { - const filteredAlerts = alert.filter(alertObj => alertObj.alert !== alertObjToClose); + const handleClose = (alertObjToClose: VisibleAlert) => { + const filteredAlerts = alert.filter(alertObj => alertObj !== alertObjToClose); setAlerts(filteredAlerts); }; const { t } = i18nReact.useTranslation(); - const getHeader = alert => { + const getHeader = (alert: VisibleAlert) => { if (alert.type === 'error') { return t('Error'); } else if (alert.type === 'info') { @@ -101,7 +111,7 @@ const AlertComponent: React.FC = () => { description={alertObj.alert.message} showIcon={true} closable={true} - onClose={() => handleClose(alertObj.alert)} + onClose={() => handleClose(alertObj)} /> ))} From 3483c886d76b10ffda42070c46e8207d7e1e2fbb Mon Sep 17 00:00:00 2001 From: Ananya_Agarwal Date: Tue, 5 Mar 2024 19:36:32 +0530 Subject: [PATCH 2/5] Fixed Linting issues --- .../js/reactComponents/AlertComponent/AlertComponent.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/desktop/core/src/desktop/js/reactComponents/AlertComponent/AlertComponent.tsx b/desktop/core/src/desktop/js/reactComponents/AlertComponent/AlertComponent.tsx index 2eda41bcc06..89e7f8146b2 100644 --- a/desktop/core/src/desktop/js/reactComponents/AlertComponent/AlertComponent.tsx +++ b/desktop/core/src/desktop/js/reactComponents/AlertComponent/AlertComponent.tsx @@ -45,9 +45,9 @@ const AlertComponent: React.FC = () => { return activeAlerts; } - const newAlert:VisibleAlert = { alert, type }; + const newAlert: VisibleAlert = { alert, type }; - if(type === 'info') { + if (type === 'info') { setTimeout(() => { handleClose(newAlert); }, 3000); From 59b9088c4feb5829b447906439fc6fd26e4f94c1 Mon Sep 17 00:00:00 2001 From: Ananya_Agarwal Date: Sat, 9 Mar 2024 11:43:09 +0530 Subject: [PATCH 3/5] Unit testing --- .../AlertComponent/AlertComponent.test.tsx | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/desktop/core/src/desktop/js/reactComponents/AlertComponent/AlertComponent.test.tsx b/desktop/core/src/desktop/js/reactComponents/AlertComponent/AlertComponent.test.tsx index 3ce49b93ee5..5bf27d454ea 100644 --- a/desktop/core/src/desktop/js/reactComponents/AlertComponent/AlertComponent.test.tsx +++ b/desktop/core/src/desktop/js/reactComponents/AlertComponent/AlertComponent.test.tsx @@ -89,4 +89,19 @@ describe('AlertComponent', () => { expect(alertsAfterClosing[0]).toHaveTextContent('Error 1'); expect(alertsAfterClosing[1]).toHaveTextContent('Error 3'); }); + + test('info alerts should close automatically after 3 seconds', async () => { + render(); + expect(screen.queryAllByRole('alert')).toHaveLength(0); + act(() => huePubSub.publish('hue.global.info', { message: 'info' })); + expect(screen.queryAllByRole('alert')).toHaveLength(1); + + //It should still be open after 2 seconds + jest.advanceTimersByTime(2000); + expect(screen.queryAllByRole('alert')).toHaveLength(1); + + //After 3.1 seconds, it should really be closed + jest.advanceTimersByTime(1000); + expect(screen.queryAllByRole('alert')).toHaveLength(0); + }); }); From e5181cf1b9c1420583676891809b086af74dd784 Mon Sep 17 00:00:00 2001 From: Ananya_Agarwal Date: Sat, 9 Mar 2024 16:04:45 +0530 Subject: [PATCH 4/5] Fixing the jest --- .../js/reactComponents/AlertComponent/AlertComponent.test.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/desktop/core/src/desktop/js/reactComponents/AlertComponent/AlertComponent.test.tsx b/desktop/core/src/desktop/js/reactComponents/AlertComponent/AlertComponent.test.tsx index 5bf27d454ea..5685c08e669 100644 --- a/desktop/core/src/desktop/js/reactComponents/AlertComponent/AlertComponent.test.tsx +++ b/desktop/core/src/desktop/js/reactComponents/AlertComponent/AlertComponent.test.tsx @@ -21,6 +21,7 @@ import userEvent from '@testing-library/user-event'; import huePubSub from '../../utils/huePubSub'; import AlertComponent from './AlertComponent'; +jest.useFakeTimers(); // Enable fake timers describe('AlertComponent', () => { test('it should show a global error message', async () => { From 90b10c2cca9c0e1d046ccfbcbd1137ca3be62aea Mon Sep 17 00:00:00 2001 From: Ananya_Agarwal Date: Mon, 11 Mar 2024 14:31:59 +0530 Subject: [PATCH 5/5] Fixing the issues in the PR --- .../js/reactComponents/AlertComponent/AlertComponent.test.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/desktop/core/src/desktop/js/reactComponents/AlertComponent/AlertComponent.test.tsx b/desktop/core/src/desktop/js/reactComponents/AlertComponent/AlertComponent.test.tsx index 5685c08e669..86ab9b6f964 100644 --- a/desktop/core/src/desktop/js/reactComponents/AlertComponent/AlertComponent.test.tsx +++ b/desktop/core/src/desktop/js/reactComponents/AlertComponent/AlertComponent.test.tsx @@ -21,7 +21,6 @@ import userEvent from '@testing-library/user-event'; import huePubSub from '../../utils/huePubSub'; import AlertComponent from './AlertComponent'; -jest.useFakeTimers(); // Enable fake timers describe('AlertComponent', () => { test('it should show a global error message', async () => { @@ -92,6 +91,7 @@ describe('AlertComponent', () => { }); test('info alerts should close automatically after 3 seconds', async () => { + jest.useFakeTimers(); render(); expect(screen.queryAllByRole('alert')).toHaveLength(0); act(() => huePubSub.publish('hue.global.info', { message: 'info' })); @@ -104,5 +104,7 @@ describe('AlertComponent', () => { //After 3.1 seconds, it should really be closed jest.advanceTimersByTime(1000); expect(screen.queryAllByRole('alert')).toHaveLength(0); + + jest.useRealTimers(); }); });