diff --git a/.env b/.env index 8f03a83..55d5131 100644 --- a/.env +++ b/.env @@ -1,4 +1,5 @@ EXTEND_ESLINT=true +REACT_APP_DEBUG_REQUESTS=false REACT_APP_API_GATEWAY=/api/gateway REACT_APP_WS_GATEWAY=/ws/gateway diff --git a/package-lock.json b/package-lock.json index e3abda6..ac57a02 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "@emotion/react": "^11.8.2", "@emotion/styled": "^11.8.1", - "@gridsuite/commons-ui": "^0.44.0", + "@gridsuite/commons-ui": "^0.46.0", "@hookform/resolvers": "^3.3.1", "@mui/icons-material": "^5.5.1", "@mui/lab": "^5.0.0-alpha.75", @@ -2470,9 +2470,9 @@ } }, "node_modules/@gridsuite/commons-ui": { - "version": "0.44.0", - "resolved": "https://registry.npmjs.org/@gridsuite/commons-ui/-/commons-ui-0.44.0.tgz", - "integrity": "sha512-tIBZHdO/mURDeKz1ttSRtleriKGBebwgL1TekPtzyT/YxHGIORLSpUr8DsbFL+Dxr4VgXNQ+JD4/sJMAnoUDZA==", + "version": "0.46.0", + "resolved": "https://registry.npmjs.org/@gridsuite/commons-ui/-/commons-ui-0.46.0.tgz", + "integrity": "sha512-0Av3FNXXo7SXwtDqnwah/2AVBtff/hVVZTKpIB8LvklGFQvQNv8UN1av3UzBja54dd51TXYyZisG/+qG1uw+1w==", "dependencies": { "autosuggest-highlight": "^3.2.0", "clsx": "^1.0.4", diff --git a/package.json b/package.json index 478e8fc..83ce1ae 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "dependencies": { "@emotion/react": "^11.8.2", "@emotion/styled": "^11.8.1", - "@gridsuite/commons-ui": "^0.44.0", + "@gridsuite/commons-ui": "^0.46.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.tsx b/src/components/app.tsx index 9031113..7c08ebf 100644 --- a/src/components/app.tsx +++ b/src/components/app.tsx @@ -37,12 +37,12 @@ import { import { AppState } from '../redux/reducer'; import { ConfigSrv, + ConfigNotif, ConfigParameter, ConfigParameters, UserAdminSrv, AppsMetadataSrv, } from '../services'; -import { connectNotificationsWsUpdateConfig } from '../utils/rest-api'; import { UserManager } from 'oidc-client'; import { APP_NAME, @@ -104,7 +104,7 @@ const App: FunctionComponent = () => { const connectNotificationsUpdateConfig: () => ReconnectingWebSocket = useCallback(() => { - const ws = connectNotificationsWsUpdateConfig(); + const ws = ConfigNotif.connectNotificationsWsUpdateConfig(); ws.onmessage = function (event) { let eventData = JSON.parse(event.data); if (eventData?.headers?.parameterName) { @@ -174,7 +174,7 @@ const App: FunctionComponent = () => { }) ); - ConfigSrv.fetchConfigParameters(APP_NAME) + ConfigSrv.fetchConfigParameters(APP_NAME.toLowerCase()) .then((params) => updateParams(params)) .catch((error) => snackError({ diff --git a/src/services/apps-metadata.ts b/src/services/apps-metadata.ts index ba87af7..1401aa6 100644 --- a/src/services/apps-metadata.ts +++ b/src/services/apps-metadata.ts @@ -1,4 +1,4 @@ -import { ReqResponse } from '../utils/rest-api'; +import { ReqResponse } from '../utils/api-rest'; export type EnvJson = typeof import('../../public/env.json'); diff --git a/src/services/config-notification.ts b/src/services/config-notification.ts new file mode 100644 index 0000000..5260b0d --- /dev/null +++ b/src/services/config-notification.ts @@ -0,0 +1,20 @@ +import ReconnectingWebSocket, { Event } from 'reconnecting-websocket'; +import { APP_NAME } from '../utils/config-params'; +import { getUrlWithToken, getWsBase } from '../utils/api-ws'; + +const PREFIX_CONFIG_NOTIFICATION_WS = `${process.env.REACT_APP_WS_GATEWAY}/config-notification`; + +export function connectNotificationsWsUpdateConfig(): ReconnectingWebSocket { + const webSocketUrl = `${getWsBase()}${PREFIX_CONFIG_NOTIFICATION_WS}/notify?appName=${APP_NAME.toLowerCase()}`; + const reconnectingWebSocket = new ReconnectingWebSocket( + () => getUrlWithToken(webSocketUrl), + undefined, + { debug: process.env.REACT_APP_DEBUG_REQUESTS === 'true' } + ); + reconnectingWebSocket.onopen = function (event: Event) { + console.info( + `Connected Websocket update config ui ${webSocketUrl} ...` + ); + }; + return reconnectingWebSocket; +} diff --git a/src/services/config.ts b/src/services/config.ts index f120d7d..97dbba5 100644 --- a/src/services/config.ts +++ b/src/services/config.ts @@ -1,5 +1,5 @@ import { getAppName } from '../utils/config-params'; -import { backendFetch, backendFetchJson } from '../utils/rest-api'; +import { backendFetch, backendFetchJson } from '../utils/api-rest'; const PREFIX_CONFIG_QUERIES = `${process.env.REACT_APP_API_GATEWAY}/config`; diff --git a/src/services/index.ts b/src/services/index.ts index a953828..c9ef2ba 100644 --- a/src/services/index.ts +++ b/src/services/index.ts @@ -1,10 +1,12 @@ import * as Config from './config'; +import * as ConfigNotif from './config-notification'; import * as AppsMetadata from './apps-metadata'; import * as Study from './study'; import * as UserAdmin from './user-admin'; const _ = { ...Config, + ...ConfigNotif, ...AppsMetadata, ...Study, ...UserAdmin, @@ -14,6 +16,9 @@ export default _; export * as ConfigSrv from './config'; export type * from './config'; +export * as ConfigNotif from './config-notification'; +export type * from './config-notification'; + export * as AppsMetadataSrv from './apps-metadata'; export type * from './apps-metadata'; diff --git a/src/services/study.ts b/src/services/study.ts index 240333d..622fd40 100644 --- a/src/services/study.ts +++ b/src/services/study.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 { backendFetchJson, Token } from '../utils/rest-api'; +import { backendFetchJson, Token } from '../utils/api-rest'; const STUDY_URL = `${process.env.REACT_APP_API_GATEWAY}/study/v1`; diff --git a/src/services/user-admin.ts b/src/services/user-admin.ts index 2067823..0c0b8a5 100644 --- a/src/services/user-admin.ts +++ b/src/services/user-admin.ts @@ -1,4 +1,4 @@ -import { backendFetch, ReqResponse } from '../utils/rest-api'; +import { backendFetch, ReqResponse } from '../utils/api-rest'; const USER_ADMIN_URL = `${process.env.REACT_APP_API_GATEWAY}/user-admin`; diff --git a/src/setupProxy.js b/src/setupProxy.js index 3711a13..ec0aa65 100644 --- a/src/setupProxy.js +++ b/src/setupProxy.js @@ -1,13 +1,19 @@ const { createProxyMiddleware } = require('http-proxy-middleware'); +const GATEWAY_URL = 'http://localhost:9000'; +const debugReqs = process.env.REACT_APP_DEBUG_REQUESTS === 'true'; module.exports = function (app) { app.use( - createProxyMiddleware('http://localhost:9000/api/gateway', { - pathRewrite: { [`^${process.env.REACT_APP_API_GATEWAY}`]: '/' }, + createProxyMiddleware(process.env.REACT_APP_API_GATEWAY, { + logLevel: debugReqs ? 'debug' : 'info', + target: GATEWAY_URL, + pathRewrite: { [`^${process.env.REACT_APP_API_GATEWAY}/`]: '/' }, }) ); app.use( - createProxyMiddleware('http://localhost:9000/ws/gateway', { - pathRewrite: { [`^${process.env.REACT_APP_WS_GATEWAY}`]: '/' }, + createProxyMiddleware(process.env.REACT_APP_WS_GATEWAY, { + logLevel: debugReqs ? 'debug' : 'info', + target: GATEWAY_URL, + pathRewrite: { [`^${process.env.REACT_APP_WS_GATEWAY}/`]: '/' }, ws: true, }) ); diff --git a/src/utils/rest-api.ts b/src/utils/api-rest.ts similarity index 68% rename from src/utils/rest-api.ts rename to src/utils/api-rest.ts index b8acb73..536c077 100644 --- a/src/utils/rest-api.ts +++ b/src/utils/api-rest.ts @@ -5,10 +5,9 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { APP_NAME } from './config-params'; -import { store } from '../redux/store'; -import ReconnectingWebSocket, { Event } from 'reconnecting-websocket'; -import { AppState } from '../redux/reducer'; +import { getToken, parseError, Token } from './api'; + +export type * from './api'; export interface ErrorWithStatus extends Error { status?: number; @@ -16,41 +15,8 @@ export interface ErrorWithStatus extends Error { export type Url = Exclude[0], Request>; //string | URL; export type InitRequest = Partial[1]>; //Partial; -export type Token = string; export type ReqResponse = Awaited>; -const PREFIX_CONFIG_NOTIFICATION_WS = `${process.env.REACT_APP_WS_GATEWAY}/config-notification`; - -export function connectNotificationsWsUpdateConfig(): ReconnectingWebSocket { - 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()}` - ); - reconnectingWebSocket.onopen = function (event: Event) { - console.info( - `Connected Websocket update config ui ${webSocketUrl} ...` - ); - }; - return reconnectingWebSocket; -} - -function getToken(): Token { - const state: AppState = store.getState(); - return state.user?.id_token; -} - -function parseError(text: string): any { - try { - return JSON.parse(text); - } catch (err) { - return null; - } -} - function handleError(response: ReqResponse): Promise { return response.text().then((text: string) => { const errorName = 'HttpResponseError : '; diff --git a/src/utils/api-ws.ts b/src/utils/api-ws.ts new file mode 100644 index 0000000..1083770 --- /dev/null +++ b/src/utils/api-ws.ts @@ -0,0 +1,14 @@ +import { getToken } from './api'; + +export type * from './api'; + +export function getWsBase(): string { + return document.baseURI + .replace(/^http(s?):\/\//, 'ws$1://') + .replace(/\/$/, ''); +} + +export function getUrlWithToken(baseUrl: string): string { + const querySymbol = baseUrl.includes('?') ? '&' : '?'; + return `${baseUrl}${querySymbol}access_token=${getToken()}`; +} diff --git a/src/utils/api.ts b/src/utils/api.ts new file mode 100644 index 0000000..4570046 --- /dev/null +++ b/src/utils/api.ts @@ -0,0 +1,17 @@ +import { AppState } from '../redux/reducer'; +import { store } from '../redux/store'; + +export type Token = string; + +export function getToken(): Token { + const state: AppState = store.getState(); + return state.user?.id_token; +} + +export function parseError(text: string): any { + try { + return JSON.parse(text); + } catch (err) { + return null; + } +}