diff --git a/package-lock.json b/package-lock.json index 1f47d9b9..3d91cd05 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,6 @@ "clsx": "^2.1.0", "jwt-decode": "^4.0.0", "localized-countries": "^2.0.0", - "memoize-one": "^6.0.0", "oidc-client": "^1.11.5", "prop-types": "^15.8.1", "react-beautiful-dnd": "^13.1.1", @@ -12919,11 +12918,6 @@ "tmpl": "1.0.5" } }, - "node_modules/memoize-one": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", - "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==" - }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", diff --git a/package.json b/package.json index 7e205ca7..09c97e5f 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,6 @@ "clsx": "^2.1.0", "jwt-decode": "^4.0.0", "localized-countries": "^2.0.0", - "memoize-one": "^6.0.0", "oidc-client": "^1.11.5", "prop-types": "^15.8.1", "react-beautiful-dnd": "^13.1.1", diff --git a/src/components/authentication/SignInCallbackHandler.tsx b/src/components/authentication/SignInCallbackHandler.tsx index 59e35507..c956222c 100644 --- a/src/components/authentication/SignInCallbackHandler.tsx +++ b/src/components/authentication/SignInCallbackHandler.tsx @@ -6,7 +6,7 @@ */ import { useEffect } from 'react'; -import { UserManager } from 'oidc-client'; +import type { UserManager } from 'oidc-client'; export interface SignInCallbackHandlerProps { userManager: UserManager | null; diff --git a/src/components/authentication/SilentRenewCallbackHandler.tsx b/src/components/authentication/SilentRenewCallbackHandler.tsx index 8e2e8cd5..37152ed2 100644 --- a/src/components/authentication/SilentRenewCallbackHandler.tsx +++ b/src/components/authentication/SilentRenewCallbackHandler.tsx @@ -6,7 +6,7 @@ */ import { useEffect } from 'react'; -import { UserManager } from 'oidc-client'; +import type { UserManager } from 'oidc-client'; export interface SilentRenewCallbackHandlerProps { userManager: UserManager | null; diff --git a/src/components/authentication/authenticationType.ts b/src/components/authentication/authenticationType.ts index 5b88fe8d..b74be8f8 100644 --- a/src/components/authentication/authenticationType.ts +++ b/src/components/authentication/authenticationType.ts @@ -5,7 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { UserManager } from 'oidc-client'; +import type { UserManager } from 'oidc-client'; import { Dispatch } from 'react'; import { NavigateFunction, Location } from 'react-router-dom'; import { AuthenticationActions } from '../../redux/actions/authActions'; diff --git a/src/components/authentication/utils/authService.ts b/src/components/authentication/utils/authService.ts index 77f97b1e..71651d5a 100644 --- a/src/components/authentication/utils/authService.ts +++ b/src/components/authentication/utils/authService.ts @@ -39,8 +39,13 @@ type CustomUserManager = UserManager & { }; }; +declare global { + interface Window { + OIDCLog?: Log; + } +} + // set as a global variable to allow log level configuration at runtime -// @ts-ignore window.OIDCLog = Log; const hackAuthorityKey = 'oidc.hack.authority'; @@ -69,9 +74,8 @@ function reload() { function reloadTimerOnExpiresIn(user: User, userManager: UserManager, expiresIn: number) { // Not allowed by TS because expires_in is supposed to be readonly - // @ts-ignore - // eslint-disable-next-line no-param-reassign - user.expires_in = expiresIn; + // @ts-expect-error TS2540: Cannot assign to expires_in because it is a read-only property. + user.expires_in = expiresIn; // eslint-disable-line no-param-reassign userManager.storeUser(user).then(() => { userManager.getUser(); }); diff --git a/src/components/authentication/utils/userManagerMock.ts b/src/components/authentication/utils/userManagerMock.ts index 47531a41..121d82ca 100644 --- a/src/components/authentication/utils/userManagerMock.ts +++ b/src/components/authentication/utils/userManagerMock.ts @@ -8,33 +8,38 @@ /* eslint-disable max-classes-per-file, class-methods-use-this */ import { - MetadataService, - SigninRequest, - SigninResponse, - SignoutRequest, - SignoutResponse, - User, + type MetadataService, + type OidcClientSettings, + type Profile, + type SessionStatus, + type SigninRequest, + type SigninResponse, + type SignoutRequest, + type SignoutResponse, + type User, UserManager, UserManagerEvents, - UserManagerSettings, + type UserManagerSettings, } from 'oidc-client'; class Events implements UserManagerEvents { - userLoadedCallbacks: ((data: User) => void)[] = []; + public userLoadedCallbacks: UserManagerEvents.UserLoadedCallback[] = []; - addUserLoaded(callback: (data: User) => void) { - this.userLoadedCallbacks.push(callback); - } + load() {} - addSilentRenewError() { - // Nothing to do - } + unload() {} - load(/* container: User */) { - // not implemented - } + addAccessTokenExpiring() {} - unload() {} + removeAccessTokenExpiring() {} + + addAccessTokenExpired() {} + + removeAccessTokenExpired() {} + + addUserLoaded(callback: UserManagerEvents.UserLoadedCallback) { + this.userLoadedCallbacks.push(callback); + } removeUserLoaded() {} @@ -42,6 +47,8 @@ class Events implements UserManagerEvents { removeUserUnloaded() {} + addSilentRenewError() {} + removeSilentRenewError() {} addUserSignedIn() {} @@ -55,23 +62,15 @@ class Events implements UserManagerEvents { addUserSessionChanged() {} removeUserSessionChanged() {} - - addAccessTokenExpiring() {} - - removeAccessTokenExpiring() {} - - addAccessTokenExpired() {} - - removeAccessTokenExpired() {} } export class UserManagerMock implements UserManager { - settings; + events: Events; - events; + readonly settings: OidcClientSettings; - user: User = { - profile: { + private static readonly user = Object.freeze({ + profile: Object.freeze({ name: 'John Doe', email: 'Jhon.Doe@rte-france.com', iss: '', @@ -79,7 +78,7 @@ export class UserManagerMock implements UserManager { aud: '', exp: Number.MAX_SAFE_INTEGER, iat: 0, - }, + }), id_token: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IllNRUxIVDBndmIwbXhvU0RvWWZvbWpxZmpZVSJ9.eyJhdWQiOiI5YzQwMjQ2MS1iMmFiLTQ3NjctOWRiMy02Njg1OWJiMGZjZDAiLCJpc3MiOiJodHRwczovL2' + 'xvZ2luLm1pY3Jvc29mdG9ubGluZS5jb20vNzUwMmRhZDUtZDY0Yy00NmM3LTlkNDctYjE2ZjU4MGZjZmE5L3YyLjAiLCJpYXQiOjE1ODUzMzEyNDksIm5iZiI6MTU4NTMzMTI0OSwiZXhwIjoyNTg1MzM1MTQ5LCJhaW8iOiJBV1FB' + @@ -110,132 +109,123 @@ export class UserManagerMock implements UserManager { expired: false, state: null, toStorageString: () => 'Mock of UserManager', - }; + }); + + readonly metadataService = null as unknown as MetadataService; - readonly metadataService: MetadataService = null as unknown as MetadataService; + private static readonly STORAGE_KEY = 'powsybl-gridsuite-mock-user'; constructor(settings: UserManagerSettings) { this.settings = settings; this.events = new Events(); } - // eslint-disable-next-line class-methods-use-this - getUser() { - return Promise.resolve(JSON.parse(sessionStorage.getItem('powsybl-gridsuite-mock-user') ?? 'null')); + async getUser() { + return JSON.parse(sessionStorage.getItem(UserManagerMock.STORAGE_KEY) ?? 'null') as User | null; } - async signinSilent(): Promise { + async signinSilent() { console.info('signinSilent..............'); - const localStorageUser = JSON.parse(localStorage.getItem('powsybl-gridsuite-mock-user') ?? 'null'); + const localStorageUser = JSON.parse(localStorage.getItem(UserManagerMock.STORAGE_KEY) ?? 'null') as User | null; if (localStorageUser === null) { throw new Error('End-User authentication required'); } - sessionStorage.setItem('powsybl-gridsuite-mock-user', JSON.stringify(localStorageUser)); + sessionStorage.setItem(UserManagerMock.STORAGE_KEY, JSON.stringify(localStorageUser)); this.events.userLoadedCallbacks.forEach((c) => c(localStorageUser)); return localStorageUser; } - // eslint-disable-next-line class-methods-use-this signinSilentCallback() { console.error('Unsupported, iframe signinSilentCallback in UserManagerMock (dev mode)'); return Promise.reject(); } - signinRedirect() { - localStorage.setItem('powsybl-gridsuite-mock-user', JSON.stringify(this.user)); + async signinRedirect() { + localStorage.setItem(UserManagerMock.STORAGE_KEY, JSON.stringify(UserManagerMock.user)); window.location.href = './sign-in-callback'; - return Promise.resolve(); } - // eslint-disable-next-line class-methods-use-this - signoutRedirect() { - sessionStorage.removeItem('powsybl-gridsuite-mock-user'); - localStorage.removeItem('powsybl-gridsuite-mock-user'); + async signoutRedirect() { + sessionStorage.removeItem(UserManagerMock.STORAGE_KEY); + localStorage.removeItem(UserManagerMock.STORAGE_KEY); window.location.href = '.'; - return Promise.resolve(); } - signinRedirectCallback() { - sessionStorage.setItem('powsybl-gridsuite-mock-user', JSON.stringify(this.user)); - this.events.userLoadedCallbacks.forEach((c) => c(this.user)); - return Promise.resolve(this.user); + async signinRedirectCallback() { + sessionStorage.setItem(UserManagerMock.STORAGE_KEY, JSON.stringify(UserManagerMock.user)); + this.events.userLoadedCallbacks.forEach((c) => c(UserManagerMock.user)); + return UserManagerMock.user; } - clearStaleState() { - return Promise.resolve(); + async clearStaleState() { + // do nothing (@typescript-eslint/no-empty-function). } - storeUser() { - return Promise.resolve(); + async storeUser() { + // do nothing (@typescript-eslint/no-empty-function). } - removeUser() { - return Promise.resolve(); + async removeUser() { + // do nothing (@typescript-eslint/no-empty-function). } - signinPopup() { - return Promise.resolve(this.user); + async signinPopup() { + return UserManagerMock.user; } - signinPopupCallback() { - return Promise.resolve(undefined); + async signinPopupCallback() { + return undefined; } - signoutRedirectCallback() { - return Promise.resolve({} as SignoutResponse); + async signoutRedirectCallback() { + return {} as SignoutResponse; } - signoutPopup() { - return Promise.resolve(); + async signoutPopup() { + // do nothing (@typescript-eslint/no-empty-function). } - signoutPopupCallback() { - return Promise.resolve(); + async signoutPopupCallback() { + // do nothing (@typescript-eslint/no-empty-function). } - signinCallback() { - return Promise.resolve(this.user); + async signinCallback() { + return UserManagerMock.user; } - signoutCallback() { - return Promise.resolve(undefined); + async signoutCallback() { + return undefined; } - querySessionStatus() { - return Promise.resolve({ + async querySessionStatus() { + return { session_state: '', sub: '', sid: undefined, - }); + } satisfies SessionStatus; } - revokeAccessToken() { - return Promise.resolve(); + async revokeAccessToken() { + // do nothing (@typescript-eslint/no-empty-function). } - startSilentRenew() { - return Promise.resolve(); - } + startSilentRenew() {} - stopSilentRenew() { - return Promise.resolve(); - } + stopSilentRenew() {} - createSigninRequest() { - return Promise.resolve({} as SigninRequest); + async createSigninRequest() { + return {} as SigninRequest; } - processSigninResponse() { - return Promise.resolve({} as SigninResponse); + async processSigninResponse() { + return {} as SigninResponse; } - createSignoutRequest() { - return Promise.resolve({} as SignoutRequest); + async createSignoutRequest() { + return {} as SignoutRequest; } - processSignoutResponse() { - return Promise.resolve({} as SignoutResponse); + async processSignoutResponse() { + return {} as SignoutResponse; } } - -export default UserManagerMock; diff --git a/src/components/cardErrorBoundary/CardErrorBoundary.tsx b/src/components/cardErrorBoundary/CardErrorBoundary.tsx index 9684573d..41143563 100644 --- a/src/components/cardErrorBoundary/CardErrorBoundary.tsx +++ b/src/components/cardErrorBoundary/CardErrorBoundary.tsx @@ -18,12 +18,12 @@ import { CardHeader, Collapse, IconButton, - IconButtonProps, + type IconButtonProps, + styled, Theme, Typography, - styled, } from '@mui/material'; -import { Component, ErrorInfo, ReactNode } from 'react'; +import { Component, type ErrorInfo, type PropsWithChildren } from 'react'; import { FormattedMessage } from 'react-intl'; export interface ExpandMoreProps extends IconButtonProps { @@ -43,10 +43,6 @@ const ExpandMore = styled((props: ExpandMoreProps) => { // Extracted from https://react-typescript-cheatsheet.netlify.app/docs/basic/getting-started/error_boundaries/ for types -interface Props { - children?: ReactNode; -} - type CardErrorBoundaryStateError = { hasError: true; error: Error; @@ -60,8 +56,8 @@ type CardErrorBoundaryState = (CardErrorBoundaryStateError | CardErrorBoundarySt expanded: boolean; }; -export class CardErrorBoundary extends Component { - constructor(props: Props) { +export class CardErrorBoundary extends Component, CardErrorBoundaryState> { + constructor(props: PropsWithChildren<{}>) { super(props); this.state = { hasError: false, @@ -76,18 +72,16 @@ export class CardErrorBoundary extends Component return { hasError: true, error }; } - componentDidCatch(error: Error, errorInfo: ErrorInfo) { + override componentDidCatch(error: Error, errorInfo: ErrorInfo) { // You can also log the error to an error reporting service console.error('CardErrorBoundary caught: ', error, errorInfo); } - handleExpandClick() { - this.setState((state: CardErrorBoundaryState) => ({ - expanded: !state.expanded, - })); + private handleExpandClick() { + this.setState((state: CardErrorBoundaryState) => ({ expanded: !state.expanded })); } - handleReloadClick() { + private handleReloadClick() { this.setState(() => ({ hasError: false, expanded: false, @@ -95,7 +89,7 @@ export class CardErrorBoundary extends Component })); } - render() { + override render() { const { hasError } = this.state; const { children } = this.props; if (hasError) { diff --git a/src/components/flatParameters/FlatParameters.tsx b/src/components/flatParameters/FlatParameters.tsx index 9a3b84af..a8e5284f 100644 --- a/src/components/flatParameters/FlatParameters.tsx +++ b/src/components/flatParameters/FlatParameters.tsx @@ -262,6 +262,7 @@ export function FlatParameters({ const renderField = (param: Parameter) => { const fieldValue = mixInitAndDefault(param); + // eslint-disable-next-line default-case switch (param.type) { case 'BOOLEAN': return onFieldChange(e.target.checked, param)} />; @@ -381,8 +382,6 @@ export function FlatParameters({ renderInput={(inputProps) => } /> ); - - // @ts-ignore fallthrough is the expected behavior case 'STRING': if (param.possibleValues) { return ( @@ -404,20 +403,19 @@ export function FlatParameters({ ); } - // else fallthrough to default - default: - return ( - onUncommitted(param, true)} - onBlur={() => onUncommitted(param, false)} - onChange={(e) => onFieldChange(e.target.value, param)} - variant={variant} - /> - ); + // else continu/fallthrough to default } + return ( + onUncommitted(param, true)} + onBlur={() => onUncommitted(param, false)} + onChange={(e) => onFieldChange(e.target.value, param)} + variant={variant} + /> + ); }; return ( diff --git a/src/components/inputs/reactHookForm/DirectoryItemsInput.tsx b/src/components/inputs/reactHookForm/DirectoryItemsInput.tsx index 8054678f..b4a39444 100644 --- a/src/components/inputs/reactHookForm/DirectoryItemsInput.tsx +++ b/src/components/inputs/reactHookForm/DirectoryItemsInput.tsx @@ -170,7 +170,7 @@ export function DirectoryItemsInput({ ; + let container: Element; declare global { @@ -65,9 +67,8 @@ describe('NotificationsProvider', () => { return

empty

; } - const reconnectingWebSocketClass = {}; - // @ts-ignore - ReconnectingWebSocket.mockImplementation(() => reconnectingWebSocketClass); + const reconnectingWebSocketClass = {} as jest.Mocked; + MockedReconnectingWebSocket.mockImplementation(() => reconnectingWebSocketClass); act(() => { root.render( @@ -76,10 +77,9 @@ describe('NotificationsProvider', () => { ); }); - const event = { test: 'test' }; + const event = { data: 'test' } as MessageEvent; act(() => { - // @ts-ignore - reconnectingWebSocketClass.onmessage(event); + reconnectingWebSocketClass.onmessage?.(event); }); waitFor(() => expect(eventCallback).toBeCalledWith(event)); @@ -94,9 +94,8 @@ describe('NotificationsProvider', () => { return

empty

; } - const reconnectingWebSocketClass = {}; - // @ts-ignore - ReconnectingWebSocket.mockImplementation(() => reconnectingWebSocketClass); + const reconnectingWebSocketClass = {} as jest.Mocked; + MockedReconnectingWebSocket.mockImplementation(() => reconnectingWebSocketClass); act(() => { root.render( @@ -106,8 +105,7 @@ describe('NotificationsProvider', () => { ); }); act(() => { - // @ts-ignore - reconnectingWebSocketClass.onmessage({ test: 'test' }); + reconnectingWebSocketClass.onmessage?.({ data: 'test' } as MessageEvent); }); expect(eventCallback).not.toBeCalled(); @@ -119,15 +117,14 @@ describe('NotificationsProvider', () => { const onOpenCallback = jest.fn(); const reconnectingWebSocketClass = { onopen: onOpenCallback, - }; + } as Partial as jest.Mocked; const eventCallback = jest.fn(); function NotificationsConsumer() { useNotificationsListener('Fake_Key', { listenerCallbackOnReopen: eventCallback }); return

empty

; } - // @ts-ignore - ReconnectingWebSocket.mockImplementation(() => reconnectingWebSocketClass); + MockedReconnectingWebSocket.mockImplementation(() => reconnectingWebSocketClass); act(() => { root.render( diff --git a/src/components/topBar/TopBar.tsx b/src/components/topBar/TopBar.tsx index 2ab7c8ad..479435ab 100644 --- a/src/components/topBar/TopBar.tsx +++ b/src/components/topBar/TopBar.tsx @@ -7,7 +7,6 @@ import { MouseEvent, PropsWithChildren, ReactNode, useMemo, useState } from 'react'; import { FormattedMessage } from 'react-intl'; - import { AppBar, Box, @@ -33,18 +32,18 @@ import { Apps as AppsIcon, ArrowDropDown as ArrowDropDownIcon, ArrowDropUp as ArrowDropUpIcon, + Badge as BadgeIcon, Brightness3 as Brightness3Icon, Computer as ComputerIcon, ExitToApp as ExitToAppIcon, HelpOutline as HelpOutlineIcon, - Person as PersonIcon, ManageAccounts, + Person as PersonIcon, WbSunny as WbSunnyIcon, - Badge as BadgeIcon, } from '@mui/icons-material'; import { styled } from '@mui/system'; -import { User } from 'oidc-client'; +import type { User } from 'oidc-client'; import { GridLogo, GridLogoProps } from './GridLogo'; import { AboutDialog, AboutDialogProps } from './AboutDialog'; import { LogoutProps } from '../authentication/Logout'; @@ -156,13 +155,18 @@ const CustomListItemIcon = styled(ListItemIcon)({ borderRadius: '25px', }); -const EN = 'EN'; -const FR = 'FR'; - export type GsLangUser = typeof LANG_ENGLISH | typeof LANG_FRENCH; export type GsLang = GsLangUser | typeof LANG_SYSTEM; export type GsTheme = typeof LIGHT_THEME | typeof DARK_THEME; +function abbreviationFromUserName(name: string) { + const tab = name.split(' ').map((x) => x.charAt(0)); + if (tab.length === 1) { + return tab[0]; + } + return tab[0] + tab[tab.length - 1]; +} + export type TopBarProps = Omit & Omit & Omit & { @@ -236,14 +240,6 @@ export function TopBar({ } }; - const abbreviationFromUserName = (name: string) => { - const tab = name.split(' ').map((x) => x.charAt(0)); - if (tab.length === 1) { - return tab[0]; - } - return tab[0] + tab[tab.length - 1]; - }; - const changeTheme = (_: MouseEvent, value: GsTheme) => { if (onThemeClick && value !== null) { onThemeClick(value); @@ -264,8 +260,7 @@ export function TopBar({ const [isAboutDialogOpen, setAboutDialogOpen] = useState(false); const onAboutClicked = () => { - // @ts-ignore should be an Element, or maybe we should use null ? - setAnchorElSettingsMenu(false); + setAnchorElSettingsMenu(null); if (onAboutClick) { onAboutClick(); } else { @@ -292,7 +287,7 @@ export function TopBar({ ); return ( - // @ts-ignore appBar style is not defined + // @ts-expect-error appBar style is not defined {user && developerMode && ( @@ -369,12 +364,7 @@ export function TopBar({ style={anchorElSettingsMenu ? { cursor: 'initial' } : { cursor: 'pointer' }} > - {user !== null - ? abbreviationFromUserName( - // @ts-ignore name could be undefined, how to handle this case ? - user.profile.name - ) - : ''} + {user.profile.name !== undefined ? abbreviationFromUserName(user.profile.name) : ''} {anchorElSettingsMenu ? ( @@ -573,14 +563,14 @@ export function TopBar({ aria-label={LANG_ENGLISH} sx={styles.languageToggleButton} > - {EN} + EN - {FR} + FR diff --git a/src/components/topBar/UserInformationDialog.tsx b/src/components/topBar/UserInformationDialog.tsx index 91cfcf97..ece8e948 100644 --- a/src/components/topBar/UserInformationDialog.tsx +++ b/src/components/topBar/UserInformationDialog.tsx @@ -8,7 +8,7 @@ import { Dialog, DialogActions, DialogContent, DialogTitle, Grid, Typography } from '@mui/material'; import { Box } from '@mui/system'; import { FormattedMessage } from 'react-intl'; -import { User } from 'oidc-client'; +import type { User } from 'oidc-client'; import { useEffect, useState } from 'react'; import { CancelButton } from '../inputs/reactHookForm/utils/CancelButton'; import fetchUserDetails from '../../services/userAdmin'; diff --git a/src/hooks/useLocalizedCountries.ts b/src/hooks/useLocalizedCountries.ts index 0ee8b5ad..bf644538 100644 --- a/src/hooks/useLocalizedCountries.ts +++ b/src/hooks/useLocalizedCountries.ts @@ -7,9 +7,7 @@ import { useCallback, useEffect, useMemo, useState } from 'react'; import localizedCountries, { LocalizedCountries } from 'localized-countries'; -// @ts-ignore import countriesFr from 'localized-countries/data/fr'; -// @ts-ignore import countriesEn from 'localized-countries/data/en'; import { LANG_ENGLISH, LANG_FRENCH, LANG_SYSTEM } from '../utils/constants/browserConstants'; diff --git a/src/module-localized-countries.d.ts b/src/module-localized-countries.d.ts new file mode 100644 index 00000000..6f541a96 --- /dev/null +++ b/src/module-localized-countries.d.ts @@ -0,0 +1,16 @@ +/* + * Copyright © 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/. + */ + +declare module 'localized-countries/data/en' { + const countries: Readonly; + export default countries; +} + +declare module 'localized-countries/data/fr' { + const countries: Readonly; + export default countries; +} diff --git a/src/redux/actions/authActions.ts b/src/redux/actions/authActions.ts index 298cf5bd..de44bbcd 100644 --- a/src/redux/actions/authActions.ts +++ b/src/redux/actions/authActions.ts @@ -4,7 +4,7 @@ * 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 { User } from 'oidc-client'; +import type { User } from 'oidc-client'; // Is redux or isn't redux, that is the question, 🎭 export interface Action { diff --git a/src/redux/commonStore.ts b/src/redux/commonStore.ts index d9a53c09..efc402bc 100644 --- a/src/redux/commonStore.ts +++ b/src/redux/commonStore.ts @@ -5,7 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { User } from 'oidc-client'; +import type { User } from 'oidc-client'; export type CommonStoreState = { user: User | null; diff --git a/src/tests/testsUtils.test.tsx b/src/tests/testsUtils.test.tsx index 04aab50b..e007c0f8 100644 --- a/src/tests/testsUtils.test.tsx +++ b/src/tests/testsUtils.test.tsx @@ -6,27 +6,27 @@ */ import { render as rtlRender } from '@testing-library/react'; -import { createTheme, ThemeProvider } from '@mui/material/styles'; +import { type ReactElement } from 'react'; +import { createTheme, type Theme, ThemeProvider } from '@mui/material'; import { IntlProvider } from 'react-intl'; -import { Theme } from '@mui/system'; import { - loginEn, - reportViewerEn, - topBarEn, - tableEn, - treeviewFinderEn, + cardErrorBoundaryEn, + commonButtonEn, + csvEn, + descriptionEn, + directoryItemsInputEn, elementSearchEn, equipmentSearchEn, + equipmentsEn, filterEn, filterExpertEn, - descriptionEn, - equipmentsEn, - csvEn, - cardErrorBoundaryEn, flatParametersEn, + loginEn, multipleSelectionDialogEn, - commonButtonEn, - directoryItemsInputEn, + reportViewerEn, + tableEn, + topBarEn, + treeviewFinderEn, } from '../translations/en'; const fullTrad = { @@ -48,11 +48,13 @@ const fullTrad = { ...commonButtonEn, ...directoryItemsInputEn, }; -const renderWithTranslation = (ui: React.ReactElement, trad: Record = fullTrad) => ( - - {ui} - -); +function renderWithTranslation(ui: ReactElement, trad: Record) { + return ( + + {ui} + + ); +} const lightTheme = createTheme( { @@ -85,19 +87,18 @@ const lightTheme = createTheme( }, } ); -const renderWithTheme = (ui: React.ReactElement, theme: Theme = lightTheme) => ( - {ui} -); +function renderWithTheme(ui: ReactElement, theme: Theme) { + return {ui}; +} -// eslint-disable-next-line import/prefer-default-export export class RenderBuilder { - renderWithTheme: boolean = false; + private renderWithTheme = false; - theme: Theme = lightTheme; + private theme = lightTheme; - renderWithTrad: boolean = false; + private renderWithTrad = false; - trad: Record = fullTrad; + private trad: Record = fullTrad; withTrad(trad?: Record) { this.renderWithTrad = true; @@ -115,7 +116,7 @@ export class RenderBuilder { return this; } - render(ui: React.ReactElement) { + render(ui: ReactElement) { let newUi = this.renderWithTrad ? renderWithTranslation(ui, this.trad) : ui; newUi = this.renderWithTheme ? renderWithTheme(newUi, this.theme) : newUi; return rtlRender(newUi);