@@ -2,27 +2,12 @@ import { ErrorPage500 } from '@scality/core-ui/dist/components/error-pages/Error
2
2
import { IconName } from '@scality/core-ui/dist/components/icon/Icon.component' ;
3
3
import { Loader } from '@scality/core-ui/dist/components/loader/Loader.component' ;
4
4
import { SolutionUI } from '@scality/module-federation' ;
5
- import React , { createContext , useContext } from 'react' ;
5
+ import React , { useMemo , useSyncExternalStore } from 'react' ;
6
6
import { useQueries , UseQueryResult } from 'react-query' ;
7
7
import { useShellConfig } from './ShellConfigProvider' ;
8
8
import { useShellHistory } from './ShellHistoryProvider' ;
9
9
import { useDeployedApps , useDeployedAppsRetriever } from './UIListProvider' ;
10
10
11
- if ( ! window . shellContexts ) {
12
- // @ts -expect-error - FIXME when you are working on it
13
- window . shellContexts = { } ;
14
- }
15
-
16
- if ( ! window . shellContexts . WebFingersContext ) {
17
- window . shellContexts . WebFingersContext = createContext <
18
- | null
19
- | UseQueryResult <
20
- BuildtimeWebFinger | RuntimeWebFinger < Record < string , unknown > > ,
21
- unknown
22
- > [ ]
23
- > ( null ) ;
24
- }
25
-
26
11
export type OAuth2ProxyConfig = {
27
12
kind : 'OAuth2Proxy' ; //todo : add other entries
28
13
} ;
@@ -85,10 +70,8 @@ export function useConfigRetriever(): {
85
70
name : string ;
86
71
} ) => ( T extends 'build' ? BuildtimeWebFinger : RuntimeWebFinger < T > ) | null ;
87
72
} {
73
+ const { state : webFingerContextValue } = useWebFingersStore ( ) ;
88
74
const { retrieveDeployedApps } = useDeployedAppsRetriever ( ) ;
89
- const webFingerContextValue = useContext (
90
- window . shellContexts . WebFingersContext ,
91
- ) ;
92
75
93
76
if ( ! webFingerContextValue ) {
94
77
throw new Error (
@@ -142,15 +125,18 @@ export function useConfig<T extends 'build' | Record<string, unknown>>({
142
125
configType : T extends 'build' ? 'build' : 'run' ;
143
126
name : string ;
144
127
} ) : null | T extends 'build' ? BuildtimeWebFinger : RuntimeWebFinger < T > {
128
+ // Utiliser le nouveau hook useWebFingersStore
129
+ const { state : webFingerContextValue } = useWebFingersStore ( ) ;
130
+
131
+ // Utiliser le retrieveConfiguration du hook useConfigRetriever
145
132
const { retrieveConfiguration } = useConfigRetriever ( ) ;
146
- const webFingerContextValue = useContext (
147
- window . shellContexts . WebFingersContext ,
148
- ) ;
149
133
150
- if ( ! webFingerContextValue ) {
134
+ // Vérifier que le contexte est disponible
135
+ if ( ! webFingerContextValue || webFingerContextValue . length === 0 ) {
151
136
throw new Error ( "Can't use useConfig outside of ConfigurationProvider" ) ;
152
137
}
153
138
139
+ // Récupérer et retourner la configuration
154
140
return retrieveConfiguration ( {
155
141
configType,
156
142
name,
@@ -179,6 +165,72 @@ export type NonFederatedView = {
179
165
icon ?: IconName ;
180
166
} ;
181
167
export type ViewDefinition = FederatedView | NonFederatedView ;
168
+
169
+ // External store implementation
170
+ class WebFingersStore {
171
+ private listeners : Set < ( ) => void > = new Set ( ) ;
172
+ private _state : UseQueryResult <
173
+ BuildtimeWebFinger | RuntimeWebFinger < Record < string , unknown > > ,
174
+ unknown
175
+ > [ ] = [ ] ;
176
+
177
+ subscribe = ( listener : ( ) => void ) => {
178
+ this . listeners . add ( listener ) ;
179
+ return ( ) => {
180
+ this . listeners . delete ( listener ) ;
181
+ } ;
182
+ } ;
183
+
184
+ getState = ( ) => {
185
+ return this . _state ;
186
+ } ;
187
+
188
+ private isStateEqual (
189
+ currentState : UseQueryResult <
190
+ BuildtimeWebFinger | RuntimeWebFinger < Record < string , unknown > > ,
191
+ unknown
192
+ > [ ] ,
193
+ newState : UseQueryResult <
194
+ BuildtimeWebFinger | RuntimeWebFinger < Record < string , unknown > > ,
195
+ unknown
196
+ > [ ] ,
197
+ ) {
198
+ return (
199
+ currentState . length === newState . length &&
200
+ currentState . every (
201
+ ( item , index ) =>
202
+ JSON . stringify ( item ) === JSON . stringify ( newState [ index ] ) ,
203
+ )
204
+ ) ;
205
+ }
206
+
207
+ updateState = (
208
+ newState : UseQueryResult <
209
+ BuildtimeWebFinger | RuntimeWebFinger < Record < string , unknown > > ,
210
+ unknown
211
+ > [ ] ,
212
+ ) => {
213
+ if ( ! this . isStateEqual ( this . _state , newState ) ) {
214
+ this . _state = newState ;
215
+ this . listeners . forEach ( ( listener ) => listener ( ) ) ;
216
+ }
217
+ } ;
218
+ }
219
+
220
+ const webFingersStore = new WebFingersStore ( ) ;
221
+
222
+ export function useWebFingersStore ( ) {
223
+ const state = useSyncExternalStore (
224
+ webFingersStore . subscribe ,
225
+ webFingersStore . getState ,
226
+ ) ;
227
+
228
+ return {
229
+ state,
230
+ updateWebFingersState : webFingersStore . updateState ,
231
+ } ;
232
+ }
233
+
182
234
export function useDiscoveredViews ( ) : ViewDefinition [ ] {
183
235
const { retrieveConfiguration } = useConfigRetriever ( ) ;
184
236
const { retrieveDeployedApps } = useDeployedAppsRetriever ( ) ;
@@ -286,6 +338,7 @@ export const ConfigurationProvider = ({
286
338
} : {
287
339
children : React . ReactNode ;
288
340
} ) => {
341
+ const { updateWebFingersState } = useWebFingersStore ( ) ;
289
342
const deployedUIs = useDeployedApps ( ) ;
290
343
const results = useQueries (
291
344
deployedUIs . flatMap ( ( ui ) => [
@@ -323,6 +376,11 @@ export const ConfigurationProvider = ({
323
376
} ,
324
377
] ) ,
325
378
) ;
379
+
380
+ useMemo ( ( ) => {
381
+ updateWebFingersState ( results ) ;
382
+ } , [ results ] ) ;
383
+
326
384
const statuses = Array . from ( new Set ( results . map ( ( result ) => result . status ) ) ) ;
327
385
const globalStatus = statuses . includes ( 'error' )
328
386
? 'error'
@@ -333,13 +391,14 @@ export const ConfigurationProvider = ({
333
391
: statuses . includes ( 'idle' ) && statuses . includes ( 'success' )
334
392
? 'loading'
335
393
: 'success' ;
394
+
336
395
return (
337
- < window . shellContexts . WebFingersContext . Provider value = { results } >
396
+ < >
338
397
{ ( globalStatus === 'loading' || globalStatus === 'idle' ) && (
339
398
< Loader size = "massive" centered = { true } aria-label = "loading" />
340
399
) }
341
400
{ globalStatus === 'error' && < ErrorPage500 data-cy = "sc-error-page500" /> }
342
401
{ globalStatus === 'success' && children }
343
- </ window . shellContexts . WebFingersContext . Provider >
402
+ </ >
344
403
) ;
345
404
} ;
0 commit comments