Skip to content

Commit bfbe74a

Browse files
committed
frontend: Use react-query for cluster config fetching
1 parent 35f4bf1 commit bfbe74a

File tree

1 file changed

+58
-70
lines changed

1 file changed

+58
-70
lines changed

frontend/src/components/App/Layout.tsx

Lines changed: 58 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import Container from '@mui/material/Container';
2020
import CssBaseline from '@mui/material/CssBaseline';
2121
import Link from '@mui/material/Link';
2222
import { styled } from '@mui/material/styles';
23+
import { Dispatch, UnknownAction } from '@reduxjs/toolkit';
24+
import { useQuery } from '@tanstack/react-query';
2325
import { useEffect } from 'react';
2426
import { useTranslation } from 'react-i18next';
2527
import { 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+
124177
export 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

Comments
 (0)