@@ -20,7 +20,7 @@ import React from 'react';
2020import { Link as RouterLink } from 'react-router-dom' ;
2121import { formatClusterPathParam , getCluster , getSelectedClusters } from '../../lib/cluster' ;
2222import { 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' ;
2424import type { RouteURLProps } from '../../lib/router/createRouteURL' ;
2525import { createRouteURL } from '../../lib/router/createRouteURL' ;
2626import { 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+
144153export 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