From eaf18ceac06605ac9d7973fab0ab1afdd702adcc Mon Sep 17 00:00:00 2001 From: adrien guernier Date: Tue, 4 Jul 2023 10:17:45 +0200 Subject: [PATCH 1/4] Alert user if he close the window before the end of undoable notification --- .../ra-ui-materialui/src/layout/Notification.tsx | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/ra-ui-materialui/src/layout/Notification.tsx b/packages/ra-ui-materialui/src/layout/Notification.tsx index 72225a3de19..1e5ff00ece3 100644 --- a/packages/ra-ui-materialui/src/layout/Notification.tsx +++ b/packages/ra-ui-materialui/src/layout/Notification.tsx @@ -43,6 +43,14 @@ export const Notification = (props: NotificationProps) => { const translate = useTranslate(); useEffect(() => { + const beforeunload = (e: BeforeUnloadEvent) => { + if (messageInfo?.notificationOptions?.undoable) { + e.preventDefault(); + } + }; + + window.addEventListener('beforeunload', beforeunload); + if (notifications.length && !messageInfo) { // Set a new snack when we don't have an active one setMessageInfo(takeNotification()); @@ -51,6 +59,10 @@ export const Notification = (props: NotificationProps) => { // Close an active snack when a new one is added setOpen(false); } + + return () => { + window.removeEventListener('beforeunload', beforeunload); + }; }, [notifications, messageInfo, open, takeNotification]); const handleRequestClose = useCallback(() => { From 87f74b63a9c67ad13a785a3d21953f8db64894e3 Mon Sep 17 00:00:00 2001 From: adrien guernier Date: Wed, 5 Jul 2023 10:51:03 +0200 Subject: [PATCH 2/4] add beforeunload listener only when undoable is true --- packages/ra-ui-materialui/src/layout/Notification.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/ra-ui-materialui/src/layout/Notification.tsx b/packages/ra-ui-materialui/src/layout/Notification.tsx index 1e5ff00ece3..23a0d1ce0f8 100644 --- a/packages/ra-ui-materialui/src/layout/Notification.tsx +++ b/packages/ra-ui-materialui/src/layout/Notification.tsx @@ -44,12 +44,12 @@ export const Notification = (props: NotificationProps) => { useEffect(() => { const beforeunload = (e: BeforeUnloadEvent) => { - if (messageInfo?.notificationOptions?.undoable) { - e.preventDefault(); - } + e.preventDefault(); }; - window.addEventListener('beforeunload', beforeunload); + if (messageInfo?.notificationOptions?.undoable) { + window.addEventListener('beforeunload', beforeunload); + } if (notifications.length && !messageInfo) { // Set a new snack when we don't have an active one From 2166223b73c1658b1c8524417dbeaf105a83b32a Mon Sep 17 00:00:00 2001 From: adrien guernier Date: Wed, 5 Jul 2023 11:01:29 +0200 Subject: [PATCH 3/4] improved beforeunload function for browser compatibility --- packages/ra-ui-materialui/src/layout/Notification.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/ra-ui-materialui/src/layout/Notification.tsx b/packages/ra-ui-materialui/src/layout/Notification.tsx index 23a0d1ce0f8..3f1fe0e8f33 100644 --- a/packages/ra-ui-materialui/src/layout/Notification.tsx +++ b/packages/ra-ui-materialui/src/layout/Notification.tsx @@ -45,6 +45,9 @@ export const Notification = (props: NotificationProps) => { useEffect(() => { const beforeunload = (e: BeforeUnloadEvent) => { e.preventDefault(); + const confirmationMessage = ''; + e.returnValue = confirmationMessage; + return confirmationMessage; }; if (messageInfo?.notificationOptions?.undoable) { From 8628e3e1bc28b24f792d4bf785e89711d6fec272 Mon Sep 17 00:00:00 2001 From: adrien guernier Date: Wed, 5 Jul 2023 15:00:41 +0200 Subject: [PATCH 4/4] remove beforeunload event only when undoable is true --- packages/ra-ui-materialui/src/layout/Notification.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/ra-ui-materialui/src/layout/Notification.tsx b/packages/ra-ui-materialui/src/layout/Notification.tsx index 3f1fe0e8f33..27ee893481d 100644 --- a/packages/ra-ui-materialui/src/layout/Notification.tsx +++ b/packages/ra-ui-materialui/src/layout/Notification.tsx @@ -64,7 +64,9 @@ export const Notification = (props: NotificationProps) => { } return () => { - window.removeEventListener('beforeunload', beforeunload); + if (messageInfo?.notificationOptions?.undoable) { + window.removeEventListener('beforeunload', beforeunload); + } }; }, [notifications, messageInfo, open, takeNotification]);