Skip to content

Commit afacd9d

Browse files
authored
MGMT-20135: Implement OpenShift versions select with "all versions" modal (#2864)
* Use OpenShift versions dropdown with modal in CIM * Openshift -> OpenShift
1 parent 60dcb56 commit afacd9d

34 files changed

+166
-97
lines changed

docs/DEVELOPMENT.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ apply for `libs/locales` as well.
8484
[README file](https://gitlab.cee.redhat.com/service/uhc-portal/-/blob/master/README.md) in order
8585
to set up their dev-environment.
8686
87-
## Integrating with the Openshift Console for ACM and MCE (aka CIM)
87+
## Integrating with the OpenShift Console for ACM and MCE (aka CIM)
8888
8989
Some components of the Assisted Installer UI are integrated into the Central Infrastructure
9090
Management project (a.k.a. [stolostron/console](https://github.com/stolostron/console)).

libs/ui-lib-tests/cypress/integration/ui-behaviour/cluster-creation.cy.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ describe('Assisted Installer UI behaviour - cluster creation', () => {
1818
});
1919

2020
describe('OpenShiftVersion tests', () => {
21-
it('Should have the correct values for the Openshift versions', () => {
21+
it('Should have the correct values for the OpenShift versions', () => {
2222
commonActions.visitNewClusterPage();
2323
clusterDetailsPage.inputOpenshiftVersion();
2424

libs/ui-lib-tests/cypress/integration/use-cases/create-cluster/with-custom-ocp-releases.cy.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ describe('Assisted Installer UI behaviour - cluster creation with custom OCP rel
4444
customOCPModal.getSearchResponse('No results found');
4545
});
4646

47-
it('Should search a custom OCP version and is shown in the Openshift dropdown modal', () => {
47+
it('Should search a custom OCP version and is shown in the OpenShift dropdown modal', () => {
4848
commonActions.visitNewClusterPage();
4949
clusterDetailsPage.openOpenshiftVersionDropdown();
5050
clusterDetailsPage.clickLinkAllAvailableVersions();

libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentDetailsForm.tsx

+10-4
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,16 @@ const ClusterDeploymentDetailsForm: React.FC<ClusterDeploymentDetailsFormProps>
9292
osImages,
9393
}) => {
9494
const { t } = useTranslation();
95-
const ocpVersions = React.useMemo(
95+
const versions = React.useMemo(
9696
() => getOCPVersions(clusterImages, isNutanix, osImages),
9797
[clusterImages, isNutanix, osImages],
9898
);
9999

100+
const allVersions = React.useMemo(
101+
() => getOCPVersions(clusterImages, isNutanix, osImages, true),
102+
[clusterImages, isNutanix, osImages],
103+
);
104+
100105
const forceOpenshiftVersion = agentClusterInstall
101106
? getSelectedVersion(clusterImages, agentClusterInstall)
102107
: undefined;
@@ -110,7 +115,7 @@ const ClusterDeploymentDetailsForm: React.FC<ClusterDeploymentDetailsFormProps>
110115
return cpuArchitectures;
111116
}
112117

113-
const openshiftVersion = ocpVersions
118+
const openshiftVersion = versions
114119
.find((ver) => ver.value === values.openshiftVersion)
115120
?.version.split('.')
116121
.slice(0, 2)
@@ -119,7 +124,7 @@ const ClusterDeploymentDetailsForm: React.FC<ClusterDeploymentDetailsFormProps>
119124
return osImages
120125
.filter((osImage) => osImage.openshiftVersion === openshiftVersion)
121126
.map((osImage) => osImage.cpuArchitecture as SupportedCpuArchitecture);
122-
}, [osImages, ocpVersions, values.openshiftVersion]);
127+
}, [osImages, versions, values.openshiftVersion]);
123128

124129
return (
125130
<>
@@ -134,7 +139,8 @@ const ClusterDeploymentDetailsForm: React.FC<ClusterDeploymentDetailsFormProps>
134139
)}
135140
<StackItem>
136141
<ClusterDetailsFormFields
137-
versions={ocpVersions}
142+
versions={versions}
143+
allVersions={allVersions}
138144
isEditFlow={isEditFlow}
139145
forceOpenshiftVersion={forceOpenshiftVersion}
140146
extensionAfter={extensionAfter}

libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDetailsFormFields.tsx

+46-10
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import * as React from 'react';
22
import { Alert, AlertVariant, FlexItem, Form } from '@patternfly/react-core';
33
import { useFormikContext } from 'formik';
44

5+
import { OpenShiftVersionDropdown, OpenShiftVersionModal } from '../../../common';
56
import { StaticTextField } from '../../../common/components/ui/StaticTextField';
6-
import OpenShiftVersionSelect from '../../../common/components/clusterConfiguration/OpenShiftVersionSelect';
77
import { PullSecret } from '../../../common/components/clusters';
88
import { OpenshiftVersionOptionType } from '../../../common/types';
99
import {
@@ -14,13 +14,14 @@ import {
1414
import { ClusterDetailsValues } from '../../../common/components/clusterWizard/types';
1515
import { useTranslation } from '../../../common/hooks/use-translation-wrapper';
1616
import CpuArchitectureDropdown from '../common/CpuArchitectureDropdown';
17-
import { getNetworkType } from '../helpers';
1817
import ControlPlaneNodesDropdown from '../../../common/components/clusterConfiguration/ControlPlaneNodesDropdown';
18+
1919
export type ClusterDetailsFormFieldsProps = {
2020
isEditFlow: boolean;
2121
forceOpenshiftVersion?: string;
2222
extensionAfter?: { [key: string]: React.ReactElement };
2323
versions: OpenshiftVersionOptionType[];
24+
allVersions: OpenshiftVersionOptionType[];
2425
isNutanix?: boolean;
2526
cpuArchitectures?: string[];
2627
};
@@ -46,13 +47,39 @@ export const BaseDnsHelperText: React.FC<{ name?: string; baseDnsDomain?: string
4647
export const ClusterDetailsFormFields: React.FC<ClusterDetailsFormFieldsProps> = ({
4748
isEditFlow,
4849
versions,
50+
allVersions,
4951
forceOpenshiftVersion,
5052
extensionAfter,
5153
isNutanix,
5254
cpuArchitectures,
5355
}) => {
54-
const { values, setFieldValue } = useFormikContext<ClusterDetailsValues>();
56+
const { values } = useFormikContext<ClusterDetailsValues>();
5557
const { name, baseDnsDomain } = values;
58+
const [openshiftVersionModalOpen, setOpenshiftVersionModalOpen] = React.useState(false);
59+
60+
const selectOptions = React.useMemo(
61+
() =>
62+
versions.map((version) => ({
63+
label: version.label,
64+
value: version.value,
65+
})),
66+
[versions],
67+
);
68+
69+
const additionalSelectOptions = React.useMemo(() => {
70+
if (
71+
values.customOpenshiftSelect &&
72+
!selectOptions.some((option) => option.value === values.customOpenshiftSelect?.value)
73+
) {
74+
return [
75+
{
76+
value: values.customOpenshiftSelect.value,
77+
label: values.customOpenshiftSelect.label,
78+
},
79+
];
80+
}
81+
return [];
82+
}, [selectOptions, values.customOpenshiftSelect]);
5683

5784
const nameInputRef = React.useRef<HTMLInputElement>();
5885
React.useEffect(() => {
@@ -102,13 +129,22 @@ export const ClusterDetailsFormFields: React.FC<ClusterDetailsFormFieldsProps> =
102129
{t('ai:OpenShift')} {forceOpenshiftVersion}
103130
</StaticTextField>
104131
) : (
105-
<OpenShiftVersionSelect
106-
versions={versions}
107-
onChange={(_event, value) => {
108-
const ocpVersion = versions.find((v) => v.value === value);
109-
setFieldValue('networkType', getNetworkType(ocpVersion));
110-
}}
111-
/>
132+
<>
133+
<OpenShiftVersionDropdown
134+
name="openshiftVersion"
135+
items={selectOptions}
136+
versions={versions}
137+
showReleasesLink={false}
138+
showOpenshiftVersionModal={() => setOpenshiftVersionModalOpen(true)}
139+
customItems={additionalSelectOptions}
140+
/>
141+
{openshiftVersionModalOpen && (
142+
<OpenShiftVersionModal
143+
allVersions={allVersions}
144+
setOpenshiftVersionModalOpen={setOpenshiftVersionModalOpen}
145+
/>
146+
)}
147+
</>
112148
)}
113149
<ControlPlaneNodesDropdown isNutanix={isNutanix} isDisabled={isEditFlow} />
114150
{!isNutanix && (

libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvFormPage.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ import { getErrorMessage } from '../../../common/utils';
4949
import { useTranslation } from '../../../common/hooks/use-translation-wrapper';
5050
import { TFunction } from 'i18next';
5151
import CpuArchitectureDropdown from '../common/CpuArchitectureDropdown';
52-
import OpenshiftVersionDropdown from './OpenshiftVersionDropdown';
52+
import InfraEnvOpenShiftVersionDropdown from './InfraEnvOpenShiftVersionDropdown';
5353
import { OsImage } from '../../types';
5454

5555
export type EnvironmentStepFormValues = {
@@ -228,7 +228,7 @@ const InfraEnvForm: React.FC<InfraEnvFormProps> = ({
228228
</Flex>
229229
</FormGroup>
230230
<CpuArchitectureDropdown />
231-
{!!osImages && <OpenshiftVersionDropdown osImages={osImages} />}
231+
{!!osImages && <InfraEnvOpenShiftVersionDropdown osImages={osImages} />}
232232
<RichInputField
233233
label={t('ai:Location')}
234234
name="location"

libs/ui-lib/lib/cim/components/InfraEnv/OpenshiftVersionDropdown.tsx libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvOpenShiftVersionDropdown.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { useTranslation } from '../../../common/hooks/use-translation-wrapper';
66
import { architectureData, getFieldId, SupportedCpuArchitecture } from '../../../common';
77
import { OsImage } from '../../types';
88

9-
const OpenshiftVersionDropdown = ({ osImages }: { osImages: OsImage[] }) => {
9+
const InfraEnvOpenShiftVersionDropdown = ({ osImages }: { osImages: OsImage[] }) => {
1010
const { t } = useTranslation();
1111
const [{ name, value }, , { setValue }] = useField<string>('osImageVersion');
1212
const [{ value: cpuArchitecture }] = useField<string>('cpuArchitecture');
@@ -69,4 +69,4 @@ const OpenshiftVersionDropdown = ({ osImages }: { osImages: OsImage[] }) => {
6969
);
7070
};
7171

72-
export default OpenshiftVersionDropdown;
72+
export default InfraEnvOpenShiftVersionDropdown;

libs/ui-lib/lib/cim/components/helpers/versions.ts

+19-5
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,18 @@ import {
66
ClusterVersionK8sResource,
77
OsImage,
88
} from '../../types';
9-
import { OpenshiftVersionOptionType } from '../../../common';
9+
import { CpuArchitecture, OpenshiftVersionOptionType } from '../../../common';
1010
import { OpenshiftVersion } from '@openshift-assisted/types/assisted-installer-service';
1111

1212
export const getVersionFromReleaseImage = (releaseImage = '') => {
13-
const match = /.+:(.*)-/gm.exec(releaseImage);
13+
const match = /.+:(.*)/gm.exec(releaseImage);
14+
if (match && match.length > 1 && match[1]) {
15+
return match[1];
16+
}
17+
};
18+
19+
const getCPUArchFromReleaseImage = (releaseImage = '') => {
20+
const match = /.+:.*-(.*)/gm.exec(releaseImage);
1421
if (match && match.length > 1 && match[1]) {
1522
return match[1];
1623
}
@@ -37,8 +44,12 @@ const getSupportLevelFromChannel = (
3744

3845
export const supportedNutanixPlatforms = ['x86_64', 'x86-64'];
3946

40-
export const isValidImageSet = (cis: ClusterImageSetK8sResource, architectures?: string[]) => {
41-
if (cis.metadata?.labels?.visible !== 'true') {
47+
export const isValidImageSet = (
48+
cis: ClusterImageSetK8sResource,
49+
architectures?: string[],
50+
extended?: boolean,
51+
) => {
52+
if (!extended && cis.metadata?.labels?.visible !== 'true') {
4253
return false;
4354
}
4455
if (!architectures) {
@@ -53,24 +64,27 @@ export const getOCPVersions = (
5364
clusterImageSets: ClusterImageSetK8sResource[],
5465
isNutanix?: boolean | undefined,
5566
osImages?: OsImage[],
67+
extended?: boolean,
5668
): OpenshiftVersionOptionType[] => {
5769
const ocpImageVersions = Array.from(
5870
new Set(osImages?.map((osImage) => osImage.openshiftVersion)),
5971
);
6072

6173
const versions = clusterImageSets
6274
.filter((clusterImageSet) =>
63-
isValidImageSet(clusterImageSet, isNutanix ? supportedNutanixPlatforms : undefined),
75+
isValidImageSet(clusterImageSet, isNutanix ? supportedNutanixPlatforms : undefined, extended),
6476
)
6577
.map((clusterImageSet): OpenshiftVersionOptionType => {
6678
const version = getVersionFromReleaseImage(clusterImageSet.spec?.releaseImage);
79+
const cpuArch = getCPUArchFromReleaseImage(clusterImageSet.spec?.releaseImage);
6780
return {
6881
label: `OpenShift ${version ? version : (clusterImageSet.metadata?.name as string)}`,
6982
version: version || clusterImageSet.metadata?.name || '',
7083
value: clusterImageSet.metadata?.name as string,
7184
default: false,
7285
// (rawagner) ACM does not have the warning so changing to 'production'
7386
supportLevel: 'production', // getSupportLevelFromChannel(clusterImageSet.metadata?.labels?.channel),
87+
cpuArchitectures: cpuArch ? [cpuArch as CpuArchitecture] : undefined,
7488
};
7589
})
7690
.filter((ocpVersion) => {

libs/ui-lib/lib/common/components/ui/OpenshiftSelectWithSearch.tsx libs/ui-lib/lib/common/components/ui/OpenShiftSelectWithSearch.tsx

+4-4
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@ import { useTranslation } from '../../hooks/use-translation-wrapper';
2222

2323
type OpenshiftSelectWithSearchProps = {
2424
versions: OpenshiftVersionOptionType[];
25-
getHelperText: HelperTextType;
25+
getHelperText?: HelperTextType;
2626
setCustomOpenshiftSelect: Dispatch<SetStateAction<OpenshiftVersionOptionType | undefined>>;
2727
};
2828

29-
export const OpenshiftSelectWithSearch: React.FunctionComponent<OpenshiftSelectWithSearchProps> = ({
29+
export const OpenShiftSelectWithSearch: React.FunctionComponent<OpenshiftSelectWithSearchProps> = ({
3030
versions,
3131
getHelperText,
3232
setCustomOpenshiftSelect,
@@ -232,7 +232,7 @@ export const OpenshiftSelectWithSearch: React.FunctionComponent<OpenshiftSelectW
232232
</MenuToggle>
233233
);
234234

235-
const helperText = getHelperText(selected, true);
235+
const helperText = getHelperText && getHelperText(selected, true);
236236

237237
return (
238238
<>
@@ -285,7 +285,7 @@ export const OpenshiftSelectWithSearch: React.FunctionComponent<OpenshiftSelectW
285285
<HelperText>
286286
<HelperTextItem variant="default">
287287
{helperText ??
288-
'Select an Openshift version from the list or use the type ahead to narrow down the list.'}
288+
'Select an OpenShift version from the list or use the type ahead to narrow down the list.'}
289289
</HelperTextItem>
290290
</HelperText>
291291
</FormHelperText>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#form-input-openshiftVersion-field .pf-v5-c-dropdown__menu {
2+
max-height: 22vh;
3+
overflow: auto;
4+
}
5+
6+
#form-input-openshiftVersion-field .pf-v5-c-dropdown__menu ul {
7+
list-style: none;
8+
padding-left: 0;
9+
}

libs/ui-lib/lib/common/components/ui/OpenShiftVersionDropdown.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,15 @@ import { getFieldId } from './formik';
2222
import ExternalLink from './ExternalLink';
2323
import { OCP_RELEASES_PAGE } from '../../config';
2424
import { ClusterDetailsValues, ItemDropdown } from '../clusterWizard';
25-
import './OpenshiftVersionDropdown.css';
25+
import './OpenShiftVersionDropdown.css';
2626

2727
export type HelperTextType = (value: string | undefined, inModal?: boolean) => JSX.Element | null;
2828

2929
type OpenShiftVersionDropdownProps = {
3030
name: string;
3131
items: ItemDropdown;
3232
versions: OpenshiftVersionOptionType[];
33-
getHelperText: HelperTextType;
33+
getHelperText?: HelperTextType;
3434
showReleasesLink: boolean;
3535
showOpenshiftVersionModal: () => void;
3636
customItems: ItemDropdown;
@@ -159,7 +159,7 @@ export const OpenShiftVersionDropdown = ({
159159
[setOpen, current, isDisabled],
160160
);
161161

162-
const helperText = getHelperText(field.value);
162+
const helperText = getHelperText && getHelperText(field.value);
163163

164164
return (
165165
<FormGroup

libs/ui-lib/lib/ocm/components/clusterConfiguration/OpenShiftVersionModal.tsx libs/ui-lib/lib/common/components/ui/OpenShiftVersionModal.tsx

+9-9
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
import React, { useState } from 'react';
22
import { Button, ButtonVariant, FormGroup, Modal, ModalVariant } from '@patternfly/react-core';
3-
import './OpenshiftVersionModal.css';
4-
import { OpenshiftSelectWithSearch } from '../../../common/components/ui/OpenshiftSelectWithSearch';
5-
import { useOpenshiftVersionsContext } from '../clusterWizard/OpenshiftVersionsContext';
6-
import { HelperTextType } from '../../../common/components/ui/OpenShiftVersionDropdown';
3+
import { OpenShiftSelectWithSearch } from './OpenShiftSelectWithSearch';
4+
import { HelperTextType } from './OpenShiftVersionDropdown';
75
import { useFormikContext } from 'formik';
8-
import { ClusterDetailsValues, OpenshiftVersionOptionType } from '../../../common';
6+
import { ClusterDetailsValues, OpenshiftVersionOptionType } from '../..';
7+
import './OpenShiftVersionModal.css';
98

109
type OpenShiftVersionModalProps = {
10+
allVersions: OpenshiftVersionOptionType[];
1111
setOpenshiftVersionModalOpen: (isOpen: boolean) => void;
12-
getHelperText: HelperTextType;
12+
getHelperText?: HelperTextType;
1313
};
1414

1515
export const OpenShiftVersionModal = ({
16+
allVersions,
1617
setOpenshiftVersionModalOpen,
1718
getHelperText,
1819
}: OpenShiftVersionModalProps) => {
1920
const { setFieldValue } = useFormikContext<ClusterDetailsValues>();
20-
const { allVersions: versions } = useOpenshiftVersionsContext();
2121
const onClose = () => setOpenshiftVersionModalOpen(false);
2222
const [customOpenshiftSelect, setCustomOpenshiftSelect] = useState<OpenshiftVersionOptionType>(); // Cambiar el tipo según lo que esperes aquí
2323

@@ -50,8 +50,8 @@ export const OpenShiftVersionModal = ({
5050
label={'OpenShift version'}
5151
isRequired
5252
>
53-
<OpenshiftSelectWithSearch
54-
versions={versions}
53+
<OpenShiftSelectWithSearch
54+
versions={allVersions}
5555
getHelperText={getHelperText}
5656
setCustomOpenshiftSelect={setCustomOpenshiftSelect}
5757
/>

libs/ui-lib/lib/common/components/ui/OpenshiftVersionDropdown.css

-4
This file was deleted.

libs/ui-lib/lib/common/components/ui/index.ts

+3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ export * from './PreviewBadge';
1212
export * from './TechnologyPreview';
1313
export * from './DeveloperPreview';
1414

15+
export * from './OpenShiftVersionDropdown';
16+
export * from './OpenShiftVersionModal';
17+
1518
export * from './utils';
1619

1720
export { default as PopoverIcon } from './PopoverIcon';

0 commit comments

Comments
 (0)