Skip to content

Commit 0effcdc

Browse files
committed
OCPBUGS-69387: update operator details when changing channels
1 parent 99c3437 commit 0effcdc

11 files changed

+261
-39
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import * as React from 'react';
2+
import { useCurrentChannel } from '../../hooks/useCurrentChannel';
3+
import { PackageManifestKind } from '../../types';
4+
import { CapabilityLevel } from './operator-hub-item-details';
5+
6+
export const OperatorCapability: React.FC<OperatorCapabilityProps> = ({ packageManifest }) => {
7+
const currentChannel = useCurrentChannel(packageManifest);
8+
const capabilities = currentChannel?.currentCSVDesc?.annotations?.capabilities;
9+
10+
return capabilities ? <CapabilityLevel capability={capabilities} /> : <>-</>;
11+
};
12+
13+
type OperatorCapabilityProps = {
14+
packageManifest: PackageManifestKind;
15+
};
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import * as React from 'react';
2+
import { useCurrentChannel } from '../../hooks/useCurrentChannel';
3+
import { PackageManifestKind } from '../../types';
4+
5+
export const OperatorContainerImage: React.FC<OperatorContainerImageProps> = ({
6+
packageManifest,
7+
}) => {
8+
const currentChannel = useCurrentChannel(packageManifest);
9+
const containerImage = currentChannel?.currentCSVDesc?.annotations?.containerImage;
10+
11+
return <>{containerImage || '-'}</>;
12+
};
13+
14+
type OperatorContainerImageProps = {
15+
packageManifest: PackageManifestKind;
16+
};
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import * as React from 'react';
2+
import { Timestamp } from '@console/shared/src/components/datetime/Timestamp';
3+
import { useCurrentChannel } from '../../hooks/useCurrentChannel';
4+
import { PackageManifestKind } from '../../types';
5+
6+
export const OperatorCreatedAt: React.FC<OperatorCreatedAtProps> = ({ packageManifest }) => {
7+
const currentChannel = useCurrentChannel(packageManifest);
8+
const createdAt = currentChannel?.currentCSVDesc?.annotations?.createdAt;
9+
10+
return createdAt && !Number.isNaN(Date.parse(createdAt)) ? (
11+
<Timestamp timestamp={createdAt} />
12+
) : (
13+
<>{createdAt || '-'}</>
14+
);
15+
};
16+
17+
type OperatorCreatedAtProps = {
18+
packageManifest: PackageManifestKind;
19+
};

frontend/packages/operator-lifecycle-manager/src/components/operator-hub/operator-hub-item-details.tsx

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,12 @@ import { DeprecatedOperatorWarningAlert } from '../deprecated-operator-warnings/
3434
import { useDeprecatedOperatorWarnings } from '../deprecated-operator-warnings/use-deprecated-operator-warnings';
3535
import { defaultChannelNameFor } from '../index';
3636
import { OperatorChannelSelect, OperatorVersionSelect } from './operator-channel-version-select';
37-
import { isAWSSTSCluster, isAzureWIFCluster, isGCPWIFCluster } from './operator-hub-utils';
37+
import {
38+
isAWSSTSCluster,
39+
isAzureWIFCluster,
40+
isGCPWIFCluster,
41+
getInfrastructureFeatures,
42+
} from './operator-hub-utils';
3843
import { InfrastructureFeature, OperatorHubItem } from './index';
3944

4045
// t('olm~Basic Install'),
@@ -225,7 +230,6 @@ const OperatorHubItemDetailsHint: React.FCC<OperatorHubItemDetailsHintProps> = (
225230
export const OperatorDescription: React.FCC<OperatorDescriptionProps> = ({
226231
catalogSource,
227232
description,
228-
infraFeatures,
229233
installed,
230234
isInstalling,
231235
subscription,
@@ -251,6 +255,24 @@ export const OperatorDescription: React.FCC<OperatorDescriptionProps> = ({
251255
const currentCSVDescription = useCurrentCSVDescription(packageManifest);
252256
const selectedChannelDescription = currentCSVDescription?.description || longDescription;
253257
const packageManifestStatus = packageManifest?.status;
258+
259+
// Get infrastructure features from the current channel's CSV description
260+
const infraFeatures = React.useMemo(() => {
261+
const currentCSVAnnotations = currentCSVDescription?.annotations ?? {};
262+
return getInfrastructureFeatures(currentCSVAnnotations, {
263+
clusterIsAWSSTS,
264+
clusterIsAzureWIF,
265+
clusterIsGCPWIF,
266+
onError: (error) => {
267+
// eslint-disable-next-line no-console
268+
console.warn(
269+
`Error parsing infrastructure features from PackageManifest "${packageManifest?.metadata?.name}":`,
270+
error,
271+
);
272+
},
273+
});
274+
}, [currentCSVDescription, clusterIsAWSSTS, clusterIsAzureWIF, clusterIsGCPWIF, packageManifest]);
275+
254276
const [isTokenAuth, isTokenAuthGCP] = React.useMemo(() => {
255277
return [
256278
(infraFeatures ?? []).includes(InfrastructureFeature.TokenAuth),
@@ -337,7 +359,6 @@ export const OperatorHubItemDetails: React.FCC<OperatorHubItemDetailsProps> = ({
337359
catalogSource,
338360
source,
339361
description,
340-
infraFeatures,
341362
installed,
342363
isInstalling,
343364
longDescription,
@@ -363,6 +384,28 @@ export const OperatorHubItemDetails: React.FCC<OperatorHubItemDetailsProps> = ({
363384

364385
const mappedData = (data) => data?.map?.((d) => <div key={d}>{d}</div>) ?? notAvailable;
365386

387+
const selectedUpdateChannel = updateChannel || defaultChannelNameFor(obj);
388+
const clusterIsAWSSTS = isAWSSTSCluster(cloudCredentials, infrastructure, authentication);
389+
const clusterIsAzureWIF = isAzureWIFCluster(cloudCredentials, infrastructure, authentication);
390+
const clusterIsGCPWIF = isGCPWIFCluster(cloudCredentials, infrastructure, authentication);
391+
392+
// Get infrastructure features from the current channel's CSV description
393+
const infraFeatures = React.useMemo(() => {
394+
const currentCSVAnnotations = currentCSVDescription?.annotations ?? {};
395+
return getInfrastructureFeatures(currentCSVAnnotations, {
396+
clusterIsAWSSTS,
397+
clusterIsAzureWIF,
398+
clusterIsGCPWIF,
399+
onError: (error) => {
400+
// eslint-disable-next-line no-console
401+
console.warn(
402+
`Error parsing infrastructure features from PackageManifest "${obj?.metadata?.name}":`,
403+
error,
404+
);
405+
},
406+
});
407+
}, [currentCSVDescription, clusterIsAWSSTS, clusterIsAzureWIF, clusterIsGCPWIF, obj]);
408+
366409
const mappedInfraFeatures = mappedData(infraFeatures);
367410
const mappedValidSubscription = mappedData(validSubscription);
368411

@@ -380,11 +423,6 @@ export const OperatorHubItemDetails: React.FCC<OperatorHubItemDetailsProps> = ({
380423
return null;
381424
}, [marketplaceSupportWorkflow]);
382425

383-
const selectedUpdateChannel = updateChannel || defaultChannelNameFor(obj);
384-
const clusterIsAWSSTS = isAWSSTSCluster(cloudCredentials, infrastructure, authentication);
385-
const clusterIsAzureWIF = isAzureWIFCluster(cloudCredentials, infrastructure, authentication);
386-
const clusterIsGCPWIF = isGCPWIFCluster(cloudCredentials, infrastructure, authentication);
387-
388426
return item ? (
389427
<div className="modal-body modal-body-border">
390428
<CatalogPageOverlay>
@@ -453,7 +491,6 @@ export const OperatorHubItemDetails: React.FCC<OperatorHubItemDetailsProps> = ({
453491
<OperatorDescription
454492
catalogSource={catalogSource}
455493
description={description}
456-
infraFeatures={infraFeatures}
457494
installed={installed}
458495
isInstalling={isInstalling}
459496
subscription={subscription}
@@ -496,7 +533,6 @@ type OperatorHubItemDetailsHintProps = {
496533
export type OperatorDescriptionProps = {
497534
catalogSource: string;
498535
description: string;
499-
infraFeatures: InfrastructureFeature[];
500536
installed: boolean;
501537
isInstalling: boolean;
502538
subscription: SubscriptionKind;
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import * as React from 'react';
2+
import { PlainList } from '@console/shared/src';
3+
import { useCurrentChannel } from '../../hooks/useCurrentChannel';
4+
import { PackageManifestKind } from '../../types';
5+
import { getInfrastructureFeatures } from './operator-hub-utils';
6+
import type { CSVAnnotations } from './index';
7+
8+
export const OperatorInfrastructureFeatures: React.FC<OperatorInfrastructureFeaturesProps> = ({
9+
packageManifest,
10+
clusterIsAWSSTS,
11+
clusterIsAzureWIF,
12+
clusterIsGCPWIF,
13+
}) => {
14+
const currentChannel = useCurrentChannel(packageManifest);
15+
const currentCSVAnnotations: CSVAnnotations = currentChannel?.currentCSVDesc?.annotations ?? {};
16+
17+
const infrastructureFeatures = getInfrastructureFeatures(currentCSVAnnotations, {
18+
clusterIsAWSSTS,
19+
clusterIsAzureWIF,
20+
clusterIsGCPWIF,
21+
onError: (error) =>
22+
// eslint-disable-next-line no-console
23+
console.warn(
24+
`Error parsing infrastructure features from PackageManifest "${packageManifest.metadata.name}":`,
25+
error,
26+
),
27+
});
28+
29+
return infrastructureFeatures?.length ? <PlainList items={infrastructureFeatures} /> : <>-</>;
30+
};
31+
32+
type OperatorInfrastructureFeaturesProps = {
33+
packageManifest: PackageManifestKind;
34+
clusterIsAWSSTS: boolean;
35+
clusterIsAzureWIF: boolean;
36+
clusterIsGCPWIF: boolean;
37+
};
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import * as React from 'react';
2+
import { ExternalLink } from '@console/shared/src/components/links/ExternalLink';
3+
import { useCurrentChannel } from '../../hooks/useCurrentChannel';
4+
import { PackageManifestKind } from '../../types';
5+
6+
export const OperatorRepository: React.FC<OperatorRepositoryProps> = ({ packageManifest }) => {
7+
const currentChannel = useCurrentChannel(packageManifest);
8+
const repository = currentChannel?.currentCSVDesc?.annotations?.repository;
9+
10+
return repository ? <ExternalLink href={repository} text={repository} /> : <>-</>;
11+
};
12+
13+
type OperatorRepositoryProps = {
14+
packageManifest: PackageManifestKind;
15+
};
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import * as React from 'react';
2+
import { useTranslation } from 'react-i18next';
3+
import { ExternalLink } from '@console/shared/src/components/links/ExternalLink';
4+
import { useCurrentChannel } from '../../hooks/useCurrentChannel';
5+
import { PackageManifestKind } from '../../types';
6+
import { getSupportWorkflowUrl } from './operator-hub-utils';
7+
8+
export const OperatorSupport: React.FC<OperatorSupportProps> = ({ packageManifest }) => {
9+
const { t } = useTranslation('olm');
10+
const currentChannel = useCurrentChannel(packageManifest);
11+
const currentCSVAnnotations = currentChannel?.currentCSVDesc?.annotations ?? {};
12+
const support = currentCSVAnnotations?.support;
13+
const marketplaceSupportWorkflow =
14+
currentCSVAnnotations?.['marketplace.openshift.io/support-workflow'];
15+
const supportWorkflowUrl = getSupportWorkflowUrl(marketplaceSupportWorkflow);
16+
17+
return supportWorkflowUrl ? (
18+
<ExternalLink href={supportWorkflowUrl}>{t('Get support')}</ExternalLink>
19+
) : (
20+
<>{support || '-'}</>
21+
);
22+
};
23+
24+
type OperatorSupportProps = {
25+
packageManifest: PackageManifestKind;
26+
};
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import * as React from 'react';
2+
import { PlainList } from '@console/shared/src';
3+
import { useCurrentChannel } from '../../hooks/useCurrentChannel';
4+
import { PackageManifestKind } from '../../types';
5+
import { getValidSubscription } from './operator-hub-utils';
6+
import type { CSVAnnotations } from './index';
7+
8+
export const OperatorValidSubscriptions: React.FC<OperatorValidSubscriptionsProps> = ({
9+
packageManifest,
10+
}) => {
11+
const currentChannel = useCurrentChannel(packageManifest);
12+
const currentCSVAnnotations: CSVAnnotations = currentChannel?.currentCSVDesc?.annotations ?? {};
13+
14+
const [validSubscription] = getValidSubscription(currentCSVAnnotations, {
15+
onError: (error) =>
16+
// eslint-disable-next-line no-console
17+
console.warn(
18+
`Error parsing valid subscription from PackageManifest "${packageManifest.metadata.name}":`,
19+
error,
20+
),
21+
});
22+
23+
return validSubscription?.length ? <PlainList items={validSubscription} /> : <>-</>;
24+
};
25+
26+
type OperatorValidSubscriptionsProps = {
27+
packageManifest: PackageManifestKind;
28+
};
Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,20 @@
1-
import { getQueryArgument } from '@console/internal/components/utils';
1+
import { useSearchParams } from 'react-router-dom-v5-compat';
22
import { CSVDescription, PackageManifestKind } from '../types';
33

4-
export const useCurrentCSVDescription: UseCurrentCSVDescription = (packageManifest) => {
5-
const installChannel = getQueryArgument('channel') ?? packageManifest?.status?.defaultChannel;
4+
export const useCurrentCSVDescription: UseCurrentCSVDescription = (
5+
packageManifest,
6+
selectedChannel?,
7+
) => {
8+
const [searchParams] = useSearchParams();
9+
const installChannel =
10+
selectedChannel ?? searchParams.get('channel') ?? packageManifest?.status?.defaultChannel;
611
const currentChannel =
712
packageManifest?.status.channels.find((ch) => ch.name === installChannel) ??
813
packageManifest?.status.channels[0];
914
return currentChannel?.currentCSVDesc;
1015
};
1116

12-
type UseCurrentCSVDescription = (packageManifest: PackageManifestKind) => CSVDescription;
17+
type UseCurrentCSVDescription = (
18+
packageManifest: PackageManifestKind,
19+
selectedChannel?: string,
20+
) => CSVDescription;
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { useSearchParams } from 'react-router-dom-v5-compat';
2+
import { PackageManifestKind } from '../types';
3+
4+
/**
5+
* Returns the currently selected channel based on URL query parameters,
6+
* falling back to the default channel or the first available channel.
7+
*/
8+
export const useCurrentChannel = (
9+
packageManifest: PackageManifestKind,
10+
): PackageManifestKind['status']['channels'][number] | undefined => {
11+
const [searchParams] = useSearchParams();
12+
const selectedChannel =
13+
searchParams.get('channel') ||
14+
packageManifest?.status?.defaultChannel ||
15+
packageManifest?.status?.channels?.[0]?.name;
16+
17+
const currentChannel = packageManifest?.status?.channels?.find(
18+
(ch) => ch.name === selectedChannel,
19+
);
20+
21+
return currentChannel;
22+
};

0 commit comments

Comments
 (0)