From 977b268f66ce7bbb00036a912ef8892ad2b42fdb Mon Sep 17 00:00:00 2001 From: Abdelsalem Date: Wed, 7 Feb 2024 10:08:08 +0100 Subject: [PATCH 1/2] add snackbar on maintenance message Signed-off-by: Abdelsalem --- src/components/app.js | 62 ++++++++++++++++++++++++++++- src/services/config-notification.js | 16 ++++++++ 2 files changed, 77 insertions(+), 1 deletion(-) diff --git a/src/components/app.js b/src/components/app.js index d83aa2902f..7eb281c924 100644 --- a/src/components/app.js +++ b/src/components/app.js @@ -94,7 +94,10 @@ import { getComputedLanguage } from '../utils/language'; import AppTopBar from './app-top-bar'; import { StudyContainer } from './study-container'; import { fetchValidateUser } from '../services/user-admin'; -import { connectNotificationsWsUpdateConfig } from '../services/config-notification'; +import { + connectGlobalNotificationsWs, + connectNotificationsWsUpdateConfig, +} from '../services/config-notification'; import { fetchConfigParameter, fetchConfigParameters, @@ -105,6 +108,7 @@ import { } from '../services/utils'; import { getOptionalServices } from '../services/study'; import { defaultOptionalServicesState } from 'redux/reducer'; +import { closeSnackbar, enqueueSnackbar } from 'notistack'; const noUserManager = { instance: null, error: null }; @@ -141,6 +145,12 @@ const App = () => { const [tabIndex, setTabIndex] = useState(0); + const [maintenanceSnackBarId, setMaintenanceSnackBarId] = useState(null); + + const HEADER_MAINTENANCE = 'maintenance'; + + const HEADER_CANCEL_MAINTENANCE = 'cancelMaintenance'; + const updateParams = useCallback( (params) => { console.debug('received UI parameters : ', params); @@ -380,6 +390,53 @@ const App = () => { return ws; }, [updateParams, snackError, dispatch]); + const connectGlobalNotifications = useCallback(() => { + const ws = connectGlobalNotificationsWs(); + ws.onmessage = function (event) { + let eventData = JSON.parse(event.data); + if (eventData.headers.messageType === HEADER_MAINTENANCE) { + if (eventData.headers.duration) { + setMaintenanceSnackBarId( + enqueueSnackbar(eventData.payload, { + autoHideDuration: eventData.headers.duration * 1000, + variant: 'info', + style: { + whiteSpace: 'pre-line', + }, + anchorOrigin: { + vertical: 'top', + horizontal: 'center', + }, + }) + ); + } else { + setMaintenanceSnackBarId( + enqueueSnackbar(eventData.payload, { + variant: 'info', + persist: true, + style: { + whiteSpace: 'pre-line', + }, + anchorOrigin: { + vertical: 'top', + horizontal: 'center', + }, + }) + ); + } + } else if ( + eventData.headers.messageType === HEADER_CANCEL_MAINTENANCE + ) { + //nothing happens if the id is null or if the snackbar it references is already closed + closeSnackbar(maintenanceSnackBarId); + } + }; + ws.onerror = function (event) { + console.error('Unexpected Notification WebSocket error', event); + }; + return ws; + }, [maintenanceSnackBarId]); + // Can't use lazy initializer because useRouteMatch is a hook const [initialMatchSilentRenewCallbackUrl] = useState( useMatch({ @@ -514,8 +571,10 @@ const App = () => { ); const ws = connectNotificationsUpdateConfig(); + const ws2 = connectGlobalNotifications(); return function () { ws.close(); + ws2.close(); }; } }, [ @@ -523,6 +582,7 @@ const App = () => { dispatch, updateParams, connectNotificationsUpdateConfig, + connectGlobalNotifications, snackError, ]); diff --git a/src/services/config-notification.js b/src/services/config-notification.js index 67c56a95ab..d781fd989c 100644 --- a/src/services/config-notification.js +++ b/src/services/config-notification.js @@ -28,3 +28,19 @@ export function connectNotificationsWsUpdateConfig() { }; return reconnectingWebSocket; } + +export function connectGlobalNotificationsWs() { + const webSocketBaseUrl = getWsBase(); + const webSocketUrl = + webSocketBaseUrl + PREFIX_CONFIG_NOTIFICATION_WS + '/global'; + + const reconnectingWebSocket = new ReconnectingWebSocket(() => + getUrlWithToken(webSocketUrl) + ); + reconnectingWebSocket.onopen = function () { + console.info( + 'Connected Websocket for global messages ' + webSocketUrl + ' ...' + ); + }; + return reconnectingWebSocket; +} From d75604c3e89204d7dc2df23f9bf24acde20c044a Mon Sep 17 00:00:00 2001 From: Abdelsalem Date: Wed, 7 Feb 2024 19:05:57 +0100 Subject: [PATCH 2/2] cancel previous msg when sending a new one Signed-off-by: Abdelsalem --- src/components/app.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/app.js b/src/components/app.js index 56a9547257..51981d687f 100644 --- a/src/components/app.js +++ b/src/components/app.js @@ -395,6 +395,8 @@ const App = () => { ws.onmessage = function (event) { let eventData = JSON.parse(event.data); if (eventData.headers.messageType === HEADER_MAINTENANCE) { + //first we close the previous snackbar (no need to check if there is one because closeSnackbar doesn't fail on null or wrong id) + closeSnackbar(maintenanceSnackBarId); if (eventData.headers.duration) { setMaintenanceSnackBarId( enqueueSnackbar(eventData.payload, {