@@ -20,6 +20,8 @@ import Container from '@mui/material/Container';
2020import CssBaseline from '@mui/material/CssBaseline' ;
2121import Link from '@mui/material/Link' ;
2222import { styled } from '@mui/material/styles' ;
23+ import { Dispatch , UnknownAction } from '@reduxjs/toolkit' ;
24+ import { useQuery } from '@tanstack/react-query' ;
2325import { useEffect } from 'react' ;
2426import { useTranslation } from 'react-i18next' ;
2527import { useDispatch } from 'react-redux' ;
@@ -121,6 +123,57 @@ declare global {
121123 }
122124}
123125
126+ /**
127+ * Fetches the cluster config from the backend and updates the redux store
128+ * if the present stored config is different from the fetched one.
129+ */
130+ const fetchConfig = ( dispatch : Dispatch < UnknownAction > ) => {
131+ const clusters = store . getState ( ) . config . clusters ;
132+ const statelessClusters = store . getState ( ) . config . statelessClusters ;
133+
134+ return request ( '/config' , { } , false , false ) . then ( config => {
135+ const clustersToConfig : ConfigState [ 'clusters' ] = { } ;
136+ config ?. clusters . forEach ( ( cluster : Cluster ) => {
137+ if ( cluster . meta_data ?. extensions ?. headlamp_info ?. customName ) {
138+ cluster . name = cluster . meta_data ?. extensions ?. headlamp_info ?. customName ;
139+ }
140+ clustersToConfig [ cluster . name ] = cluster ;
141+ } ) ;
142+
143+ const configToStore = { ...config , clusters : clustersToConfig } ;
144+
145+ if ( clusters === null ) {
146+ dispatch ( setConfig ( configToStore ) ) ;
147+ } else {
148+ // Check if the config is different
149+ const configDifferent = isEqualClusterConfigs ( clusters , clustersToConfig ) ;
150+
151+ if ( configDifferent ) {
152+ // Merge the new config with the current config
153+ const mergedClusters = mergeClusterConfigs (
154+ configToStore . clusters ,
155+ clusters ,
156+ statelessClusters
157+ ) ;
158+ dispatch (
159+ setConfig ( {
160+ ...configToStore ,
161+ clusters : mergedClusters ,
162+ } )
163+ ) ;
164+ }
165+ }
166+
167+ /**
168+ * Fetches the stateless cluster config from the indexDB and then sends the backend to parse it
169+ * only if the stateless cluster config is enabled in the backend.
170+ */
171+ if ( config ?. isDynamicClusterEnabled ) {
172+ fetchStatelessClusterKubeConfigs ( dispatch ) ;
173+ }
174+ } ) ;
175+ } ;
176+
124177export default function Layout ( { } : LayoutProps ) {
125178 const arePluginsLoaded = useTypedSelector ( state => state . plugins . loaded ) ;
126179 const dispatch = useDispatch ( ) ;
@@ -134,82 +187,17 @@ export default function Layout({}: LayoutProps) {
134187 * indexDB and then sends the backend to parse it and then updates the parsed value into redux
135188 * store on an interval.
136189 * */
137- useEffect ( ( ) => {
138- window . clusterConfigFetchHandler = setInterval (
139- ( ) => {
140- fetchConfig ( ) ;
141- } ,
142- CLUSTER_FETCH_INTERVAL ,
143- clusters
144- ) ;
145- fetchConfig ( ) ;
146- return ( ) => {
147- if ( window . clusterConfigFetchHandler ) {
148- clearInterval ( window . clusterConfigFetchHandler ) ;
149- }
150- } ;
151- } , [ ] ) ;
190+ useQuery ( {
191+ queryKey : [ 'cluster-fetch' ] ,
192+ queryFn : ( ) => fetchConfig ( dispatch ) ,
193+ refetchInterval : CLUSTER_FETCH_INTERVAL ,
194+ } ) ;
152195
153196 // Remove any styles from the body
154197 useEffect ( ( ) => {
155198 document . body . removeAttribute ( 'style' ) ;
156199 } , [ ] ) ;
157200
158- /**
159- * Fetches the cluster config from the backend and updates the redux store
160- * if the present stored config is different from the fetched one.
161- */
162- const fetchConfig = ( ) => {
163- const clusters = store . getState ( ) . config . clusters ;
164- const statelessClusters = store . getState ( ) . config . statelessClusters ;
165-
166- request ( '/config' , { } , false , false )
167- . then ( config => {
168- const clustersToConfig : ConfigState [ 'clusters' ] = { } ;
169- config ?. clusters . forEach ( ( cluster : Cluster ) => {
170- if ( cluster . meta_data ?. extensions ?. headlamp_info ?. customName ) {
171- cluster . name = cluster . meta_data ?. extensions ?. headlamp_info ?. customName ;
172- }
173- clustersToConfig [ cluster . name ] = cluster ;
174- } ) ;
175-
176- const configToStore = { ...config , clusters : clustersToConfig } ;
177-
178- if ( clusters === null ) {
179- dispatch ( setConfig ( configToStore ) ) ;
180- } else {
181- // Check if the config is different
182- const configDifferent = isEqualClusterConfigs ( clusters , clustersToConfig ) ;
183-
184- if ( configDifferent ) {
185- // Merge the new config with the current config
186- const mergedClusters = mergeClusterConfigs (
187- configToStore . clusters ,
188- clusters ,
189- statelessClusters
190- ) ;
191- dispatch (
192- setConfig ( {
193- ...configToStore ,
194- clusters : mergedClusters ,
195- } )
196- ) ;
197- }
198- }
199-
200- /**
201- * Fetches the stateless cluster config from the indexDB and then sends the backend to parse it
202- * only if the stateless cluster config is enabled in the backend.
203- */
204- if ( config ?. isDynamicClusterEnabled ) {
205- fetchStatelessClusterKubeConfigs ( dispatch ) ;
206- }
207- } )
208- . catch ( err => {
209- console . error ( 'Error getting config:' , err ) ;
210- } ) ;
211- } ;
212-
213201 const urlClusters = getSelectedClusters ( ) ;
214202 const clustersNotInURL =
215203 allClusters && urlClusters . length !== 0
0 commit comments