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..86ab9b6f964 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,22 @@ describe('AlertComponent', () => { expect(alertsAfterClosing[0]).toHaveTextContent('Error 1'); expect(alertsAfterClosing[1]).toHaveTextContent('Error 3'); }); + + 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' })); + 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); + + jest.useRealTimers(); + }); }); diff --git a/desktop/core/src/desktop/js/reactComponents/AlertComponent/AlertComponent.tsx b/desktop/core/src/desktop/js/reactComponents/AlertComponent/AlertComponent.tsx index 7dbdd7a5491..89e7f8146b2 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)} /> ))}