Skip to content
Open
Show file tree
Hide file tree
Changes from 3 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
23 changes: 22 additions & 1 deletion src/components/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import {
UserManagerState,
useSnackMessage,
} from '@gridsuite/commons-ui';
import { Box } from '@mui/material';
import { Box, Button } from '@mui/material';
import { selectComputedLanguage, selectEnableDeveloperMode, selectLanguage, selectTheme } from '../redux/actions';
import { ConfigParameters, fetchIdpSettings } from '../utils/rest-api';
import { APP_NAME } from '../utils/config-params';
Expand Down Expand Up @@ -158,12 +158,33 @@ export default function App() {
}
return undefined;
}, [userProfile, dispatch, updateParams, snackError]);
const CTX = window === window.parent ? 'PARENT' : 'IFRAME';
const triggerSilentRenew = useCallback(async () => {
if (userManager.instance) {
console.log(`====[${CTX}][signinSilent] start/done`);
console.log('====[debug] signinSilent start');
try {
await userManager.instance.signinSilent();
console.log('====[debug] signinSilent done');
} catch (e) {
console.error('====[debug] signinSilent error', e);
}
}
}, [CTX, userManager.instance]);

// We use <Box flex=.../> instead of <Grid/> because flex rules were too complexes or conflicts with MUI grid rules
return (
<Box display="flex" flexDirection="column" width="100%" height="100%">
<Box flexShrink={0}>
<AppTopBar userProfile={userProfile} userManagerInstance={userManager.instance} />
{import.meta.env.DEV && (
<Button
onClick={triggerSilentRenew}
style={{ position: 'fixed', bottom: 10, right: 10, zIndex: 9999 }}
>
Regénérer token
</Button>
)}
</Box>
<Box flexShrink={0}>
<AnnouncementNotification userProfile={userProfile} sx={{ marginBottom: '0 !important' }} />
Expand Down
21 changes: 12 additions & 9 deletions src/components/directory-content-dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,11 @@
const itemSelectionForCopy = useSelector((state: AppState) => state.itemSelectionForCopy);
const activeDirectory = useSelector((state: AppState) => state.activeDirectory);
const isDeveloperMode = useSelector((state: AppState) => state.isDeveloperMode);
const user = useSelector((state: AppState) => state.user);

const userProfile = useSelector(
(state: AppState) => state.user?.profile ?? null,
(a, b) =>
a === b || (a?.sub === b?.sub && a?.name === b?.name && a?.email === b?.email && a?.profile === b?.profile)
);
const [languageLocal] = useParameterState(PARAM_LANGUAGE);
const [elementName, setElementName] = useState('');
const [elementDescription, setElementDescription] = useState('');
Expand Down Expand Up @@ -377,7 +380,7 @@
titleId="editParameters"
name={elementName}
description={activeElement.description}
user={user}
userProfile={userProfile}

Check failure on line 383 in src/components/directory-content-dialog.tsx

View workflow job for this annotation

GitHub Actions / build / build

Type '{ id: `${string}-${string}-${string}-${string}-${string}`; open: true; onClose: () => void; titleId: string; name: string; description: string; userProfile: IdTokenClaims | null; activeDirectory: `${string}-${string}-${string}-${string}-${string}`; language: GsLang; isDeveloperMode: boolean; }' is not assignable to type 'IntrinsicAttributes & Readonly<ParametersEditionDialogProps>'.
Comment thread
ghazwarhili marked this conversation as resolved.
activeDirectory={activeDirectory}
language={languageLocal}
isDeveloperMode={isDeveloperMode}
Expand All @@ -393,7 +396,7 @@
titleId="editParameters"
name={elementName}
description={activeElement.description}
user={user}
userProfile={userProfile}

Check failure on line 399 in src/components/directory-content-dialog.tsx

View workflow job for this annotation

GitHub Actions / build / build

Type '{ id: `${string}-${string}-${string}-${string}-${string}`; open: true; onClose: () => void; titleId: string; name: string; description: string; userProfile: IdTokenClaims | null; activeDirectory: `${string}-${string}-${string}-${string}-${string}`; language: GsLang; }' is not assignable to type 'IntrinsicAttributes & Readonly<ParametersEditionDialogProps>'.
activeDirectory={activeDirectory}
language={languageLocal}
/>
Expand All @@ -408,7 +411,7 @@
titleId="editParameters"
name={elementName}
description={activeElement.description}
user={user}
userProfile={userProfile}

Check failure on line 414 in src/components/directory-content-dialog.tsx

View workflow job for this annotation

GitHub Actions / build / build

Type '{ id: `${string}-${string}-${string}-${string}-${string}`; open: true; onClose: () => void; titleId: string; name: string; description: string; userProfile: IdTokenClaims | null; activeDirectory: `${string}-${string}-${string}-${string}-${string}`; language: GsLang; }' is not assignable to type 'IntrinsicAttributes & Readonly<ParametersEditionDialogProps>'.
activeDirectory={activeDirectory}
language={languageLocal}
/>
Expand All @@ -423,7 +426,7 @@
titleId="editParameters"
name={elementName}
description={activeElement.description}
user={user}
userProfile={userProfile}

Check failure on line 429 in src/components/directory-content-dialog.tsx

View workflow job for this annotation

GitHub Actions / build / build

Type '{ id: `${string}-${string}-${string}-${string}-${string}`; open: true; onClose: () => void; titleId: string; name: string; description: string; userProfile: IdTokenClaims | null; activeDirectory: `${string}-${string}-${string}-${string}-${string}`; language: GsLang; }' is not assignable to type 'IntrinsicAttributes & Readonly<ParametersEditionDialogProps>'.
activeDirectory={activeDirectory}
language={languageLocal}
/>
Expand All @@ -438,7 +441,7 @@
titleId="editParameters"
name={elementName}
description={activeElement.description}
user={user}
userProfile={userProfile}

Check failure on line 444 in src/components/directory-content-dialog.tsx

View workflow job for this annotation

GitHub Actions / build / build

Type '{ id: `${string}-${string}-${string}-${string}-${string}`; open: true; onClose: () => void; titleId: string; name: string; description: string; userProfile: IdTokenClaims | null; activeDirectory: `${string}-${string}-${string}-${string}-${string}`; language: GsLang; }' is not assignable to type 'IntrinsicAttributes & Readonly<ParametersEditionDialogProps>'.
activeDirectory={activeDirectory}
language={languageLocal}
/>
Expand All @@ -453,7 +456,7 @@
titleId="editParameters"
name={elementName}
description={activeElement.description}
user={user}
userProfile={userProfile}

Check failure on line 459 in src/components/directory-content-dialog.tsx

View workflow job for this annotation

GitHub Actions / build / build

Type '{ id: `${string}-${string}-${string}-${string}-${string}`; open: true; onClose: () => void; titleId: string; name: string; description: string; userProfile: IdTokenClaims | null; activeDirectory: `${string}-${string}-${string}-${string}-${string}`; language: GsLang; isDeveloperMode: boolean; }' is not assignable to type 'IntrinsicAttributes & Readonly<ParametersEditionDialogProps>'.
activeDirectory={activeDirectory}
language={languageLocal}
isDeveloperMode={isDeveloperMode}
Expand All @@ -469,7 +472,7 @@
titleId="editParameters"
name={elementName}
description={activeElement.description}
user={user}
userProfile={userProfile}

Check failure on line 475 in src/components/directory-content-dialog.tsx

View workflow job for this annotation

GitHub Actions / build / build

Type '{ id: `${string}-${string}-${string}-${string}-${string}`; open: true; onClose: () => void; titleId: string; name: string; description: string; userProfile: IdTokenClaims | null; activeDirectory: `${string}-${string}-${string}-${string}-${string}`; language: GsLang; }' is not assignable to type 'IntrinsicAttributes & Readonly<ParametersEditionDialogProps>'.
activeDirectory={activeDirectory}
language={languageLocal}
/>
Expand Down
42 changes: 42 additions & 0 deletions src/components/silent-renew-app.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* Copyright (c) 2026, 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 { useCallback, useEffect, useState } from 'react';
import type { UserManager } from 'oidc-client-ts';
import {
handleSilentRenewCallback,
initializeAuthenticationProd,
SilentRenewCallbackHandler,
} from '@gridsuite/commons-ui';
import { getCachedIdpSettings } from '../utils/rest-api';

export default function SilentRenewApp() {
const [userManager, setUserManager] = useState<UserManager | null>(null);

useEffect(() => {
initializeAuthenticationProd(
() => undefined /* dispatch: unused when isSilentRenew=true */,
true /* isSilentRenew */,
getCachedIdpSettings /* reads the cache instead of fetching idpSettings.json */,
false /* isSigningCallback */
)
.then(setUserManager)
.catch((e) => console.error('Silent renew init failed:', e));
}, []);

const handleSilentRenewCallbackClosure = useCallback(() => {
if (userManager) {
handleSilentRenewCallback(userManager);
}
}, [userManager]);

return (
<SilentRenewCallbackHandler
userManager={userManager}
handleSilentRenewCallback={handleSilentRenewCallbackClosure}
/>
);
}
10 changes: 7 additions & 3 deletions src/components/tree-views-container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,11 @@ export default function TreeViewsContainer({ sourceItemUuid }: { readonly source

const [openDialog, setOpenDialog] = useState(constants.DialogsId.NONE);

const user = useSelector((state: AppState) => state.user);
const userProfile = useSelector(
(state: AppState) => state.user?.profile ?? null,
(a, b) =>
a === b || (a?.sub === b?.sub && a?.name === b?.name && a?.email === b?.email && a?.profile === b?.profile)
);
const selectedDirectory = useSelector((state: AppState) => state.selectedDirectory);
const activeDirectory = useSelector((state: AppState) => state.activeDirectory);
const currentPath = useSelector((state: AppState) => state.currentPath);
Expand Down Expand Up @@ -210,10 +214,10 @@ export default function TreeViewsContainer({ sourceItemUuid }: { readonly source

/* rootDirectories initialization */
useEffect(() => {
if (user != null) {
if (userProfile != null) {
updateRootDirectories();
}
}, [user, updateRootDirectories]);
}, [userProfile, updateRootDirectories]);

/* Manage current path data */
useEffect(() => {
Expand Down
9 changes: 8 additions & 1 deletion src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ import './configure-yup-init';

import { createRoot } from 'react-dom/client';
import AppWrapper from './components/app-wrapper';
import SilentRenewApp from './components/silent-renew-app';

const container = document.getElementById('root');
createRoot(container!).render(<AppWrapper />);
const root = createRoot(container!);

if (window.location.pathname.endsWith('/silent-renew-callback')) {
root.render(<SilentRenewApp />);
} else {
root.render(<AppWrapper />);
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
27 changes: 25 additions & 2 deletions src/utils/rest-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
type GsLang,
type GsTheme,
hasElementPermission,
IdpSettings,
LAST_SELECTED_DIRECTORY,
PARAM_DEVELOPER_MODE,
PARAM_LANGUAGE,
Expand Down Expand Up @@ -44,6 +45,7 @@ const PREFIX_NETWORK_CONVERSION_SERVER_QUERIES = `${import.meta.env.VITE_API_GAT
const PREFIX_FILTERS_QUERIES = `${import.meta.env.VITE_API_GATEWAY}/filter/v1/filters`;
const PREFIX_STUDY_QUERIES = `${import.meta.env.VITE_API_GATEWAY}/study`;
const PREFIX_SPREADSHEET_CONFIG_QUERIES = `${import.meta.env.VITE_API_GATEWAY}/study-config`;
const IDP_SETTINGS_CACHE_KEY = 'gridsuite-idp-settings';

export type KeyOfWithoutIndexSignature<T> = {
// copy every declared property from T but remove index signatures
Expand Down Expand Up @@ -93,8 +95,29 @@ const getContingencyUriParamType = (contingencyListType: string | null | undefin
}
};

export function fetchIdpSettings() {
return fetch('idpSettings.json').then((res) => res.json());
// Always hits the network: picks up config changes on each full app load
// AND refreshes the cache read by the silent-renew iframe.
export function fetchIdpSettings(): Promise<IdpSettings> {
return fetch('idpSettings.json')
.then((res) => res.json())
.then((settings: IdpSettings) => {
localStorage.setItem(IDP_SETTINGS_CACHE_KEY, JSON.stringify(settings));
return settings;
});
}

// Used only on the silent-renew path: reads the cache (no network),
// falls back to a real fetch if the cache is missing/corrupted.
export function getCachedIdpSettings(): Promise<IdpSettings> {
const cached = localStorage.getItem(IDP_SETTINGS_CACHE_KEY);
if (cached) {
try {
return Promise.resolve(JSON.parse(cached) as IdpSettings);
} catch {
// corrupted cache -> fall back to a fresh fetch
}
}
return fetchIdpSettings();
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}

export function fetchVersion() {
Expand Down
Loading