From 841af03393c4c4212153e460e02af255fb2cbee0 Mon Sep 17 00:00:00 2001 From: Deluan Date: Fri, 25 Apr 2025 08:09:06 -0400 Subject: [PATCH 1/4] fix: load ND_DEFAULTLANGUAGE on app startup Added in to apply on initial mount, ensuring the locale is set even when the login page is skipped by reverse-proxy authentication. Removed the redundant language-init effect from . Fixes #3605. --- ui/src/App.jsx | 24 ++++++++++++++++++++++-- ui/src/layout/Login.jsx | 24 +----------------------- 2 files changed, 23 insertions(+), 25 deletions(-) diff --git a/ui/src/App.jsx b/ui/src/App.jsx index a3a34a5f3..6c7ea3bb5 100644 --- a/ui/src/App.jsx +++ b/ui/src/App.jsx @@ -1,7 +1,7 @@ import ReactGA from 'react-ga' import { Provider } from 'react-redux' import { createHashHistory } from 'history' -import { Admin as RAAdmin, Resource } from 'react-admin' +import { Admin as RAAdmin, Resource, useSetLocale, useRefresh } from 'react-admin' import { HotKeys } from 'react-hotkeys' import dataProvider from './dataProvider' import authProvider from './authProvider' @@ -31,7 +31,7 @@ import { shareDialogReducer, } from './reducers' import createAdminStore from './store/createAdminStore' -import { i18nProvider } from './i18n' +import { i18nProvider, retrieveTranslation } from './i18n' import config, { shareInfo } from './config' import { keyMap } from './hotkeys' import useChangeThemeColor from './useChangeThemeColor' @@ -39,6 +39,7 @@ import SharePlayer from './share/SharePlayer' import { HTML5Backend } from 'react-dnd-html5-backend' import { DndProvider } from 'react-dnd' import missing from './missing/index.js' +import { useEffect } from 'react' const history = createHashHistory() @@ -143,6 +144,25 @@ const Admin = (props) => { } const AppWithHotkeys = () => { + // Initialize default language on app mount + const setLocale = useSetLocale() + const refresh = useRefresh() + useEffect(() => { + if (config.defaultLanguage !== '' && !localStorage.getItem('locale')) { + retrieveTranslation(config.defaultLanguage) + .then(() => { + setLocale(config.defaultLanguage).then(() => { + localStorage.setItem('locale', config.defaultLanguage) + }) + refresh(true) + }) + .catch((e) => { + throw new Error( + 'Cannot load language "' + config.defaultLanguage + '": ' + e + ) + }) + } + }, [setLocale, refresh]) let language = localStorage.getItem('locale') || 'en' document.documentElement.lang = language if (config.enableSharing && shareInfo) { diff --git a/ui/src/layout/Login.jsx b/ui/src/layout/Login.jsx index 2244f4dfd..7b1c752bf 100644 --- a/ui/src/layout/Login.jsx +++ b/ui/src/layout/Login.jsx @@ -1,4 +1,4 @@ -import React, { useState, useCallback, useEffect } from 'react' +import React, { useState, useCallback } from 'react' import PropTypes from 'prop-types' import { Field, Form } from 'react-final-form' import { useDispatch } from 'react-redux' @@ -13,8 +13,6 @@ import { createMuiTheme, useLogin, useNotify, - useRefresh, - useSetLocale, useTranslate, useVersion, } from 'react-admin' @@ -24,7 +22,6 @@ import Notification from './Notification' import useCurrentTheme from '../themes/useCurrentTheme' import config from '../config' import { clearQueue } from '../actions' -import { retrieveTranslation } from '../i18n' import { INSIGHTS_DOC_URL } from '../consts.js' const useStyles = makeStyles( @@ -400,27 +397,8 @@ Login.propTypes = { // the right theme const LoginWithTheme = (props) => { const theme = useCurrentTheme() - const setLocale = useSetLocale() - const refresh = useRefresh() const version = useVersion() - useEffect(() => { - if (config.defaultLanguage !== '' && !localStorage.getItem('locale')) { - retrieveTranslation(config.defaultLanguage) - .then(() => { - setLocale(config.defaultLanguage).then(() => { - localStorage.setItem('locale', config.defaultLanguage) - }) - refresh(true) - }) - .catch((e) => { - throw new Error( - 'Cannot load language "' + config.defaultLanguage + '": ' + e, - ) - }) - } - }, [refresh, setLocale]) - return ( From 4548e75d49a8c025f19d8727fdbe6e556c454c49 Mon Sep 17 00:00:00 2001 From: Deluan Date: Fri, 25 Apr 2025 08:12:44 -0400 Subject: [PATCH 2/4] style(ui): format App.jsx with Prettier Ran Prettier on ui/src/App.jsx to satisfy code style checks after adding default-language useEffect. --- ui/src/App.jsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/ui/src/App.jsx b/ui/src/App.jsx index 6c7ea3bb5..4c6441fed 100644 --- a/ui/src/App.jsx +++ b/ui/src/App.jsx @@ -1,7 +1,12 @@ import ReactGA from 'react-ga' import { Provider } from 'react-redux' import { createHashHistory } from 'history' -import { Admin as RAAdmin, Resource, useSetLocale, useRefresh } from 'react-admin' +import { + Admin as RAAdmin, + Resource, + useSetLocale, + useRefresh, +} from 'react-admin' import { HotKeys } from 'react-hotkeys' import dataProvider from './dataProvider' import authProvider from './authProvider' @@ -158,7 +163,7 @@ const AppWithHotkeys = () => { }) .catch((e) => { throw new Error( - 'Cannot load language "' + config.defaultLanguage + '": ' + e + 'Cannot load language "' + config.defaultLanguage + '": ' + e, ) }) } From 2b744c878efdcccf09ef9f950086bca85eca80b8 Mon Sep 17 00:00:00 2001 From: Deluan Date: Fri, 25 Apr 2025 12:40:27 -0400 Subject: [PATCH 3/4] fix(ui): move default language initialization to Admin component Signed-off-by: Deluan --- ui/src/App.jsx | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/ui/src/App.jsx b/ui/src/App.jsx index 4c6441fed..3ac705b0a 100644 --- a/ui/src/App.jsx +++ b/ui/src/App.jsx @@ -82,6 +82,25 @@ const App = () => ( ) const Admin = (props) => { + const setLocale = useSetLocale() + const refresh = useRefresh() + useEffect(() => { + if (config.defaultLanguage !== '' && !localStorage.getItem('locale')) { + retrieveTranslation(config.defaultLanguage) + .then(() => { + setLocale(config.defaultLanguage).then(() => { + localStorage.setItem('locale', config.defaultLanguage) + }) + refresh(true) + }) + .catch((e) => { + // eslint-disable-next-line no-console + console.error( + 'Cannot load language "' + config.defaultLanguage + '": ' + e, + ) + }) + } + }, [setLocale, refresh]) useChangeThemeColor() /* eslint-disable react/jsx-key */ return ( @@ -149,25 +168,6 @@ const Admin = (props) => { } const AppWithHotkeys = () => { - // Initialize default language on app mount - const setLocale = useSetLocale() - const refresh = useRefresh() - useEffect(() => { - if (config.defaultLanguage !== '' && !localStorage.getItem('locale')) { - retrieveTranslation(config.defaultLanguage) - .then(() => { - setLocale(config.defaultLanguage).then(() => { - localStorage.setItem('locale', config.defaultLanguage) - }) - refresh(true) - }) - .catch((e) => { - throw new Error( - 'Cannot load language "' + config.defaultLanguage + '": ' + e, - ) - }) - } - }, [setLocale, refresh]) let language = localStorage.getItem('locale') || 'en' document.documentElement.lang = language if (config.enableSharing && shareInfo) { From 5c18951e31c511b1627a069ccb0a1b9d0d750304 Mon Sep 17 00:00:00 2001 From: Deluan Date: Mon, 28 Apr 2025 09:52:53 -0400 Subject: [PATCH 4/4] fix(ui): streamline locale setting in App component Signed-off-by: Deluan --- ui/src/App.jsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ui/src/App.jsx b/ui/src/App.jsx index 3ac705b0a..d51604e83 100644 --- a/ui/src/App.jsx +++ b/ui/src/App.jsx @@ -87,10 +87,9 @@ const Admin = (props) => { useEffect(() => { if (config.defaultLanguage !== '' && !localStorage.getItem('locale')) { retrieveTranslation(config.defaultLanguage) + .then(() => setLocale(config.defaultLanguage)) .then(() => { - setLocale(config.defaultLanguage).then(() => { - localStorage.setItem('locale', config.defaultLanguage) - }) + localStorage.setItem('locale', config.defaultLanguage) refresh(true) }) .catch((e) => {