Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for disabling resource details links on extensions list pages #3489

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading