Skip to content

Commit ad01d08

Browse files
frontend: src: Use kind and apiGroup for Link component routing
frontend: src: Change apiVersion to apiGroup and fix linting error frontend: src: Fix check using kind and apiGroup
1 parent 022469e commit ad01d08

File tree

1 file changed

+90
-52
lines changed

1 file changed

+90
-52
lines changed

frontend/src/components/common/Link.tsx

Lines changed: 90 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import React from 'react';
2020
import { Link as RouterLink } from 'react-router-dom';
2121
import { formatClusterPathParam, getCluster, getSelectedClusters } from '../../lib/cluster';
2222
import { kubeObjectQueryKey, useEndpoints } from '../../lib/k8s/api/v2/hooks';
23-
import type { KubeObject } from '../../lib/k8s/KubeObject';
23+
import type { KubeObject, KubeObjectClass } from '../../lib/k8s/KubeObject';
2424
import type { RouteURLProps } from '../../lib/router/createRouteURL';
2525
import { createRouteURL } from '../../lib/router/createRouteURL';
2626
import { useTypedSelector } from '../../redux/hooks';
@@ -64,7 +64,10 @@ function KubeObjectLink(props: {
6464

6565
const client = useQueryClient();
6666
const { namespace, name } = kubeObject.metadata;
67-
const { endpoint } = useEndpoints(kubeObject._class().apiEndpoint.apiInfo, kubeObject.cluster);
67+
const { endpoint } = useEndpoints(
68+
(kubeObject.constructor as KubeObjectClass).apiEndpoint.apiInfo,
69+
kubeObject.cluster
70+
);
6871

6972
return (
7073
<MuiLink
@@ -141,68 +144,102 @@ function PureLink(
141144
);
142145
}
143146

147+
function getApiGroup(apiVersion: string) {
148+
if (!apiVersion) return '';
149+
if (!apiVersion.includes('/')) return '';
150+
return apiVersion.split('/')[0];
151+
}
152+
144153
export default function Link(props: React.PropsWithChildren<LinkProps | LinkObjectProps>) {
145154
const drawerEnabled = useTypedSelector(state => state?.drawerMode?.isDetailDrawerEnabled);
146155

147156
const { tooltip, ...propsRest } = props as LinkObjectProps;
148157

149-
const kind = 'kubeObject' in props ? props.kubeObject?._class().kind : props?.routeName;
158+
const kind = 'kubeObject' in props ? props.kubeObject?.kind : props?.routeName;
150159
const cluster =
151160
'kubeObject' in props && props.kubeObject?.cluster
152161
? props.kubeObject?.cluster
153162
: props.activeCluster ?? getCluster() ?? '';
154163

164+
let matchesStandard = true;
165+
166+
if ('kubeObject' in props && props.kubeObject) {
167+
const obj = props.kubeObject;
168+
const objClass = obj.constructor as KubeObjectClass;
169+
170+
171+
// 1. The Class explicitly claims the same 'kind' as the object instance.
172+
// 2. The Class explicitly claims the same 'apiGroup' (via apiVersion) as the object instance.
173+
const kindMatches = objClass.kind === obj.kind;
174+
let groupMatches = false;
175+
176+
if (obj.jsonData && obj.jsonData.apiVersion && objClass.apiVersion) {
177+
const instanceGroup = getApiGroup(obj.jsonData.apiVersion);
178+
const classVersions = Array.isArray(objClass.apiVersion)
179+
? objClass.apiVersion
180+
: [objClass.apiVersion];
181+
const classGroups = classVersions.map(v => getApiGroup(v));
182+
183+
if (classGroups.includes(instanceGroup)) {
184+
groupMatches = true;
185+
}
186+
}
187+
188+
if (!kindMatches || !groupMatches) {
189+
matchesStandard = false;
190+
}
191+
}
192+
155193
const openDrawer =
156-
drawerEnabled && canRenderDetails(kind)
194+
drawerEnabled && canRenderDetails(kind) && matchesStandard
157195
? () => {
158-
// Object information can be provided throught kubeObject or route parameters
159-
const name = 'kubeObject' in props ? props.kubeObject?.getName() : props.params?.name;
160-
const namespace =
161-
'kubeObject' in props ? props.kubeObject?.getNamespace() : props.params?.namespace;
162-
163-
const selectedResource =
164-
kind === 'customresource'
165-
? {
166-
// Custom resource links don't follow the same convention
167-
// so we need to create a different object
168-
kind,
169-
metadata: {
170-
name: props.params?.crName,
171-
namespace,
172-
},
173-
cluster,
174-
customResourceDefinition: props.params?.crd,
175-
}
176-
: { kind, metadata: { name, namespace }, cluster };
177-
178-
Activity.launch({
179-
id:
180-
'details' +
181-
selectedResource.kind +
182-
' ' +
183-
selectedResource.metadata.name +
184-
selectedResource.cluster,
185-
title: selectedResource.kind + ' ' + selectedResource.metadata.name,
186-
hideTitleInHeader: true,
187-
location: 'split-right',
188-
cluster: selectedResource.cluster,
189-
temporary: true,
190-
content: (
191-
<KubeObjectDetails
192-
resource={{
193-
kind: selectedResource.kind,
194-
metadata: {
195-
name: selectedResource.metadata.name,
196-
namespace: selectedResource.metadata.namespace,
197-
},
198-
cluster: selectedResource.cluster,
199-
}}
200-
customResourceDefinition={selectedResource.customResourceDefinition}
201-
/>
202-
),
203-
icon: <KubeIcon kind={selectedResource.kind} width="100%" height="100%" />,
204-
});
205-
}
196+
197+
const name = 'kubeObject' in props ? props.kubeObject?.getName() : props.params?.name;
198+
const namespace =
199+
'kubeObject' in props ? props.kubeObject?.getNamespace() : props.params?.namespace;
200+
201+
const selectedResource =
202+
kind === 'customresource'
203+
? {
204+
205+
kind,
206+
metadata: {
207+
name: props.params?.crName,
208+
namespace,
209+
},
210+
cluster,
211+
customResourceDefinition: props.params?.crd,
212+
}
213+
: { kind, metadata: { name, namespace }, cluster };
214+
215+
Activity.launch({
216+
id:
217+
'details' +
218+
selectedResource.kind +
219+
' ' +
220+
selectedResource.metadata.name +
221+
selectedResource.cluster,
222+
title: selectedResource.kind + ' ' + selectedResource.metadata.name,
223+
hideTitleInHeader: true,
224+
location: 'split-right',
225+
cluster: selectedResource.cluster,
226+
temporary: true,
227+
content: (
228+
<KubeObjectDetails
229+
resource={{
230+
kind: selectedResource.kind,
231+
metadata: {
232+
name: selectedResource.metadata.name,
233+
namespace: selectedResource.metadata.namespace,
234+
},
235+
cluster: selectedResource.cluster,
236+
}}
237+
customResourceDefinition={selectedResource.customResourceDefinition}
238+
/>
239+
),
240+
icon: <KubeIcon kind={selectedResource.kind} width="100%" height="100%" />,
241+
});
242+
}
206243
: undefined;
207244

208245
const link = <PureLink {...propsRest} onClick={openDrawer} />;
@@ -228,3 +265,4 @@ export default function Link(props: React.PropsWithChildren<LinkProps | LinkObje
228265

229266
return link;
230267
}
268+

0 commit comments

Comments
 (0)