@openshift-assisted/ui-lib 2.15.2-cim → 2.15.4-cim
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/@types/cim/components/Agent/tableUtils.d.ts +5 -1
- package/build/@types/cim/components/Agent/tableUtils.d.ts.map +1 -1
- package/build/@types/cim/components/ClusterDeployment/ClusterDeploymentDetailsForm.d.ts +1 -1
- package/build/@types/cim/components/ClusterDeployment/ClusterDeploymentDetailsForm.d.ts.map +1 -1
- package/build/@types/cim/components/ClusterDeployment/ClusterDetailsFormFields.d.ts +0 -1
- package/build/@types/cim/components/ClusterDeployment/ClusterDetailsFormFields.d.ts.map +1 -1
- package/build/@types/cim/components/Hypershift/HostedClusterWizard/DetailsStep/DetailsForm.d.ts.map +1 -1
- package/build/@types/cim/components/Hypershift/HostedClusterWizard/DetailsStep/DetailsStep.d.ts.map +1 -1
- package/build/@types/cim/components/Hypershift/HostedClusterWizard/DetailsStep/types.d.ts +6 -1
- package/build/@types/cim/components/Hypershift/HostedClusterWizard/DetailsStep/types.d.ts.map +1 -1
- package/build/@types/cim/components/Hypershift/HostedClusterWizard/HostsStep/HostsStep.d.ts.map +1 -1
- package/build/@types/cim/components/Hypershift/HostedClusterWizard/HostsStep/NodePoolForm.d.ts.map +1 -1
- package/build/@types/cim/components/Hypershift/forms/NodePoolAgentsForm.d.ts.map +1 -1
- package/build/@types/cim/components/Hypershift/hooks/useSupportedOCPVersions.d.ts +1 -1
- package/build/@types/cim/components/Hypershift/hooks/useSupportedOCPVersions.d.ts.map +1 -1
- package/build/@types/cim/components/InfraEnv/InfraEnvAgentTable.d.ts.map +1 -1
- package/build/@types/cim/components/helpers/versions.d.ts +1 -1
- package/build/@types/cim/components/helpers/versions.d.ts.map +1 -1
- package/build/@types/cim/index.d.ts +1 -0
- package/build/@types/cim/index.d.ts.map +1 -1
- package/build/@types/common/components/clusterConfiguration/index.d.ts +0 -1
- package/build/@types/common/components/clusterConfiguration/index.d.ts.map +1 -1
- package/build/@types/common/components/hosts/AITable.d.ts +3 -1
- package/build/@types/common/components/hosts/AITable.d.ts.map +1 -1
- package/build/@types/common/components/hosts/HostsTable.d.ts +2 -1
- package/build/@types/common/components/hosts/HostsTable.d.ts.map +1 -1
- package/build/@types/common/components/hosts/utils.d.ts +4 -1
- package/build/@types/common/components/hosts/utils.d.ts.map +1 -1
- package/build/@types/common/components/ui/formik/TextAreaField.d.ts.map +1 -1
- package/build/cjs/cim/components/Agent/tableUtils.js +4 -3
- package/build/cjs/cim/components/Agent/tableUtils.js.map +1 -1
- package/build/cjs/cim/components/ClusterDeployment/ClusterDeploymentDetailsForm.js +12 -17
- package/build/cjs/cim/components/ClusterDeployment/ClusterDeploymentDetailsForm.js.map +1 -1
- package/build/cjs/cim/components/ClusterDeployment/ClusterDetailsFormFields.js +23 -19
- package/build/cjs/cim/components/ClusterDeployment/ClusterDetailsFormFields.js.map +1 -1
- package/build/cjs/cim/components/Hypershift/HostedClusterWizard/DetailsStep/DetailsForm.js +21 -3
- package/build/cjs/cim/components/Hypershift/HostedClusterWizard/DetailsStep/DetailsForm.js.map +1 -1
- package/build/cjs/cim/components/Hypershift/HostedClusterWizard/DetailsStep/DetailsStep.js +3 -1
- package/build/cjs/cim/components/Hypershift/HostedClusterWizard/DetailsStep/DetailsStep.js.map +1 -1
- package/build/cjs/cim/components/Hypershift/HostedClusterWizard/HostsStep/HostsStep.js +2 -11
- package/build/cjs/cim/components/Hypershift/HostedClusterWizard/HostsStep/HostsStep.js.map +1 -1
- package/build/cjs/cim/components/Hypershift/HostedClusterWizard/HostsStep/NodePoolForm.js +0 -28
- package/build/cjs/cim/components/Hypershift/HostedClusterWizard/HostsStep/NodePoolForm.js.map +1 -1
- package/build/cjs/cim/components/Hypershift/forms/NodePoolAgentsForm.js +8 -3
- package/build/cjs/cim/components/Hypershift/forms/NodePoolAgentsForm.js.map +1 -1
- package/build/cjs/cim/components/Hypershift/hooks/useSupportedOCPVersions.js +3 -3
- package/build/cjs/cim/components/Hypershift/hooks/useSupportedOCPVersions.js.map +1 -1
- package/build/cjs/cim/components/Hypershift/modals/AddNodePoolModal.js +1 -1
- package/build/cjs/cim/components/Hypershift/modals/AddNodePoolModal.js.map +1 -1
- package/build/cjs/cim/components/Hypershift/modals/ManageHostsModal.js +2 -2
- package/build/cjs/cim/components/Hypershift/modals/ManageHostsModal.js.map +1 -1
- package/build/cjs/cim/components/InfraEnv/InfraEnvAgentTable.js +2 -2
- package/build/cjs/cim/components/InfraEnv/InfraEnvAgentTable.js.map +1 -1
- package/build/cjs/cim/components/helpers/versions.js +42 -27
- package/build/cjs/cim/components/helpers/versions.js.map +1 -1
- package/build/cjs/cim/global.css +12 -0
- package/build/cjs/cim/index.js +2 -0
- package/build/cjs/cim/index.js.map +1 -1
- package/build/cjs/common/components/clusterConfiguration/index.js +1 -3
- package/build/cjs/common/components/clusterConfiguration/index.js.map +1 -1
- package/build/cjs/common/components/hosts/AITable.js +54 -38
- package/build/cjs/common/components/hosts/AITable.js.map +1 -1
- package/build/cjs/common/components/hosts/HostsTable.js +8 -5
- package/build/cjs/common/components/hosts/HostsTable.js.map +1 -1
- package/build/cjs/common/components/hosts/utils.js +12 -2
- package/build/cjs/common/components/hosts/utils.js.map +1 -1
- package/build/cjs/common/components/ui/formik/TextAreaField.js +2 -1
- package/build/cjs/common/components/ui/formik/TextAreaField.js.map +1 -1
- package/lib/cim/components/Agent/tableUtils.tsx +4 -3
- package/lib/cim/components/ClusterDeployment/ClusterDeploymentDetailsForm.tsx +9 -19
- package/lib/cim/components/ClusterDeployment/ClusterDetailsFormFields.tsx +25 -22
- package/lib/cim/components/Hypershift/HostedClusterWizard/DetailsStep/DetailsForm.tsx +48 -3
- package/lib/cim/components/Hypershift/HostedClusterWizard/DetailsStep/DetailsStep.tsx +4 -0
- package/lib/cim/components/Hypershift/HostedClusterWizard/DetailsStep/types.ts +6 -1
- package/lib/cim/components/Hypershift/HostedClusterWizard/HostsStep/HostsStep.tsx +2 -13
- package/lib/cim/components/Hypershift/HostedClusterWizard/HostsStep/NodePoolForm.tsx +1 -33
- package/lib/cim/components/Hypershift/forms/NodePoolAgentsForm.tsx +24 -12
- package/lib/cim/components/Hypershift/hooks/useSupportedOCPVersions.ts +3 -2
- package/lib/cim/components/Hypershift/modals/AddNodePoolModal.tsx +1 -1
- package/lib/cim/components/Hypershift/modals/ManageHostsModal.tsx +2 -2
- package/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsx +2 -0
- package/lib/cim/components/helpers/versions.ts +51 -34
- package/lib/cim/global.css +12 -0
- package/lib/cim/index.ts +3 -0
- package/lib/common/components/clusterConfiguration/index.ts +0 -1
- package/lib/common/components/hosts/AITable.tsx +61 -37
- package/lib/common/components/hosts/HostsTable.tsx +21 -9
- package/lib/common/components/hosts/utils.ts +18 -2
- package/lib/common/components/ui/formik/TextAreaField.tsx +14 -7
- package/package.json +3 -3
- package/build/@types/common/components/clusterConfiguration/OpenShiftVersionSelect.d.ts +0 -10
- package/build/@types/common/components/clusterConfiguration/OpenShiftVersionSelect.d.ts.map +0 -1
- package/build/cjs/common/components/clusterConfiguration/OpenShiftVersionSelect.js +0 -52
- package/build/cjs/common/components/clusterConfiguration/OpenShiftVersionSelect.js.map +0 -1
- package/lib/common/components/clusterConfiguration/OpenShiftVersionSelect.tsx +0 -81
|
@@ -6,8 +6,6 @@ import { Stack, StackItem } from '@patternfly/react-core';
|
|
|
6
6
|
import HostsForm from './HostsForm';
|
|
7
7
|
import { HostsStepProps, HostsFormValues, NodePoolFormValue } from './types';
|
|
8
8
|
import { useTranslation } from '../../../../../common/hooks/use-translation-wrapper';
|
|
9
|
-
import { getAgentsForSelection } from '../../../helpers';
|
|
10
|
-
import { INFRAENV_AGENTINSTALL_LABEL_KEY } from '../../../common';
|
|
11
9
|
import { TFunction } from 'i18next';
|
|
12
10
|
import { NodePoolK8sResource } from '../../types';
|
|
13
11
|
|
|
@@ -61,16 +59,7 @@ const HostsStep: React.FC<HostsStepProps> = ({
|
|
|
61
59
|
olmCatalogPlacement,
|
|
62
60
|
}) => {
|
|
63
61
|
const { t } = useTranslation();
|
|
64
|
-
const availableAgents = getAgentsForSelection(agents);
|
|
65
62
|
|
|
66
|
-
const infraEnvsWithAgents = infraEnvs.filter((ie) =>
|
|
67
|
-
availableAgents.some(
|
|
68
|
-
(a) =>
|
|
69
|
-
a.metadata?.labels?.[INFRAENV_AGENTINSTALL_LABEL_KEY] === ie.metadata?.name &&
|
|
70
|
-
a.metadata?.namespace === ie.metadata?.namespace &&
|
|
71
|
-
!a.spec.clusterDeploymentName,
|
|
72
|
-
),
|
|
73
|
-
);
|
|
74
63
|
return (
|
|
75
64
|
<Stack hasGutter>
|
|
76
65
|
<StackItem>
|
|
@@ -84,7 +73,7 @@ const HostsStep: React.FC<HostsStepProps> = ({
|
|
|
84
73
|
controllerAvailabilityPolicy: controllerAvailabilityPolicy || 'HighlyAvailable',
|
|
85
74
|
infrastructureAvailabilityPolicy: infrastructureAvailabilityPolicy || 'HighlyAvailable',
|
|
86
75
|
olmCatalogPlacement: olmCatalogPlacement || 'management',
|
|
87
|
-
agentNamespace: initInfraEnv ||
|
|
76
|
+
agentNamespace: initInfraEnv || infraEnvs[0]?.metadata?.namespace || '',
|
|
88
77
|
nodePools: initNodePools || [
|
|
89
78
|
{
|
|
90
79
|
nodePoolName: `nodepool-${clusterName}-1`,
|
|
@@ -106,7 +95,7 @@ const HostsStep: React.FC<HostsStepProps> = ({
|
|
|
106
95
|
>
|
|
107
96
|
<HostsForm
|
|
108
97
|
onValuesChanged={onValuesChanged}
|
|
109
|
-
infraEnvs={
|
|
98
|
+
infraEnvs={infraEnvs}
|
|
110
99
|
agents={agents}
|
|
111
100
|
clusterName={clusterName}
|
|
112
101
|
initReleaseImage={initReleaseImage}
|
|
@@ -22,7 +22,6 @@ import { HostsFormValues } from './types';
|
|
|
22
22
|
import { useFormikContext } from 'formik';
|
|
23
23
|
import { getAgentsForSelection } from '../../../helpers';
|
|
24
24
|
import { useTranslation } from '../../../../../common/hooks/use-translation-wrapper';
|
|
25
|
-
import { useFormikHelpers } from '../../../../../common/hooks/useFormikHelpers';
|
|
26
25
|
|
|
27
26
|
import './NodePoolForm.css';
|
|
28
27
|
import NodePoolAgentsForm from '../../forms/NodePoolAgentsForm';
|
|
@@ -37,14 +36,8 @@ type NodePoolFormProps = {
|
|
|
37
36
|
const NodePoolForm: React.FC<NodePoolFormProps> = ({ infraEnvs, agents, index, onRemove }) => {
|
|
38
37
|
const { t } = useTranslation();
|
|
39
38
|
const { values } = useFormikContext<HostsFormValues>();
|
|
40
|
-
const { setValue: setCountValue } = useFormikHelpers(`nodePools[${index}].count`);
|
|
41
|
-
const { setValue: setMinAutoscalingValue } = useFormikHelpers(
|
|
42
|
-
`nodePools[${index}].autoscaling.minReplicas`,
|
|
43
|
-
);
|
|
44
|
-
const { setValue: setMaxAutoscalingValue } = useFormikHelpers(
|
|
45
|
-
`nodePools[${index}].autoscaling.maxReplicas`,
|
|
46
|
-
);
|
|
47
39
|
const [isExpanded, setExpanded] = React.useState(true);
|
|
40
|
+
|
|
48
41
|
const infraEnvAgents = React.useMemo(() => {
|
|
49
42
|
const infraEnv = infraEnvs.find((ie) => ie.metadata?.namespace === values.agentNamespace);
|
|
50
43
|
return agents.filter((agent) => isAgentOfInfraEnv(infraEnv, agent));
|
|
@@ -79,31 +72,6 @@ const NodePoolForm: React.FC<NodePoolFormProps> = ({ infraEnvs, agents, index, o
|
|
|
79
72
|
Math.min(matchingAgents.length, availableAgents.length - previousNodePoolsCount),
|
|
80
73
|
);
|
|
81
74
|
|
|
82
|
-
const currentCount = values.nodePools[index].useAutoscaling
|
|
83
|
-
? values.nodePools[index].autoscaling.maxReplicas
|
|
84
|
-
: values.nodePools[index].count;
|
|
85
|
-
|
|
86
|
-
React.useEffect(() => {
|
|
87
|
-
if (currentCount > maxAgents) {
|
|
88
|
-
if (values.nodePools[index].useAutoscaling) {
|
|
89
|
-
if (maxAgents === 0) {
|
|
90
|
-
void setMinAutoscalingValue(maxAgents);
|
|
91
|
-
}
|
|
92
|
-
void setMaxAutoscalingValue(maxAgents);
|
|
93
|
-
} else {
|
|
94
|
-
void setCountValue(maxAgents);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}, [
|
|
98
|
-
maxAgents,
|
|
99
|
-
currentCount,
|
|
100
|
-
values.nodePools,
|
|
101
|
-
index,
|
|
102
|
-
setCountValue,
|
|
103
|
-
setMinAutoscalingValue,
|
|
104
|
-
setMaxAutoscalingValue,
|
|
105
|
-
]);
|
|
106
|
-
|
|
107
75
|
return (
|
|
108
76
|
<Stack hasGutter>
|
|
109
77
|
<StackItem>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Grid, GridItem } from '@patternfly/react-core';
|
|
1
|
+
import { Alert, AlertVariant, Grid, GridItem, Text } from '@patternfly/react-core';
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import { CheckboxField, NumberInputField, PopoverIcon } from '../../../../common';
|
|
4
4
|
import { useTranslation } from '../../../../common/hooks/use-translation-wrapper';
|
|
@@ -27,6 +27,7 @@ const NodePoolAgentsForm = ({
|
|
|
27
27
|
}: NodePoolAgentsFormProps) => {
|
|
28
28
|
const { t } = useTranslation();
|
|
29
29
|
|
|
30
|
+
const [{ value: count }] = useField<number>(countName);
|
|
30
31
|
const [{ value: minValue }] = useField<number>(`${autoscalingName}.minReplicas`);
|
|
31
32
|
const [{ value: maxValue }] = useField<number>(`${autoscalingName}.maxReplicas`);
|
|
32
33
|
const [{ value: useAutoscalingValue }] = useField<boolean>(useAutoscalingName);
|
|
@@ -60,7 +61,7 @@ const NodePoolAgentsForm = ({
|
|
|
60
61
|
label={t('ai:Minimum number of hosts')}
|
|
61
62
|
isRequired
|
|
62
63
|
minValue={1}
|
|
63
|
-
maxValue={maxValue
|
|
64
|
+
maxValue={maxValue}
|
|
64
65
|
/>
|
|
65
66
|
</GridItem>
|
|
66
67
|
<GridItem>
|
|
@@ -69,22 +70,33 @@ const NodePoolAgentsForm = ({
|
|
|
69
70
|
label={t('ai:Maximum number of hosts')}
|
|
70
71
|
isRequired
|
|
71
72
|
minValue={minValue || 1}
|
|
72
|
-
maxValue={maxAgents}
|
|
73
73
|
helperText={helperText}
|
|
74
74
|
/>
|
|
75
75
|
</GridItem>
|
|
76
76
|
</>
|
|
77
77
|
) : (
|
|
78
|
+
<>
|
|
79
|
+
<GridItem>
|
|
80
|
+
<NumberInputField
|
|
81
|
+
label={t('ai:Number of hosts')}
|
|
82
|
+
idPostfix="count"
|
|
83
|
+
name={countName}
|
|
84
|
+
isRequired
|
|
85
|
+
minValue={0}
|
|
86
|
+
helperText={helperText}
|
|
87
|
+
/>
|
|
88
|
+
</GridItem>
|
|
89
|
+
</>
|
|
90
|
+
)}
|
|
91
|
+
{(useAutoscalingValue ? maxValue : count) > maxAgents && (
|
|
78
92
|
<GridItem>
|
|
79
|
-
<
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
helperText={helperText}
|
|
87
|
-
/>
|
|
93
|
+
<Alert
|
|
94
|
+
isInline
|
|
95
|
+
variant={AlertVariant.warning}
|
|
96
|
+
title={t('ai:Host count exceeds the current number of available hosts.')}
|
|
97
|
+
>
|
|
98
|
+
<Text>{t('ai:Scale down the nodepool or make more hosts available.')}</Text>
|
|
99
|
+
</Alert>
|
|
88
100
|
</GridItem>
|
|
89
101
|
)}
|
|
90
102
|
</Grid>
|
|
@@ -11,9 +11,10 @@ export const getSupportedCM = (configMaps: ConfigMapK8sResource[]) =>
|
|
|
11
11
|
export const useSupportedOCPVersions = (
|
|
12
12
|
clusterImages: ClusterImageSetK8sResource[],
|
|
13
13
|
supportedVersionsCM?: ConfigMapK8sResource,
|
|
14
|
+
extended?: boolean,
|
|
14
15
|
) => {
|
|
15
16
|
return React.useMemo(() => {
|
|
16
|
-
const ocpVersions = getOCPVersions(clusterImages, false);
|
|
17
|
+
const ocpVersions = getOCPVersions(clusterImages, false, undefined, extended);
|
|
17
18
|
const supportedVersionsString = supportedVersionsCM?.data?.['supported-versions'];
|
|
18
19
|
if (supportedVersionsString) {
|
|
19
20
|
try {
|
|
@@ -25,5 +26,5 @@ export const useSupportedOCPVersions = (
|
|
|
25
26
|
}
|
|
26
27
|
}
|
|
27
28
|
return ocpVersions;
|
|
28
|
-
}, [clusterImages, supportedVersionsCM]);
|
|
29
|
+
}, [clusterImages, extended, supportedVersionsCM?.data]);
|
|
29
30
|
};
|
|
@@ -41,7 +41,7 @@ const AddNodePoolModal = ({
|
|
|
41
41
|
const handleSubmit = async (values: NodePoolFormValues) => {
|
|
42
42
|
setError(undefined);
|
|
43
43
|
const nodePool: NodePoolK8sResource = {
|
|
44
|
-
apiVersion: 'hypershift.openshift.io/
|
|
44
|
+
apiVersion: 'hypershift.openshift.io/v1beta1',
|
|
45
45
|
kind: 'NodePool',
|
|
46
46
|
metadata: {
|
|
47
47
|
name: values.nodePoolName,
|
|
@@ -66,7 +66,7 @@ const getPatches = (values: NodePoolFormValues, nodePool: NodePoolK8sResource) =
|
|
|
66
66
|
);
|
|
67
67
|
}
|
|
68
68
|
} else {
|
|
69
|
-
if (
|
|
69
|
+
if (nodePool.spec.replicas !== undefined) {
|
|
70
70
|
patches.push({
|
|
71
71
|
op: 'replace',
|
|
72
72
|
value: values.count,
|
|
@@ -127,7 +127,7 @@ const ManageHostsModal = ({
|
|
|
127
127
|
agentLabels: labelsToFormikValue(
|
|
128
128
|
nodePool.spec.platform?.agent?.agentLabelSelector?.matchLabels || {},
|
|
129
129
|
),
|
|
130
|
-
count: nodePool.spec.replicas ||
|
|
130
|
+
count: nodePool.spec.replicas || 0,
|
|
131
131
|
useAutoscaling: !!nodePool.spec.autoScaling,
|
|
132
132
|
autoscaling: {
|
|
133
133
|
minReplicas: nodePool.spec.autoScaling?.min || 1,
|
|
@@ -123,6 +123,7 @@ const InfraEnvAgentTable: React.FC<InfraEnvAgentTableProps> = ({
|
|
|
123
123
|
setStatusFilter,
|
|
124
124
|
statusFilter,
|
|
125
125
|
filteredHosts: hosts,
|
|
126
|
+
sorted,
|
|
126
127
|
} = useAgentsFilter({
|
|
127
128
|
agents,
|
|
128
129
|
agentStatuses,
|
|
@@ -226,6 +227,7 @@ const InfraEnvAgentTable: React.FC<InfraEnvAgentTableProps> = ({
|
|
|
226
227
|
<StackItem>
|
|
227
228
|
<HostsTable
|
|
228
229
|
hosts={hosts}
|
|
230
|
+
alreadySorted={sorted}
|
|
229
231
|
content={content}
|
|
230
232
|
actionResolver={actionResolver}
|
|
231
233
|
selectedIDs={selectedHostIDs}
|
|
@@ -61,48 +61,65 @@ export const isValidImageSet = (
|
|
|
61
61
|
);
|
|
62
62
|
};
|
|
63
63
|
|
|
64
|
+
// Extracts major.minor version, strips any non-numeric prefix (e.g., "img4.18.55" → "4.18")
|
|
65
|
+
const extractMajorMinor = (version: string): string => {
|
|
66
|
+
const versionWithoutPrefix = version.replace(/^[^\d]*/, '');
|
|
67
|
+
return versionWithoutPrefix.split('.').slice(0, 2).join('.');
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
// Converts a ClusterImageSet to an OpenshiftVersionOptionType
|
|
71
|
+
const toVersionOption = (
|
|
72
|
+
clusterImageSet: ClusterImageSetK8sResource,
|
|
73
|
+
): OpenshiftVersionOptionType => {
|
|
74
|
+
const version =
|
|
75
|
+
getVersionFromReleaseImage(clusterImageSet.spec?.releaseImage) ||
|
|
76
|
+
clusterImageSet.metadata?.name ||
|
|
77
|
+
'';
|
|
78
|
+
const cpuArch = getCPUArchFromReleaseImage(clusterImageSet.spec?.releaseImage);
|
|
79
|
+
return {
|
|
80
|
+
label: `OpenShift ${version}`,
|
|
81
|
+
version,
|
|
82
|
+
value: clusterImageSet.metadata?.name as string,
|
|
83
|
+
default: false,
|
|
84
|
+
// (rawagner) ACM does not have the warning so changing to 'production'
|
|
85
|
+
// supportLevel : getSupportLevelFromChannel(clusterImageSet.metadata?.labels?.channel)
|
|
86
|
+
supportLevel: 'production',
|
|
87
|
+
cpuArchitectures: cpuArch ? [cpuArch as CpuArchitecture] : undefined,
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* In case there are osImages specified on the AgentServiceConfig, we want to limit
|
|
93
|
+
* the availability in the dropdown to only versions that are listed there.
|
|
94
|
+
* Otherwise the installation fails.
|
|
95
|
+
*/
|
|
96
|
+
const hasMatchingOsImage = (
|
|
97
|
+
version: OpenshiftVersionOptionType,
|
|
98
|
+
osImageVersions: (string | undefined)[],
|
|
99
|
+
): boolean => {
|
|
100
|
+
if (!osImageVersions.length) return true;
|
|
101
|
+
return osImageVersions.includes(extractMajorMinor(version.version));
|
|
102
|
+
};
|
|
103
|
+
|
|
64
104
|
export const getOCPVersions = (
|
|
65
105
|
clusterImageSets: ClusterImageSetK8sResource[],
|
|
66
|
-
isNutanix?: boolean
|
|
106
|
+
isNutanix?: boolean,
|
|
67
107
|
osImages?: OsImage[],
|
|
68
108
|
extended?: boolean,
|
|
69
109
|
): OpenshiftVersionOptionType[] => {
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
);
|
|
110
|
+
const architectures = isNutanix ? supportedNutanixPlatforms : undefined;
|
|
111
|
+
const osImageVersions = [...new Set(osImages?.map((img) => img.openshiftVersion))];
|
|
73
112
|
|
|
74
113
|
const versions = clusterImageSets
|
|
75
|
-
.filter((clusterImageSet) =>
|
|
76
|
-
|
|
77
|
-
)
|
|
78
|
-
.
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
label: `OpenShift ${version ? version : (clusterImageSet.metadata?.name as string)}`,
|
|
83
|
-
version: version || clusterImageSet.metadata?.name || '',
|
|
84
|
-
value: clusterImageSet.metadata?.name as string,
|
|
85
|
-
default: false,
|
|
86
|
-
// (rawagner) ACM does not have the warning so changing to 'production'
|
|
87
|
-
supportLevel: 'production', // getSupportLevelFromChannel(clusterImageSet.metadata?.labels?.channel),
|
|
88
|
-
cpuArchitectures: cpuArch ? [cpuArch as CpuArchitecture] : undefined,
|
|
89
|
-
};
|
|
90
|
-
})
|
|
91
|
-
.filter((ocpVersion) => {
|
|
92
|
-
const ver = ocpVersion.version.split('.').slice(0, 2).join('.');
|
|
93
|
-
return !!ocpImageVersions.length ? ocpImageVersions.includes(ver) : true;
|
|
94
|
-
})
|
|
95
|
-
.sort(
|
|
96
|
-
(versionA, versionB) => /* descending */ -1 * versionA.label.localeCompare(versionB.label),
|
|
97
|
-
);
|
|
98
|
-
|
|
99
|
-
if (versions.length) {
|
|
100
|
-
// make sure that the pre-selected one is the first-one after sorting
|
|
101
|
-
versions[0].default = true;
|
|
102
|
-
}
|
|
114
|
+
.filter((clusterImageSet) => isValidImageSet(clusterImageSet, architectures, extended))
|
|
115
|
+
.map(toVersionOption)
|
|
116
|
+
.filter((v) => hasMatchingOsImage(v, osImageVersions))
|
|
117
|
+
.sort((a, b) => b.label.localeCompare(a.label));
|
|
118
|
+
|
|
119
|
+
// Mark first version as the default selection
|
|
120
|
+
versions[0] && (versions[0].default = true);
|
|
103
121
|
|
|
104
|
-
|
|
105
|
-
return deduped;
|
|
122
|
+
return uniqBy(versions, (v) => v.version);
|
|
106
123
|
};
|
|
107
124
|
|
|
108
125
|
export const getSelectedVersion = (
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/*
|
|
2
|
+
In readonly form controls in PF5, text is unreadable in dark theme due to its background color.
|
|
3
|
+
Original color is disabled-color-300, see effect at https://v5-archive.patternfly.org/utility-classes/background-color
|
|
4
|
+
|
|
5
|
+
Applied to:
|
|
6
|
+
- Add hosts modal
|
|
7
|
+
- AI cluster installation progress card
|
|
8
|
+
*/
|
|
9
|
+
.pf-v5-theme-dark #add-host-modal .pf-v5-c-form-control.pf-m-readonly,
|
|
10
|
+
.pf-v5-theme-dark #aiprogress .pf-v5-c-form-control.pf-m-readonly {
|
|
11
|
+
--pf-v5-c-form-control--m-readonly--BackgroundColor: var(--pf-v5-global--disabled-color--200);
|
|
12
|
+
}
|
package/lib/cim/index.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
export { default as SNOControlGroup } from './SNOControlGroup';
|
|
2
2
|
export { default as SNODisclaimer } from './SNODisclaimer';
|
|
3
|
-
export { default as OpenShiftVersionSelect } from './OpenShiftVersionSelect';
|
|
4
3
|
export { default as UploadSSH } from './UploadSSH';
|
|
5
4
|
export { default as ProxyFields, ProxyInputFields } from './ProxyFields';
|
|
6
5
|
export { default as DownloadIsoModal } from './DownloadIsoModal';
|
|
@@ -80,6 +80,7 @@ export type AITableProps<R> = ReturnType<typeof usePagination> & {
|
|
|
80
80
|
actionResolver?: ActionsResolver<R>;
|
|
81
81
|
canSelectAll?: boolean;
|
|
82
82
|
variant?: TableProps['variant'];
|
|
83
|
+
alreadySorted?: boolean;
|
|
83
84
|
};
|
|
84
85
|
|
|
85
86
|
// eslint-disable-next-line
|
|
@@ -103,8 +104,21 @@ const AITable = <R extends any>({
|
|
|
103
104
|
perPageOptions,
|
|
104
105
|
canSelectAll,
|
|
105
106
|
variant,
|
|
107
|
+
alreadySorted,
|
|
106
108
|
}: WithTestID & AITableProps<R>) => {
|
|
107
109
|
const itemIDs = React.useMemo(() => data.map(getDataId), [data, getDataId]);
|
|
110
|
+
const [openRows, setOpenRows] = React.useState<OpenRows>({});
|
|
111
|
+
|
|
112
|
+
const sortByRef = React.useRef<ISortBy>();
|
|
113
|
+
const [sortBy, setSortBy] = React.useState<ISortBy>({
|
|
114
|
+
index: onSelect ? 1 : 0,
|
|
115
|
+
direction: SortByDirection.asc,
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
const dataRef = React.useRef(data);
|
|
119
|
+
if (dataRef.current !== data) {
|
|
120
|
+
dataRef.current = data;
|
|
121
|
+
}
|
|
108
122
|
|
|
109
123
|
React.useEffect(() => {
|
|
110
124
|
if (selectedIDs && setSelectedIDs) {
|
|
@@ -121,16 +135,29 @@ const AITable = <R extends any>({
|
|
|
121
135
|
}
|
|
122
136
|
}, [data, setSelectedIDs, selectedIDs, getDataId]);
|
|
123
137
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
138
|
+
React.useEffect(() => {
|
|
139
|
+
if (alreadySorted) {
|
|
140
|
+
sortByRef.current = sortBy;
|
|
141
|
+
setSortBy({
|
|
142
|
+
index: -1,
|
|
143
|
+
direction: SortByDirection.asc,
|
|
144
|
+
});
|
|
145
|
+
} else {
|
|
146
|
+
if (sortBy.index === -1 && sortByRef.current) {
|
|
147
|
+
setSortBy(sortByRef.current);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
151
|
+
}, [alreadySorted]);
|
|
152
|
+
|
|
153
|
+
React.useEffect(() => {
|
|
154
|
+
if (!alreadySorted) {
|
|
155
|
+
sortByRef.current = sortBy;
|
|
156
|
+
} else if (alreadySorted && sortBy.index !== -1) {
|
|
157
|
+
sortByRef.current = sortBy;
|
|
158
|
+
}
|
|
159
|
+
}, [sortBy, alreadySorted]);
|
|
129
160
|
|
|
130
|
-
const dataRef = React.useRef(data);
|
|
131
|
-
if (dataRef.current !== data) {
|
|
132
|
-
dataRef.current = data;
|
|
133
|
-
}
|
|
134
161
|
const onSelectAll = React.useCallback(
|
|
135
162
|
(isChecked: boolean) => {
|
|
136
163
|
setSelectedIDs?.(isChecked ? dataRef.current.map(getDataId) : []);
|
|
@@ -169,33 +196,27 @@ const AITable = <R extends any>({
|
|
|
169
196
|
return [newContent, columns];
|
|
170
197
|
}, [canSelectAll, content, getDataId, onSelect, onSelectAll]);
|
|
171
198
|
|
|
172
|
-
const
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
ExpandComponent,
|
|
194
|
-
getDataId,
|
|
195
|
-
contentWithAdditions,
|
|
196
|
-
openRows,
|
|
197
|
-
actionResolver,
|
|
198
|
-
]);
|
|
199
|
+
const getRows = React.useCallback(
|
|
200
|
+
(data: R[]) =>
|
|
201
|
+
(data || [])
|
|
202
|
+
.map<IRow>((obj) => {
|
|
203
|
+
const id = getDataId(obj);
|
|
204
|
+
const cells = contentWithAdditions.filter((c) => !!c.cell).map((c) => c.cell?.(obj));
|
|
205
|
+
const isOpen = !!openRows[id];
|
|
206
|
+
return {
|
|
207
|
+
isOpen,
|
|
208
|
+
cells,
|
|
209
|
+
key: `${id}-master`,
|
|
210
|
+
id,
|
|
211
|
+
actions: actionResolver ? actionResolver(obj) : undefined,
|
|
212
|
+
nestedComponent: ExpandComponent ? <ExpandComponent obj={obj} /> : undefined,
|
|
213
|
+
};
|
|
214
|
+
})
|
|
215
|
+
.slice((page - 1) * perPage, page * perPage),
|
|
216
|
+
[page, perPage, getDataId, contentWithAdditions, openRows, actionResolver, ExpandComponent],
|
|
217
|
+
);
|
|
218
|
+
|
|
219
|
+
const hostRows = React.useMemo(() => getRows(data), [data, getRows]);
|
|
199
220
|
|
|
200
221
|
const rows = React.useMemo(() => {
|
|
201
222
|
if (hostRows.length) {
|
|
@@ -223,10 +244,13 @@ const AITable = <R extends any>({
|
|
|
223
244
|
}, []);
|
|
224
245
|
|
|
225
246
|
const sortedRows = React.useMemo(() => {
|
|
247
|
+
if (alreadySorted && sortBy.index === -1) {
|
|
248
|
+
return getRows(data);
|
|
249
|
+
}
|
|
226
250
|
return rows.sort(
|
|
227
251
|
rowSorter(sortBy, (row: IRow, index = 0) => row.cells?.[index] as string | HumanizedSortable),
|
|
228
252
|
);
|
|
229
|
-
}, [rows,
|
|
253
|
+
}, [alreadySorted, sortBy, rows, getRows, data]);
|
|
230
254
|
|
|
231
255
|
return (
|
|
232
256
|
<>
|
|
@@ -60,20 +60,32 @@ type HostsTableProps = ReturnType<typeof usePagination> &
|
|
|
60
60
|
| 'variant'
|
|
61
61
|
> & {
|
|
62
62
|
hosts: Host[];
|
|
63
|
+
alreadySorted?: boolean;
|
|
63
64
|
skipDisabled?: boolean;
|
|
64
65
|
children: React.ReactNode;
|
|
65
66
|
};
|
|
66
67
|
|
|
67
|
-
const HostsTable = ({
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
68
|
+
const HostsTable = ({
|
|
69
|
+
hosts,
|
|
70
|
+
skipDisabled,
|
|
71
|
+
alreadySorted,
|
|
72
|
+
...rest
|
|
73
|
+
}: HostsTableProps & WithTestID) => {
|
|
74
|
+
const data = React.useMemo(() => {
|
|
75
|
+
const filteredHosts = (hosts || []).filter(
|
|
76
|
+
(host) => !skipDisabled || host.status !== 'disabled',
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
return alreadySorted
|
|
80
|
+
? filteredHosts
|
|
81
|
+
: filteredHosts.sort((a, b) =>
|
|
82
|
+
a.createdAt && b.createdAt && a.createdAt < b.createdAt ? -1 : 1,
|
|
83
|
+
);
|
|
84
|
+
}, [hosts, skipDisabled, alreadySorted]);
|
|
75
85
|
|
|
76
|
-
return
|
|
86
|
+
return (
|
|
87
|
+
<AITable<Host> getDataId={getHostId} data={data} alreadySorted={alreadySorted} {...rest} />
|
|
88
|
+
);
|
|
77
89
|
};
|
|
78
90
|
|
|
79
91
|
export default HostsTable;
|
|
@@ -196,7 +196,7 @@ export const getInventory = (host: Host) => {
|
|
|
196
196
|
|
|
197
197
|
export const filterByHostname = (hosts: Host[], hostnameFilter: string | undefined) => {
|
|
198
198
|
if (!hostnameFilter) {
|
|
199
|
-
return hosts;
|
|
199
|
+
return { hosts, sorted: false };
|
|
200
200
|
}
|
|
201
201
|
const hostsWithHostname = hosts.map((host) => {
|
|
202
202
|
const { inventory: inventoryString = '' } = host;
|
|
@@ -209,12 +209,28 @@ export const filterByHostname = (hosts: Host[], hostnameFilter: string | undefin
|
|
|
209
209
|
});
|
|
210
210
|
|
|
211
211
|
const fuse = new Fuse(hostsWithHostname, {
|
|
212
|
+
includeScore: true,
|
|
212
213
|
ignoreLocation: true,
|
|
213
214
|
threshold: 0.3,
|
|
214
215
|
keys: ['hostname'],
|
|
215
216
|
});
|
|
216
217
|
|
|
217
|
-
|
|
218
|
+
const filteredHosts = fuse.search(hostnameFilter);
|
|
219
|
+
|
|
220
|
+
const sortedHosts = filteredHosts
|
|
221
|
+
.sort((a, b) => (a.score || 0) - (b.score || 0))
|
|
222
|
+
.map(({ item }) => item.host);
|
|
223
|
+
|
|
224
|
+
const sorted =
|
|
225
|
+
filteredHosts.length > 1 &&
|
|
226
|
+
filteredHosts.some(
|
|
227
|
+
(result, index) => index > 0 && (result.score || 0) !== (filteredHosts[0].score || 0),
|
|
228
|
+
);
|
|
229
|
+
|
|
230
|
+
return {
|
|
231
|
+
hosts: sortedHosts,
|
|
232
|
+
sorted,
|
|
233
|
+
};
|
|
218
234
|
};
|
|
219
235
|
|
|
220
236
|
export const getFailingHostValidations = (validationsInfo: HostValidationsInfo) =>
|
|
@@ -60,13 +60,20 @@ const TextAreaField: React.FC<TextAreaFieldProps> = ({
|
|
|
60
60
|
{(errorMessage || helperText) && (
|
|
61
61
|
<FormHelperText>
|
|
62
62
|
<HelperText>
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
63
|
+
{errorMessage && (
|
|
64
|
+
<HelperTextItem
|
|
65
|
+
icon={<ExclamationCircleIcon />}
|
|
66
|
+
variant={'error'}
|
|
67
|
+
id={`${fieldId}-helper-error`}
|
|
68
|
+
>
|
|
69
|
+
{errorMessage}
|
|
70
|
+
</HelperTextItem>
|
|
71
|
+
)}
|
|
72
|
+
{helperText && (
|
|
73
|
+
<HelperTextItem variant={'default'} id={`${fieldId}-helper`}>
|
|
74
|
+
{helperText}
|
|
75
|
+
</HelperTextItem>
|
|
76
|
+
)}
|
|
70
77
|
</HelperText>
|
|
71
78
|
</FormHelperText>
|
|
72
79
|
)}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"dependencies": {
|
|
3
|
-
"@openshift-assisted/locales": "2.15.
|
|
4
|
-
"@openshift-assisted/types": "2.15.
|
|
3
|
+
"@openshift-assisted/locales": "2.15.4-cim",
|
|
4
|
+
"@openshift-assisted/types": "2.15.4-cim",
|
|
5
5
|
"@openshift-console/dynamic-plugin-sdk": "0.0.3",
|
|
6
6
|
"@patternfly/patternfly": "5.2.0",
|
|
7
7
|
"@patternfly/react-code-editor": "5.2.0",
|
|
@@ -140,5 +140,5 @@
|
|
|
140
140
|
]
|
|
141
141
|
}
|
|
142
142
|
},
|
|
143
|
-
"version": "2.15.
|
|
143
|
+
"version": "2.15.4-cim"
|
|
144
144
|
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { OpenshiftVersionOptionType } from '../../types';
|
|
3
|
-
import { SelectFieldProps } from '../ui/formik/types';
|
|
4
|
-
type OpenShiftVersionSelectProps = {
|
|
5
|
-
versions: OpenshiftVersionOptionType[];
|
|
6
|
-
onChange?: SelectFieldProps['onChange'];
|
|
7
|
-
};
|
|
8
|
-
declare const OpenShiftVersionSelect: React.FC<OpenShiftVersionSelectProps>;
|
|
9
|
-
export default OpenShiftVersionSelect;
|
|
10
|
-
//# sourceMappingURL=OpenShiftVersionSelect.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"OpenShiftVersionSelect.d.ts","sourceRoot":"","sources":["../../../../../lib/common/components/clusterConfiguration/OpenShiftVersionSelect.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAM1B,OAAO,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AAGzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AA4CtD,KAAK,2BAA2B,GAAG;IACjC,QAAQ,EAAE,0BAA0B,EAAE,CAAC;IACvC,QAAQ,CAAC,EAAE,gBAAgB,CAAC,UAAU,CAAC,CAAC;CACzC,CAAC;AACF,QAAA,MAAM,sBAAsB,EAAE,KAAK,CAAC,EAAE,CAAC,2BAA2B,CAqBjE,CAAC;AAEF,eAAe,sBAAsB,CAAC"}
|