diff --git a/demo/src/app.jsx b/demo/src/app.jsx
index 55bc0fb2..0cc9508c 100644
--- a/demo/src/app.jsx
+++ b/demo/src/app.jsx
@@ -331,6 +331,8 @@ function AppContent({ language, onLanguageClick }) {
const [openTreeViewFinderDialog, setOpenTreeViewFinderDialog] = useState(false);
const [openTreeViewFinderDialogCustomDialog, setOpenTreeViewFinderDialogCustomDialog] = useState(false);
+ const [developerMode, setDeveloperMode] = useState(false);
+
// Can't use lazy initializer because useMatch is a hook
const [initialMatchSilentRenewCallbackUrl] = useState(useMatch('/silent-renew-callback'));
@@ -812,6 +814,7 @@ function AppContent({ language, onLanguageClick }) {
+
);
@@ -825,7 +828,8 @@ function AppContent({ language, onLanguageClick }) {
appName="Demo"
appColor="#808080"
appLogo={}
- onParametersClick={() => console.log('settings')}
+ onUserSettingsClick={() => console.log('user settings')}
+ developerMode={developerMode}
onLogoutClick={() => logout(dispatch, userManager.instance)}
onLogoClick={() => console.log('logo')}
onThemeClick={handleThemeClick}
diff --git a/src/components/topBar/MessageBanner.tsx b/src/components/topBar/MessageBanner.tsx
new file mode 100644
index 00000000..dcb81d6c
--- /dev/null
+++ b/src/components/topBar/MessageBanner.tsx
@@ -0,0 +1,75 @@
+/**
+ * Copyright (c) 2025, RTE (http://www.rte-france.com)
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+import { ReactNode, useState } from 'react';
+import { Box, Theme } from '@mui/material';
+import CloseIcon from '@mui/icons-material/Close';
+import WarningAmberIcon from '@mui/icons-material/WarningAmber';
+import { SystemStyleObject } from '@mui/system/styleFunctionSx/styleFunctionSx';
+
+const styles = {
+ banner: (theme: Theme): SystemStyleObject => ({
+ left: 0,
+ width: '100%',
+ backgroundColor: '#f6b26b',
+ color: 'black',
+ padding: theme.spacing(1),
+ textAlign: 'left',
+ boxShadow: '0px 2px 5px rgba(0, 0, 0, 0.1)',
+ zIndex: 1000,
+ display: 'flex',
+ justifyContent: 'flex-start',
+ alignItems: 'center',
+ }),
+ icon: (theme: Theme): SystemStyleObject => ({
+ paddingRight: theme.spacing(0.75),
+ color: 'red',
+ marginTop: theme.spacing(0.5),
+ }),
+ message: {
+ flexGrow: 1,
+ },
+ button: (theme: Theme): SystemStyleObject => ({
+ backgroundColor: '#f6b26b',
+ border: 'none',
+ cursor: 'pointer',
+ borderRadius: theme.spacing(0.5),
+ marginRight: theme.spacing(0.5),
+ width: theme.spacing(3.5),
+ height: theme.spacing(3.5),
+ '&:hover': {
+ backgroundColor: '#e39648',
+ },
+ '& svg': {
+ width: '100%',
+ height: '100%',
+ },
+ }),
+};
+
+export interface MessageBannerProps {
+ children: ReactNode;
+}
+
+function MessageBanner({ children }: MessageBannerProps) {
+ const [visible, setVisible] = useState(true);
+
+ return (
+ visible && (
+
+
+
+
+ {children}
+ setVisible(false)}>
+
+
+
+ )
+ );
+}
+
+export default MessageBanner;
diff --git a/src/components/topBar/TopBar.tsx b/src/components/topBar/TopBar.tsx
index 2c29d1dc..2ab7c8ad 100644
--- a/src/components/topBar/TopBar.tsx
+++ b/src/components/topBar/TopBar.tsx
@@ -39,8 +39,8 @@ import {
HelpOutline as HelpOutlineIcon,
Person as PersonIcon,
ManageAccounts,
- Settings as SettingsIcon,
WbSunny as WbSunnyIcon,
+ Badge as BadgeIcon,
} from '@mui/icons-material';
import { styled } from '@mui/system';
@@ -58,6 +58,7 @@ import {
LANG_SYSTEM,
LIGHT_THEME,
} from '../../utils/constants/browserConstants';
+import MessageBanner from './MessageBanner';
const styles = {
grow: {
@@ -165,7 +166,7 @@ export type GsTheme = typeof LIGHT_THEME | typeof DARK_THEME;
export type TopBarProps = Omit &
Omit &
Omit & {
- onParametersClick?: () => void;
+ onUserSettingsClick?: () => void;
onLogoClick: GridLogoProps['onClick'];
user?: User;
onAboutClick?: () => void;
@@ -177,6 +178,7 @@ export type TopBarProps = Omit &
equipmentLabelling?: boolean;
onLanguageClick: (value: GsLang) => void;
language: GsLang;
+ developerMode?: boolean;
};
export function TopBar({
@@ -186,7 +188,7 @@ export function TopBar({
appVersion,
appLicense,
logoAboutDialog,
- onParametersClick,
+ onUserSettingsClick,
onLogoutClick,
onLogoClick,
user,
@@ -197,6 +199,7 @@ export function TopBar({
additionalModulesPromise,
onThemeClick,
theme,
+ developerMode,
onEquipmentLabellingClick,
equipmentLabelling,
onLanguageClick,
@@ -226,10 +229,10 @@ export function TopBar({
setAnchorElAppsMenu(null);
};
- const onParametersClicked = () => {
+ const onUserSettingsClicked = () => {
setAnchorElSettingsMenu(null);
- if (onParametersClick) {
- onParametersClick();
+ if (onUserSettingsClick) {
+ onUserSettingsClick();
}
};
@@ -291,6 +294,11 @@ export function TopBar({
return (
// @ts-ignore appBar style is not defined
+ {user && developerMode && (
+
+
+
+ )}
{logoClickable}
{children}
@@ -401,6 +409,58 @@ export function TopBar({
+ {/* User information */}
+ {!isHiddenUserInformation() && (
+
+
+
+
+
+
+
+
+
+
+ )}
+
+ {/* User settings */}
+
+
+
+
+
+
+
+
+
+
+
+ {/* About */}
+ {/* If the callback onAboutClick is undefined, we open default about dialog */}
+
+
+
+
+
+
+
+
+
+
+
{/* Display mode */}
- {/* /!* Equipment labelling *!/ */}
- {/* If the callback onEquipmentLabellingClick is undefined, equipment labelling component should not be displayed */}
+ {/* Equipment labeling */}
+ {/* If the callback onEquipmentLabellingClick is undefined, equipment labeling component should not be displayed */}
{onEquipmentLabellingClick && (
- {/* Settings */}
- {/* If the callback onParametersClicked is undefined, parameters component should be disabled */}
- {onParametersClick && (
-
-
-
-
-
-
-
-
-
-
- )}
-
- {/* User information */}
- {!isHiddenUserInformation() && (
-
-
-
-
-
-
-
-
-
-
- )}
-
- {/* About */}
- {/* If the callback onAboutClick is undefined, we open default about dialog */}
-
-
-
-
-
-
-
-
-
-
-
{/* Loggout */}
diff --git a/src/components/topBar/tests/TopBar.test.tsx b/src/components/topBar/tests/TopBar.test.tsx
index c5cc78b4..2587431b 100644
--- a/src/components/topBar/tests/TopBar.test.tsx
+++ b/src/components/topBar/tests/TopBar.test.tsx
@@ -51,7 +51,7 @@ it('renders', () => {
appName="Demo"
appColor="#808080"
appLogo={}
- onParametersClick={() => {}}
+ onUserSettingsClick={() => {}}
onLogoutClick={() => {}}
onLogoClick={() => {}}
user={{
diff --git a/src/translations/en/topBarEn.ts b/src/translations/en/topBarEn.ts
index f2a50d56..c2158611 100644
--- a/src/translations/en/topBarEn.ts
+++ b/src/translations/en/topBarEn.ts
@@ -6,17 +6,18 @@
*/
export const topBarEn = {
- 'top-bar/settings': 'Settings',
+ 'top-bar/userSettings': 'User settings',
'top-bar/logout': 'Logout',
'top-bar/goFullScreen': 'Full screen',
'top-bar/exitFullScreen': 'Exit full screen mode',
- 'top-bar/user-information': 'User information',
+ 'top-bar/userInformation': 'User information',
'top-bar/about': 'About',
'top-bar/displayMode': 'Display mode',
'top-bar/equipmentLabel': 'Equipment label',
'top-bar/id': 'Id',
'top-bar/name': 'Name',
'top-bar/language': 'Language',
+ 'top-bar/developerModeWarning': 'Developer mode: Some features are incomplete and may not work as expected.',
'about-dialog/title': 'About',
'about-dialog/version': 'Version {version}',
diff --git a/src/translations/fr/topBarFr.ts b/src/translations/fr/topBarFr.ts
index 87d3c6fc..282a5162 100644
--- a/src/translations/fr/topBarFr.ts
+++ b/src/translations/fr/topBarFr.ts
@@ -6,7 +6,7 @@
*/
export const topBarFr = {
- 'top-bar/settings': 'Paramètres',
+ 'top-bar/userSettings': 'Paramètres utilisateur',
'top-bar/logout': 'Se déconnecter',
'top-bar/goFullScreen': 'Plein écran',
'top-bar/exitFullScreen': 'Quitter mode plein écran',
@@ -17,6 +17,8 @@ export const topBarFr = {
'top-bar/id': 'Id',
'top-bar/name': 'Nom',
'top-bar/language': 'Langue',
+ 'top-bar/developerModeWarning':
+ 'Mode développeur : Certaines fonctionnalités ne sont pas complètes et peuvent ne pas fonctionner comme prévu.',
'about-dialog/title': 'À propos',
'about-dialog/version': 'Version {version}',