@openshift-assisted/ui-lib 2.56.1 → 2.56.3

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 (148) hide show
  1. package/build/@types/common/api/assisted-service/OfflineOpenshiftVersionsAPI.d.ts +7 -0
  2. package/build/@types/common/api/assisted-service/OfflineOpenshiftVersionsAPI.d.ts.map +1 -0
  3. package/build/@types/common/api/assisted-service/index.d.ts +1 -0
  4. package/build/@types/common/api/assisted-service/index.d.ts.map +1 -1
  5. package/build/@types/common/components/ui/OpenShiftVersionDropdown.d.ts +3 -2
  6. package/build/@types/common/components/ui/OpenShiftVersionDropdown.d.ts.map +1 -1
  7. package/build/@types/common/config/constants.d.ts.map +1 -1
  8. package/build/@types/ocm/components/wizard/NewClusterWizard.d.ts.map +1 -1
  9. package/build/@types/ocm/components/wizard/clusterWizardContext/ClusterWizardContext.d.ts.map +1 -1
  10. package/build/@types/ocm/components/wizard/clusterWizardContext/ClusterWizardContextProvider.d.ts +1 -1
  11. package/build/@types/ocm/components/wizard/clusterWizardContext/ClusterWizardContextProvider.d.ts.map +1 -1
  12. package/build/@types/ocm/components/wizard/clusterWizardContext/utils.d.ts +7 -0
  13. package/build/@types/ocm/components/wizard/clusterWizardContext/utils.d.ts.map +1 -0
  14. package/build/@types/ocm/components/wizard/steps/clusterDetails/ClusterDetailsForm.d.ts.map +1 -1
  15. package/build/@types/ocm/components/wizard/steps/disconnected/BasicStep.d.ts +1 -1
  16. package/build/@types/ocm/components/wizard/steps/disconnected/BasicStep.d.ts.map +1 -1
  17. package/build/@types/ocm/components/wizard/steps/disconnected/DisconnectedReviewStep.d.ts.map +1 -1
  18. package/build/@types/ocm/components/wizard/steps/disconnected/DisconnectedStaticIp.d.ts +4 -0
  19. package/build/@types/ocm/components/wizard/steps/disconnected/DisconnectedStaticIp.d.ts.map +1 -0
  20. package/build/@types/ocm/components/wizard/steps/disconnected/InstallDisconnectedSwitch.d.ts.map +1 -1
  21. package/build/@types/ocm/components/wizard/steps/disconnected/OptionalConfigurationsStep.d.ts.map +1 -1
  22. package/build/@types/ocm/components/wizard/steps/disconnected/index.d.ts +1 -0
  23. package/build/@types/ocm/components/wizard/steps/disconnected/index.d.ts.map +1 -1
  24. package/build/@types/ocm/components/wizard/steps/staticIp/StaticIp.d.ts +1 -1
  25. package/build/@types/ocm/components/wizard/steps/staticIp/StaticIp.d.ts.map +1 -1
  26. package/build/@types/ocm/components/wizard/steps/staticIp/commonValidationSchemas.d.ts +6 -1
  27. package/build/@types/ocm/components/wizard/steps/staticIp/commonValidationSchemas.d.ts.map +1 -1
  28. package/build/@types/ocm/components/wizard/steps/staticIp/components/FormViewNetworkWide/FormViewNetworkWide.d.ts.map +1 -1
  29. package/build/@types/ocm/components/wizard/steps/staticIp/components/FormViewNetworkWide/FormViewNetworkWideFields.d.ts.map +1 -1
  30. package/build/@types/ocm/components/wizard/steps/staticIp/components/FormViewNetworkWide/disconnectedNetworkWideValidationSchema.d.ts +24 -0
  31. package/build/@types/ocm/components/wizard/steps/staticIp/components/FormViewNetworkWide/disconnectedNetworkWideValidationSchema.d.ts.map +1 -0
  32. package/build/@types/ocm/components/wizard/steps/staticIp/components/FormViewNetworkWide/formViewNetworkWideValidationSchema.d.ts +46 -1
  33. package/build/@types/ocm/components/wizard/steps/staticIp/components/FormViewNetworkWide/formViewNetworkWideValidationSchema.d.ts.map +1 -1
  34. package/build/@types/ocm/components/wizard/steps/staticIp/components/StaticIpPage.d.ts.map +1 -1
  35. package/build/@types/ocm/components/wizard/steps/staticIp/data/dataTypes.d.ts +1 -1
  36. package/build/@types/ocm/components/wizard/steps/staticIp/data/dataTypes.d.ts.map +1 -1
  37. package/build/@types/ocm/components/wizard/steps/staticIp/data/disconnectedNetworkWide.d.ts +8 -0
  38. package/build/@types/ocm/components/wizard/steps/staticIp/data/disconnectedNetworkWide.d.ts.map +1 -0
  39. package/build/@types/ocm/components/wizard/steps/staticIp/data/formDataFromInfraEnvField.d.ts.map +1 -1
  40. package/build/@types/ocm/components/wizard/steps/staticIp/data/fromInfraEnv.d.ts +2 -0
  41. package/build/@types/ocm/components/wizard/steps/staticIp/data/fromInfraEnv.d.ts.map +1 -1
  42. package/build/@types/ocm/components/wizard/steps/staticIp/data/index.d.ts +1 -0
  43. package/build/@types/ocm/components/wizard/steps/staticIp/data/index.d.ts.map +1 -1
  44. package/build/@types/ocm/components/wizard/steps/staticIp/data/nmstateYaml.d.ts +1 -0
  45. package/build/@types/ocm/components/wizard/steps/staticIp/data/nmstateYaml.d.ts.map +1 -1
  46. package/build/@types/ocm/components/wizard/steps/staticIp/data/protocolVersion.d.ts +2 -2
  47. package/build/@types/ocm/components/wizard/steps/staticIp/data/protocolVersion.d.ts.map +1 -1
  48. package/build/@types/ocm/components/wizard/wizardComponents/ClusterWizardNavigation.d.ts +7 -0
  49. package/build/@types/ocm/components/wizard/wizardComponents/ClusterWizardNavigation.d.ts.map +1 -1
  50. package/build/@types/ocm/services/apis/index.d.ts +1 -1
  51. package/build/@types/ocm/services/apis/index.d.ts.map +1 -1
  52. package/build/cjs/common/api/assisted-service/OfflineOpenshiftVersionsAPI.js +13 -0
  53. package/build/cjs/common/api/assisted-service/OfflineOpenshiftVersionsAPI.js.map +1 -0
  54. package/build/cjs/common/api/assisted-service/index.js +3 -1
  55. package/build/cjs/common/api/assisted-service/index.js.map +1 -1
  56. package/build/cjs/common/components/clusterWizard/ClusterWizardStep.css +9 -0
  57. package/build/cjs/common/components/ui/OpenShiftVersionDropdown.js +5 -5
  58. package/build/cjs/common/components/ui/OpenShiftVersionDropdown.js.map +1 -1
  59. package/build/cjs/common/config/constants.js +1 -0
  60. package/build/cjs/common/config/constants.js.map +1 -1
  61. package/build/cjs/common/validationSchemas/addressValidation.js +2 -2
  62. package/build/cjs/common/validationSchemas/addressValidation.js.map +1 -1
  63. package/build/cjs/ocm/components/wizard/NewClusterWizard.js +4 -0
  64. package/build/cjs/ocm/components/wizard/NewClusterWizard.js.map +1 -1
  65. package/build/cjs/ocm/components/wizard/clusterWizardContext/ClusterWizardContext.js.map +1 -1
  66. package/build/cjs/ocm/components/wizard/clusterWizardContext/ClusterWizardContextProvider.js +62 -62
  67. package/build/cjs/ocm/components/wizard/clusterWizardContext/ClusterWizardContextProvider.js.map +1 -1
  68. package/build/cjs/ocm/components/wizard/clusterWizardContext/utils.js +61 -0
  69. package/build/cjs/ocm/components/wizard/clusterWizardContext/utils.js.map +1 -0
  70. package/build/cjs/ocm/components/wizard/steps/clusterDetails/ClusterDetailsForm.js +1 -3
  71. package/build/cjs/ocm/components/wizard/steps/clusterDetails/ClusterDetailsForm.js.map +1 -1
  72. package/build/cjs/ocm/components/wizard/steps/disconnected/BasicStep.js +148 -11
  73. package/build/cjs/ocm/components/wizard/steps/disconnected/BasicStep.js.map +1 -1
  74. package/build/cjs/ocm/components/wizard/steps/disconnected/DisconnectedReviewStep.js +23 -12
  75. package/build/cjs/ocm/components/wizard/steps/disconnected/DisconnectedReviewStep.js.map +1 -1
  76. package/build/cjs/ocm/components/wizard/steps/disconnected/DisconnectedStaticIp.js +26 -0
  77. package/build/cjs/ocm/components/wizard/steps/disconnected/DisconnectedStaticIp.js.map +1 -0
  78. package/build/cjs/ocm/components/wizard/steps/disconnected/InstallDisconnectedSwitch.js +1 -1
  79. package/build/cjs/ocm/components/wizard/steps/disconnected/InstallDisconnectedSwitch.js.map +1 -1
  80. package/build/cjs/ocm/components/wizard/steps/disconnected/OptionalConfigurationsStep.js +87 -56
  81. package/build/cjs/ocm/components/wizard/steps/disconnected/OptionalConfigurationsStep.js.map +1 -1
  82. package/build/cjs/ocm/components/wizard/steps/disconnected/index.js +1 -0
  83. package/build/cjs/ocm/components/wizard/steps/disconnected/index.js.map +1 -1
  84. package/build/cjs/ocm/components/wizard/steps/staticIp/StaticIp.js.map +1 -1
  85. package/build/cjs/ocm/components/wizard/steps/staticIp/commonValidationSchemas.js +49 -12
  86. package/build/cjs/ocm/components/wizard/steps/staticIp/commonValidationSchemas.js.map +1 -1
  87. package/build/cjs/ocm/components/wizard/steps/staticIp/components/FormViewNetworkWide/FormViewNetworkWide.js +13 -4
  88. package/build/cjs/ocm/components/wizard/steps/staticIp/components/FormViewNetworkWide/FormViewNetworkWide.js.map +1 -1
  89. package/build/cjs/ocm/components/wizard/steps/staticIp/components/FormViewNetworkWide/FormViewNetworkWideFields.js +96 -4
  90. package/build/cjs/ocm/components/wizard/steps/staticIp/components/FormViewNetworkWide/FormViewNetworkWideFields.js.map +1 -1
  91. package/build/cjs/ocm/components/wizard/steps/staticIp/components/FormViewNetworkWide/disconnectedNetworkWideValidationSchema.js +70 -0
  92. package/build/cjs/ocm/components/wizard/steps/staticIp/components/FormViewNetworkWide/disconnectedNetworkWideValidationSchema.js.map +1 -0
  93. package/build/cjs/ocm/components/wizard/steps/staticIp/components/FormViewNetworkWide/formViewNetworkWideValidationSchema.js +19 -9
  94. package/build/cjs/ocm/components/wizard/steps/staticIp/components/FormViewNetworkWide/formViewNetworkWideValidationSchema.js.map +1 -1
  95. package/build/cjs/ocm/components/wizard/steps/staticIp/components/StaticIpPage.js +8 -2
  96. package/build/cjs/ocm/components/wizard/steps/staticIp/components/StaticIpPage.js.map +1 -1
  97. package/build/cjs/ocm/components/wizard/steps/staticIp/data/disconnectedNetworkWide.js +55 -0
  98. package/build/cjs/ocm/components/wizard/steps/staticIp/data/disconnectedNetworkWide.js.map +1 -0
  99. package/build/cjs/ocm/components/wizard/steps/staticIp/data/formDataFromInfraEnvField.js +5 -1
  100. package/build/cjs/ocm/components/wizard/steps/staticIp/data/formDataFromInfraEnvField.js.map +1 -1
  101. package/build/cjs/ocm/components/wizard/steps/staticIp/data/fromInfraEnv.js +48 -1
  102. package/build/cjs/ocm/components/wizard/steps/staticIp/data/fromInfraEnv.js.map +1 -1
  103. package/build/cjs/ocm/components/wizard/steps/staticIp/data/index.js +1 -0
  104. package/build/cjs/ocm/components/wizard/steps/staticIp/data/index.js.map +1 -1
  105. package/build/cjs/ocm/components/wizard/steps/staticIp/data/nmstateYaml.js +12 -1
  106. package/build/cjs/ocm/components/wizard/steps/staticIp/data/nmstateYaml.js.map +1 -1
  107. package/build/cjs/ocm/components/wizard/steps/staticIp/data/protocolVersion.js +9 -7
  108. package/build/cjs/ocm/components/wizard/steps/staticIp/data/protocolVersion.js.map +1 -1
  109. package/build/cjs/ocm/components/wizard/wizardComponents/ClusterWizardNavigation.js +31 -20
  110. package/build/cjs/ocm/components/wizard/wizardComponents/ClusterWizardNavigation.js.map +1 -1
  111. package/build/cjs/ocm/services/apis/index.js +2 -1
  112. package/build/cjs/ocm/services/apis/index.js.map +1 -1
  113. package/lib/common/api/assisted-service/OfflineOpenshiftVersionsAPI.ts +14 -0
  114. package/lib/common/api/assisted-service/index.ts +1 -0
  115. package/lib/common/components/clusterWizard/ClusterWizardStep.css +9 -0
  116. package/lib/common/components/ui/OpenShiftVersionDropdown.tsx +13 -8
  117. package/lib/common/config/constants.ts +1 -0
  118. package/lib/common/validationSchemas/_validationSchemas.test.ts +1 -1
  119. package/lib/common/validationSchemas/addressValidation.tsx +2 -2
  120. package/lib/ocm/components/wizard/NewClusterWizard.tsx +5 -0
  121. package/lib/ocm/components/wizard/clusterWizardContext/ClusterWizardContext.tsx +1 -1
  122. package/lib/ocm/components/wizard/clusterWizardContext/ClusterWizardContextProvider.tsx +63 -85
  123. package/lib/ocm/components/wizard/clusterWizardContext/utils.ts +73 -0
  124. package/lib/ocm/components/wizard/steps/clusterDetails/ClusterDetailsForm.tsx +0 -5
  125. package/lib/ocm/components/wizard/steps/disconnected/BasicStep.tsx +251 -16
  126. package/lib/ocm/components/wizard/steps/disconnected/DisconnectedReviewStep.tsx +47 -20
  127. package/lib/ocm/components/wizard/steps/disconnected/DisconnectedStaticIp.tsx +29 -0
  128. package/lib/ocm/components/wizard/steps/disconnected/InstallDisconnectedSwitch.tsx +1 -0
  129. package/lib/ocm/components/wizard/steps/disconnected/OptionalConfigurationsStep.tsx +137 -69
  130. package/lib/ocm/components/wizard/steps/disconnected/index.tsx +1 -0
  131. package/lib/ocm/components/wizard/steps/staticIp/StaticIp.tsx +1 -1
  132. package/lib/ocm/components/wizard/steps/staticIp/commonValidationSchemas.tsx +42 -3
  133. package/lib/ocm/components/wizard/steps/staticIp/components/FormViewNetworkWide/FormViewNetworkWide.tsx +15 -4
  134. package/lib/ocm/components/wizard/steps/staticIp/components/FormViewNetworkWide/FormViewNetworkWideFields.tsx +232 -14
  135. package/lib/ocm/components/wizard/steps/staticIp/components/FormViewNetworkWide/disconnectedNetworkWideValidationSchema.tsx +98 -0
  136. package/lib/ocm/components/wizard/steps/staticIp/components/FormViewNetworkWide/formViewNetworkWideValidationSchema.tsx +14 -5
  137. package/lib/ocm/components/wizard/steps/staticIp/components/StaticIpPage.tsx +8 -3
  138. package/lib/ocm/components/wizard/steps/staticIp/data/dataTypes.ts +1 -1
  139. package/lib/ocm/components/wizard/steps/staticIp/data/disconnectedNetworkWide.ts +81 -0
  140. package/lib/ocm/components/wizard/steps/staticIp/data/formDataFromInfraEnvField.ts +6 -2
  141. package/lib/ocm/components/wizard/steps/staticIp/data/fromInfraEnv.ts +57 -2
  142. package/lib/ocm/components/wizard/steps/staticIp/data/index.tsx +1 -0
  143. package/lib/ocm/components/wizard/steps/staticIp/data/nmstateYaml.ts +16 -0
  144. package/lib/ocm/components/wizard/steps/staticIp/data/protocolVersion.ts +9 -7
  145. package/lib/ocm/components/wizard/utils/_wizardTransition.test.ts +60 -1
  146. package/lib/ocm/components/wizard/wizardComponents/ClusterWizardNavigation.tsx +39 -16
  147. package/lib/ocm/services/apis/index.ts +1 -0
  148. package/package.json +3 -3
@@ -1,76 +1,26 @@
1
1
  import React, { PropsWithChildren } from 'react';
2
2
  import { useLocation } from 'react-router';
3
- import { ClusterWizardContextType, ClusterWizardContext } from './ClusterWizardContext';
3
+ import { AlertVariant } from '@patternfly/react-core';
4
+ import { Cluster, InfraEnv } from '@openshift-assisted/types/assisted-installer-service';
5
+
6
+ import { useAlerts, AssistedInstallerOCMPermissionTypesListType } from '../../../../common';
7
+ import { isThirdPartyCNI } from '../../../../common/types/networkType';
8
+ import { useFeature, useUISettings } from '../../../hooks';
9
+ import useSetClusterPermissions from '../../../hooks/useSetClusterPermissions';
10
+ import { HostsNetworkConfigurationType } from '../../../services';
11
+ import { isOciPlatformType } from '../../utils';
12
+ import { StaticIpView } from '../steps/staticIp/data/dataTypes';
13
+ import { getStaticIpInfo } from '../steps/staticIp/data/fromInfraEnv';
4
14
  import {
5
- ClusterWizardFlowStateType,
6
15
  ClusterWizardStepsType,
16
+ ClusterWizardFlowStateType,
7
17
  disconnectedSteps,
8
18
  getClusterWizardFirstStep,
9
- isStaticIpStep,
10
19
  isStepAfter,
11
- } from '../utils/wizardTransition';
12
- import { HostsNetworkConfigurationType } from '../../../services';
13
- import { defaultWizardSteps, staticIpFormViewSubSteps } from '../constants';
14
- import { AssistedInstallerOCMPermissionTypesListType, useAlerts } from '../../../../common';
15
- import useSetClusterPermissions from '../../../hooks/useSetClusterPermissions';
16
- import { Cluster, InfraEnv } from '@openshift-assisted/types/assisted-installer-service';
17
- import { useUISettings } from '../../../hooks';
18
- import { AlertVariant } from '@patternfly/react-core';
19
- import { useFeature } from '../../../hooks/use-feature';
20
- import { isThirdPartyCNI } from '../../../../common/types/networkType';
21
- import { isOciPlatformType } from '../../utils';
22
- import { StaticIpView, getStaticIpInfo } from '../steps/staticIp/data';
23
-
24
- const addStepToClusterWizard = (
25
- wizardStepIds: ClusterWizardStepsType[],
26
- addAfterStep: ClusterWizardStepsType,
27
- itemsToAdd: ClusterWizardStepsType[],
28
- ) => {
29
- const stepsIds = [...wizardStepIds];
30
- const referencePosition = stepsIds.findIndex((step) => step === addAfterStep);
31
- const found = wizardStepIds.filter((step) => step === itemsToAdd[0]);
32
- if (referencePosition !== -1 && found.length === 0) {
33
- stepsIds.splice(referencePosition + 1, 0, ...itemsToAdd);
34
- }
35
- return stepsIds;
36
- };
37
-
38
- const removeStepFromClusterWizard = (
39
- wizardStepIds: ClusterWizardStepsType[],
40
- itemToRemove: ClusterWizardStepsType,
41
- numberItemsToRemove: number,
42
- ) => {
43
- const stepsIds = [...wizardStepIds];
44
- const position = stepsIds.findIndex((step) => step === itemToRemove);
45
- if (position !== -1) {
46
- stepsIds.splice(position, numberItemsToRemove);
47
- }
48
- return stepsIds;
49
- };
50
-
51
- const getWizardStepIds = (
52
- wizardStepIds: ClusterWizardStepsType[] | undefined,
53
- staticIpView?: StaticIpView | 'dhcp-selected',
54
-
55
- isSingleClusterFeatureEnabled?: boolean,
56
- ): ClusterWizardStepsType[] => {
57
- let stepsCopy = wizardStepIds ? [...wizardStepIds] : [...defaultWizardSteps];
58
- if (staticIpView === StaticIpView.YAML) {
59
- stepsCopy = removeStepFromClusterWizard(stepsCopy, 'static-ip-network-wide-configurations', 2);
60
- stepsCopy = addStepToClusterWizard(stepsCopy, 'cluster-details', ['static-ip-yaml-view']);
61
- } else if (staticIpView === StaticIpView.FORM) {
62
- stepsCopy = removeStepFromClusterWizard(stepsCopy, 'static-ip-yaml-view', 1);
63
- stepsCopy = addStepToClusterWizard(stepsCopy, 'cluster-details', staticIpFormViewSubSteps);
64
- } else if (staticIpView === 'dhcp-selected') {
65
- stepsCopy = removeStepFromClusterWizard(stepsCopy, 'static-ip-network-wide-configurations', 2);
66
- }
67
-
68
- if (isSingleClusterFeatureEnabled && !stepsCopy.includes('credentials-download')) {
69
- stepsCopy = addStepToClusterWizard(stepsCopy, 'custom-manifests', ['credentials-download']);
70
- }
71
-
72
- return stepsCopy;
73
- };
20
+ isStaticIpStep,
21
+ } from '../utils';
22
+ import { ClusterWizardContextType, ClusterWizardContext } from './ClusterWizardContext';
23
+ import { getDisconnectedWizardStepIds, getWizardStepIds } from './utils';
74
24
 
75
25
  export const ClusterWizardContextProvider = ({
76
26
  children,
@@ -89,6 +39,8 @@ export const ClusterWizardContextProvider = ({
89
39
  const [installDisconnected, setInstallDisconnected] = React.useState(false);
90
40
  const [disconnectedCluster, setDisconnectedCluster] = React.useState<Cluster | undefined>();
91
41
  const [disconnectedInfraEnv, setDisconnectedInfraEnv] = React.useState<InfraEnv | undefined>();
42
+ const [disconnectedWizardStepIds, setDisconnectedWizardStepIds] =
43
+ React.useState<ClusterWizardStepsType[]>(disconnectedSteps);
92
44
  const location = useLocation();
93
45
  const locationState = location.state as ClusterWizardFlowStateType | undefined;
94
46
  const {
@@ -100,7 +52,7 @@ export const ClusterWizardContextProvider = ({
100
52
  const { clearAlerts, addAlert, alerts } = useAlerts();
101
53
  const setClusterPermissions = useSetClusterPermissions();
102
54
 
103
- const wizardStepIds = installDisconnected ? disconnectedSteps : connectedWizardStepIds;
55
+ const wizardStepIds = installDisconnected ? disconnectedWizardStepIds : connectedWizardStepIds;
104
56
 
105
57
  React.useEffect(() => {
106
58
  if (!UISettingsLoading) {
@@ -158,17 +110,26 @@ export const ClusterWizardContextProvider = ({
158
110
 
159
111
  const handleMoveFromStaticIp = () => {
160
112
  //if static ip view change wasn't persisted, moving from static ip step should change the wizard steps to match the view in the infra env
161
- const staticIpInfo = infraEnv ? getStaticIpInfo(infraEnv) : undefined;
162
- if (!staticIpInfo) {
163
- throw `Wizard step is currently ${currentStepId}, but no static ip info is defined`;
113
+ if (installDisconnected) {
114
+ const staticIpInfo = disconnectedInfraEnv
115
+ ? getStaticIpInfo(disconnectedInfraEnv)
116
+ : undefined;
117
+ if (!staticIpInfo) {
118
+ throw `Wizard step is currently ${currentStepId}, but no static ip info is defined`;
119
+ }
120
+ setDisconnectedWizardStepIds(getDisconnectedWizardStepIds(staticIpInfo.view));
121
+ } else {
122
+ const staticIpInfo = infraEnv ? getStaticIpInfo(infraEnv) : undefined;
123
+ if (!staticIpInfo) {
124
+ throw `Wizard step is currently ${currentStepId}, but no static ip info is defined`;
125
+ }
126
+ const newStepIds = getWizardStepIds(
127
+ wizardStepIds,
128
+ staticIpInfo.view,
129
+ isSingleClusterFeatureEnabled,
130
+ );
131
+ setWizardStepIds(newStepIds);
164
132
  }
165
-
166
- const newStepIds = getWizardStepIds(
167
- wizardStepIds,
168
- staticIpInfo.view,
169
- isSingleClusterFeatureEnabled,
170
- );
171
- setWizardStepIds(newStepIds);
172
133
  };
173
134
 
174
135
  const onSetCurrentStepId = (stepId: ClusterWizardStepsType) => {
@@ -200,17 +161,33 @@ export const ClusterWizardContextProvider = ({
200
161
  } else {
201
162
  setCurrentStepId('static-ip-network-wide-configurations');
202
163
  }
203
- setWizardStepIds(getWizardStepIds(wizardStepIds, view, isSingleClusterFeatureEnabled));
164
+ if (installDisconnected) {
165
+ setDisconnectedWizardStepIds(getDisconnectedWizardStepIds(view));
166
+ } else {
167
+ setWizardStepIds(getWizardStepIds(wizardStepIds, view, isSingleClusterFeatureEnabled));
168
+ }
204
169
  },
205
170
  onUpdateHostNetworkConfigType(type: HostsNetworkConfigurationType): void {
206
- if (type === HostsNetworkConfigurationType.STATIC) {
207
- setWizardStepIds(
208
- getWizardStepIds(wizardStepIds, StaticIpView.FORM, isSingleClusterFeatureEnabled),
209
- );
171
+ if (installDisconnected) {
172
+ if (type === HostsNetworkConfigurationType.STATIC) {
173
+ const staticIpInfo = disconnectedInfraEnv
174
+ ? getStaticIpInfo(disconnectedInfraEnv)
175
+ : undefined;
176
+ const view = staticIpInfo?.view ?? StaticIpView.FORM;
177
+ setDisconnectedWizardStepIds(getDisconnectedWizardStepIds(view));
178
+ } else {
179
+ setDisconnectedWizardStepIds(getDisconnectedWizardStepIds('dhcp-selected'));
180
+ }
210
181
  } else {
211
- setWizardStepIds(
212
- getWizardStepIds(wizardStepIds, 'dhcp-selected', isSingleClusterFeatureEnabled),
213
- );
182
+ if (type === HostsNetworkConfigurationType.STATIC) {
183
+ const staticIpInfo = infraEnv ? getStaticIpInfo(infraEnv) : undefined;
184
+ const view = staticIpInfo?.view ?? StaticIpView.FORM;
185
+ setWizardStepIds(getWizardStepIds(wizardStepIds, view, isSingleClusterFeatureEnabled));
186
+ } else {
187
+ setWizardStepIds(
188
+ getWizardStepIds(wizardStepIds, 'dhcp-selected', isSingleClusterFeatureEnabled),
189
+ );
190
+ }
214
191
  }
215
192
  },
216
193
  wizardStepIds: wizardStepIds,
@@ -224,6 +201,7 @@ export const ClusterWizardContextProvider = ({
224
201
  setInstallDisconnected: (enabled: boolean) => {
225
202
  setInstallDisconnected(enabled);
226
203
  if (enabled) {
204
+ setDisconnectedWizardStepIds(disconnectedSteps);
227
205
  onSetCurrentStepId(disconnectedSteps[0]);
228
206
  } else {
229
207
  connectedWizardStepIds?.length && onSetCurrentStepId(connectedWizardStepIds[0]);
@@ -0,0 +1,73 @@
1
+ import { defaultWizardSteps, staticIpFormViewSubSteps } from '../constants';
2
+ import { StaticIpView } from '../steps/staticIp/data/dataTypes';
3
+ import { ClusterWizardStepsType, disconnectedSteps } from '../utils';
4
+
5
+ export const addStepToClusterWizard = (
6
+ wizardStepIds: ClusterWizardStepsType[],
7
+ addAfterStep: ClusterWizardStepsType,
8
+ itemsToAdd: ClusterWizardStepsType[],
9
+ ): ClusterWizardStepsType[] => {
10
+ const stepsIds = [...wizardStepIds];
11
+ const referencePosition = stepsIds.findIndex((step) => step === addAfterStep);
12
+ const found = wizardStepIds.filter((step) => step === itemsToAdd[0]);
13
+ if (referencePosition !== -1 && found.length === 0) {
14
+ stepsIds.splice(referencePosition + 1, 0, ...itemsToAdd);
15
+ }
16
+ return stepsIds;
17
+ };
18
+
19
+ export const removeStepFromClusterWizard = (
20
+ wizardStepIds: ClusterWizardStepsType[],
21
+ itemToRemove: ClusterWizardStepsType,
22
+ numberItemsToRemove: number,
23
+ ): ClusterWizardStepsType[] => {
24
+ const stepsIds = [...wizardStepIds];
25
+ const position = stepsIds.findIndex((step) => step === itemToRemove);
26
+ if (position !== -1) {
27
+ stepsIds.splice(position, numberItemsToRemove);
28
+ }
29
+ return stepsIds;
30
+ };
31
+
32
+ export const getWizardStepIds = (
33
+ wizardStepIds: ClusterWizardStepsType[] | undefined,
34
+ staticIpView?: StaticIpView | 'dhcp-selected',
35
+ isSingleClusterFeatureEnabled?: boolean,
36
+ ): ClusterWizardStepsType[] => {
37
+ let stepsCopy = wizardStepIds ? [...wizardStepIds] : [...defaultWizardSteps];
38
+ if (staticIpView === StaticIpView.YAML) {
39
+ stepsCopy = removeStepFromClusterWizard(stepsCopy, 'static-ip-network-wide-configurations', 2);
40
+ stepsCopy = addStepToClusterWizard(stepsCopy, 'cluster-details', ['static-ip-yaml-view']);
41
+ } else if (staticIpView === StaticIpView.FORM) {
42
+ stepsCopy = removeStepFromClusterWizard(stepsCopy, 'static-ip-yaml-view', 1);
43
+ stepsCopy = addStepToClusterWizard(stepsCopy, 'cluster-details', staticIpFormViewSubSteps);
44
+ } else if (staticIpView === 'dhcp-selected') {
45
+ stepsCopy = removeStepFromClusterWizard(stepsCopy, 'static-ip-network-wide-configurations', 2);
46
+ }
47
+
48
+ if (isSingleClusterFeatureEnabled && !stepsCopy.includes('credentials-download')) {
49
+ stepsCopy = addStepToClusterWizard(stepsCopy, 'custom-manifests', ['credentials-download']);
50
+ }
51
+
52
+ return stepsCopy;
53
+ };
54
+
55
+ export const getDisconnectedWizardStepIds = (
56
+ staticIpView?: StaticIpView | 'dhcp-selected',
57
+ ): ClusterWizardStepsType[] => {
58
+ // Always rebuild from the base disconnected steps so toggling static IP / DHCP
59
+ // cannot leave leftover sub-steps in the list.
60
+ const copy = [...disconnectedSteps];
61
+
62
+ if (staticIpView === StaticIpView.YAML) {
63
+ return addStepToClusterWizard(copy, 'disconnected-basic', ['static-ip-yaml-view']);
64
+ }
65
+ if (staticIpView === StaticIpView.FORM) {
66
+ return addStepToClusterWizard(copy, 'disconnected-basic', [
67
+ 'static-ip-network-wide-configurations',
68
+ 'static-ip-host-configurations',
69
+ ]);
70
+ }
71
+
72
+ return copy;
73
+ };
@@ -19,7 +19,6 @@ import {
19
19
  getFormikErrorFields,
20
20
  ClusterWizardStep,
21
21
  ClusterWizardStepHeader,
22
- TechnologyPreview,
23
22
  isInOcm,
24
23
  useTranslation,
25
24
  } from '../../../../../common';
@@ -181,10 +180,6 @@ export const ClusterDetailsForm = (props: ClusterDetailsFormProps) => {
181
180
  <GridItem>
182
181
  <Flex alignItems={{ default: 'alignItemsCenter' }} gap={{ default: 'gapSm' }}>
183
182
  <InstallDisconnectedSwitch isDisabled={!!cluster} />
184
- <span>
185
- {t("ai:I'm installing on a disconnected/air-gapped/secured environment")}
186
- </span>
187
- <TechnologyPreview />
188
183
  </Flex>
189
184
  </GridItem>
190
185
  )}
@@ -1,24 +1,104 @@
1
1
  import * as React from 'react';
2
- import { Grid, GridItem, Content, Flex, Form } from '@patternfly/react-core';
2
+ import * as Yup from 'yup';
3
+ import { Formik, useFormikContext } from 'formik';
4
+ import { Alert, AlertVariant, Grid, GridItem, Content, Flex, Form } from '@patternfly/react-core';
5
+ import { ImageType, OpenshiftVersion } from '@openshift-assisted/types/assisted-installer-service';
6
+ import OfflineOpenshiftVersionsAPI from '../../../../../common/api/assisted-service/OfflineOpenshiftVersionsAPI';
3
7
  import {
4
8
  ClusterWizardStep,
5
- TechnologyPreview,
6
9
  StaticTextField,
7
10
  WithErrorBoundary,
11
+ useAlerts,
12
+ ClustersAPI,
13
+ InfraEnvsAPI,
14
+ handleApiError,
15
+ getApiErrorMessage,
16
+ isInOcm,
17
+ PullSecret,
18
+ pullSecretValidationSchema,
19
+ useTranslation,
20
+ getFormikErrorFields,
21
+ LoadingState,
22
+ OpenShiftVersionDropdown,
23
+ OpenshiftVersionOptionType,
24
+ CpuArchitecture,
8
25
  } from '../../../../../common';
26
+ import { usePullSecret } from '../../../../hooks';
9
27
  import { useClusterWizardContext } from '../../clusterWizardContext';
10
28
  import { ClusterWizardNavigation, ClusterWizardFooter } from '../../wizardComponents';
29
+ import { HostsNetworkConfigurationControlGroup } from '../clusterDetails/fields/HostsNetworkConfigurationControlGroup';
30
+ import { HostsNetworkConfigurationType } from '../../../../services/types';
31
+ import { getDummyInfraEnvField } from '../staticIp/data/dummyData';
32
+ import { getStaticNetworkConfig } from '../staticIp/data/fromInfraEnv';
11
33
  import { InstallDisconnectedSwitch } from './InstallDisconnectedSwitch';
12
34
 
13
- export const DISCONNECTED_OPENSHIFT_VERSION = '4.21.27';
35
+ const DISCONNECTED_IMAGE_TYPE: ImageType = 'disconnected-iso';
36
+ const DISCONNECTED_CLUSTER_NAME = 'disconnected-cluster';
14
37
 
15
- export const BasicStep = () => {
16
- const { moveNext } = useClusterWizardContext();
38
+ const sortVersions = (versions: OpenshiftVersionOptionType[]) =>
39
+ [...versions].sort((version1, version2) =>
40
+ version1.value.localeCompare(version2.value, undefined, { numeric: true }),
41
+ );
42
+
43
+ const mapOfflineVersions = (
44
+ data: Record<string, OpenshiftVersion>,
45
+ ): OpenshiftVersionOptionType[] => {
46
+ const versions = Object.entries(data).map(([key, versionItem]) => {
47
+ const version = versionItem.displayName;
48
+
49
+ return {
50
+ label: `OpenShift ${version}`,
51
+ value: String(key),
52
+ version,
53
+ default: Boolean(versionItem.default),
54
+ supportLevel: versionItem.supportLevel,
55
+ cpuArchitectures: versionItem.cpuArchitectures as CpuArchitecture[],
56
+ };
57
+ });
58
+
59
+ return sortVersions(versions);
60
+ };
61
+
62
+ type BasicStepValues = {
63
+ openshiftVersion: string;
64
+ hostsNetworkConfigurationType: HostsNetworkConfigurationType;
65
+ pullSecret: string;
66
+ };
67
+
68
+ type BasicStepFormProps = {
69
+ isSubmitting: boolean;
70
+ defaultPullSecret?: string;
71
+ versions: OpenshiftVersionOptionType[];
72
+ loading: boolean;
73
+ error?: string;
74
+ clusterExists: boolean;
75
+ };
76
+
77
+ const BasicStepForm: React.FC<BasicStepFormProps> = ({
78
+ isSubmitting,
79
+ defaultPullSecret,
80
+ versions,
81
+ loading,
82
+ error,
83
+ clusterExists,
84
+ }) => {
85
+ const { submitForm, isValid, errors, touched, values } = useFormikContext<BasicStepValues>();
86
+ const errorFields = getFormikErrorFields(errors, touched);
87
+
88
+ const selectedVersionItem = versions.find((version) => version.value === values.openshiftVersion);
89
+ const cpuArchitecture = selectedVersionItem?.cpuArchitectures?.[0] ?? 'x86_64';
17
90
 
18
91
  return (
19
92
  <ClusterWizardStep
20
93
  navigation={<ClusterWizardNavigation />}
21
- footer={<ClusterWizardFooter onNext={moveNext} />}
94
+ footer={
95
+ <ClusterWizardFooter
96
+ onNext={() => void submitForm()}
97
+ isSubmitting={isSubmitting}
98
+ isNextDisabled={loading || !!error || !isValid || isSubmitting}
99
+ errorFields={errorFields}
100
+ />
101
+ }
22
102
  >
23
103
  <WithErrorBoundary title="Failed to load Basic step">
24
104
  <Grid hasGutter>
@@ -28,22 +108,177 @@ export const BasicStep = () => {
28
108
  <GridItem>
29
109
  <Flex alignItems={{ default: 'alignItemsCenter' }} gap={{ default: 'gapSm' }}>
30
110
  <InstallDisconnectedSwitch />
31
- <span>I'm installing on a disconnected/air-gapped/secured environment</span>
32
- <TechnologyPreview />
33
111
  </Flex>
34
112
  </GridItem>
35
113
  <GridItem>
36
- <Form id="wizard-cluster-basic-info__form">
37
- <StaticTextField name="openshiftVersion" label="OpenShift version">
38
- {DISCONNECTED_OPENSHIFT_VERSION}
39
- </StaticTextField>
40
- <StaticTextField name="cpuArchitecture" label="CPU architecture">
41
- x86_64
42
- </StaticTextField>
43
- </Form>
114
+ {loading && <LoadingState />}
115
+ {error && (
116
+ <Alert
117
+ isInline
118
+ variant={AlertVariant.danger}
119
+ title="Failed to retrieve list of supported OpenShift versions."
120
+ >
121
+ {error}
122
+ </Alert>
123
+ )}
124
+ {!loading && !error && (
125
+ <Form id="wizard-cluster-basic-info__form">
126
+ <OpenShiftVersionDropdown
127
+ name="openshiftVersion"
128
+ versions={versions}
129
+ showReleasesLink={false}
130
+ isDisabled={clusterExists}
131
+ />
132
+ <StaticTextField name="cpuArchitecture" label="CPU architecture">
133
+ {cpuArchitecture}
134
+ </StaticTextField>
135
+ <HostsNetworkConfigurationControlGroup clusterExists={false} isDisabled={false} />
136
+ {!isInOcm && <PullSecret isOcm={false} defaultPullSecret={defaultPullSecret} />}
137
+ </Form>
138
+ )}
44
139
  </GridItem>
45
140
  </Grid>
46
141
  </WithErrorBoundary>
47
142
  </ClusterWizardStep>
48
143
  );
49
144
  };
145
+
146
+ export const BasicStep = () => {
147
+ const { t } = useTranslation();
148
+ const {
149
+ moveNext,
150
+ disconnectedCluster,
151
+ setDisconnectedCluster,
152
+ disconnectedInfraEnv,
153
+ setDisconnectedInfraEnv,
154
+ } = useClusterWizardContext();
155
+ const { addAlert, clearAlerts } = useAlerts();
156
+ const [isSubmitting, setIsSubmitting] = React.useState(false);
157
+ const [versions, setVersions] = React.useState<OpenshiftVersionOptionType[]>([]);
158
+ const [loading, setLoading] = React.useState(true);
159
+ const [error, setError] = React.useState<string>();
160
+ const defaultPullSecret = usePullSecret();
161
+
162
+ React.useEffect(() => {
163
+ const fetchVersions = async () => {
164
+ setLoading(true);
165
+ setError(undefined);
166
+ try {
167
+ const { data } = await OfflineOpenshiftVersionsAPI.list();
168
+ const mappedVersions = mapOfflineVersions(data);
169
+ setVersions(mappedVersions);
170
+ if (mappedVersions.length === 0) {
171
+ setError('No OpenShift versions available.');
172
+ }
173
+ } catch (e) {
174
+ handleApiError(e, (err) => {
175
+ setError(getApiErrorMessage(err));
176
+ });
177
+ } finally {
178
+ setLoading(false);
179
+ }
180
+ };
181
+
182
+ void fetchVersions();
183
+ }, []);
184
+
185
+ const validationSchema = React.useMemo(
186
+ () =>
187
+ Yup.object({
188
+ openshiftVersion: Yup.string().required('OpenShift version is required'),
189
+ pullSecret: isInOcm ? Yup.string() : pullSecretValidationSchema(t),
190
+ }),
191
+ [t],
192
+ );
193
+
194
+ const clusterExists = Boolean(disconnectedCluster?.id && disconnectedInfraEnv?.id);
195
+
196
+ const initialValues: BasicStepValues = {
197
+ openshiftVersion: disconnectedInfraEnv?.openshiftVersion ?? '',
198
+ hostsNetworkConfigurationType: disconnectedInfraEnv?.staticNetworkConfig
199
+ ? HostsNetworkConfigurationType.STATIC
200
+ : HostsNetworkConfigurationType.DHCP,
201
+ pullSecret: defaultPullSecret ?? '',
202
+ };
203
+
204
+ const handleNext = React.useCallback(
205
+ async (values: BasicStepValues) => {
206
+ clearAlerts();
207
+ setIsSubmitting(true);
208
+ try {
209
+ const isStatic =
210
+ values.hostsNetworkConfigurationType === HostsNetworkConfigurationType.STATIC;
211
+ let infraEnvToUse = disconnectedInfraEnv;
212
+
213
+ if (!disconnectedCluster?.id || !infraEnvToUse?.id) {
214
+ const { data: cluster } = await ClustersAPI.registerDisconnected({
215
+ name: DISCONNECTED_CLUSTER_NAME,
216
+ openshiftVersion: values.openshiftVersion,
217
+ });
218
+ setDisconnectedCluster(cluster);
219
+
220
+ const pullSecret = isInOcm ? defaultPullSecret ?? '' : values.pullSecret;
221
+ const { data: createdInfraEnv } = await InfraEnvsAPI.register({
222
+ name: 'disconnected-infra-env',
223
+ pullSecret,
224
+ clusterId: cluster.id,
225
+ imageType: DISCONNECTED_IMAGE_TYPE,
226
+ openshiftVersion: values.openshiftVersion,
227
+ staticNetworkConfig: isStatic ? getDummyInfraEnvField() : undefined,
228
+ });
229
+ infraEnvToUse = createdInfraEnv;
230
+ } else {
231
+ const staticNetworkConfig = isStatic
232
+ ? getStaticNetworkConfig(infraEnvToUse) ?? getDummyInfraEnvField()
233
+ : [];
234
+ const { data: updatedInfraEnv } = await InfraEnvsAPI.update(infraEnvToUse.id, {
235
+ staticNetworkConfig,
236
+ });
237
+ infraEnvToUse = updatedInfraEnv;
238
+ }
239
+
240
+ setDisconnectedInfraEnv(infraEnvToUse);
241
+ moveNext();
242
+ } catch (error) {
243
+ handleApiError(error, () => {
244
+ addAlert({
245
+ title: 'Failed to save basic information',
246
+ message: getApiErrorMessage(error),
247
+ variant: AlertVariant.danger,
248
+ });
249
+ });
250
+ } finally {
251
+ setIsSubmitting(false);
252
+ }
253
+ },
254
+ [
255
+ clearAlerts,
256
+ defaultPullSecret,
257
+ disconnectedCluster,
258
+ disconnectedInfraEnv,
259
+ setDisconnectedCluster,
260
+ setDisconnectedInfraEnv,
261
+ addAlert,
262
+ moveNext,
263
+ ],
264
+ );
265
+
266
+ return (
267
+ <Formik<BasicStepValues>
268
+ initialValues={initialValues}
269
+ validationSchema={validationSchema}
270
+ onSubmit={(values) => void handleNext(values)}
271
+ >
272
+ <BasicStepForm
273
+ isSubmitting={isSubmitting}
274
+ defaultPullSecret={defaultPullSecret}
275
+ versions={versions}
276
+ loading={loading}
277
+ error={error}
278
+ clusterExists={clusterExists}
279
+ />
280
+ </Formik>
281
+ );
282
+ };
283
+
284
+ export default BasicStep;