@openshift-assisted/ui-lib 2.54.0 → 2.54.2

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 (78) hide show
  1. package/build/@types/cim/components/ClusterDeployment/wizardTransition.d.ts +1 -1
  2. package/build/@types/cim/components/ClusterDeployment/wizardTransition.d.ts.map +1 -1
  3. package/build/@types/cim/components/modals/CimConfiguration/CimStorageMissingAlert.d.ts.map +1 -1
  4. package/build/@types/common/components/clusterConfiguration/DiscoveryImageConfigForm.d.ts.map +1 -1
  5. package/build/@types/common/components/hosts/utils.d.ts.map +1 -1
  6. package/build/@types/common/config/constants.d.ts.map +1 -1
  7. package/build/@types/common/config/docs_links.d.ts.map +1 -1
  8. package/build/@types/common/selectors/clusterSelectors.d.ts +1 -0
  9. package/build/@types/common/selectors/clusterSelectors.d.ts.map +1 -1
  10. package/build/@types/common/utils.d.ts.map +1 -1
  11. package/build/@types/ocm/components/clusterConfiguration/operators/OperatorCheckbox.d.ts +3 -1
  12. package/build/@types/ocm/components/clusterConfiguration/operators/OperatorCheckbox.d.ts.map +1 -1
  13. package/build/@types/ocm/components/clusterConfiguration/operators/utils.d.ts +1 -4
  14. package/build/@types/ocm/components/clusterConfiguration/operators/utils.d.ts.map +1 -1
  15. package/build/@types/ocm/components/clusterWizard/OperatorsSelect.d.ts.map +1 -1
  16. package/build/@types/ocm/components/clusterWizard/wizardTransition.d.ts +1 -1
  17. package/build/@types/ocm/components/clusterWizard/wizardTransition.d.ts.map +1 -1
  18. package/build/cjs/cim/components/ClusterDeployment/ClusterInstallationError.js +1 -1
  19. package/build/cjs/cim/components/ClusterDeployment/ClusterInstallationError.js.map +1 -1
  20. package/build/cjs/cim/components/InfraEnv/InfraEnvFormPage.js +1 -1
  21. package/build/cjs/cim/components/InfraEnv/InfraEnvFormPage.js.map +1 -1
  22. package/build/cjs/cim/components/modals/CimConfiguration/CimStorageMissingAlert.js +1 -1
  23. package/build/cjs/cim/components/modals/CimConfiguration/CimStorageMissingAlert.js.map +1 -1
  24. package/build/cjs/common/components/clusterConfiguration/DiscoveryImageConfigForm.js +1 -1
  25. package/build/cjs/common/components/clusterConfiguration/DiscoveryImageConfigForm.js.map +1 -1
  26. package/build/cjs/common/components/clusterConfiguration/DownloadIso.js +1 -1
  27. package/build/cjs/common/components/clusterConfiguration/DownloadIso.js.map +1 -1
  28. package/build/cjs/common/components/clusterDetail/ConsoleModal.js +1 -1
  29. package/build/cjs/common/components/clusterDetail/ConsoleModal.js.map +1 -1
  30. package/build/cjs/common/components/hosts/utils.js +6 -1
  31. package/build/cjs/common/components/hosts/utils.js.map +1 -1
  32. package/build/cjs/common/config/constants.js +4 -0
  33. package/build/cjs/common/config/constants.js.map +1 -1
  34. package/build/cjs/common/config/docs_links.js +3 -2
  35. package/build/cjs/common/config/docs_links.js.map +1 -1
  36. package/build/cjs/common/selectors/clusterSelectors.js +6 -1
  37. package/build/cjs/common/selectors/clusterSelectors.js.map +1 -1
  38. package/build/cjs/common/utils.js +3 -0
  39. package/build/cjs/common/utils.js.map +1 -1
  40. package/build/cjs/ocm/components/clusterConfiguration/OcmClusterProgressItems.js +1 -1
  41. package/build/cjs/ocm/components/clusterConfiguration/OcmClusterProgressItems.js.map +1 -1
  42. package/build/cjs/ocm/components/clusterConfiguration/operators/OperatorCheckbox.js +37 -39
  43. package/build/cjs/ocm/components/clusterConfiguration/operators/OperatorCheckbox.js.map +1 -1
  44. package/build/cjs/ocm/components/clusterConfiguration/operators/utils.js +4 -22
  45. package/build/cjs/ocm/components/clusterConfiguration/operators/utils.js.map +1 -1
  46. package/build/cjs/ocm/components/clusterConfiguration/platformIntegration/ExternalPlatformDropdown.js +1 -1
  47. package/build/cjs/ocm/components/clusterConfiguration/platformIntegration/ExternalPlatformDropdown.js.map +1 -1
  48. package/build/cjs/ocm/components/clusterConfiguration/review/ReviewOperatorsTable.js +1 -1
  49. package/build/cjs/ocm/components/clusterConfiguration/review/ReviewOperatorsTable.js.map +1 -1
  50. package/build/cjs/ocm/components/clusterDetail/ClusterInstallationError.js +1 -1
  51. package/build/cjs/ocm/components/clusterDetail/ClusterInstallationError.js.map +1 -1
  52. package/build/cjs/ocm/components/clusterDetail/ProgressBarAlerts.js +1 -1
  53. package/build/cjs/ocm/components/clusterDetail/ProgressBarAlerts.js.map +1 -1
  54. package/build/cjs/ocm/components/clusterWizard/OperatorsSelect.js +18 -4
  55. package/build/cjs/ocm/components/clusterWizard/OperatorsSelect.js.map +1 -1
  56. package/build/cjs/ocm/components/clusterWizard/wizardTransition.js +2 -1
  57. package/build/cjs/ocm/components/clusterWizard/wizardTransition.js.map +1 -1
  58. package/lib/cim/components/ClusterDeployment/ClusterInstallationError.tsx +1 -1
  59. package/lib/cim/components/InfraEnv/InfraEnvFormPage.tsx +1 -1
  60. package/lib/cim/components/modals/CimConfiguration/CimStorageMissingAlert.tsx +4 -1
  61. package/lib/common/components/clusterConfiguration/DiscoveryImageConfigForm.tsx +3 -1
  62. package/lib/common/components/clusterConfiguration/DownloadIso.tsx +1 -1
  63. package/lib/common/components/clusterDetail/ConsoleModal.tsx +1 -1
  64. package/lib/common/components/hosts/utils.ts +8 -1
  65. package/lib/common/config/constants.ts +4 -0
  66. package/lib/common/config/docs_links.ts +3 -2
  67. package/lib/common/selectors/clusterSelectors.ts +7 -0
  68. package/lib/common/utils.ts +3 -0
  69. package/lib/ocm/components/clusterConfiguration/OcmClusterProgressItems.tsx +2 -2
  70. package/lib/ocm/components/clusterConfiguration/operators/OperatorCheckbox.tsx +52 -58
  71. package/lib/ocm/components/clusterConfiguration/operators/utils.tsx +1 -33
  72. package/lib/ocm/components/clusterConfiguration/platformIntegration/ExternalPlatformDropdown.tsx +1 -1
  73. package/lib/ocm/components/clusterConfiguration/review/ReviewOperatorsTable.tsx +2 -2
  74. package/lib/ocm/components/clusterDetail/ClusterInstallationError.tsx +1 -1
  75. package/lib/ocm/components/clusterDetail/ProgressBarAlerts.tsx +1 -1
  76. package/lib/ocm/components/clusterWizard/OperatorsSelect.tsx +21 -4
  77. package/lib/ocm/components/clusterWizard/wizardTransition.ts +2 -1
  78. package/package.json +3 -3
@@ -213,7 +213,7 @@ const InfraEnvForm: React.FC<React.PropsWithChildren<InfraEnvFormProps>> = ({
213
213
  window.open(
214
214
  getOCPStaticIPDocLink(docVersion),
215
215
  '_blank',
216
- 'noopener',
216
+ 'noopener,noreferrer',
217
217
  )
218
218
  }
219
219
  >
@@ -23,7 +23,10 @@ export const CimStorageMissingAlert: React.FC<{
23
23
  <AlertActionLink key="install-storage-operator" onClick={() => navigate(storageOperatorUrl)}>
24
24
  {t('ai:Install storage operator')}
25
25
  </AlertActionLink>,
26
- <AlertActionLink key="storage-class" onClick={() => window.open(docStorageUrl, '_blank')}>
26
+ <AlertActionLink
27
+ key="storage-class"
28
+ onClick={() => window.open(docStorageUrl, '_blank', 'noopener,noreferrer')}
29
+ >
27
30
  {contentWorkaround as unknown as string}
28
31
  </AlertActionLink>,
29
32
  ];
@@ -46,7 +46,9 @@ export const StaticIPInfo = ({ docVersion }: { docVersion?: string }) => {
46
46
  icon={<ExternalLinkAltIcon />}
47
47
  iconPosition="right"
48
48
  isInline
49
- onClick={() => window.open(getOCPStaticIPDocLink(docVersion), '_blank', 'noopener')}
49
+ onClick={() =>
50
+ window.open(getOCPStaticIPDocLink(docVersion), '_blank', 'noopener,noreferrer')
51
+ }
50
52
  >
51
53
  {t('ai:View documentation')}
52
54
  </Button>
@@ -45,7 +45,7 @@ const DownloadIso = ({
45
45
 
46
46
  const openCiscoIntersightHostsLink = (downloadUrl: string) => {
47
47
  updateTagsForCiscoIntersight ? updateTagsForCiscoIntersight() : '';
48
- window.open(getCiscoIntersightLink(downloadUrl, ciscoUrl), '_blank', 'noopener');
48
+ window.open(getCiscoIntersightLink(downloadUrl, ciscoUrl), '_blank', 'noopener,noreferrer');
49
49
  };
50
50
 
51
51
  return (
@@ -138,7 +138,7 @@ export const ConsoleModal: React.FC<ConsoleModalProps> = ({
138
138
  type="submit"
139
139
  key="launch"
140
140
  variant={ButtonVariant.primary}
141
- onClick={() => window.open(consoleUrl, '_blank', 'noopener')}
141
+ onClick={() => window.open(consoleUrl, '_blank', 'noopener,noreferrer')}
142
142
  isDisabled={!consoleUrl}
143
143
  >
144
144
  {t('ai:Launch OpenShift Console')}
@@ -263,7 +263,14 @@ export const areOnlySoftValidationsFailing = (validationsInfo: HostValidationsIn
263
263
  );
264
264
  if (!failingValidationIds.length) return false;
265
265
  for (const id of failingValidationIds) {
266
- if (!['ntp-synced', 'container-images-available', 'mtu-valid'].includes(id)) {
266
+ if (
267
+ ![
268
+ 'ntp-synced',
269
+ 'container-images-available',
270
+ 'mtu-valid',
271
+ 'inventory-not-partially-truncated',
272
+ ].includes(id)
273
+ ) {
267
274
  return false;
268
275
  }
269
276
  }
@@ -92,6 +92,8 @@ export const hostValidationLabels = (t: TFunction): { [key in HostValidationId]:
92
92
  'sufficient-network-latency-requirement-for-role': t('ai:Network latency'),
93
93
  'sufficient-packet-loss-requirement-for-role': t('ai:Packet loss'),
94
94
  'has-inventory': t('ai:Hardware information'),
95
+ 'inventory-not-partially-truncated': t('ai:Inventory partially truncated'),
96
+ 'inventory-not-fully-truncated': t('ai:Inventory fully truncated'),
95
97
  'has-min-cpu-cores': t('ai:Minimum CPU cores'),
96
98
  'has-min-memory': t('ai:Minimum Memory'),
97
99
  'has-min-valid-disks': t('ai:Minimum disks of required size'),
@@ -163,6 +165,8 @@ export const hostValidationFailureHints = (
163
165
  'sufficient-network-latency-requirement-for-role': '',
164
166
  'sufficient-packet-loss-requirement-for-role': '',
165
167
  'has-inventory': '',
168
+ 'inventory-not-partially-truncated': '',
169
+ 'inventory-not-fully-truncated': '',
166
170
  'has-min-cpu-cores': '',
167
171
  'has-min-memory': '',
168
172
  'has-min-valid-disks': '',
@@ -150,10 +150,11 @@ export const CHANGE_ISO_PASSWORD_FILE_LINK =
150
150
  'https://raw.githubusercontent.com/openshift/assisted-service/master/docs/change-iso-password.sh';
151
151
 
152
152
  export const getCiscoIntersightLink = (downloadIsoUrl: string, ciscoUrl?: string) => {
153
+ const isoUrl = encodeURIComponent(downloadIsoUrl);
153
154
  if (ciscoUrl) {
154
- return `${ciscoUrl}?_workflow_Version=1&IsoUrl=${downloadIsoUrl}`;
155
+ return `${ciscoUrl}?_workflow_Version=1&IsoUrl=${isoUrl}`;
155
156
  }
156
- return `https://www.intersight.com/an/workflow/workflow-definitions/execute/AddServersFromISO?_workflow_Version=1&IsoUrl=${downloadIsoUrl}`;
157
+ return `https://www.intersight.com/an/workflow/workflow-definitions/execute/AddServersFromISO?_workflow_Version=1&IsoUrl=${isoUrl}`;
157
158
  };
158
159
 
159
160
  export const MTV_LINK =
@@ -44,6 +44,13 @@ export const selectOlmOperators = (cluster?: Pick<Cluster, 'monitoredOperators'>
44
44
  );
45
45
  };
46
46
 
47
+ // Includes dependency-only operators
48
+ export const selectAllOlmOperators = (cluster?: Pick<Cluster, 'monitoredOperators'>) => {
49
+ return selectMonitoredOperators(cluster?.monitoredOperators).filter(
50
+ (operator) => operator.operatorType === 'olm' && !!operator.name,
51
+ );
52
+ };
53
+
47
54
  export const hasEnabledOperators = (
48
55
  monitoredOperators: Cluster['monitoredOperators'],
49
56
  searchOperator: string,
@@ -90,6 +90,9 @@ export const stringToJSON = <T>(jsonString: string | undefined): T | undefined =
90
90
  export const downloadFile = (fileUrl?: string, dataBlob?: Blob, fileName?: string) => {
91
91
  const link = document.createElement('a');
92
92
  if (fileUrl && fileUrl !== '') {
93
+ if (!/^(https?|blob):/i.test(fileUrl)) {
94
+ return;
95
+ }
93
96
  link.setAttribute('href', fileUrl);
94
97
  }
95
98
  if (dataBlob) {
@@ -4,7 +4,7 @@ import {
4
4
  EventListFetchProps,
5
5
  getEnabledHosts,
6
6
  RenderIf,
7
- selectOlmOperators,
7
+ selectAllOlmOperators,
8
8
  } from '../../../common';
9
9
  import { FinalizingProgress } from '../../../common/components/clusterDetail/FinalizingProgress';
10
10
  import { ProgressBarTexts } from '../../../common/components/clusterDetail/ProgressBarTexts';
@@ -26,7 +26,7 @@ const OcmClusterProgressItems = ({
26
26
  fallbackEventsURL,
27
27
  }: OcmClusterProgressItemsProps) => {
28
28
  const enabledHosts = getEnabledHosts(cluster.hosts);
29
- const olmOperators = selectOlmOperators(cluster);
29
+ const olmOperators = selectAllOlmOperators(cluster);
30
30
 
31
31
  const masterHosts = enabledHosts.filter((host) => host.role && 'master' === host.role);
32
32
  const workerHosts = enabledHosts.filter((host) => host.role && 'worker' === host.role);
@@ -24,7 +24,6 @@ import {
24
24
  import NewFeatureSupportLevelBadge from '../../../../common/components/newFeatureSupportLevels/NewFeatureSupportLevelBadge';
25
25
  import { getFieldId, OperatorsValues, PopoverIcon } from '../../../../common';
26
26
  import { useNewFeatureSupportLevel } from '../../../../common/components/newFeatureSupportLevels';
27
- import { getNewOperators } from './utils';
28
27
  import {
29
28
  highlightMatch,
30
29
  OperatorSpec,
@@ -110,8 +109,10 @@ const OperatorRequirements = ({
110
109
 
111
110
  const OperatorCheckbox = ({
112
111
  bundles,
112
+ checkedOperatorIds,
113
113
  cluster,
114
114
  operatorId,
115
+ isChecked,
115
116
  title,
116
117
  featureId,
117
118
  notStandalone,
@@ -122,8 +123,10 @@ const OperatorCheckbox = ({
122
123
  searchTerm,
123
124
  }: {
124
125
  bundles: Bundle[];
126
+ checkedOperatorIds: Set<string>;
125
127
  cluster: Cluster;
126
128
  operatorId: string;
129
+ isChecked: boolean;
127
130
  openshiftVersion?: string;
128
131
  preflightRequirements: PreflightHardwareRequirements | undefined;
129
132
  searchTerm?: string;
@@ -135,52 +138,54 @@ const OperatorCheckbox = ({
135
138
  const { values, setFieldValue } = useFormikContext<OperatorsValues>();
136
139
  const fieldId = getFieldId(operatorId, 'input');
137
140
  const supportLevel = getFeatureSupportLevel(featureId);
141
+ const getDisabledReason = (): string | undefined => {
142
+ const featureDisabledReason = getFeatureDisabledReason(featureId);
143
+ if (featureDisabledReason) {
144
+ return featureDisabledReason;
145
+ }
146
+
147
+ const isRequiredByBundle = values.selectedBundles.some(
148
+ (selectedBundle) =>
149
+ !!bundles
150
+ .find((bundle) => bundle.id === selectedBundle.id)
151
+ ?.operators?.includes(operatorId),
152
+ );
153
+ if (isRequiredByBundle) {
154
+ return 'This operator is part of a selected bundle and cannot be deselected.';
155
+ }
138
156
 
139
- const isRequiredByBundle = values.selectedBundles.some(
140
- (selectedBundle) =>
141
- !!bundles.find((bundle) => bundle.id === selectedBundle.id)?.operators?.includes(operatorId),
142
- );
143
- const isSelectedForBundle = values.selectedBundles.some((selectedBundle) =>
144
- selectedBundle.optionalOperators?.includes(operatorId),
145
- );
146
- const isInBundle = isRequiredByBundle || isSelectedForBundle;
147
-
148
- const isOperatorActive = (opName: string) =>
149
- values.selectedOperators.includes(opName) ||
150
- values.selectedBundles.some((selectedBundle) => {
151
- const bundle = bundles.find(({ id }) => id === selectedBundle.id);
152
- return (
153
- bundle?.operators?.includes(opName) || selectedBundle.optionalOperators?.includes(opName)
154
- );
155
- });
156
-
157
- const isChecked = values.selectedOperators.includes(operatorId) || isInBundle;
158
-
159
- const parentOperator = preflightRequirements?.operators?.find(
160
- (op) =>
161
- !!op.operatorName &&
162
- op.dependencies?.includes(operatorId) &&
163
- isOperatorActive(op.operatorName),
164
- );
165
-
166
- let requiredByOperatorName = '';
167
- if (parentOperator?.operatorName) {
168
- requiredByOperatorName =
169
- opSpecs[parentOperator.operatorName]?.title || parentOperator.operatorName;
170
- }
171
-
172
- let disabledReason = getFeatureDisabledReason(featureId);
173
-
174
- if (isRequiredByBundle) {
175
- disabledReason = 'This operator is part of a selected bundle and cannot be deselected.';
176
- } else if (isSelectedForBundle) {
177
- disabledReason =
178
- 'This optional operator is selected through a bundle. Use the bundle card to change it.';
179
- } else if (requiredByOperatorName) {
180
- disabledReason = `This operator is required by ${requiredByOperatorName}`;
181
- } else if (notStandalone && !values.selectedOperators.includes(operatorId)) {
182
- disabledReason = 'This operator cannot be installed as a standalone';
183
- }
157
+ const isOptionallySelectedForBundle = values.selectedBundles.some((selectedBundle) =>
158
+ selectedBundle.optionalOperators?.includes(operatorId),
159
+ );
160
+ if (isOptionallySelectedForBundle) {
161
+ return 'This optional operator is selected through a bundle. Use the bundle card to change it.';
162
+ }
163
+
164
+ const parentOperator = preflightRequirements?.operators?.find(
165
+ ({ operatorName, dependencies }) =>
166
+ !!operatorName &&
167
+ dependencies?.includes(operatorId) &&
168
+ checkedOperatorIds.has(operatorName),
169
+ );
170
+ if (parentOperator?.operatorName) {
171
+ const parentName = opSpecs[parentOperator.operatorName]?.title || parentOperator.operatorName;
172
+ return `This operator is required by ${parentName}`;
173
+ }
174
+
175
+ if (notStandalone && !checkedOperatorIds.has(operatorId)) {
176
+ return 'This operator cannot be installed as a standalone';
177
+ }
178
+
179
+ return undefined;
180
+ };
181
+
182
+ const disabledReason = getDisabledReason();
183
+ const handleClick = (_: React.FormEvent, checked: boolean) => {
184
+ const next = checked
185
+ ? [...values.selectedOperators, operatorId]
186
+ : values.selectedOperators.filter((op) => op !== operatorId);
187
+ setFieldValue('selectedOperators', next);
188
+ };
184
189
 
185
190
  return (
186
191
  <FormGroup fieldId={fieldId} id={`form-control__${fieldId}`}>
@@ -202,18 +207,7 @@ const OperatorCheckbox = ({
202
207
  }
203
208
  aria-describedby={`${fieldId}-helper`}
204
209
  isChecked={isChecked}
205
- onChange={(_, checked) => {
206
- setFieldValue(
207
- 'selectedOperators',
208
- getNewOperators(
209
- values.selectedOperators,
210
- operatorId,
211
- preflightRequirements,
212
- checked,
213
- opSpecs,
214
- ),
215
- );
216
- }}
210
+ onChange={handleClick}
217
211
  isDisabled={isViewerMode || !!disabledReason}
218
212
  description={
219
213
  !!Description && (
@@ -3,9 +3,7 @@ import {
3
3
  Bundle,
4
4
  PreflightHardwareRequirements,
5
5
  } from '@openshift-assisted/types/assisted-installer-service';
6
- import { OperatorSpec } from '../../../../common/components/operators/operatorSpecs';
7
-
8
- const getOperatorDependencies = (
6
+ export const getOperatorDependencies = (
9
7
  operatorId: string,
10
8
  preflightRequirements: PreflightHardwareRequirements | undefined,
11
9
  dependencies: Set<string> = new Set(),
@@ -26,36 +24,6 @@ const getOperatorDependencies = (
26
24
  return [...dependencies];
27
25
  };
28
26
 
29
- export const getNewOperators = (
30
- currentOperators: string[],
31
- operatorId: string,
32
- preflightRequirements: PreflightHardwareRequirements | undefined,
33
- add: boolean,
34
- opSpecs: { [key: string]: OperatorSpec },
35
- ): string[] => {
36
- const dependencies = getOperatorDependencies(operatorId, preflightRequirements);
37
-
38
- if (add) {
39
- const uniqueOps = new Set([...currentOperators, ...dependencies, operatorId]);
40
- return Array.from(uniqueOps);
41
- }
42
-
43
- const newOperators = currentOperators.filter((op) => op !== operatorId);
44
- const notStandaloneDeps = dependencies
45
- .filter((dep) => opSpecs[dep]?.notStandalone)
46
- .filter((dep) => {
47
- const hasDependency = newOperators.some((op) =>
48
- getOperatorDependencies(op, preflightRequirements).includes(dep),
49
- );
50
- if (!hasDependency) {
51
- newOperators.splice(newOperators.indexOf(dep), 1);
52
- }
53
- return !hasDependency;
54
- });
55
-
56
- return currentOperators.filter((op) => op !== operatorId && !notStandaloneDeps.includes(op));
57
- };
58
-
59
27
  const getBundleOperators = (
60
28
  bundle: Bundle,
61
29
  preflightRequirements: PreflightHardwareRequirements | undefined,
@@ -155,7 +155,7 @@ export const ExternalPlatformDropdown = ({
155
155
 
156
156
  const handleClick = (event: MouseEvent<HTMLButtonElement>, href: string): void => {
157
157
  event.stopPropagation(); // Stop event propagation here
158
- window.open(href, '_blank');
158
+ window.open(href, '_blank', 'noopener,noreferrer');
159
159
  };
160
160
 
161
161
  const { getFeatureSupportLevel, getFeatureDisabledReason } = useNewFeatureSupportLevel();
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import { Title } from '@patternfly/react-core';
3
3
  import { Table, TableVariant, Tbody, Td, Tr } from '@patternfly/react-table';
4
- import { genericTableRowKey, selectOlmOperators } from '../../../../common';
4
+ import { genericTableRowKey, selectAllOlmOperators } from '../../../../common';
5
5
  import { useStateSafely } from '../../../../common/hooks';
6
6
  import { Bundle, Cluster } from '@openshift-assisted/types/assisted-installer-service';
7
7
  import { TableSummaryExpandable } from './TableSummaryExpandable';
@@ -68,7 +68,7 @@ export const ReviewOperatorsTable = ({ cluster }: { cluster: Cluster }) => {
68
68
 
69
69
  const rows = React.useMemo(
70
70
  () =>
71
- selectOlmOperators(cluster)
71
+ selectAllOlmOperators(cluster)
72
72
  .filter(({ name }) => !!name && !!opSpecs[name])
73
73
  .map((op) => {
74
74
  const opId = op.name as string;
@@ -42,7 +42,7 @@ const ClusterInstallationError: React.FC<ClusterInstallationErrorProps> = ({
42
42
  Download Installation Logs
43
43
  </AlertActionLink>
44
44
  <AlertActionLink
45
- onClick={() => window.open(getReportIssueLink(), '_blank')}
45
+ onClick={() => window.open(getReportIssueLink(), '_blank', 'noopener,noreferrer')}
46
46
  id={getID('button-report-bug')}
47
47
  >
48
48
  Report a bug
@@ -157,7 +157,7 @@ export const HostsInstallationFailed = ({
157
157
  Download installation logs
158
158
  </AlertActionLink>
159
159
  <AlertActionLink
160
- onClick={() => window.open(getReportIssueLink(), '_blank')}
160
+ onClick={() => window.open(getReportIssueLink(), '_blank', 'noopener,noreferrer')}
161
161
  id={getID('button-report-bug')}
162
162
  >
163
163
  Report a bug
@@ -19,6 +19,7 @@ import { OperatorsService } from '../../services';
19
19
  import { useFeature } from '../../hooks/use-feature';
20
20
  import OperatorCheckbox from '../clusterConfiguration/operators/OperatorCheckbox';
21
21
  import { useOperatorSpecs } from '../../../common/components/operators/operatorSpecs';
22
+ import { getOperatorDependencies } from '../clusterConfiguration/operators/utils';
22
23
 
23
24
  const OperatorsSelect = ({
24
25
  cluster,
@@ -36,7 +37,6 @@ const OperatorsSelect = ({
36
37
  const [isExpanded, setIsExpanded] = React.useState(false);
37
38
  const [supportedOperators, setSupportedOperators] = useStateSafely<string[]>([]);
38
39
  const isSingleClusterFeatureEnabled = useFeature('ASSISTED_INSTALLER_SINGLE_CLUSTER_FEATURE');
39
- const { values } = useFormikContext<OperatorsValues>();
40
40
  React.useEffect(() => {
41
41
  const fetchSupportedOperators = async () => {
42
42
  try {
@@ -54,6 +54,7 @@ const OperatorsSelect = ({
54
54
  void fetchSupportedOperators();
55
55
  }, [addAlert, setSupportedOperators, setIsLoading]);
56
56
 
57
+ const { values } = useFormikContext<OperatorsValues>();
57
58
  const { byCategory, byKey: opSpecs } = useOperatorSpecs();
58
59
 
59
60
  const operators = React.useMemo(() => {
@@ -65,10 +66,24 @@ const OperatorsSelect = ({
65
66
  });
66
67
  }, [isSingleClusterFeatureEnabled, supportedOperators]);
67
68
 
68
- const selectedOperators = values.selectedOperators.filter(
69
- (opKey) => operators.includes(opKey) && !!opSpecs[opKey],
69
+ const bundleOperators = new Set<string>();
70
+ values.selectedBundles.forEach((b) => {
71
+ b.optionalOperators?.forEach((op) => bundleOperators.add(op));
72
+ bundles.find(({ id }) => id === b.id)?.operators?.forEach((op) => bundleOperators.add(op));
73
+ });
74
+
75
+ const dependencies = new Set<string>();
76
+ [...values.selectedOperators, ...bundleOperators].forEach((op) =>
77
+ getOperatorDependencies(op, preflightRequirements, dependencies),
70
78
  );
71
79
 
80
+ const checkedOperatorIds = new Set([
81
+ ...values.selectedOperators,
82
+ ...bundleOperators,
83
+ ...dependencies,
84
+ ]);
85
+ const operatorsCount = operators.filter((op) => checkedOperatorIds.has(op)).length;
86
+
72
87
  if (isLoading) {
73
88
  return <LoadingState />;
74
89
  }
@@ -76,7 +91,7 @@ const OperatorsSelect = ({
76
91
  return (
77
92
  <>
78
93
  <ExpandableSection
79
- toggleText={`Single Operators (${operators.length} | ${selectedOperators.length} selected)`}
94
+ toggleText={`Single operators (${operatorsCount} selected)`}
80
95
  onToggle={() => setIsExpanded(!isExpanded)}
81
96
  isExpanded={isExpanded}
82
97
  data-testid="single-operators-section"
@@ -113,6 +128,8 @@ const OperatorsSelect = ({
113
128
  <OperatorCheckbox
114
129
  bundles={bundles}
115
130
  operatorId={spec.operatorKey}
131
+ checkedOperatorIds={checkedOperatorIds}
132
+ isChecked={checkedOperatorIds.has(spec.operatorKey)}
116
133
  cluster={cluster}
117
134
  openshiftVersion={cluster.openshiftVersion}
118
135
  preflightRequirements={preflightRequirements}
@@ -242,6 +242,7 @@ const hostDiscoveryStepValidationsMap: WizardStepValidationMap = {
242
242
  'no-skip-missing-disk',
243
243
  'compatible-agent',
244
244
  'openshift-ai-gpu-requirements-satisfied',
245
+ 'inventory-not-partially-truncated',
245
246
  ],
246
247
  };
247
248
 
@@ -260,7 +261,7 @@ const storageStepValidationsMap: WizardStepValidationMap = {
260
261
  'no-skip-missing-disk',
261
262
  ],
262
263
  },
263
- softValidationIds: [],
264
+ softValidationIds: ['inventory-not-partially-truncated'],
264
265
  };
265
266
 
266
267
  const networkingStepValidationsMap: WizardStepValidationMap = {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "dependencies": {
3
- "@openshift-assisted/locales": "2.54.0",
4
- "@openshift-assisted/types": "2.54.0",
3
+ "@openshift-assisted/locales": "2.54.2",
4
+ "@openshift-assisted/types": "2.54.2",
5
5
  "@openshift-console/dynamic-plugin-sdk": "^4.19.1",
6
6
  "@patternfly/patternfly": "6.4.0",
7
7
  "@patternfly/react-code-editor": "6.4.1",
@@ -136,5 +136,5 @@
136
136
  ]
137
137
  }
138
138
  },
139
- "version": "2.54.0"
139
+ "version": "2.54.2"
140
140
  }