diff --git a/.prettierrc.json b/.prettierrc.json index 27512b6..fda48c3 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -1,5 +1,6 @@ { "trailingComma": "es5", "tabWidth": 4, + "printWidth": 120, "singleQuote": true } diff --git a/README.md b/README.md index 11e6ab7..3491c20 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ This template setup the authentication mechanism and provides a configured empty To customize this repository for an app, search and replace the string `XXX` with the name of the app. For example, GridXXX -> GridFoo, gridXXX-app -> gridfoo-app. -Create a new view in study-server and replace `yyy` with the new token in rest api `src/rest/study.ts`. +Create a new view in study-server and replace `yyy` with the new token in rest api `src/rest/study.ts`. ## Typescript config @@ -20,7 +20,7 @@ To check dependencies license compatibility with this project one locally, pleas npm run licenses-check ``` -Notes : +Notes : * Check [license-checker-config.json](license-checker-config.json) for license white list and exclusion. If you need to update this list, please inform organization's owners. * Excluded dependencies : diff --git a/license-checker-config.json b/license-checker-config.json index 94edbfb..8f50cca 100644 --- a/license-checker-config.json +++ b/license-checker-config.json @@ -1,5 +1,5 @@ { - "onlyAllow" : [ + "onlyAllow": [ "MPL-2.0", "MIT", "BSD-3-Clause", diff --git a/src/__mocks__/svgrMock.js b/src/__mocks__/svgrMock.js index 2e01553..2eecbf2 100644 --- a/src/__mocks__/svgrMock.js +++ b/src/__mocks__/svgrMock.js @@ -7,9 +7,7 @@ import React from 'react'; -const SvgrMock = React.forwardRef((props, ref) => ( - -)); +const SvgrMock = React.forwardRef((props, ref) => ); export const ReactComponent = SvgrMock; export default SvgrMock; diff --git a/src/components/app-top-bar.tsx b/src/components/app-top-bar.tsx index 645bbe8..a77bcfd 100644 --- a/src/components/app-top-bar.tsx +++ b/src/components/app-top-bar.tsx @@ -5,26 +5,12 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import React, { - FunctionComponent, - useCallback, - useEffect, - useState, -} from 'react'; -import { - LIGHT_THEME, - logout, - TopBar, - UserManagerState, -} from '@gridsuite/commons-ui'; +import React, { FunctionComponent, useCallback, useEffect, useState } from 'react'; +import { LIGHT_THEME, logout, TopBar, UserManagerState } from '@gridsuite/commons-ui'; import Parameters, { useParameterState } from './parameters'; import { APP_NAME, PARAM_LANGUAGE, PARAM_THEME } from '../utils/config-params'; import { useDispatch, useSelector } from 'react-redux'; -import { - fetchAppsAndUrls, - fetchVersion, - MetadataJson, -} from '../utils/rest-api'; +import { fetchAppsAndUrls, fetchVersion, MetadataJson } from '../utils/rest-api'; import { getServersInfos } from '../rest/study'; import { useNavigate } from 'react-router-dom'; import { ReactComponent as PowsyblLogo } from '../images/powsybl_logo.svg'; @@ -47,8 +33,7 @@ const AppTopBar: FunctionComponent = (props) => { const [themeLocal, handleChangeTheme] = useParameterState(PARAM_THEME); - const [languageLocal, handleChangeLanguage] = - useParameterState(PARAM_LANGUAGE); + const [languageLocal, handleChangeLanguage] = useParameterState(PARAM_LANGUAGE); const [showParameters, setShowParameters] = useState(false); const displayParameters = useCallback(() => setShowParameters(true), []); @@ -77,27 +62,18 @@ const AppTopBar: FunctionComponent = (props) => { appVersion={AppPackage.version} appLicense={AppPackage.license} onParametersClick={displayParameters} - onLogoutClick={() => - logout(dispatch, props.userManager.instance) - } + onLogoutClick={() => logout(dispatch, props.userManager.instance)} onLogoClick={() => navigate('/', { replace: true })} user={props.user ?? undefined} appsAndUrls={appsAndUrls} - globalVersionPromise={() => - fetchVersion().then( - (res) => res?.deployVersion ?? 'unknown' - ) - } + globalVersionPromise={() => fetchVersion().then((res) => res?.deployVersion ?? 'unknown')} additionalModulesPromise={getServersInfos} onThemeClick={handleChangeTheme} theme={themeLocal} onLanguageClick={handleChangeLanguage} language={languageLocal} /> - + ); }; diff --git a/src/components/app-wrapper.tsx b/src/components/app-wrapper.tsx index 0803483..c9ec50f 100644 --- a/src/components/app-wrapper.tsx +++ b/src/components/app-wrapper.tsx @@ -8,12 +8,7 @@ import App from './app'; import React, { FunctionComponent } from 'react'; import { CssBaseline } from '@mui/material'; -import { - createTheme, - StyledEngineProvider, - Theme, - ThemeProvider, -} from '@mui/material/styles'; +import { createTheme, StyledEngineProvider, Theme, ThemeProvider } from '@mui/material/styles'; import { card_error_boundary_en, card_error_boundary_fr, @@ -118,15 +113,10 @@ const messages: Record = { const basename = new URL(document.querySelector('base')?.href ?? '').pathname; const AppWrapperWithRedux: FunctionComponent = () => { - const computedLanguage = useSelector( - (state: AppState) => state.computedLanguage - ); + const computedLanguage = useSelector((state: AppState) => state.computedLanguage); const theme = useSelector((state: AppState) => state[PARAM_THEME]); return ( - + diff --git a/src/components/app.test.tsx b/src/components/app.test.tsx index 4bb28d7..4799e8d 100644 --- a/src/components/app.test.tsx +++ b/src/components/app.test.tsx @@ -15,11 +15,7 @@ import { Provider } from 'react-redux'; import { BrowserRouter } from 'react-router-dom'; import App from './app'; import { store } from '../redux/store'; -import { - createTheme, - StyledEngineProvider, - ThemeProvider, -} from '@mui/material/styles'; +import { createTheme, StyledEngineProvider, ThemeProvider } from '@mui/material/styles'; import { SnackbarProvider } from '@gridsuite/commons-ui'; import { CssBaseline } from '@mui/material'; diff --git a/src/components/app.tsx b/src/components/app.tsx index 299a60a..983e728 100644 --- a/src/components/app.tsx +++ b/src/components/app.tsx @@ -5,21 +5,9 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import React, { - FunctionComponent, - useCallback, - useEffect, - useState, -} from 'react'; +import React, { FunctionComponent, useCallback, useEffect, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { - Navigate, - Route, - Routes, - useLocation, - useMatch, - useNavigate, -} from 'react-router-dom'; +import { Navigate, Route, Routes, useLocation, useMatch, useNavigate } from 'react-router-dom'; import { FormattedMessage } from 'react-intl'; import { Box, Typography } from '@mui/material'; import { @@ -30,11 +18,7 @@ import { initializeAuthenticationProd, useSnackMessage, } from '@gridsuite/commons-ui'; -import { - selectComputedLanguage, - selectLanguage, - selectTheme, -} from '../redux/actions'; +import { selectComputedLanguage, selectLanguage, selectTheme } from '../redux/actions'; import { AppState } from '../redux/reducer'; import { ConfigParameters, @@ -44,12 +28,7 @@ import { fetchIdpSettings, fetchValidateUser, } from '../utils/rest-api'; -import { - APP_NAME, - COMMON_APP_NAME, - PARAM_LANGUAGE, - PARAM_THEME, -} from '../utils/config-params'; +import { APP_NAME, COMMON_APP_NAME, PARAM_LANGUAGE, PARAM_THEME } from '../utils/config-params'; import { getComputedLanguage } from '../utils/language'; import AppTopBar, { AppTopBarProps } from './app-top-bar'; import ReconnectingWebSocket from 'reconnecting-websocket'; @@ -61,19 +40,11 @@ const App: FunctionComponent = () => { const user = useSelector((state: AppState) => state.user); - const signInCallbackError = useSelector( - (state: AppState) => state.signInCallbackError - ); - const authenticationRouterError = useSelector( - (state: AppState) => state.authenticationRouterError - ); - const showAuthenticationRouterLogin = useSelector( - (state: AppState) => state.showAuthenticationRouterLogin - ); + const signInCallbackError = useSelector((state: AppState) => state.signInCallbackError); + const authenticationRouterError = useSelector((state: AppState) => state.authenticationRouterError); + const showAuthenticationRouterLogin = useSelector((state: AppState) => state.showAuthenticationRouterLogin); - const [userManager, setUserManager] = useState< - AppTopBarProps['userManager'] - >({ instance: null, error: null }); + const [userManager, setUserManager] = useState({ instance: null, error: null }); const navigate = useNavigate(); @@ -91,11 +62,7 @@ const App: FunctionComponent = () => { break; case PARAM_LANGUAGE: dispatch(selectLanguage(param.value)); - dispatch( - selectComputedLanguage( - getComputedLanguage(param.value) - ) - ); + dispatch(selectComputedLanguage(getComputedLanguage(param.value))); break; default: break; @@ -105,27 +72,26 @@ const App: FunctionComponent = () => { [dispatch] ); - const connectNotificationsUpdateConfig = - useCallback((): ReconnectingWebSocket => { - const ws = connectNotificationsWsUpdateConfig(); - ws.onmessage = function (event) { - let eventData = JSON.parse(event.data); - if (eventData.headers?.parameterName) { - fetchConfigParameter(eventData.headers.parameterName) - .then((param) => updateParams([param])) - .catch((error) => - snackError({ - messageTxt: error.message, - headerId: 'paramsRetrievingError', - }) - ); - } - }; - ws.onerror = function (event) { - console.error('Unexpected Notification WebSocket error', event); - }; - return ws; - }, [updateParams, snackError]); + const connectNotificationsUpdateConfig = useCallback((): ReconnectingWebSocket => { + const ws = connectNotificationsWsUpdateConfig(); + ws.onmessage = function (event) { + let eventData = JSON.parse(event.data); + if (eventData.headers?.parameterName) { + fetchConfigParameter(eventData.headers.parameterName) + .then((param) => updateParams([param])) + .catch((error) => + snackError({ + messageTxt: error.message, + headerId: 'paramsRetrievingError', + }) + ); + } + }; + ws.onerror = function (event) { + console.error('Unexpected Notification WebSocket error', event); + }; + return ws; + }, [updateParams, snackError]); // Can't use lazy initializer because useMatch is a hook const [initialMatchSilentRenewCallbackUrl] = useState( @@ -144,9 +110,7 @@ const App: FunctionComponent = () => { // need subfunction when async as suggested by rule react-hooks/exhaustive-deps (async function initializeAuthentication() { try { - console.debug( - `auth dev mode: ${process.env.REACT_APP_USE_AUTHENTICATION}` - ); + console.debug(`auth dev mode: ${process.env.REACT_APP_USE_AUTHENTICATION}`); const initAuth = process.env.REACT_APP_USE_AUTHENTICATION === 'true' ? initializeAuthenticationProd( @@ -174,11 +138,7 @@ const App: FunctionComponent = () => { } })(); // Note: dispatch and initialMatchSilentRenewCallbackUrl won't change - }, [ - initialMatchSigninCallbackUrl, - initialMatchSilentRenewCallbackUrl, - dispatch, - ]); + }, [initialMatchSigninCallbackUrl, initialMatchSilentRenewCallbackUrl, dispatch]); useEffect(() => { if (user !== null) { @@ -203,13 +163,7 @@ const App: FunctionComponent = () => { const ws = connectNotificationsUpdateConfig(); return () => ws.close(); } - }, [ - user, - dispatch, - updateParams, - snackError, - connectNotificationsUpdateConfig, - ]); + }, [user, dispatch, updateParams, snackError, connectNotificationsUpdateConfig]); return ( <> @@ -221,33 +175,16 @@ const App: FunctionComponent = () => { path="/" element={ - + Connected } /> - - } - /> + } /> - Error: logout failed; you are still logged - in. - - } + element={

Error: logout failed; you are still logged in.

} /> { userManager={userManager} signInCallbackError={signInCallbackError} authenticationRouterError={authenticationRouterError} - showAuthenticationRouterLogin={ - showAuthenticationRouterLogin - } + showAuthenticationRouterLogin={showAuthenticationRouterLogin} dispatch={dispatch} navigate={navigate} location={location} @@ -278,7 +213,5 @@ const App: FunctionComponent = () => { export default App; function validateUserDev(): Promise { - return new Promise((resolve) => - window.setTimeout(() => resolve(true), 500) - ); + return new Promise((resolve) => window.setTimeout(() => resolve(true), 500)); } diff --git a/src/components/parameters.tsx b/src/components/parameters.tsx index b46df2b..31ed0e2 100644 --- a/src/components/parameters.tsx +++ b/src/components/parameters.tsx @@ -5,14 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import React, { - FunctionComponent, - PropsWithChildren, - ReactElement, - useCallback, - useEffect, - useState, -} from 'react'; +import React, { FunctionComponent, PropsWithChildren, ReactElement, useCallback, useEffect, useState } from 'react'; import { FormattedMessage } from 'react-intl'; import { useSelector } from 'react-redux'; import { @@ -48,9 +41,7 @@ const styles = { } as CSSObject, }; -export function useParameterState( - paramName: K -): [AppState[K], (value: AppState[K]) => void] { +export function useParameterState(paramName: K): [AppState[K], (value: AppState[K]) => void] { const { snackError } = useSnackMessage(); const paramGlobalState = useSelector((state: AppState) => state[paramName]); const [paramLocalState, setParamLocalState] = useState(paramGlobalState); @@ -81,15 +72,8 @@ function GUITab(): ReactElement { return ; } -type TabPanelProps = PropsWithChildren< - TypographyTypeMap<{ index: number; value: number }, 'div'>['props'] ->; -function TabPanel({ - children, - value, - index, - ...typoProps -}: TabPanelProps): ReactElement { +type TabPanelProps = PropsWithChildren['props']>; +function TabPanel({ children, value, index, ...typoProps }: TabPanelProps): ReactElement { return ( = (props) => { - diff --git a/src/index.css b/src/index.css index 407ba15..8e8c67b 100644 --- a/src/index.css +++ b/src/index.css @@ -1,22 +1,20 @@ body { margin: 0; - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', - 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', - 'Helvetica Neue', sans-serif; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', + 'Droid Sans', 'Helvetica Neue', sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } code { - font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', - monospace; + font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace; } /* In order for oidc-client-js silent renew to work it inserts an iframe in the DOM directly under body tag, it is supposed to be invisible thus its height and width are set to 0 by default. Except iframes have a border value set to 2 which can cause a slight offset to the UI. This rule prevent the iframe to cause an unwanted offset. It can be removed if oidc-client-js is no longer the authentification library in use in this project. */ - + body > iframe[width='0'][height='0'] { border: 0; } diff --git a/src/module-mui.d.ts b/src/module-mui.d.ts index 27c4207..f746709 100644 --- a/src/module-mui.d.ts +++ b/src/module-mui.d.ts @@ -7,10 +7,7 @@ // https://mui.com/material-ui/customization/theming/#typescript import { CSSObject } from '@mui/styled-engine'; -import { - Theme as MuiTheme, - ThemeOptions as MuiThemeOptions, -} from '@mui/material/styles/createTheme'; +import { Theme as MuiTheme, ThemeOptions as MuiThemeOptions } from '@mui/material/styles/createTheme'; declare module '@mui/material/styles/createTheme' { export * from '@mui/material/styles/createTheme'; @@ -25,7 +22,5 @@ declare module '@mui/material/styles/createTheme' { }; export interface Theme extends MuiTheme, Required {} // allow configuration using `createTheme` - export interface ThemeOptions - extends MuiThemeOptions, - Partial {} + export interface ThemeOptions extends MuiThemeOptions, Partial {} } diff --git a/src/plugins/README.md b/src/plugins/README.md index fd2ae97..3650fb0 100644 --- a/src/plugins/README.md +++ b/src/plugins/README.md @@ -1,4 +1,3 @@ - # How to add plugins Add a plugin component or object in the corresponding group represented as folders. @@ -12,6 +11,7 @@ export default MyNewPlugin; ``` Edit `index.ts` to export your new plugin in the corresponding group + ```ts import MyNewPlugin from './myPluginGroup/myNewPlugin'; ... @@ -48,5 +48,6 @@ const MyPluggableComponent: FunctionComponent = () => { # How to overwrite translations Add your private translations to the following files to complete or overwrite existing translations -* `src/plugins/translations/en.json` -* `src/plugins/translations/fr.json` + +- `src/plugins/translations/en.json` +- `src/plugins/translations/fr.json` diff --git a/src/plugins/translations/en.json b/src/plugins/translations/en.json index 2c63c08..0967ef4 100644 --- a/src/plugins/translations/en.json +++ b/src/plugins/translations/en.json @@ -1,2 +1 @@ -{ -} +{} diff --git a/src/plugins/translations/fr.json b/src/plugins/translations/fr.json index 2c63c08..0967ef4 100644 --- a/src/plugins/translations/fr.json +++ b/src/plugins/translations/fr.json @@ -1,2 +1 @@ -{ -} +{} diff --git a/src/redux/actions.ts b/src/redux/actions.ts index 65aa3cf..7dc9e9d 100644 --- a/src/redux/actions.ts +++ b/src/redux/actions.ts @@ -29,15 +29,11 @@ export function selectLanguage(language: AppState['language']): LanguageAction { } export const SELECT_COMPUTED_LANGUAGE = 'SELECT_COMPUTED_LANGUAGE'; -export type ComputedLanguageAction = Readonly< - Action -> & { +export type ComputedLanguageAction = Readonly> & { computedLanguage: AppState['computedLanguage']; }; -export function selectComputedLanguage( - computedLanguage: AppState['computedLanguage'] -): ComputedLanguageAction { +export function selectComputedLanguage(computedLanguage: AppState['computedLanguage']): ComputedLanguageAction { return { type: SELECT_COMPUTED_LANGUAGE, computedLanguage: computedLanguage, diff --git a/src/redux/local-storage.ts b/src/redux/local-storage.ts index f38ddab..6de769e 100644 --- a/src/redux/local-storage.ts +++ b/src/redux/local-storage.ts @@ -5,13 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { - DARK_THEME, - GsLang, - GsLangUser, - GsTheme, - LANG_SYSTEM, -} from '@gridsuite/commons-ui'; +import { DARK_THEME, GsLang, GsLangUser, GsTheme, LANG_SYSTEM } from '@gridsuite/commons-ui'; import { getComputedLanguage } from '../utils/language'; import { APP_NAME } from '../utils/config-params'; @@ -19,9 +13,7 @@ const LOCAL_STORAGE_THEME_KEY = (APP_NAME + '_THEME').toUpperCase(); const LOCAL_STORAGE_LANGUAGE_KEY = (APP_NAME + '_LANGUAGE').toUpperCase(); export function getLocalStorageTheme() { - return ( - (localStorage.getItem(LOCAL_STORAGE_THEME_KEY) as GsTheme) || DARK_THEME - ); + return (localStorage.getItem(LOCAL_STORAGE_THEME_KEY) as GsTheme) || DARK_THEME; } export function saveLocalStorageTheme(theme: GsTheme): void { @@ -29,10 +21,7 @@ export function saveLocalStorageTheme(theme: GsTheme): void { } export function getLocalStorageLanguage() { - return ( - (localStorage.getItem(LOCAL_STORAGE_LANGUAGE_KEY) as GsLang) || - LANG_SYSTEM - ); + return (localStorage.getItem(LOCAL_STORAGE_LANGUAGE_KEY) as GsLang) || LANG_SYSTEM; } export function saveLocalStorageLanguage(language: GsLang): void { diff --git a/src/redux/reducer.ts b/src/redux/reducer.ts index be19e4b..65220fb 100644 --- a/src/redux/reducer.ts +++ b/src/redux/reducer.ts @@ -12,13 +12,7 @@ import { getLocalStorageTheme, saveLocalStorageTheme, } from './local-storage'; -import { - ComputedLanguageAction, - LanguageAction, - SELECT_COMPUTED_LANGUAGE, - SELECT_THEME, - ThemeAction, -} from './actions'; +import { ComputedLanguageAction, LanguageAction, SELECT_COMPUTED_LANGUAGE, SELECT_THEME, ThemeAction } from './actions'; import { AuthenticationActions, AuthenticationRouterErrorAction, @@ -67,86 +61,48 @@ const initialState: AppState = { computedLanguage: getLocalStorageComputedLanguage(), }; -export type Actions = - | AuthenticationActions - | ThemeAction - | LanguageAction - | ComputedLanguageAction; +export type Actions = AuthenticationActions | ThemeAction | LanguageAction | ComputedLanguageAction; export type AppStateKey = keyof AppState; -export const reducer: ReducerWithInitialState = createReducer( - initialState, - (builder) => { - builder.addCase( - SELECT_THEME, - (state: Draft, action: ThemeAction) => { - state.theme = action.theme; - saveLocalStorageTheme(state.theme); - } - ); - - builder.addCase(USER, (state: Draft, action: UserAction) => { - state.user = action.user; - }); - - builder.addCase( - SIGNIN_CALLBACK_ERROR, - (state: Draft, action: SignInCallbackErrorAction) => { - state.signInCallbackError = action.signInCallbackError; - } - ); - - builder.addCase( - UNAUTHORIZED_USER_INFO, - (state: Draft, action: UnauthorizedUserAction) => { - state.authenticationRouterError = - action.authenticationRouterError; - } - ); - - builder.addCase( - LOGOUT_ERROR, - (state: Draft, action: LogoutErrorAction) => { - state.authenticationRouterError = - action.authenticationRouterError; - } - ); - - builder.addCase( - USER_VALIDATION_ERROR, - (state: Draft, action: UserValidationErrorAction) => { - state.authenticationRouterError = - action.authenticationRouterError; - } - ); - - builder.addCase( - RESET_AUTHENTICATION_ROUTER_ERROR, - ( - state: Draft, - action: AuthenticationRouterErrorAction - ) => { - state.authenticationRouterError = null; - } - ); - - builder.addCase( - SHOW_AUTH_INFO_LOGIN, - ( - state: Draft, - action: ShowAuthenticationRouterLoginAction - ) => { - state.showAuthenticationRouterLogin = - action.showAuthenticationRouterLogin; - } - ); - - builder.addCase( - SELECT_COMPUTED_LANGUAGE, - (state: Draft, action: ComputedLanguageAction) => { - state.computedLanguage = action.computedLanguage; - } - ); - } -); +export const reducer: ReducerWithInitialState = createReducer(initialState, (builder) => { + builder.addCase(SELECT_THEME, (state: Draft, action: ThemeAction) => { + state.theme = action.theme; + saveLocalStorageTheme(state.theme); + }); + + builder.addCase(USER, (state: Draft, action: UserAction) => { + state.user = action.user; + }); + + builder.addCase(SIGNIN_CALLBACK_ERROR, (state: Draft, action: SignInCallbackErrorAction) => { + state.signInCallbackError = action.signInCallbackError; + }); + + builder.addCase(UNAUTHORIZED_USER_INFO, (state: Draft, action: UnauthorizedUserAction) => { + state.authenticationRouterError = action.authenticationRouterError; + }); + + builder.addCase(LOGOUT_ERROR, (state: Draft, action: LogoutErrorAction) => { + state.authenticationRouterError = action.authenticationRouterError; + }); + + builder.addCase(USER_VALIDATION_ERROR, (state: Draft, action: UserValidationErrorAction) => { + state.authenticationRouterError = action.authenticationRouterError; + }); + + builder.addCase( + RESET_AUTHENTICATION_ROUTER_ERROR, + (state: Draft, action: AuthenticationRouterErrorAction) => { + state.authenticationRouterError = null; + } + ); + + builder.addCase(SHOW_AUTH_INFO_LOGIN, (state: Draft, action: ShowAuthenticationRouterLoginAction) => { + state.showAuthenticationRouterLogin = action.showAuthenticationRouterLogin; + }); + + builder.addCase(SELECT_COMPUTED_LANGUAGE, (state: Draft, action: ComputedLanguageAction) => { + state.computedLanguage = action.computedLanguage; + }); +}); diff --git a/src/rest/study.ts b/src/rest/study.ts index ae23221..9395b7d 100644 --- a/src/rest/study.ts +++ b/src/rest/study.ts @@ -22,9 +22,7 @@ export function getServersInfos() { }, cache: 'default', }).catch((error) => { - console.error( - `Error while fetching the servers infos : ${getErrorMessage(error)}` - ); + console.error(`Error while fetching the servers infos : ${getErrorMessage(error)}`); throw error; }) as Promise; } diff --git a/src/utils/config-params.ts b/src/utils/config-params.ts index 30807f3..177a13f 100644 --- a/src/utils/config-params.ts +++ b/src/utils/config-params.ts @@ -13,10 +13,7 @@ export const PARAM_LANGUAGE = 'language'; const COMMON_CONFIG_PARAMS_NAMES = new Set([PARAM_THEME, PARAM_LANGUAGE]); -export type AppConfigParameter = - | typeof PARAM_THEME - | typeof PARAM_LANGUAGE - | string; +export type AppConfigParameter = typeof PARAM_THEME | typeof PARAM_LANGUAGE | string; export type AppConfigType = typeof COMMON_APP_NAME | typeof APP_NAME; @@ -25,7 +22,5 @@ export type AppConfigType = typeof COMMON_APP_NAME | typeof APP_NAME; * @param paramName the parameter name/key */ export function getAppName(paramName: AppConfigParameter): AppConfigType { - return COMMON_CONFIG_PARAMS_NAMES.has(paramName) - ? COMMON_APP_NAME - : APP_NAME; + return COMMON_CONFIG_PARAMS_NAMES.has(paramName) ? COMMON_APP_NAME : APP_NAME; } diff --git a/src/utils/language.ts b/src/utils/language.ts index aa7003a..725f944 100644 --- a/src/utils/language.ts +++ b/src/utils/language.ts @@ -5,21 +5,13 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { - GsLang, - GsLangUser, - LANG_ENGLISH, - LANG_FRENCH, - LANG_SYSTEM, -} from '@gridsuite/commons-ui'; +import { GsLang, GsLangUser, LANG_ENGLISH, LANG_FRENCH, LANG_SYSTEM } from '@gridsuite/commons-ui'; const supportedLanguages = [LANG_FRENCH, LANG_ENGLISH]; export function getSystemLanguage(): GsLangUser { const systemLanguage = navigator.language.split(/[-_]/)[0]; - return supportedLanguages.includes(systemLanguage) - ? (systemLanguage as GsLangUser) - : LANG_ENGLISH; + return supportedLanguages.includes(systemLanguage) ? (systemLanguage as GsLangUser) : LANG_ENGLISH; } export function getComputedLanguage(language: GsLang) { diff --git a/src/utils/rest-api.ts b/src/utils/rest-api.ts index c91a2bf..1cdee09 100644 --- a/src/utils/rest-api.ts +++ b/src/utils/rest-api.ts @@ -7,12 +7,7 @@ import { Env, GsLangUser, GsTheme } from '@gridsuite/commons-ui'; import { User } from 'oidc-client'; -import { - APP_NAME, - getAppName, - PARAM_LANGUAGE, - PARAM_THEME, -} from './config-params'; +import { APP_NAME, getAppName, PARAM_LANGUAGE, PARAM_THEME } from './config-params'; import { store } from '../redux/store'; import ReconnectingWebSocket, { Event } from 'reconnecting-websocket'; import { AppState } from '../redux/reducer'; @@ -56,18 +51,12 @@ function getToken(): Token | null { } export function connectNotificationsWsUpdateConfig(): ReconnectingWebSocket { - const webSocketBaseUrl = document.baseURI - .replace(/^http:\/\//, 'ws://') - .replace(/^https:\/\//, 'wss://'); + const webSocketBaseUrl = document.baseURI.replace(/^http:\/\//, 'ws://').replace(/^https:\/\//, 'wss://'); const webSocketUrl = `${webSocketBaseUrl}${PREFIX_CONFIG_NOTIFICATION_WS}/notify?appName=${APP_NAME}`; - const reconnectingWebSocket = new ReconnectingWebSocket( - () => `${webSocketUrl}&access_token=${getToken()}` - ); + const reconnectingWebSocket = new ReconnectingWebSocket(() => `${webSocketUrl}&access_token=${getToken()}`); reconnectingWebSocket.onopen = function (event: Event) { - console.info( - `Connected Websocket update config ui ${webSocketUrl} ...` - ); + console.info(`Connected Websocket update config ui ${webSocketUrl} ...`); }; return reconnectingWebSocket; } @@ -91,9 +80,7 @@ function handleError(response: Response): Promise { ) as ErrorWithStatus; error.status = errorJson.status; } else { - error = new Error( - `${errorName}${response.status} ${response.statusText}` - ) as ErrorWithStatus; + error = new Error(`${errorName}${response.status} ${response.statusText}`) as ErrorWithStatus; error.status = response.status; } throw error; @@ -102,9 +89,7 @@ function handleError(response: Response): Promise { function prepareRequest(init?: InitRequest, token?: Token): RequestInit { if (!(typeof init == 'undefined' || typeof init == 'object')) { - throw new TypeError( - `Argument 2 of backendFetch is not an object ${typeof init}` - ); + throw new TypeError(`Argument 2 of backendFetch is not an object ${typeof init}`); } const initCopy: RequestInit = { ...init }; initCopy.headers = new Headers(initCopy.headers || {}); @@ -114,47 +99,25 @@ function prepareRequest(init?: InitRequest, token?: Token): RequestInit { } function safeFetch(url: Url, initCopy?: InitRequest) { - return fetch(url, initCopy).then((response: Response) => - response.ok ? response : handleError(response) - ); + return fetch(url, initCopy).then((response: Response) => (response.ok ? response : handleError(response))); } -export function backendFetch( - url: Url, - init?: InitRequest, - token?: Token -): Promise { +export function backendFetch(url: Url, init?: InitRequest, token?: Token): Promise { return safeFetch(url, prepareRequest(init, token)); } -export function backendFetchText( - url: Url, - init?: InitRequest, - token?: Token -): Promise { - return backendFetch(url, init, token).then((safeResponse: Response) => - safeResponse.text() - ); +export function backendFetchText(url: Url, init?: InitRequest, token?: Token): Promise { + return backendFetch(url, init, token).then((safeResponse: Response) => safeResponse.text()); } -export function backendFetchJson( - url: Url, - init?: InitRequest, - token?: Token -): Promise { - return backendFetch(url, init, token).then((safeResponse: Response) => - safeResponse.json() - ); +export function backendFetchJson(url: Url, init?: InitRequest, token?: Token): Promise { + return backendFetch(url, init, token).then((safeResponse: Response) => safeResponse.json()); } export function fetchValidateUser(user: User): Promise { const sub = user?.profile?.sub; if (!sub) { - return Promise.reject( - new Error( - `Error : Fetching access for missing user.profile.sub : ${user}` - ) - ); + return Promise.reject(new Error(`Error : Fetching access for missing user.profile.sub : ${user}`)); } console.info(`Fetching access for user...`); @@ -192,14 +155,10 @@ export type VersionJson = { export function fetchVersion(): Promise { console.info(`Fetching global metadata...`); return fetchEnv() - .then((env: EnvJson) => - fetch(`${env.appsMetadataServerUrl}/version.json`) - ) + .then((env: EnvJson) => fetch(`${env.appsMetadataServerUrl}/version.json`)) .then((response: Response) => response.json()) .catch((error) => { - console.error( - `Error while fetching the version : ${getErrorMessage(error)}` - ); + console.error(`Error while fetching the version : ${getErrorMessage(error)}`); throw error; }); } @@ -242,9 +201,7 @@ export type MetadataJson = MetadataCommon | MetadataStudy; export function fetchAppsAndUrls(): Promise { console.info(`Fetching apps and urls...`); return fetchEnv() - .then((env: EnvJson) => - fetch(`${env.appsMetadataServerUrl}/apps-metadata.json`) - ) + .then((env: EnvJson) => fetch(`${env.appsMetadataServerUrl}/apps-metadata.json`)) .then((response: Response) => response.json()); } @@ -260,9 +217,7 @@ export type ConfigParameter = }; export type ConfigParameters = ConfigParameter[]; -export function fetchConfigParameters( - appName: string = APP_NAME -): Promise { +export function fetchConfigParameters(appName: string = APP_NAME): Promise { console.info(`Fetching UI configuration params for app : ${appName}`); const fetchParams = `${PREFIX_CONFIG_QUERIES}/v1/applications/${appName}/parameters`; return backendFetchJson(fetchParams) as Promise; @@ -275,14 +230,9 @@ export function fetchConfigParameter(name: string): Promise { return backendFetchJson(fetchParams) as Promise; } -export function updateConfigParameter( - name: string, - value: Parameters[0] -): Promise { +export function updateConfigParameter(name: string, value: Parameters[0]): Promise { const appName = getAppName(name); - console.info( - `Updating config parameter '${name}=${value}' for app '${appName}'` - ); + console.info(`Updating config parameter '${name}=${value}' for app '${appName}'`); const updateParams = `${PREFIX_CONFIG_QUERIES}/v1/applications/${appName}/parameters/${name}?value=${encodeURIComponent( value )}`;