diff --git a/.env b/.env index 04d31c9..f6fd4d0 100644 --- a/.env +++ b/.env @@ -2,4 +2,5 @@ REACT_APP_USE_AUTHENTICATION=true REACT_APP_API_GATEWAY=api/gateway REACT_APP_WS_GATEWAY=ws/gateway -EXTEND_ESLINT=true \ No newline at end of file + +EXTEND_ESLINT=true diff --git a/.env.development b/.env.development index 2f1d4e1..1451cfd 100644 --- a/.env.development +++ b/.env.development @@ -1 +1,3 @@ REACT_APP_USE_AUTHENTICATION=false + +REACT_APP_SRV_STUDY_URI=study-server diff --git a/package-lock.json b/package-lock.json index c16fc81..e8eefbf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "dependencies": { "@emotion/react": "^11.8.2", "@emotion/styled": "^11.8.1", - "@gridsuite/commons-ui": "0.41.0", + "@gridsuite/commons-ui": "^0.42.0", "@hookform/resolvers": "^3.3.1", "@mui/icons-material": "^5.5.1", "@mui/lab": "^5.0.0-alpha.75", @@ -2458,9 +2458,9 @@ } }, "node_modules/@gridsuite/commons-ui": { - "version": "0.41.0", - "resolved": "https://registry.npmjs.org/@gridsuite/commons-ui/-/commons-ui-0.41.0.tgz", - "integrity": "sha512-GxRZBWhvXxVKgXAg6HIWX+t2UpCTdgkKlnwjceLY5FxaZcBCaNAISzz7HNGYtAvj3gePNlKGSeGNNQcoOe9pRA==", + "version": "0.42.0", + "resolved": "https://registry.npmjs.org/@gridsuite/commons-ui/-/commons-ui-0.42.0.tgz", + "integrity": "sha512-v8b52OEMGmyDNvosXpnC/Q8HXPY6v93g2qFKr6NB46ubKmADB1Q0fcKoopHg8/fbcFrkdvcGUFpWpHdqZ5fPog==", "dependencies": { "autosuggest-highlight": "^3.2.0", "clsx": "^1.0.4", diff --git a/package.json b/package.json index 10cf182..a534df2 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "dependencies": { "@emotion/react": "^11.8.2", "@emotion/styled": "^11.8.1", - "@gridsuite/commons-ui": "0.41.0", + "@gridsuite/commons-ui": "^0.42.0", "@hookform/resolvers": "^3.3.1", "@mui/icons-material": "^5.5.1", "@mui/lab": "^5.0.0-alpha.75", diff --git a/src/components/app-top-bar.js b/src/components/app-top-bar.js index 5dfc78e..d6a56d7 100644 --- a/src/components/app-top-bar.js +++ b/src/components/app-top-bar.js @@ -9,10 +9,12 @@ import { LIGHT_THEME, logout, TopBar } 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 } from '../utils/rest-api'; +import { fetchAppsAndUrls, fetchVersion } from '../utils/rest-api'; +import { getServersInfos } from '../rest/study'; import PropTypes from 'prop-types'; import { useNavigate } from 'react-router-dom'; import { ReactComponent as PowsyblLogo } from '../images/powsybl_logo.svg'; +import AppPackage from '../../package.json'; const AppTopBar = ({ user, userManager }) => { const navigate = useNavigate(); @@ -38,14 +40,6 @@ const AppTopBar = ({ user, userManager }) => { } }, [user]); - function hideParameters() { - setShowParameters(false); - } - - function onLogoClicked() { - navigate.replace('/'); - } - return ( <> { //GridXXXLogoDark ) } + appVersion={AppPackage.version} + appLicense={AppPackage.license} onParametersClick={() => setShowParameters(true)} onLogoutClick={() => logout(dispatch, userManager.instance)} - onLogoClick={() => onLogoClicked()} + onLogoClick={() => navigate.replace('/')} user={user} appsAndUrls={appsAndUrls} - onAboutClick={() => console.debug('about')} + getGlobalVersion={(setGlobalVersion) => + fetchVersion() + .then((res) => setGlobalVersion(res.deployVersion)) + .catch((reason) => { + console.error( + 'Error while fetching the version : ' + reason + ); + setGlobalVersion(null); + }) + } + getAdditionalModules={(setServers) => + getServersInfos(user?.id_token) + .then((res) => + setServers( + Object.entries(res).map(([name, infos]) => ({ + name: + infos?.build?.name || + infos?.build?.artifact || + name, + type: 'server', + version: infos?.build?.version, + gitTag: + infos?.git?.tags || + infos?.git?.commit?.id[ + 'describe-short' + ], + })) + ) + ) + .catch((reason) => { + console.error( + 'Error while fetching the servers infos : ' + + reason + ); + setServers(null); + }) + } onThemeClick={handleChangeTheme} theme={themeLocal} onLanguageClick={handleChangeLanguage} @@ -71,7 +103,7 @@ const AppTopBar = ({ user, userManager }) => { /> setShowParameters(false)} /> ); diff --git a/src/rest/study.js b/src/rest/study.js new file mode 100644 index 0000000..7390e1d --- /dev/null +++ b/src/rest/study.js @@ -0,0 +1,25 @@ +/** + * Copyright (c) 2023, 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/. + */ +import { backendFetchJson } from '../utils/rest-api'; +const API_URL = + '/api/' + + (process.env.REACT_APP_USE_AUTHENTICATION === 'true' + ? process.env.REACT_APP_API_GATEWAY + '/study/v1' + : process.env.REACT_APP_SRV_STUDY_URI + '/v1'); +export function getServersInfos(token) { + return backendFetchJson( + `${API_URL}/servers/infos`, + { + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + }, + cache: 'default', + }, + token + ); +} diff --git a/src/setupProxy.js b/src/setupProxy.js index f16061f..e074a4a 100644 --- a/src/setupProxy.js +++ b/src/setupProxy.js @@ -11,4 +11,9 @@ module.exports = function (app) { ws: true, }) ); + app.use( + createProxyMiddleware('http://localhost:5001/api/study-server', { + pathRewrite: { '^/api/study-server/': '/' }, + }) + ); }; diff --git a/src/translations/en.json b/src/translations/en.json index ec6a894..8d9c045 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -1,4 +1,5 @@ { + "close": "Close", "parameters": "Parameters", "paramsChangingError": "An error occured when changing the parameters", "paramsRetrievingError": "An error occurred while retrieving the parameters" diff --git a/src/translations/fr.json b/src/translations/fr.json index 2a4745d..8a3500a 100644 --- a/src/translations/fr.json +++ b/src/translations/fr.json @@ -1,4 +1,5 @@ { + "close": "Fermer", "parameters": "Paramètres", "paramsChangingError": "Une erreur est survenue lors de la modification des paramètres", "paramsRetrievingError": "Une erreur est survenue lors de la récupération des paramètres" diff --git a/src/utils/rest-api.js b/src/utils/rest-api.js index 6b17025..c22aa9d 100644 --- a/src/utils/rest-api.js +++ b/src/utils/rest-api.js @@ -156,44 +156,48 @@ export function fetchValidateUser(user) { }); } +function fetchEnv() { + return fetch('env.json').then((res) => res.json()); +} + export function fetchAuthorizationCodeFlowFeatureFlag() { console.info(`Fetching authorization code flow feature flag...`); - return fetch('env.json') + return fetchEnv() + .then((res) => + fetch(res.appsMetadataServerUrl + '/authentication.json') + ) .then((res) => res.json()) .then((res) => { - return fetch(res.appsMetadataServerUrl + '/authentication.json') - .then((res) => res.json()) - .then((res) => { - console.log( - `Authorization code flow is ${ - res.authorizationCodeFlowFeatureFlag - ? 'enabled' - : 'disabled' - }` - ); - return res.authorizationCodeFlowFeatureFlag; - }) - .catch((error) => { - console.error(error); - console.warn( - `Something wrong happened when retrieving authentication.json: authorization code flow will be disabled` - ); - return false; - }); + console.log( + `Authorization code flow is ${ + res.authorizationCodeFlowFeatureFlag + ? 'enabled' + : 'disabled' + }` + ); + return res.authorizationCodeFlowFeatureFlag; + }) + .catch((error) => { + console.error(error); + console.warn( + `Something wrong happened when retrieving authentication.json: authorization code flow will be disabled` + ); + return false; }); } +export function fetchVersion() { + console.info(`Fetching global metadata...`); + return fetchEnv() + .then((env) => fetch(env.appsMetadataServerUrl + '/version.json')) + .then((response) => response.json()); +} + export function fetchAppsAndUrls() { console.info(`Fetching apps and urls...`); - return fetch('env.json') - .then((res) => res.json()) - .then((res) => { - return fetch( - res.appsMetadataServerUrl + '/apps-metadata.json' - ).then((response) => { - return response.json(); - }); - }); + return fetchEnv() + .then((res) => fetch(res.appsMetadataServerUrl + '/apps-metadata.json')) + .then((response) => response.json()); } export function fetchConfigParameters(appName) {