From 94abce5eb0650beb9d705864cb821e82b9f5523c Mon Sep 17 00:00:00 2001 From: Oleksandr Dubenko Date: Mon, 2 Dec 2024 17:12:36 +0100 Subject: [PATCH 1/3] frontend: Move useKubeObject key into a separate function Signed-off-by: Oleksandr Dubenko --- frontend/src/lib/k8s/api/v2/hooks.ts | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/frontend/src/lib/k8s/api/v2/hooks.ts b/frontend/src/lib/k8s/api/v2/hooks.ts index 68b38187ae..bde11f2425 100644 --- a/frontend/src/lib/k8s/api/v2/hooks.ts +++ b/frontend/src/lib/k8s/api/v2/hooks.ts @@ -65,6 +65,20 @@ export interface QueryListResponse clusterErrors?: Record | null; } +export const kubeObjectQueryKey = ({ + cluster, + endpoint, + namespace, + name, + queryParams, +}: { + cluster: string; + endpoint?: KubeObjectEndpoint | null; + namespace?: string; + name: string; + queryParams?: QueryParameters; +}) => ['object', cluster, endpoint, namespace ?? '', name, queryParams ?? {}]; + /** * Returns a single KubeObject. */ @@ -94,7 +108,8 @@ export function useKubeObject({ ); const queryKey = useMemo( - () => ['object', cluster, endpoint, namespace ?? '', name, cleanedUpQueryParams], + () => + kubeObjectQueryKey({ cluster, name, namespace, endpoint, queryParams: cleanedUpQueryParams }), [endpoint, namespace, name] ); From c72b442aefc5a9db7dede65a71d79737d0aa8afb Mon Sep 17 00:00:00 2001 From: Oleksandr Dubenko Date: Mon, 2 Dec 2024 17:12:57 +0100 Subject: [PATCH 2/3] frontend: Use Link component in workload Overview page Signed-off-by: Oleksandr Dubenko --- frontend/src/components/workload/Overview.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/frontend/src/components/workload/Overview.tsx b/frontend/src/components/workload/Overview.tsx index bd96119d14..c39df79fa8 100644 --- a/frontend/src/components/workload/Overview.tsx +++ b/frontend/src/components/workload/Overview.tsx @@ -1,7 +1,6 @@ import Grid from '@mui/material/Grid'; import React, { useMemo } from 'react'; import { useTranslation } from 'react-i18next'; -import { useLocation } from 'react-router-dom'; import CronJob from '../../lib/k8s/cronJob'; import DaemonSet from '../../lib/k8s/daemonSet'; import Deployment from '../../lib/k8s/deployment'; @@ -13,7 +12,7 @@ import { WorkloadClass } from '../../lib/k8s/Workload'; import { Workload } from '../../lib/k8s/Workload'; import { getReadyReplicas, getTotalReplicas } from '../../lib/util'; import Link from '../common/Link'; -import { PageGrid, ResourceLink } from '../common/Resource'; +import { PageGrid } from '../common/Resource'; import ResourceListView from '../common/Resource/ResourceListView'; import { SectionBox } from '../common/SectionBox'; import { WorkloadCircleChart } from './Charts'; @@ -44,7 +43,6 @@ export default function Overview() { [pods, deployments, statefulSets, daemonSets, replicaSets, jobs, cronJobs] ); - const location = useLocation(); const { t } = useTranslation('glossary'); function getPods(item: Workload) { @@ -130,7 +128,7 @@ export default function Overview() { id: 'name', label: t('translation|Name'), getValue: item => item.metadata.name, - render: item => , + render: item => , }, 'namespace', 'cluster', From 3b423a494235af31ffff71cd297ff02bafe064d7 Mon Sep 17 00:00:00 2001 From: Oleksandr Dubenko Date: Mon, 2 Dec 2024 17:14:08 +0100 Subject: [PATCH 3/3] frontend: Separate Link case where kubeObject is passed and prepopulate cache Signed-off-by: Oleksandr Dubenko --- frontend/src/components/common/Link.tsx | 39 +++++++++++++++++++++---- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/frontend/src/components/common/Link.tsx b/frontend/src/components/common/Link.tsx index 0551ee387e..69f1155a73 100644 --- a/frontend/src/components/common/Link.tsx +++ b/frontend/src/components/common/Link.tsx @@ -1,6 +1,8 @@ import MuiLink from '@mui/material/Link'; +import { useQueryClient } from '@tanstack/react-query'; import React from 'react'; import { Link as RouterLink } from 'react-router-dom'; +import { kubeObjectQueryKey, useEndpoints } from '../../lib/k8s/api/v2/hooks'; import { KubeObject } from '../../lib/k8s/KubeObject'; import { createRouteURL, RouteURLProps } from '../../lib/router'; import { LightTooltip } from './Tooltip'; @@ -28,14 +30,41 @@ export interface LinkObjectProps extends LinkBaseProps { [prop: string]: any; } +function KubeObjectLink(props: { kubeObject: KubeObject; [prop: string]: any }) { + const { kubeObject, ...otherProps } = props; + + const client = useQueryClient(); + const { namespace, name } = kubeObject.metadata; + const endpoint = useEndpoints(kubeObject._class().apiEndpoint.apiInfo, kubeObject.cluster); + + return ( + { + const key = kubeObjectQueryKey({ + cluster: kubeObject.cluster, + endpoint, + namespace, + name, + }); + // prepopulate the query cache with existing object + client.setQueryData(key, kubeObject); + // and invalidate it (mark as stale) + // so that the latest version will be downloaded in the background + client.invalidateQueries({ queryKey: key }); + }} + component={RouterLink} + to={kubeObject.getDetailsLink()} + {...otherProps} + > + {props.children || kubeObject!.getName()} + + ); +} + function PureLink(props: React.PropsWithChildren) { if ((props as LinkObjectProps).kubeObject) { const { kubeObject, ...otherProps } = props as LinkObjectProps; - return ( - - {props.children || kubeObject!.getName()} - - ); + return ; } const { routeName, params = {}, search, state, ...otherProps } = props as LinkProps;