Skip to content

Commit

Permalink
Add new ControlPlaneNodesDropdown to CIM
Browse files Browse the repository at this point in the history
  • Loading branch information
ammont82 committed Dec 23, 2024
1 parent 1166f41 commit 7b00002
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 6 deletions.
6 changes: 6 additions & 0 deletions libs/locales/lib/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,16 @@
"ai:{{selectedAgentsCount}} host selected out of {{matchingAgentsCount}} matching.": "{{selectedAgentsCount}} host selected out of {{matchingAgentsCount}} identified.",
"ai:{{selectedAgentsCount}} host selected out of {{matchingAgentsCount}} matching._plural": "{{selectedAgentsCount}} hosts selected out of {{matchingAgentsCount}} identified.",
"ai:<i>This IP will be allocated by the DHCP server</i>": "<i>This IP address is allocated by the DHCP server.</i>",
"ai:1 (Single Node OpenShift - not highly available cluster)": "1 (Single Node OpenShift - not highly available cluster)",
"ai:1-{{count}} characters": "1-{{count}} characters",
"ai:1-{{count}} characters_plural": "1-{{count}} characters",
"ai:1-253 characters": "1-253 characters",
"ai:1-63 characters": "1-63 characters",
"ai:2-{{count}} characters": "2-{{count}} characters",
"ai:2-{{count}} characters_plural": "2-{{count}} characters",
"ai:3 (highly available cluster)": "3 (highly available cluster)",
"ai:4 (highly available cluster+)": "4 (highly available cluster+)",
"ai:5 (highly available cluster++)": "5 (highly available cluster++)",
"ai:A change will require booting hosts with a new discovery ISO file.": "A change will require booting hosts with a new discovery ISO file.",
"ai:A cluster can have {{HOSTS_MIN_COUNT}} hosts at minimum.": "A cluster can have a minimum of {{HOSTS_MIN_COUNT}} hosts.",
"ai:A comma separated list of IP or domain names of the NTP pools or servers.": "A comma-separated list of IP addresses or the domain names of the NTP pools or servers.",
Expand Down Expand Up @@ -594,6 +598,7 @@
"ai:NTP synchronization": "NTP synchronization",
"ai:NTP synchronization failure": "NTP synchronization failure",
"ai:Number of characters between dots (.) must be 1-63": "Number of characters between dots (.) must be 1-63",
"ai:Number of control plane nodes": "Number of control plane nodes",
"ai:Number of hosts": "Number of hosts",
"ai:NVIDIA GPU": "NVIDIA GPU",
"ai:NVIDIA GPU requirements": "NVIDIA GPU requirements",
Expand Down Expand Up @@ -830,6 +835,7 @@
"ai:This IP is being allocated by the DHCP server": "This IP is being allocated by the DHCP server",
"ai:This IP was allocated by the DHCP server.": "This IP was allocated by the DHCP server.",
"ai:This name will replace the original discovered hostname.": "This name will replace the original discovered hostname.",
"ai:This option is not available for Nutanix platform": "This option is not available for Nutanix platform",
"ai:This option is not editable after the draft cluster is created": "This option is not editable after the draft cluster is created",
"ai:this script.": "this script.",
"ai:This stage may take a while to finish. To view detailed information, click the events log link below.": "This stage might take a while to finish. To view detailed information, click the events log link.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ import {
import { ClusterDetailsValues } from '../../../common/components/clusterWizard/types';
import { useTranslation } from '../../../common/hooks/use-translation-wrapper';
import CpuArchitectureDropdown from '../common/CpuArchitectureDropdown';
import { SNOControlGroup } from '../../../common';
import { getNetworkType } from '../helpers';
import ControlPlaneNodesDropdown from '../../../common/components/clusterConfiguration/ControlPlaneNodesDropdown';
export type ClusterDetailsFormFieldsProps = {
isEditFlow: boolean;
forceOpenshiftVersion?: string;
Expand Down Expand Up @@ -52,7 +52,7 @@ export const ClusterDetailsFormFields: React.FC<ClusterDetailsFormFieldsProps> =
cpuArchitectures,
}) => {
const { values, setFieldValue } = useFormikContext<ClusterDetailsValues>();
const { name, baseDnsDomain, highAvailabilityMode } = values;
const { name, baseDnsDomain } = values;

const nameInputRef = React.useRef<HTMLInputElement>();
React.useEffect(() => {
Expand Down Expand Up @@ -110,11 +110,9 @@ export const ClusterDetailsFormFields: React.FC<ClusterDetailsFormFieldsProps> =
}}
/>
)}
<ControlPlaneNodesDropdown isNutanix={isNutanix} isDisabled={isEditFlow} />
{!isNutanix && (
<>
<SNOControlGroup versions={versions} highAvailabilityMode={highAvailabilityMode} />
<CpuArchitectureDropdown isDisabled={isEditFlow} cpuArchitectures={cpuArchitectures} />
</>
<CpuArchitectureDropdown cpuArchitectures={cpuArchitectures} isDisabled={isEditFlow} />
)}
{extensionAfter?.['openshiftVersion'] && extensionAfter['openshiftVersion']}
{!isEditFlow && <PullSecret />}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import * as React from 'react';
import { Dropdown, DropdownItem, DropdownToggle, FormGroup, Tooltip } from '@patternfly/react-core';
import { useTranslation } from '../../hooks/use-translation-wrapper';
import { getFieldId, StaticField } from '../..';
import { useField } from 'formik';

interface ControlPlaneNodesOption {
value: string;
label: string;
}

const isDropdownItemEnabled = (controlPlaneNodeCount: string, isNutanix?: boolean): boolean => {
return (controlPlaneNodeCount === '1' && !isNutanix) || controlPlaneNodeCount !== '1';
};

const ControlPlaneNodesDropdown = ({
isDisabled = false,
isNutanix,
}: {
isDisabled?: boolean;
isNutanix?: boolean;
}) => {
const { t } = useTranslation();
const [{ name, value }, , { setValue }] = useField<string | ''>('controlPlaneAgents');
const [current, setCurrent] = React.useState<string>('3');

const options: ControlPlaneNodesOption[] = [
{ value: '1', label: t('ai:1 (Single Node OpenShift - not highly available cluster)') },
{ value: '3', label: t('ai:3 (highly available cluster)') },
{ value: '4', label: t('ai:4 (highly available cluster+)') },
{ value: '5', label: t('ai:5 (highly available cluster++)') },
];

const dropdownItems = options.map(({ value, label }) => {
const isItemEnabled = isDropdownItemEnabled(value, isNutanix);
const disabledReason = t('ai:This option is not available for Nutanix platform');
return (
<DropdownItem
key={value}
id={value}
isAriaDisabled={!isItemEnabled}
selected={current === value}
>
<Tooltip hidden={isItemEnabled} content={disabledReason} position="top">
<div>{label}</div>
</Tooltip>
</DropdownItem>
);
});

const [controlPlanelOpen, setControlPlanelOpen] = React.useState(false);
const fieldId = getFieldId(name, 'input');

const onControlPlaneSelect = (e?: React.SyntheticEvent<HTMLDivElement>) => {
const val = e?.currentTarget.id as string;
setValue(val);
setCurrent(val);
setControlPlanelOpen(false);
};

return !isDisabled ? (
<FormGroup isInline fieldId={fieldId} label={t('ai:Number of control plane nodes')} isRequired>
<Dropdown
toggle={
<DropdownToggle
onToggle={() => setControlPlanelOpen(!controlPlanelOpen)}
className="pf-u-w-100"
>
{value ? value : '3'}
</DropdownToggle>
}
name="controlPlaneAgents"
isOpen={controlPlanelOpen}
onSelect={onControlPlaneSelect}
dropdownItems={dropdownItems}
className="pf-u-w-100"
/>
</FormGroup>
) : (
<StaticField
name={'controlPlaneAgents'}
label={t('ai:Number of control plane nodes')}
isRequired
>
{value}
</StaticField>
);
};

export default ControlPlaneNodesDropdown;

0 comments on commit 7b00002

Please sign in to comment.