Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update commons UI #39

Merged
merged 14 commits into from
Jul 10, 2024
212 changes: 180 additions & 32 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"dependencies": {
"@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.5",
"@gridsuite/commons-ui": "0.53.0",
"@gridsuite/commons-ui": "0.61.4",
"@hookform/resolvers": "^3.3.4",
"@mui/icons-material": "^5.15.14",
"@mui/lab": "5.0.0-alpha.169",
Expand Down Expand Up @@ -85,8 +85,8 @@
"jest-environment-jsdom": "^29.7.0",
"jest-svg-transformer": "^1.0.0",
"prettier": "^2.8.8",
"typescript": "5.1.6",
"ts-node": "^10.9.2",
"typescript": "5.1.6",
"vite": "^5.2.7",
"vite-plugin-eslint": "^1.8.1",
"vite-plugin-svgr": "^4.2.0",
Expand Down
9 changes: 6 additions & 3 deletions src/components/App/app-top-bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import GridAdminLogoDark from '../../images/GridAdmin_logo_dark.svg?react';
import AppPackage from '../../../package.json';
import { AppState } from '../../redux/reducer';
import { MainPaths } from '../../routes';
import { AppDispatch } from '../../redux/store';

const tabs = new Map<MainPaths, ReactElement>([
[
Expand Down Expand Up @@ -65,7 +66,7 @@ const tabs = new Map<MainPaths, ReactElement>([

const AppTopBar: FunctionComponent = () => {
const theme = useTheme();
const dispatch = useDispatch();
const dispatch = useDispatch<AppDispatch>();
const user = useSelector((state: AppState) => state.user);
const userManagerInstance = useSelector(
(state: AppState) => state.userManager?.instance
Expand Down Expand Up @@ -110,10 +111,12 @@ const AppTopBar: FunctionComponent = () => {
appLicense={AppPackage.license}
onLogoutClick={() => logout(dispatch, userManagerInstance)}
onLogoClick={() => navigate('/', { replace: true })}
user={user}
user={user ?? undefined}
appsAndUrls={appsAndUrls}
globalVersionPromise={() =>
AppsMetadataSrv.fetchVersion().then((res) => res?.deployVersion)
AppsMetadataSrv.fetchVersion().then(
(res) => res?.deployVersion ?? 'unknown'
)
}
additionalModulesPromise={StudySrv.getServersInfos}
onThemeClick={handleChangeTheme}
Expand Down
7 changes: 4 additions & 3 deletions src/components/App/app-wrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import {
card_error_boundary_en,
card_error_boundary_fr,
CardErrorBoundary,
GsLangUser,
GsTheme,
LANG_ENGLISH,
LANG_FRENCH,
LIGHT_THEME,
Expand All @@ -30,7 +32,6 @@ import {
} from '@gridsuite/commons-ui';
import { IntlProvider } from 'react-intl';
import { Provider, useSelector } from 'react-redux';
import { SupportedLanguages } from '../../utils/language';
import messages_en from '../../translations/en.json';
import messages_fr from '../../translations/fr.json';
import { store } from '../../redux/store';
Expand Down Expand Up @@ -91,7 +92,7 @@ const darkTheme: ThemeOptions = {
agGridTheme: 'ag-theme-alpine-dark',
};

const getMuiTheme = (theme: unknown, locale: SupportedLanguages): Theme => {
const getMuiTheme = (theme: GsTheme, locale: GsLangUser): Theme => {
return responsiveFontSizes(
createTheme(
theme === LIGHT_THEME ? lightTheme : darkTheme,
Expand All @@ -100,7 +101,7 @@ const getMuiTheme = (theme: unknown, locale: SupportedLanguages): Theme => {
);
};

const messages: Record<SupportedLanguages, IntlConfig['messages']> = {
const messages: Record<GsLangUser, IntlConfig['messages']> = {
en: {
...messages_en,
...login_en,
Expand Down
3 changes: 2 additions & 1 deletion src/components/App/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,12 @@ import { getComputedLanguage } from '../../utils/language';
import AppTopBar from './app-top-bar';
import ReconnectingWebSocket from 'reconnecting-websocket';
import { useDebugRender } from '../../utils/hooks';
import { AppDispatch } from '../../redux/store';

const App: FunctionComponent<PropsWithChildren<{}>> = (props, context) => {
useDebugRender('app');
const { snackError } = useSnackMessage();
const dispatch = useDispatch();
const dispatch = useDispatch<AppDispatch>();
const user = useSelector((state: AppState) => state.user);

const updateParams = useCallback(
Expand Down
6 changes: 6 additions & 0 deletions src/module-mui.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,9 @@ declare module '@mui/material/styles/createTheme' {
extends MuiThemeOptions,
Partial<ThemeExtension> {}
}

declare module '@mui/utils/capitalize' {
export default function capitalize<S extends string>(
string: S
): Capitalize<S>;
}
10 changes: 1 addition & 9 deletions src/pages/profiles/modification/parameter-selection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,7 @@ import { Grid, IconButton, Tooltip } from '@mui/material';
import { useIntl } from 'react-intl';
import { DirectoryItemSelector, ElementType } from '@gridsuite/commons-ui';
import { useController, useWatch } from 'react-hook-form';
import {
fetchDirectoryContent,
fetchPath,
fetchRootFolders,
} from 'services/directory';
import { fetchElementsInfos } from 'services/explore';
import { fetchPath } from 'services/directory';
import LinkedPathDisplay from './linked-path-display';

export interface ParameterSelectionProps {
Expand Down Expand Up @@ -140,9 +135,6 @@ const ParameterSelection: FunctionComponent<ParameterSelectionProps> = (
contentText={intl.formatMessage({
id: 'profiles.form.modification.parameterSelection.dialog.message',
})}
fetchDirectoryContent={fetchDirectoryContent}
fetchRootFolders={fetchRootFolders}
fetchElementsInfos={fetchElementsInfos}
/>
</Grid>
);
Expand Down
13 changes: 10 additions & 3 deletions src/redux/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,24 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

import { GsTheme, UserManagerState } from '@gridsuite/commons-ui';
import { PARAM_LANGUAGE } from '../utils/config-params';
import { Action } from 'redux';
import { AppState } from './reducer';
import { UserManagerState } from '../routes';

export const UPDATE_USER_MANAGER_STATE = 'UPDATE_USER_MANAGER_STATE';
export type UserManagerAction = Readonly<
Action<typeof UPDATE_USER_MANAGER_STATE>
> & {
userManager: UserManagerState;
};

export function updateUserManager(
userManager: UserManagerState
): UserManagerAction {
return { type: UPDATE_USER_MANAGER_STATE, userManager };
}

export function updateUserManagerDestructured(
instance: UserManagerState['instance'],
error: UserManagerState['error']
Expand All @@ -32,6 +34,7 @@ export const UPDATE_USER_MANAGER_INSTANCE = 'UPDATE_USER_MANAGER_INSTANCE';
export type UserManagerInstanceAction = Readonly<
Action<typeof UPDATE_USER_MANAGER_INSTANCE>
> & { instance: UserManagerState['instance'] };

export function updateUserManagerInstance(
instance: UserManagerState['instance']
): UserManagerInstanceAction {
Expand All @@ -42,6 +45,7 @@ export const UPDATE_USER_MANAGER_ERROR = 'UPDATE_USER_MANAGER_ERROR';
export type UserManagerErrorAction = Readonly<
Action<typeof UPDATE_USER_MANAGER_ERROR>
> & { error: UserManagerState['error'] };

export function updateUserManagerError(
error: UserManagerState['error']
): UserManagerErrorAction {
Expand All @@ -50,16 +54,18 @@ export function updateUserManagerError(

export const SELECT_THEME = 'SELECT_THEME';
export type ThemeAction = Readonly<Action<typeof SELECT_THEME>> & {
theme: string;
theme: GsTheme;
};
export function selectTheme(theme: string): ThemeAction {

export function selectTheme(theme: GsTheme): ThemeAction {
return { type: SELECT_THEME, theme: theme };
}

export const SELECT_LANGUAGE = 'SELECT_LANGUAGE';
export type LanguageAction = Readonly<Action<typeof SELECT_LANGUAGE>> & {
[PARAM_LANGUAGE]: AppState['language'];
};

export function selectLanguage(language: AppState['language']): LanguageAction {
return { type: SELECT_LANGUAGE, [PARAM_LANGUAGE]: language };
}
Expand All @@ -70,6 +76,7 @@ export type ComputedLanguageAction = Readonly<
> & {
computedLanguage: AppState['computedLanguage'];
};

export function selectComputedLanguage(
computedLanguage: AppState['computedLanguage']
): ComputedLanguageAction {
Expand Down
27 changes: 18 additions & 9 deletions src/redux/local-storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,39 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

import { DARK_THEME, LANG_SYSTEM } from '@gridsuite/commons-ui';
import {
DARK_THEME,
GsLang,
GsTheme,
LANG_SYSTEM,
} from '@gridsuite/commons-ui';
import { getComputedLanguage } from '../utils/language';
import { APP_NAME } from '../utils/config-params';
import { AppState } from './reducer';

const LOCAL_STORAGE_THEME_KEY = (APP_NAME + '_THEME').toUpperCase();
const LOCAL_STORAGE_LANGUAGE_KEY = (APP_NAME + '_LANGUAGE').toUpperCase();

export function getLocalStorageTheme(): string {
return localStorage.getItem(LOCAL_STORAGE_THEME_KEY) || DARK_THEME;
export function getLocalStorageTheme() {
return (
(localStorage.getItem(LOCAL_STORAGE_THEME_KEY) as GsTheme) || DARK_THEME
);
}

export function saveLocalStorageTheme(theme: string): void {
export function saveLocalStorageTheme(theme: GsTheme): void {
localStorage.setItem(LOCAL_STORAGE_THEME_KEY, theme);
}

export function getLocalStorageLanguage(): AppState['language'] {
return localStorage.getItem(LOCAL_STORAGE_LANGUAGE_KEY) || LANG_SYSTEM;
export function getLocalStorageLanguage() {
return (
(localStorage.getItem(LOCAL_STORAGE_LANGUAGE_KEY) as GsLang) ||
LANG_SYSTEM
);
}

export function saveLocalStorageLanguage(language: AppState['language']): void {
export function saveLocalStorageLanguage(language: GsLang): void {
localStorage.setItem(LOCAL_STORAGE_LANGUAGE_KEY, language);
}

export function getLocalStorageComputedLanguage(): AppState['computedLanguage'] {
export function getLocalStorageComputedLanguage() {
return getComputedLanguage(getLocalStorageLanguage());
}
56 changes: 35 additions & 21 deletions src/redux/reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

import { AnyAction, createReducer, Draft } from '@reduxjs/toolkit';

import { createReducer, Draft } from '@reduxjs/toolkit';
import {
getLocalStorageComputedLanguage,
getLocalStorageLanguage,
Expand All @@ -27,31 +26,40 @@ import {
UserManagerErrorAction,
UserManagerInstanceAction,
} from './actions';

import {
AuthenticationActions,
AuthenticationRouterErrorAction,
AuthenticationRouterErrorState,
CommonStoreState,
GsLang,
GsLangUser,
GsTheme,
LOGOUT_ERROR,
LogoutErrorAction,
RESET_AUTHENTICATION_ROUTER_ERROR,
SHOW_AUTH_INFO_LOGIN,
ShowAuthenticationRouterLoginAction,
SIGNIN_CALLBACK_ERROR,
SignInCallbackErrorAction,
UNAUTHORIZED_USER_INFO,
UnauthorizedUserAction,
USER,
USER_VALIDATION_ERROR,
UserAction,
UserManagerState,
UserValidationErrorAction,
} from '@gridsuite/commons-ui';
import { PARAM_LANGUAGE, PARAM_THEME } from '../utils/config-params';
import { ReducerWithInitialState } from '@reduxjs/toolkit/dist/createReducer';
import { LanguageParameters, SupportedLanguages } from '../utils/language';
import { User } from '../utils/auth';
import { UserManagerState } from '../routes';

export type AppState = {
computedLanguage: SupportedLanguages;
[PARAM_THEME]: string;
[PARAM_LANGUAGE]: LanguageParameters;
export type AppState = CommonStoreState & {
computedLanguage: GsLangUser;
[PARAM_THEME]: GsTheme;
[PARAM_LANGUAGE]: GsLang;

userManager: UserManagerState;
user: User | null; //TODO delete when migrated into commons-ui
signInCallbackError: unknown;
authenticationRouterError: unknown;
signInCallbackError: Error | null;
authenticationRouterError: AuthenticationRouterErrorState | null;
showAuthenticationRouterLogin: boolean;
};

Expand All @@ -73,7 +81,7 @@ const initialState: AppState = {
};

export type Actions =
| AnyAction
| AuthenticationActions
| UserManagerAction
| UserManagerInstanceAction
| UserManagerErrorAction
Expand Down Expand Up @@ -115,51 +123,57 @@ export const reducer: ReducerWithInitialState<AppState> = createReducer(
}
);

builder.addCase(USER, (state: Draft<AppState>, action: AnyAction) => {
builder.addCase(USER, (state: Draft<AppState>, action: UserAction) => {
state.user = action.user;
});

builder.addCase(
SIGNIN_CALLBACK_ERROR,
(state: Draft<AppState>, action: AnyAction) => {
(state: Draft<AppState>, action: SignInCallbackErrorAction) => {
state.signInCallbackError = action.signInCallbackError;
}
);

builder.addCase(
UNAUTHORIZED_USER_INFO,
(state: Draft<AppState>, action: AnyAction) => {
(state: Draft<AppState>, action: UnauthorizedUserAction) => {
state.authenticationRouterError =
action.authenticationRouterError;
}
);

builder.addCase(
LOGOUT_ERROR,
(state: Draft<AppState>, action: AnyAction) => {
(state: Draft<AppState>, action: LogoutErrorAction) => {
state.authenticationRouterError =
action.authenticationRouterError;
}
);

builder.addCase(
USER_VALIDATION_ERROR,
(state: Draft<AppState>, action: AnyAction) => {
(state: Draft<AppState>, action: UserValidationErrorAction) => {
state.authenticationRouterError =
action.authenticationRouterError;
}
);

builder.addCase(
RESET_AUTHENTICATION_ROUTER_ERROR,
(state: Draft<AppState>, action: AnyAction) => {
(
state: Draft<AppState>,
action: AuthenticationRouterErrorAction
) => {
state.authenticationRouterError = null;
}
);

builder.addCase(
SHOW_AUTH_INFO_LOGIN,
(state: Draft<AppState>, action: AnyAction) => {
(
state: Draft<AppState>,
action: ShowAuthenticationRouterLoginAction
) => {
state.showAuthenticationRouterLogin =
action.showAuthenticationRouterLogin;
}
Expand Down
1 change: 1 addition & 0 deletions src/redux/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { createStore, Store } from 'redux';
import { Actions, AppState, reducer } from './reducer';

export const store: Store<AppState, Actions> = createStore(reducer);
export type AppDispatch = typeof store.dispatch;

// to avoid to reset the state with HMR
// https://redux.js.org/usage/configuring-your-store#hot-reloading
Expand Down
Loading
Loading