Skip to content

Commit

Permalink
Add support for disabling resource details links on extensions list p…
Browse files Browse the repository at this point in the history
…ages

Also rename the extension `displayname` field to `displayName`. Keep support
for `displayname` for backwards compatibility. It is now deprecated and will
be removed after a few releases.
  • Loading branch information
AlanGreene authored and tekton-robot committed Jul 3, 2024
1 parent 8784fb2 commit b0813c6
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 24 deletions.
2 changes: 1 addition & 1 deletion base/202-extension-crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ spec:
jsonPath: .spec.name
- name: Display name
type: string
jsonPath: .spec.displayname
jsonPath: .spec.displayName
- name: Age
type: date
jsonPath: .metadata.creationTimestamp
Expand Down
15 changes: 8 additions & 7 deletions docs/extensions.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,13 @@ See the [Example: Register a CronJob extension](#example-register-a-cronjob-exte

#### ExtensionSpec

| Variable Name | Type | Required | Default | Description |
|---------------|-------------------|----------|---------|------------------------------------------------------------------|
| apiVersion | string | Yes | - | Extension resource group |
| name | string | Yes | - | Extension resource name |
| displayname | string | Yes | - | Display name in the Dashboard UI |
| namespaced | boolean | No | true | Specifies whether the Extension represents a namespaced resource |
| Variable Name | Type | Required | Default | Description |
|-----------------------------|-------------------|----------|---------|------------------------------------------------------------------|
| apiVersion | string | Yes | - | Extension resource group |
| name | string | Yes | - | Extension resource name |
| disableResourceDetailsLinks | boolean | No | false | Disable display of links to resource details pages |
| displayName | string | Yes | - | Display name in the Dashboard UI |
| namespaced | boolean | No | true | Specifies whether the Extension represents a namespaced resource |

### Example: Register a CronJob extension

Expand All @@ -61,7 +62,7 @@ metadata:
spec:
apiVersion: batch/v1
name: cronjobs
displayname: k8s cronjobs
displayName: k8s cronjobs
EOF
```

Expand Down
2 changes: 1 addition & 1 deletion packages/e2e/cypress/e2e/common/extensions.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ metadata:
spec:
apiVersion: core/v1
name: namespaces
displayname: Namespaces
displayName: Namespaces
`);

cy.contains(`.${carbonPrefix}--side-nav a`, 'Namespaces').click();
Expand Down
11 changes: 9 additions & 2 deletions src/api/extensions.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,19 @@ export function useExtensions(params, queryConfig) {
return {
...query,
data: (data || []).map(({ spec }) => {
const { displayname: displayName, name, namespaced } = spec;
const {
disableResourceDetailsLinks,
displayname, // keep for backwards compatibility for a few releases
displayName,
name,
namespaced
} = spec;
const [apiGroup, apiVersion] = spec.apiVersion.split('/');
return {
apiGroup,
apiVersion,
displayName,
disableResourceDetailsLinks,
displayName: displayName || displayname,
name,
namespaced
};
Expand Down
34 changes: 34 additions & 0 deletions src/api/extensions.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,40 @@ import * as API from './extensions';
import * as utils from './utils';

it('useExtensions', () => {
const name = 'fake_name';
const group = 'fake_group';
const version = 'fake_version';
const apiVersion = `${group}/${version}`;
const displayName = 'fake_displayName';
const namespaced = true;
const query = {
data: [{ spec: { apiVersion, displayName, name, namespaced } }]
};
const params = { fake: 'params' };
vi.spyOn(utils, 'useCollection').mockImplementation(() => query);
const extensions = API.useExtensions(params);
expect(utils.useCollection).toHaveBeenCalledWith(
expect.objectContaining({
group: utils.dashboardAPIGroup,
kind: 'extensions',
params,
version: 'v1alpha1'
})
);
expect(extensions).toEqual({
data: [
{
apiGroup: group,
apiVersion: version,
displayName,
name,
namespaced
}
]
});
});

it('useExtensions displayname backwards compatibility', () => {
const name = 'fake_name';
const group = 'fake_group';
const version = 'fake_version';
Expand Down
43 changes: 30 additions & 13 deletions src/containers/ResourceList/ResourceList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ import ListPageLayout from '../ListPageLayout';
import {
useAPIResource,
useCustomResources,
useSelectedNamespace
useExtensions,
useSelectedNamespace,
useTenantNamespaces
} from '../../api';

export function ResourceListContainer() {
Expand All @@ -35,18 +37,29 @@ export function ResourceListContainer() {
const matches = useMatches();
const params = useParams();

const tenantNamespaces = useTenantNamespaces();
const { data: extensions = [] } = useExtensions(
{
namespace: tenantNamespaces[0] || ALL_NAMESPACES
},
{ disableWebSocket: true, retryOnMount: false }
);

const { namespace: namespaceParam } = params;
const match = matches.at(-1);
const handle = match.handle || {};
let { group, kind, version } = handle;
const { resourceURL, title } = handle;

let isExtension = false;
let extension;
if (!(group && kind && version)) {
// we're on a kubernetes resource extension page
// grab values directly from the URL
({ group, kind, version } = params);
isExtension = true;
extension = extensions?.find(
({ apiGroup, apiVersion, name }) =>
apiGroup === group && apiVersion === version && kind === name
);
}

const { selectedNamespace } = useSelectedNamespace();
Expand All @@ -59,12 +72,12 @@ export function ResourceListContainer() {
data: apiResource,
error: apiResourceError,
isLoading: isLoadingAPIResource
} = useAPIResource({ group, kind, version }, { enabled: isExtension });
const isNamespaced = isExtension
} = useAPIResource({ group, kind, version }, { enabled: !!extension });
const isNamespaced = extension
? !isLoadingAPIResource && apiResource?.namespaced
: handle?.isNamespaced;

if (isExtension && typeof apiResource?.namespaced !== 'undefined') {
if (extension && typeof apiResource?.namespaced !== 'undefined') {
// dynamically toggle the namespace dropdown behaviour depending on
// whether the kind is namespaced or cluster-scoped
match.handle.isNamespaced = isNamespaced;
Expand All @@ -83,7 +96,7 @@ export function ResourceListContainer() {
version
},
{
enabled: !isExtension || (!isLoadingAPIResource && !apiResourceError)
enabled: !extension || (!isLoadingAPIResource && !apiResourceError)
}
);

Expand Down Expand Up @@ -176,7 +189,7 @@ export function ResourceListContainer() {
})
}
].filter(Boolean)}
loading={(isExtension && isLoadingAPIResource) || isLoadingResources}
loading={(extension && isLoadingAPIResource) || isLoadingResources}
rows={paginatedResources.map(resource => {
const {
creationTimestamp,
Expand All @@ -185,15 +198,19 @@ export function ResourceListContainer() {
uid
} = resource.metadata;

let resourceLink;
if (!extension?.disableResourceDetailsLinks) {
resourceLink = getResourceURL({ name, resourceNamespace });
}

return {
id: uid,
name: (
<Link
to={getResourceURL({ name, resourceNamespace })}
title={name}
>
name: resourceLink ? (
<Link to={resourceLink} title={name}>
{name}
</Link>
) : (
name
),
namespace: resourceNamespace,
createdTime: <FormattedDate date={creationTimestamp} relative />
Expand Down

0 comments on commit b0813c6

Please sign in to comment.