@openshift-assisted/ui-lib 2.39.5 → 2.40.0

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.
Files changed (125) hide show
  1. package/build/@types/cim/components/InfraEnv/InfraTableToolbar.d.ts.map +1 -1
  2. package/build/@types/cim/components/helpers/toAssisted.d.ts.map +1 -1
  3. package/build/@types/cim/index.d.ts +1 -0
  4. package/build/@types/cim/index.d.ts.map +1 -1
  5. package/build/@types/common/api/assisted-service/ClustersAPI.d.ts +1 -0
  6. package/build/@types/common/api/assisted-service/ClustersAPI.d.ts.map +1 -1
  7. package/build/@types/common/components/clusterDetail/ClusterCredentials.d.ts.map +1 -1
  8. package/build/@types/common/components/clusterWizard/ClusterWizardStep.d.ts.map +1 -1
  9. package/build/@types/common/components/operators/operatorSpecs.d.ts.map +1 -1
  10. package/build/@types/common/components/ui/ClusterEventsToolbar.d.ts.map +1 -1
  11. package/build/@types/common/components/ui/WizardFooter.d.ts +1 -0
  12. package/build/@types/common/components/ui/WizardFooter.d.ts.map +1 -1
  13. package/build/@types/common/components/ui/WizardNavItem.d.ts +1 -1
  14. package/build/@types/common/components/ui/WizardNavItem.d.ts.map +1 -1
  15. package/build/@types/common/components/ui/formik/MultiSelectField.d.ts.map +1 -1
  16. package/build/@types/common/components/ui/formik/types.d.ts +2 -2
  17. package/build/@types/common/components/ui/formik/types.d.ts.map +1 -1
  18. package/build/@types/common/components/ui/utils.d.ts +1 -1
  19. package/build/@types/common/components/ui/utils.d.ts.map +1 -1
  20. package/build/@types/common/config/constants.d.ts.map +1 -1
  21. package/build/@types/common/config/docs_links.d.ts +1 -0
  22. package/build/@types/common/config/docs_links.d.ts.map +1 -1
  23. package/build/@types/common/index.d.ts +0 -3
  24. package/build/@types/common/index.d.ts.map +1 -1
  25. package/build/@types/ocm/components/clusterConfiguration/networkConfiguration/NetworkConfigurationForm.d.ts.map +1 -1
  26. package/build/@types/ocm/components/clusterConfiguration/operators/bundleSpecs.d.ts.map +1 -1
  27. package/build/@types/ocm/components/clusterDetail/ClusterDetailStatusMessages.d.ts.map +1 -1
  28. package/build/@types/ocm/components/clusterDetail/ClusterDetailsButtonGroup.d.ts +1 -0
  29. package/build/@types/ocm/components/clusterDetail/ClusterDetailsButtonGroup.d.ts.map +1 -1
  30. package/build/@types/ocm/components/clusterWizard/CredentialsDownload.d.ts +7 -0
  31. package/build/@types/ocm/components/clusterWizard/CredentialsDownload.d.ts.map +1 -0
  32. package/build/@types/ocm/components/clusterWizard/wizardTransition.d.ts +1 -1
  33. package/build/@types/ocm/components/clusterWizard/wizardTransition.d.ts.map +1 -1
  34. package/build/@types/ocm/components/clusters/ClustersListToolbar.d.ts.map +1 -1
  35. package/build/cjs/cim/components/InfraEnv/InfraTableToolbar.js +12 -12
  36. package/build/cjs/cim/components/InfraEnv/InfraTableToolbar.js.map +1 -1
  37. package/build/cjs/cim/components/helpers/toAssisted.js +3 -5
  38. package/build/cjs/cim/components/helpers/toAssisted.js.map +1 -1
  39. package/build/cjs/cim/components/helpers/versions.js +1 -1
  40. package/build/cjs/cim/components/helpers/versions.js.map +1 -1
  41. package/build/cjs/cim/index.js +1 -0
  42. package/build/cjs/cim/index.js.map +1 -1
  43. package/build/cjs/common/api/assisted-service/ClustersAPI.js +5 -0
  44. package/build/cjs/common/api/assisted-service/ClustersAPI.js.map +1 -1
  45. package/build/cjs/common/components/clusterDetail/ClusterCredentials.js +1 -1
  46. package/build/cjs/common/components/clusterDetail/ClusterCredentials.js.map +1 -1
  47. package/build/cjs/common/components/clusterWizard/ClusterWizardStep.js +2 -4
  48. package/build/cjs/common/components/clusterWizard/ClusterWizardStep.js.map +1 -1
  49. package/build/cjs/common/components/operators/operatorSpecs.js +2 -2
  50. package/build/cjs/common/components/operators/operatorSpecs.js.map +1 -1
  51. package/build/cjs/common/components/ui/ClusterEventsToolbar.js +18 -10
  52. package/build/cjs/common/components/ui/ClusterEventsToolbar.js.map +1 -1
  53. package/build/cjs/common/components/ui/WizardFooter.js +2 -2
  54. package/build/cjs/common/components/ui/WizardFooter.js.map +1 -1
  55. package/build/cjs/common/components/ui/WizardNavItem.js +2 -2
  56. package/build/cjs/common/components/ui/WizardNavItem.js.map +1 -1
  57. package/build/cjs/common/components/ui/formik/MultiSelectField.js +26 -28
  58. package/build/cjs/common/components/ui/formik/MultiSelectField.js.map +1 -1
  59. package/build/cjs/common/components/ui/utils.js +1 -1
  60. package/build/cjs/common/components/ui/utils.js.map +1 -1
  61. package/build/cjs/common/config/constants.js +1 -0
  62. package/build/cjs/common/config/constants.js.map +1 -1
  63. package/build/cjs/common/config/docs_links.js +2 -1
  64. package/build/cjs/common/config/docs_links.js.map +1 -1
  65. package/build/cjs/common/index.js +0 -3
  66. package/build/cjs/common/index.js.map +1 -1
  67. package/build/cjs/ocm/components/AddHosts/day2Wizard/Day2Wizard.js +2 -2
  68. package/build/cjs/ocm/components/AddHosts/day2Wizard/Day2Wizard.js.map +1 -1
  69. package/build/cjs/ocm/components/AddHosts/day2Wizard/Day2WizardNav.js +5 -5
  70. package/build/cjs/ocm/components/AddHosts/day2Wizard/Day2WizardNav.js.map +1 -1
  71. package/build/cjs/ocm/components/clusterConfiguration/networkConfiguration/NetworkConfigurationForm.js +23 -1
  72. package/build/cjs/ocm/components/clusterConfiguration/networkConfiguration/NetworkConfigurationForm.js.map +1 -1
  73. package/build/cjs/ocm/components/clusterConfiguration/operators/bundleSpecs.js +4 -18
  74. package/build/cjs/ocm/components/clusterConfiguration/operators/bundleSpecs.js.map +1 -1
  75. package/build/cjs/ocm/components/clusterDetail/ClusterDetailStatusMessages.js +16 -14
  76. package/build/cjs/ocm/components/clusterDetail/ClusterDetailStatusMessages.js.map +1 -1
  77. package/build/cjs/ocm/components/clusterDetail/ClusterDetailsButtonGroup.js +1 -0
  78. package/build/cjs/ocm/components/clusterDetail/ClusterDetailsButtonGroup.js.map +1 -1
  79. package/build/cjs/ocm/components/clusterWizard/ClusterWizard.js +3 -3
  80. package/build/cjs/ocm/components/clusterWizard/ClusterWizard.js.map +1 -1
  81. package/build/cjs/ocm/components/clusterWizard/ClusterWizardContextProvider.js +1 -1
  82. package/build/cjs/ocm/components/clusterWizard/ClusterWizardContextProvider.js.map +1 -1
  83. package/build/cjs/ocm/components/clusterWizard/ClusterWizardNavigation.js +5 -5
  84. package/build/cjs/ocm/components/clusterWizard/ClusterWizardNavigation.js.map +1 -1
  85. package/build/cjs/ocm/components/clusterWizard/CredentialsDownload.js +62 -0
  86. package/build/cjs/ocm/components/clusterWizard/CredentialsDownload.js.map +1 -0
  87. package/build/cjs/ocm/components/clusterWizard/constants.js +1 -1
  88. package/build/cjs/ocm/components/clusterWizard/constants.js.map +1 -1
  89. package/build/cjs/ocm/components/clusterWizard/wizardTransition.js +3 -3
  90. package/build/cjs/ocm/components/clusterWizard/wizardTransition.js.map +1 -1
  91. package/build/cjs/ocm/components/clusters/ClustersListToolbar.js +3 -3
  92. package/build/cjs/ocm/components/clusters/ClustersListToolbar.js.map +1 -1
  93. package/lib/cim/components/InfraEnv/InfraTableToolbar.tsx +40 -28
  94. package/lib/cim/components/helpers/toAssisted.ts +3 -4
  95. package/lib/cim/components/helpers/versions.ts +1 -1
  96. package/lib/cim/index.ts +1 -0
  97. package/lib/common/api/assisted-service/ClustersAPI.ts +6 -0
  98. package/lib/common/components/clusterDetail/ClusterCredentials.tsx +12 -2
  99. package/lib/common/components/clusterWizard/ClusterWizardStep.tsx +2 -4
  100. package/lib/common/components/operators/operatorSpecs.tsx +3 -2
  101. package/lib/common/components/ui/ClusterEventsToolbar.tsx +78 -45
  102. package/lib/common/components/ui/WizardFooter.tsx +3 -0
  103. package/lib/common/components/ui/WizardNavItem.tsx +1 -1
  104. package/lib/common/components/ui/formik/MultiSelectField.tsx +98 -58
  105. package/lib/common/components/ui/formik/types.ts +2 -2
  106. package/lib/common/components/ui/utils.ts +4 -2
  107. package/lib/common/config/constants.ts +1 -0
  108. package/lib/common/config/docs_links.ts +3 -0
  109. package/lib/common/index.ts +0 -4
  110. package/lib/ocm/components/AddHosts/day2Wizard/Day2Wizard.tsx +1 -1
  111. package/lib/ocm/components/AddHosts/day2Wizard/Day2WizardNav.tsx +5 -5
  112. package/lib/ocm/components/clusterConfiguration/networkConfiguration/NetworkConfigurationForm.tsx +29 -1
  113. package/lib/ocm/components/clusterConfiguration/operators/bundleSpecs.tsx +5 -25
  114. package/lib/ocm/components/clusterDetail/ClusterDetailStatusMessages.tsx +18 -19
  115. package/lib/ocm/components/clusterDetail/ClusterDetailsButtonGroup.tsx +2 -0
  116. package/lib/ocm/components/clusterWizard/ClusterWizard.tsx +3 -3
  117. package/lib/ocm/components/clusterWizard/ClusterWizardContextProvider.tsx +1 -1
  118. package/lib/ocm/components/clusterWizard/ClusterWizardNavigation.tsx +5 -5
  119. package/lib/ocm/components/clusterWizard/CredentialsDownload.tsx +105 -0
  120. package/lib/ocm/components/clusterWizard/constants.ts +1 -1
  121. package/lib/ocm/components/clusterWizard/wizardTransition.ts +4 -4
  122. package/lib/ocm/components/clusters/ClustersListToolbar.tsx +39 -19
  123. package/package.json +3 -3
  124. /package/build/cjs/{common/styles.css → ocm/components/clusterDetail/ClusterDetailsButtonGroup.css} +0 -0
  125. /package/lib/{common/styles.css → ocm/components/clusterDetail/ClusterDetailsButtonGroup.css} +0 -0
@@ -14,7 +14,9 @@ export const getHumanizedTime = (dateTime?: string) => {
14
14
  };
15
15
 
16
16
  // TypesScript safe
17
- export const isSelectEventChecked = (event: React.MouseEvent | React.ChangeEvent): boolean => {
18
- const target = event.target as { checked?: boolean };
17
+ export const isSelectEventChecked = (
18
+ event: React.MouseEvent | React.ChangeEvent | undefined,
19
+ ): boolean => {
20
+ const target = event?.target as { checked?: boolean };
19
21
  return !!target?.checked;
20
22
  };
@@ -328,6 +328,7 @@ export const singleClusterOperators = [
328
328
  OPERATOR_NAME_SELF_NODE_REMEDIATION,
329
329
  OPERATOR_NAME_ODF,
330
330
  OPERATOR_NAME_LSO,
331
+ OPERATOR_NAME_LVM,
331
332
  ];
332
333
 
333
334
  export const singleClusterBundles = ['virtualization'];
@@ -182,3 +182,6 @@ export const getServiceMeshLink = (ocpVersion?: string) =>
182
182
 
183
183
  export const SERVERLESS_OPERATOR_LINK =
184
184
  'https://docs.openshift.com/serverless/1.28/install/install-serverless-operator.html#serverless-install-web-console_install-serverless-operator';
185
+
186
+ export const KUBECONFIG_INFO_LINK =
187
+ 'https://docs.redhat.com/en/documentation/openshift_container_platform/4.18/html/cli_tools/openshift-cli-oc#about-switches-between-cli-profiles_managing-cli-profiles';
@@ -1,7 +1,3 @@
1
- import './configurations';
2
- import './styles.css';
3
- import './utils';
4
-
5
1
  export * from './components';
6
2
  export * from './api';
7
3
  export * from './types';
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { Modal, ModalVariant } from '@patternfly/react-core';
3
- import { WizardHeader } from '@patternfly/react-core/deprecated';
3
+ import { WizardHeader } from '@patternfly/react-core';
4
4
  import classNames from 'classnames';
5
5
  import { ClusterWizardStep } from '../../../../common';
6
6
  import { useModalDialogsContext } from '../../hosts/ModalDialogsContext';
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { WizardNav, WizardNavItem } from '@patternfly/react-core/deprecated';
2
+ import { WizardNav, WizardNavItem } from '@patternfly/react-core';
3
3
  import { Day2WizardStepsType, day2WizardStepNames, staticIpFormViewSubSteps } from './constants';
4
4
  import { useDay2WizardContext } from './Day2WizardContext';
5
5
  import { isStaticIpStep } from '../../clusterWizard/wizardTransition';
@@ -18,10 +18,10 @@ const Day2WizardNav = () => {
18
18
  const getNavItem = (idx: number, stepId: Day2WizardStepsType): React.ReactNode => {
19
19
  return (
20
20
  <WizardNavItem
21
- step={idx}
21
+ stepIndex={idx}
22
22
  key={stepId}
23
23
  content={day2WizardStepNames[stepId]}
24
- onNavItemClick={() => wizardContext.setCurrentStepId(stepId)}
24
+ onClick={() => wizardContext.setCurrentStepId(stepId)}
25
25
  isCurrent={wizardContext.currentStepId === stepId}
26
26
  isDisabled={isStepDisabled(idx, stepId)}
27
27
  />
@@ -31,14 +31,14 @@ const Day2WizardNav = () => {
31
31
  const getStaticIpFormViewNavItem = (idx: number): React.ReactNode => {
32
32
  return (
33
33
  <WizardNavItem
34
- step={idx}
34
+ stepIndex={idx}
35
35
  isExpandable={true}
36
36
  content="Static network configurations"
37
37
  key="static-network-configuration-form-view"
38
38
  isCurrent={isStaticIpStep(wizardContext.currentStepId)}
39
39
  isDisabled={isStepIdxAfterCurrent(idx)}
40
40
  >
41
- <WizardNav returnList>
41
+ <WizardNav isInnerList>
42
42
  {staticIpFormViewSubSteps.map((stepId, subIdx) => {
43
43
  return getNavItem(idx + subIdx, stepId);
44
44
  })}
@@ -16,6 +16,7 @@ import {
16
16
  SecurityFields,
17
17
  useAlerts,
18
18
  useFormikAutoSave,
19
+ ClustersAPI,
19
20
  } from '../../../../common';
20
21
  import { useDefaultConfiguration } from '../ClusterDefaultConfigurationContext';
21
22
  import { useClusterWizardContext } from '../../clusterWizard/ClusterWizardContext';
@@ -45,6 +46,7 @@ import {
45
46
  V2ClusterUpdateParams,
46
47
  } from '@openshift-assisted/types/assisted-installer-service';
47
48
  import { useNewFeatureSupportLevel } from '../../../../common/components/newFeatureSupportLevels';
49
+ import { useFeature } from '../../../hooks/use-feature';
48
50
 
49
51
  const NetworkConfigurationForm: React.FC<{
50
52
  cluster: Cluster;
@@ -65,6 +67,9 @@ const NetworkConfigurationForm: React.FC<{
65
67
  useFormikContext<NetworkConfigurationValues>();
66
68
  const isAutoSaveRunning = useFormikAutoSave();
67
69
  const errorFields = getFormikErrorFields(errors, touched);
70
+ const isSingleClusterFeatureEnabled = useFeature('ASSISTED_INSTALLER_SINGLE_CLUSTER_FEATURE');
71
+ const { addAlert } = useAlerts();
72
+ const dispatch = useDispatch();
68
73
 
69
74
  // DHCP allocation is currently not supported for Nutanix hosts
70
75
  // https://issues.redhat.com/browse/MGMT-12382
@@ -79,6 +84,29 @@ const NetworkConfigurationForm: React.FC<{
79
84
  }
80
85
  }, [isHostsPlatformTypeNutanix, setFieldValue, values.vipDhcpAllocation]);
81
86
 
87
+ const onNext = React.useCallback(async () => {
88
+ if (isSingleClusterFeatureEnabled) {
89
+ try {
90
+ await ClustersAPI.updateInstallConfig(
91
+ cluster.id,
92
+ JSON.stringify(JSON.stringify({ featureSet: 'TechPreviewNoUpgrade' })),
93
+ );
94
+ } catch (e) {
95
+ handleApiError(e, () =>
96
+ addAlert({
97
+ title: 'Failed to update install-config',
98
+ message: getApiErrorMessage(e),
99
+ }),
100
+ );
101
+ if (isUnknownServerError(e as Error)) {
102
+ dispatch(setServerUpdateError());
103
+ }
104
+ return;
105
+ }
106
+ }
107
+ clusterWizardContext.moveNext();
108
+ }, [addAlert, cluster.id, clusterWizardContext, dispatch, isSingleClusterFeatureEnabled]);
109
+
82
110
  const footer = (
83
111
  <ClusterWizardFooter
84
112
  cluster={cluster}
@@ -91,7 +119,7 @@ const NetworkConfigurationForm: React.FC<{
91
119
  !isValid ||
92
120
  !canNextNetwork({ cluster })
93
121
  }
94
- onNext={() => clusterWizardContext.moveNext()}
122
+ onNext={() => void onNext()}
95
123
  onBack={() => clusterWizardContext.moveBack()}
96
124
  isBackDisabled={isSubmitting || isAutoSaveRunning}
97
125
  />
@@ -1,6 +1,5 @@
1
1
  import * as React from 'react';
2
2
  import { List, ListItem } from '@patternfly/react-core';
3
- import { OPENSHIFT_AI_REQUIREMENTS_LINK } from '../../../../common';
4
3
 
5
4
  export type BundleSpec = {
6
5
  noSNO?: boolean;
@@ -11,6 +10,7 @@ export type BundleSpec = {
11
10
 
12
11
  export const bundleSpecs: { [key: string]: BundleSpec } = {
13
12
  virtualization: {
13
+ noSNO: true,
14
14
  Description: () => (
15
15
  <List>
16
16
  <ListItem>
@@ -26,36 +26,16 @@ export const bundleSpecs: { [key: string]: BundleSpec } = {
26
26
  </List>
27
27
  ),
28
28
  },
29
- 'openshift-ai-nvidia': {
30
- noSNO: true,
31
- incompatibleBundles: ['openshift-ai-amd'],
32
- Description: () => (
33
- <List>
34
- <ListItem>At least two worker nodes.</ListItem>
35
- <ListItem>
36
- Each worker node requires 32 additional GiB of memory and 8 additional CPUs.
37
- </ListItem>
38
- <ListItem>At least one supported NVIDIA GPU.</ListItem>
39
- <ListItem>
40
- Nodes that have NVIDIA GPUs installed need to have secure boot disabled.
41
- </ListItem>
42
- </List>
43
- ),
44
- docsLink: OPENSHIFT_AI_REQUIREMENTS_LINK,
45
- },
46
- 'openshift-ai-amd': {
29
+ 'openshift-ai': {
47
30
  noSNO: true,
48
- incompatibleBundles: ['openshift-ai-nvidia'],
31
+ incompatibleBundles: [],
49
32
  Description: () => (
50
33
  <List>
51
- <ListItem>At least two worker nodes.</ListItem>
52
34
  <ListItem>
53
- Each worker node requires 32 additional GiB of memory and 8 additional CPUs.
35
+ NVIDIA GPU, AMD GPU and Kernel Module Management may or may not be installed based on the
36
+ GPU discovered on your hosts.
54
37
  </ListItem>
55
- <ListItem>At least one supported AMD GPU.</ListItem>
56
- <ListItem>Nodes that have AMD GPUs installed need to have secure boot disabled.</ListItem>
57
38
  </List>
58
39
  ),
59
- docsLink: OPENSHIFT_AI_REQUIREMENTS_LINK,
60
40
  },
61
41
  };
@@ -1,7 +1,6 @@
1
1
  import React from 'react';
2
2
  import { Alert } from '@patternfly/react-core';
3
3
  import {
4
- RenderIf,
5
4
  REDHAT_CONSOLE_OPENSHIFT,
6
5
  canDownloadKubeconfig,
7
6
  isSNO,
@@ -16,6 +15,7 @@ import { ExternalPlatformLinks } from '../clusterConfiguration/platformIntegrati
16
15
  import { useNewFeatureSupportLevel } from '../../../common/components/newFeatureSupportLevels';
17
16
  import { Cluster, PlatformType } from '@openshift-assisted/types/assisted-installer-service';
18
17
  import PostInstallAlert from '../../../common/components/clusterDetail/PostInstallAlert';
18
+ import { useFeature } from '../../hooks/use-feature';
19
19
 
20
20
  type ClusterDetailStatusMessagesProps = {
21
21
  cluster: Cluster;
@@ -26,6 +26,7 @@ const ClusterDetailStatusMessages = ({
26
26
  cluster,
27
27
  showAddHostsInfo,
28
28
  }: ClusterDetailStatusMessagesProps) => {
29
+ const isSingleClusterFeatureEnabled = useFeature('ASSISTED_INSTALLER_SINGLE_CLUSTER_FEATURE');
29
30
  const featureSupportLevelContext = useNewFeatureSupportLevel();
30
31
  const { inactiveDeletionHours } = useDefaultConfiguration(['inactiveDeletionHours']);
31
32
  const inactiveDeletionDays = Math.round((inactiveDeletionHours || 0) / 24);
@@ -43,23 +44,21 @@ const ClusterDetailStatusMessages = ({
43
44
 
44
45
  return (
45
46
  <>
46
- <RenderIf
47
- condition={
48
- typeof inactiveDeletionHours === 'number' && canDownloadKubeconfig(cluster.status)
49
- }
50
- >
51
- <Alert
52
- variant="info"
53
- isInline
54
- title={
55
- dateDifference > 0
56
- ? `Download and save your kubeconfig file in a safe place. This file will be automatically ` +
57
- `deleted from Assisted Installer's service in ${dateDifference} days.`
58
- : `Kubeconfig file was automatically deleted ${inactiveDeletionDays} days after installation.`
59
- }
60
- />
61
- </RenderIf>
62
- <RenderIf condition={showAddHostsAlert}>
47
+ {!isSingleClusterFeatureEnabled &&
48
+ typeof inactiveDeletionHours === 'number' &&
49
+ canDownloadKubeconfig(cluster.status) && (
50
+ <Alert
51
+ variant="info"
52
+ isInline
53
+ title={
54
+ dateDifference > 0
55
+ ? `Download and save your kubeconfig file in a safe place. This file will be automatically ` +
56
+ `deleted from Assisted Installer's service in ${dateDifference} days.`
57
+ : `Kubeconfig file was automatically deleted ${inactiveDeletionDays} days after installation.`
58
+ }
59
+ />
60
+ )}
61
+ {showAddHostsAlert && (
63
62
  <Alert
64
63
  variant="info"
65
64
  isInline
@@ -76,7 +75,7 @@ const ClusterDetailStatusMessages = ({
76
75
  </p>
77
76
  }
78
77
  />
79
- </RenderIf>
78
+ )}
80
79
  {platformLink && <PostInstallAlert link={platformLink} />}
81
80
  </>
82
81
  );
@@ -15,6 +15,8 @@ import ViewClusterEventsButton from '../../../common/components/ui/ViewClusterEv
15
15
  import { LaunchOpenshiftConsoleButton } from '../../../common/components/clusterDetail/ConsoleModal';
16
16
  import { Cluster, Credentials } from '@openshift-assisted/types/assisted-installer-service';
17
17
 
18
+ import './ClusterDetailsButtonGroup.css';
19
+
18
20
  type ClusterDetailsButtonGroupProps = {
19
21
  cluster: Cluster;
20
22
  credentials?: Credentials;
@@ -16,7 +16,7 @@ import {
16
16
  InfraEnv,
17
17
  InfraEnvUpdateParams,
18
18
  } from '@openshift-assisted/types/assisted-installer-service';
19
- import KubeconfigDownload from './KubeconfigDownload';
19
+ import CredentialsDownload from './CredentialsDownload';
20
20
 
21
21
  type ClusterWizardProps = {
22
22
  cluster: Cluster;
@@ -45,8 +45,8 @@ const ClusterWizard = ({ cluster, infraEnv, updateInfraEnv }: ClusterWizardProps
45
45
  case 'static-ip-network-wide-configurations':
46
46
  case 'static-ip-yaml-view':
47
47
  return <StaticIp cluster={cluster} infraEnv={infraEnv} updateInfraEnv={updateInfraEnv} />;
48
- case 'kubeconfig-download':
49
- return <KubeconfigDownload cluster={cluster} />;
48
+ case 'credentials-download':
49
+ return <CredentialsDownload cluster={cluster} />;
50
50
  case 'cluster-details':
51
51
  default:
52
52
  return <ClusterDetails cluster={cluster} infraEnv={infraEnv} />;
@@ -69,7 +69,7 @@ const getWizardStepIds = (
69
69
  stepsCopy = removeStepFromClusterWizard(stepsCopy, 'custom-manifests', 1);
70
70
  }
71
71
  if (isSingleClusterFeatureEnabled) {
72
- stepsCopy = addStepToClusterWizard(stepsCopy, 'networking', ['kubeconfig-download']);
72
+ stepsCopy = addStepToClusterWizard(stepsCopy, 'networking', ['credentials-download']);
73
73
  }
74
74
 
75
75
  return stepsCopy;
@@ -1,5 +1,5 @@
1
1
  import React, { ReactNode } from 'react';
2
- import { WizardNav } from '@patternfly/react-core/deprecated';
2
+ import { WizardNav } from '@patternfly/react-core';
3
3
  import {
4
4
  canNextClusterDetails,
5
5
  canNextHostDiscovery,
@@ -51,11 +51,11 @@ const ClusterWizardNavigation = ({ cluster }: { cluster?: Cluster }) => {
51
51
  const getNavItem = (idx: number, stepId: ClusterWizardStepsType): ReactNode => {
52
52
  return (
53
53
  <WizardNavItem
54
- step={idx}
54
+ stepIndex={idx}
55
55
  key={stepId}
56
56
  id={`wizard-nv-${stepId}`}
57
57
  content={wizardStepNames[stepId]}
58
- onNavItemClick={() => clusterWizardContext.setCurrentStepId(stepId)}
58
+ onClick={() => clusterWizardContext.setCurrentStepId(stepId)}
59
59
  isCurrent={clusterWizardContext.currentStepId === stepId}
60
60
  isDisabled={isStepDisabled(idx, stepId)}
61
61
  isValid={() => isStepValid(stepId, cluster)}
@@ -66,14 +66,14 @@ const ClusterWizardNavigation = ({ cluster }: { cluster?: Cluster }) => {
66
66
  const getStaticIpFormViewNavItem = (idx: number): ReactNode => {
67
67
  return (
68
68
  <WizardNavItem
69
- step={idx}
69
+ stepIndex={idx}
70
70
  isExpandable={true}
71
71
  content="Static network configurations"
72
72
  key="static-network-configuration-form-view"
73
73
  isCurrent={isStaticIpStep(clusterWizardContext.currentStepId)}
74
74
  isDisabled={isStepIdxAfterCurrent(idx)}
75
75
  >
76
- <WizardNav returnList>
76
+ <WizardNav isInnerList>
77
77
  {staticIpFormViewSubSteps.map((stepId, subIdx) => {
78
78
  return getNavItem(idx + subIdx, stepId);
79
79
  })}
@@ -0,0 +1,105 @@
1
+ import React from 'react';
2
+ import {
3
+ ClustersAPI,
4
+ ClusterWizardStep,
5
+ ClusterWizardStepHeader,
6
+ getApiErrorMessage,
7
+ handleApiError,
8
+ KUBECONFIG_INFO_LINK,
9
+ useAlerts,
10
+ useTranslation,
11
+ } from '../../../common';
12
+ import { useClusterWizardContext } from './ClusterWizardContext';
13
+ import ClusterWizardFooter from './ClusterWizardFooter';
14
+ import ClusterWizardNavigation from './ClusterWizardNavigation';
15
+ import { WithErrorBoundary } from '../../../common/components/ErrorHandling/WithErrorBoundary';
16
+ import { Cluster } from '@openshift-assisted/types/assisted-installer-service';
17
+ import { Alert, AlertVariant, Checkbox, Stack } from '@patternfly/react-core';
18
+ import { downloadFile } from '../../../common/utils';
19
+ import { ExternalLinkAltIcon } from '@patternfly/react-icons/dist/js/icons/external-link-alt-icon';
20
+
21
+ const CredentialsDownload: React.FC<{ cluster: Cluster }> = ({ cluster }) => {
22
+ const clusterWizardContext = useClusterWizardContext();
23
+ const [isChecked, setIsChecked] = React.useState<boolean>(false);
24
+ const [isDownloading, setIsDownloading] = React.useState(false);
25
+ const { addAlert } = useAlerts();
26
+ const { t } = useTranslation();
27
+
28
+ const downloadSingleFile = async (fileName: string) => {
29
+ try {
30
+ const response = await ClustersAPI.downloadClusterCredentials(cluster.id, fileName);
31
+ downloadFile('', response.data, fileName);
32
+ return true;
33
+ } catch (e) {
34
+ handleApiError(e, (e) => {
35
+ addAlert({
36
+ title: t('ai:Could not download {{fileName}} file', { fileName }),
37
+ message: getApiErrorMessage(e),
38
+ });
39
+ });
40
+ return false;
41
+ }
42
+ };
43
+
44
+ const handleDownloadClick = async () => {
45
+ setIsDownloading(true);
46
+
47
+ const configSuccess = await downloadSingleFile('kubeconfig');
48
+ const passwordSuccess = await downloadSingleFile('kubeadmin-password');
49
+
50
+ const hasError = !configSuccess || !passwordSuccess;
51
+
52
+ setTimeout(() => {
53
+ setIsDownloading(false);
54
+
55
+ if (!hasError) {
56
+ clusterWizardContext.moveNext();
57
+ }
58
+ }, 500);
59
+ };
60
+
61
+ const footer = (
62
+ <ClusterWizardFooter
63
+ cluster={cluster}
64
+ onNext={() => void handleDownloadClick()}
65
+ onBack={() => clusterWizardContext.moveBack()}
66
+ isNextDisabled={!isChecked || isDownloading}
67
+ nextButtonText={t('ai:Download credentials')}
68
+ isNextButtonLoading={isDownloading}
69
+ />
70
+ );
71
+
72
+ return (
73
+ <ClusterWizardStep navigation={<ClusterWizardNavigation cluster={cluster} />} footer={footer}>
74
+ <WithErrorBoundary title={t('ai:Failed to load Credentials Download step')}>
75
+ <Stack hasGutter>
76
+ <ClusterWizardStepHeader>{t('ai:Download credentials')}</ClusterWizardStepHeader>
77
+ <Alert
78
+ title={t('ai:Make sure you download and store your credentials files in a safe place')}
79
+ variant={AlertVariant.warning}
80
+ isInline
81
+ actionLinks={
82
+ <a href={KUBECONFIG_INFO_LINK} target="_blank" rel="noopener noreferrer">
83
+ {t('ai:Learn more about Kubeconfig')} <ExternalLinkAltIcon />
84
+ </a>
85
+ }
86
+ >
87
+ {t(`ai:You should use your cluster's Kubeconfig file to gain access to the cluster.`)}
88
+ <br />
89
+ {t(`ai:You can use username and password to log-in to your console through the UI.`)}
90
+ </Alert>
91
+ <Checkbox
92
+ id="credentials-download-agreement"
93
+ isChecked={isChecked}
94
+ onChange={() => setIsChecked(!isChecked)}
95
+ label={t(
96
+ 'ai:I understand that I need to download credentials files prior of proceeding with the cluster installation.',
97
+ )}
98
+ />
99
+ </Stack>
100
+ </WithErrorBoundary>
101
+ </ClusterWizardStep>
102
+ );
103
+ };
104
+
105
+ export default CredentialsDownload;
@@ -11,7 +11,7 @@ export const wizardStepNames: { [key in ClusterWizardStepsType]: string } = {
11
11
  networking: 'Networking',
12
12
  'custom-manifests': 'Custom manifests',
13
13
  review: 'Review and create',
14
- 'kubeconfig-download': 'Download Kubeconfig',
14
+ 'credentials-download': 'Download credentials',
15
15
  };
16
16
 
17
17
  export const defaultWizardSteps: ClusterWizardStepsType[] = [
@@ -29,7 +29,7 @@ export type ClusterWizardStepsType =
29
29
  | 'networking'
30
30
  | 'review'
31
31
  | 'custom-manifests'
32
- | 'kubeconfig-download';
32
+ | 'credentials-download';
33
33
 
34
34
  const wizardStepsOrder: ClusterWizardStepsType[] = [
35
35
  'cluster-details',
@@ -41,7 +41,7 @@ const wizardStepsOrder: ClusterWizardStepsType[] = [
41
41
  'storage',
42
42
  'networking',
43
43
  'custom-manifests',
44
- 'kubeconfig-download',
44
+ 'credentials-download',
45
45
  'review',
46
46
  ];
47
47
 
@@ -243,7 +243,7 @@ const reviewStepValidationsMap: WizardStepValidationMap = {
243
243
  softValidationIds: [],
244
244
  };
245
245
 
246
- const kubeconfigValidationMap = buildEmptyValidationsMap();
246
+ const credentialsValidationMap = buildEmptyValidationsMap();
247
247
 
248
248
  const customManifestsValidationsMap = buildEmptyValidationsMap();
249
249
 
@@ -258,7 +258,7 @@ export const wizardStepsValidationsMap: WizardStepsValidationMap<ClusterWizardSt
258
258
  storage: storageStepValidationsMap,
259
259
  networking: networkingStepValidationsMap,
260
260
  review: reviewStepValidationsMap,
261
- 'kubeconfig-download': kubeconfigValidationMap,
261
+ 'credentials-download': credentialsValidationMap,
262
262
  };
263
263
 
264
264
  export const allClusterWizardSoftValidationIds =
@@ -14,8 +14,12 @@ import {
14
14
  ToolbarGroup,
15
15
  Tooltip,
16
16
  InputGroupItem,
17
+ Dropdown,
18
+ DropdownItem,
19
+ DropdownList,
20
+ MenuToggle,
21
+ MenuToggleElement,
17
22
  } from '@patternfly/react-core';
18
- import { Select, SelectOption, SelectProps } from '@patternfly/react-core/deprecated';
19
23
  import { FilterIcon } from '@patternfly/react-icons/dist/js/icons/filter-icon';
20
24
  import { SyncIcon } from '@patternfly/react-icons/dist/js/icons/sync-icon';
21
25
  import { clusterStatusLabels, isSelectEventChecked, ToolbarButton } from '../../../common';
@@ -72,8 +76,11 @@ const ClustersListToolbar: React.FC<ClustersListToolbarProps> = ({
72
76
  });
73
77
  };
74
78
 
75
- const onStatusToggle: SelectProps['onToggle'] = () => setStatusExpanded(!isStatusExpanded);
76
- const onStatusSelect: SelectProps['onSelect'] = (event, val) => {
79
+ const onStatusToggle = () => setStatusExpanded(!isStatusExpanded);
80
+ const onStatusSelect = (
81
+ val: string,
82
+ event?: React.MouseEvent | React.ChangeEvent | undefined,
83
+ ) => {
77
84
  const value = val as Cluster['status'];
78
85
  onSelect('status', isSelectEventChecked(event), value);
79
86
  };
@@ -133,24 +140,37 @@ const ClustersListToolbar: React.FC<ClustersListToolbarProps> = ({
133
140
  deleteChipGroup={onDeleteChipGroup}
134
141
  categoryName="status"
135
142
  >
136
- <Select
137
- variant="checkbox"
138
- aria-label="status"
139
- onToggle={onStatusToggle}
140
- onSelect={onStatusSelect}
141
- selections={filters.status}
143
+ <Dropdown
142
144
  isOpen={isStatusExpanded}
143
- placeholderText={statusPlaceholder}
144
- toggleId="cluster-list-filter-status"
145
+ onSelect={(event, value) => onStatusSelect(value as string, event)}
146
+ onOpenChange={onStatusToggle}
147
+ toggle={(toggleRef: React.Ref<MenuToggleElement>) => (
148
+ <MenuToggle
149
+ id="cluster-list-filter-status"
150
+ ref={toggleRef}
151
+ isFullWidth
152
+ onClick={onStatusToggle}
153
+ isExpanded={isStatusExpanded}
154
+ >
155
+ {statusPlaceholder}
156
+ </MenuToggle>
157
+ )}
158
+ shouldFocusToggleOnSelect
145
159
  >
146
- {clusterStatusFilterLabels(t).map((label) => (
147
- <SelectOption
148
- key={label}
149
- value={label}
150
- inputId={`cluster-list-filter-status-${label}`}
151
- />
152
- ))}
153
- </Select>
160
+ <DropdownList>
161
+ {clusterStatusFilterLabels(t).map((label) => (
162
+ <DropdownItem
163
+ id={`cluster-list-filter-status-${label}`}
164
+ hasCheckbox
165
+ isSelected={filters.status.includes(label)}
166
+ key={label}
167
+ value={label}
168
+ >
169
+ {label}
170
+ </DropdownItem>
171
+ ))}
172
+ </DropdownList>
173
+ </Dropdown>
154
174
  </CustomToolbarFilter>
155
175
  <ToolbarButton
156
176
  variant={ButtonVariant.primary}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "dependencies": {
3
- "@openshift-assisted/locales": "2.39.5",
4
- "@openshift-assisted/types": "2.39.5",
3
+ "@openshift-assisted/locales": "2.40.0",
4
+ "@openshift-assisted/types": "2.40.0",
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.39.5"
143
+ "version": "2.40.0"
144
144
  }