Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<!DOCTYPE html>
<html lang="en" translate="no">
<head>
<base href="./" />
<base href="/" />
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="google" content="notranslate" />
Expand Down
9,924 changes: 5,208 additions & 4,716 deletions package-lock.json

Large diffs are not rendered by default.

58 changes: 28 additions & 30 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,53 +8,46 @@
"npm": "^10.2.0"
},
"dependencies": {
"@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.5",
"@gridsuite/commons-ui": "0.67.0",
"@hookform/resolvers": "^3.3.4",
"@mui/icons-material": "^5.15.14",
"@mui/lab": "^5.0.0-alpha.169",
"@mui/material": "^5.15.14",
"@mui/x-tree-view": "^6.17.0",
"@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.1",
"@gridsuite/commons-ui": "0.181.0",
"@hookform/resolvers": "^5.2.2",
"@mui/icons-material": "^5.18.0",
"@mui/lab": "^5.0.0-alpha.175",
"@mui/material": "^5.18.0",
"@mui/x-tree-view": "^8.21.0",
"@reduxjs/toolkit": "^2.2.3",
"core-js": "^3.36.1",
"notistack": "^3.0.1",
"oidc-client": "^1.11.5",
"prop-types": "^15.8.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-hook-form": "^7.51.2",
"react-intl": "^6.6.4",
"react-redux": "^9.1.0",
"react-router-dom": "^6.22.3",
"react": "^19.2.0",
"react-dom": "^19.2.0",
"react-hook-form": "^7.62.0",
"react-intl": "^7.1.11",
"react-redux": "^9.2.0",
"react-window": "^1.8.10",
"reconnecting-websocket": "^4.4.0",
"redux": "^5.0.1",
"typeface-roboto": "^1.1.13",
"yup": "^1.4.0"
"yup": "^1.4.0",
"zod": "^4.3.6"
},
"scripts": {
"start": "vite",
"start:open": "vite --open",
"build": "vite build",
"serve": "vite preview",
"test": "jest",
"test:coverage": "jest --coverage",
"generate:api": "rtk-query-codegen-openapi openapi.codegen.js",
"test": "vitest",
"test:coverage": "vitest run --coverage",
"type-check": "tsc",
"prebuild": "npm run lint && npm run type-check",
"lint": "eslint . --max-warnings 0",
"lint:fix": "eslint . --fix",
"lint:format": "prettier --check --cache .",
"licenses-check": "license-checker --summary --excludePrivatePackages --production --onlyAllow \"$( jq -r .onlyAllow[] license-checker-config.json | tr '\n' ';')\" --excludePackages \"$( jq -r .excludePackages[] license-checker-config.json | tr '\n' ';')\""
},
"jest": {
"moduleNameMapper": {
"^.+\\.(css|less|scss)$": "identity-obj-proxy"
},
"transformIgnorePatterns": [
"node_modules/(?!@gridsuite/commons-ui|react-dnd|dnd-core|@react-dnd)"
]
},
"browserslist": {
"production": [
">0.2%",
Expand All @@ -68,24 +61,29 @@
]
},
"devDependencies": {
"@vitejs/plugin-react": "^5.0.0",
"@rtk-query/codegen-openapi": "^2.2.0",
"@testing-library/jest-dom": "^6.9.1",
"@testing-library/react": "^16.3.2",
"@testing-library/user-event": "^14.6.1",
"@types/core-js": "^2.5.8",
"@types/eslint-config-prettier": "^6.11.3",
"@types/jest": "^27.5.2",
"@types/license-checker": "^25.0.6",
"@types/node": "^20.19.0",
"@types/prop-types": "^15.7.12",
"@types/react": "^18.2.75",
"@types/react-dom": "^18.2.24",
"@types/react": "^19.2.2",
"@types/react-dom": "^19.2.1",
"@types/react-window": "^1.8.8",
"@vitejs/plugin-react": "^5.0.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^4.2.1",
"jest": "^30.1.3",
"license-checker": "^25.0.1",
"prettier": "^2.8.8",
"typescript": "5.1.6",
"typescript": "~5.9.3",
"vite": "^7.1.7",
"vite-plugin-svgr": "^4.3.0",
"vite-tsconfig-paths": "^5.1.4",
"vite-plugin-svgr": "^4.3.0"
"vitest": "^4.1.2"
}
}
2 changes: 1 addition & 1 deletion public/idpSettings.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"authority": "http://172.17.0.1:9090/",
"client_id": "my-client-2",
"client_id": "gridexplore-local",
"redirect_uri": "http://localhost:3000/sign-in-callback",
"post_logout_redirect_uri": "http://localhost:3000/logout-callback",
"silent_redirect_uri": "http://localhost:3000/silent-renew-callback",
Expand Down
2 changes: 1 addition & 1 deletion src/app/App.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { createRoot } from 'react-dom/client';
import { act } from 'react-dom/test-utils';
import { IntlProvider } from 'react-intl';
import { Provider } from 'react-redux';
import { BrowserRouter } from 'react-router-dom';
import { BrowserRouter } from 'react-router';
import App from './App';
import { store } from './store';
import { createTheme, StyledEngineProvider, ThemeProvider } from '@mui/material/styles';
Expand Down
44 changes: 18 additions & 26 deletions src/app/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import React, { FunctionComponent, useCallback, useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { useLocation, useMatch, useNavigate } from 'react-router-dom';
import { useLocation, useMatch, useNavigate } from 'react-router';
import {
AuthenticationRouter,
CardErrorBoundary,
Expand All @@ -33,6 +33,7 @@ import { AppDispatch } from './store';
import { selectAuth, selectUser } from '../features/auth/model/selectors';
import AppLayout from '../app/layout/AppLayout';
import AppRouter from '../app/router/AppRouter';
import TabsNavigation from '@/features/navigation/TabsNavigation';

const App: FunctionComponent = () => {
const { snackError } = useSnackMessage();
Expand Down Expand Up @@ -109,35 +110,23 @@ const App: FunctionComponent = () => {
// need subfunction when async as suggested by rule react-hooks/exhaustive-deps
(async function initializeAuthentication() {
try {
console.debug(`auth dev mode: ${import.meta.env.VITE_USE_AUTHENTICATION}`);
const initAuth =
import.meta.env.VITE_USE_AUTHENTICATION === 'true'
? initializeAuthenticationProd(
dispatch,
initialMatchSilentRenewCallbackUrl != null,
fetchIdpSettings,
fetchValidateUser,
initialMatchSigninCallbackUrl != null
)
: initializeAuthenticationDev(
dispatch,
initialMatchSilentRenewCallbackUrl != null,
validateUserDev,
initialMatchSigninCallbackUrl != null
);
setUserManager({
instance: (await initAuth) ?? null,
instance: await initializeAuthenticationProd(
dispatch,
initialMatchSilentRenewCallbackUrl != null,
fetchIdpSettings,
initialMatchSigninCallbackUrl != null
),
error: null,
});
} catch (error) {
setUserManager({
instance: null,
error: getErrorMessage(error),
});
} catch (error: any) {
console.log('ERROR', error);

setUserManager({ instance: null, error: error.message });
}
})();
// Note: dispatch and initialMatchSilentRenewCallbackUrl won't change
}, [initialMatchSigninCallbackUrl, initialMatchSilentRenewCallbackUrl, dispatch]);
// Note: initialMatchSilentRenewCallbackUrl and dispatch don't change
}, [initialMatchSilentRenewCallbackUrl, dispatch, initialMatchSigninCallbackUrl]);

useEffect(() => {
if (user !== null) {
Expand Down Expand Up @@ -168,7 +157,10 @@ const App: FunctionComponent = () => {
<AppLayout topBar={<AppTopBar user={user} userManager={userManager} />}>
<CardErrorBoundary>
{user !== null ? (
<AppRouter />
<>
<TabsNavigation />
<AppRouter />
</>
) : (
<AuthenticationRouter
userManager={userManager}
Expand Down
2 changes: 1 addition & 1 deletion src/app/config/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import { AppConfigParameter, PARAM_LANGUAGE, PARAM_THEME } from '@/shared/config/parameters';

export const COMMON_APP_NAME = 'common';
export const APP_NAME = 'study'; // TODO, set back to template
export const APP_NAME = 'monitor'; // TODO, set back to template

const COMMON_CONFIG_PARAMS_NAMES = new Set([PARAM_THEME, PARAM_LANGUAGE]);

Expand Down
2 changes: 0 additions & 2 deletions src/app/layout/AppTopBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ const AppTopBar: FunctionComponent<AppTopBarProps> = (props) => {
const {
additionalModulesPromise,
appsAndUrls,
displayParameters,
globalVersionPromise,
handleChangeLanguage,
handleChangeTheme,
Expand All @@ -49,7 +48,6 @@ const AppTopBar: FunctionComponent<AppTopBarProps> = (props) => {
}
appVersion={AppPackage.version}
appLicense={AppPackage.license}
onParametersClick={displayParameters}
onLogoutClick={onLogoutClick}
onLogoClick={onLogoClick}
user={props.user ?? undefined}
Expand Down
2 changes: 1 addition & 1 deletion src/app/providers/AppProviders.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import {
topBarFr,
} from '@gridsuite/commons-ui';
import { IntlProvider } from 'react-intl';
import { BrowserRouter } from 'react-router-dom';
import { BrowserRouter } from 'react-router';
import { Provider, useSelector } from 'react-redux';
import messages_en from '@/shared/translations/en/common.json';
import messages_fr from '@/shared/translations/fr/common.json';
Expand Down
8 changes: 7 additions & 1 deletion src/app/router/AppRouter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@
import React, { FunctionComponent } from 'react';
import { Box, Typography } from '@mui/material';
import { FormattedMessage } from 'react-intl';
import { Navigate, Route, Routes } from 'react-router-dom';
import { Navigate, Route, Routes } from 'react-router';
import { getPreLoginPath } from '@gridsuite/commons-ui';
import ExecuteProcessPage from '@/features/process/execute/ExecuteProcessPage';
import RawJsonPage from '@/features/process/result/RawJsonPage';
import StyledJsonPage from '@/features/process/result/StyledJsonPage';

const AppRouter: FunctionComponent = () => {
return (
Expand All @@ -24,6 +27,9 @@ const AppRouter: FunctionComponent = () => {
</Box>
}
/>
<Route path="/execute" element={<ExecuteProcessPage />} />
<Route path="/raw" element={<RawJsonPage />} />
<Route path="/styled" element={<StyledJsonPage />} />
<Route path="/sign-in-callback" element={<Navigate replace to={getPreLoginPath() || '/'} />} />
<Route path="/logout-callback" element={<h1>Error: logout failed; you are still logged in.</h1>} />
<Route
Expand Down
3 changes: 2 additions & 1 deletion src/app/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
import { configureStore } from '@reduxjs/toolkit';
import { monitorApi } from '@/shared/api/monitor-api/monitor.generated';
import { reducer } from './reducer';

export const store = configureStore({
reducer,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
serializableCheck: false,
}),
}).concat(monitorApi.middleware),
});

export type RootState = ReturnType<typeof store.getState>;
Expand Down
6 changes: 6 additions & 0 deletions src/app/store/reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,15 @@ import { ComputedLanguageAction, LanguageAction, ThemeAction } from '@/features/
import { settingsReducer } from '@/features/app-settings/store/settings-slice';
import { AuthState, SessionState } from '@/features/auth/model/types';
import { SettingsState } from '@/features/app-settings/store/types';
import executionResultReducer from '@/features/process/result/store/execution-result.slice';
import { monitorApi } from '@/shared/api/monitor-api/monitor.generated';

export type RootState = {
session: SessionState;
settings: SettingsState;
auth: AuthState;
executionResult: ReturnType<typeof executionResultReducer>;
[monitorApi.reducerPath]: ReturnType<typeof monitorApi.reducer>;
};

export type AppState = RootState;
Expand All @@ -27,4 +31,6 @@ export const reducer = combineReducers({
session: sessionReducer,
settings: settingsReducer,
auth: authReducer,
executionResult: executionResultReducer,
[monitorApi.reducerPath]: monitorApi.reducer,
});
30 changes: 30 additions & 0 deletions src/app/styles/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,33 @@ code {
body > iframe[width='0'][height='0'] {
border: 0;
}

.tabs-navigation {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
padding: 12px 24px;
}

.tabs-links {
display: flex;
gap: 12px;
}

.tabs-link {
padding: 8px 12px;
color: inherit;
text-decoration: none;
border-radius: 4px;
}

.tabs-link-active {
background: #444444;
font-weight: 600;
}

.tabs-execution-input {
min-width: 220px;
padding: 8px 12px;
}
54 changes: 54 additions & 0 deletions src/features/navigation/TabsNavigation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import React from 'react';
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
import React from 'react';
/*
* 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 https://mozilla.org/MPL/2.0/.
*/
import React from 'react';

import { useDispatch, useSelector } from 'react-redux';
import { NavLink } from 'react-router';
import { AppDispatch } from '@/app/store';
import { invalidateExecutionResultCache } from '@/features/process/result/api/execution-result-cache.api';
import {
selectCurrentExecutionId,
setCurrentExecutionId,
} from '@/features/process/result/store/execution-result.slice';

const TabsNavigation = () => {
const dispatch = useDispatch<AppDispatch>();
const currentExecutionId = useSelector(selectCurrentExecutionId);

return (
<nav className="tabs-navigation" aria-label="Primary navigation">
<div className="tabs-links">
<NavLink
className={({ isActive }) => (isActive ? 'tabs-link tabs-link-active' : 'tabs-link')}
to="/execute"
>
Execute
</NavLink>
<NavLink
className={({ isActive }) => (isActive ? 'tabs-link tabs-link-active' : 'tabs-link')}
to="/raw"
>
Raw JSON
</NavLink>
<NavLink
className={({ isActive }) => (isActive ? 'tabs-link tabs-link-active' : 'tabs-link')}
to="/styled"
>
Styled JSON
</NavLink>
</div>
<input
aria-label="Execution ID"
className="tabs-execution-input"
placeholder="Execution ID"
type="text"
value={currentExecutionId ?? ''}
onChange={(event) => {
const value = event.target.value;

dispatch(setCurrentExecutionId(value));
dispatch(invalidateExecutionResultCache(value));
}}
/>
</nav>
);
};

export default TabsNavigation;
Loading
Loading