ACM-20968: Decouple InfraEnv Create Page#2826
ACM-20968: Decouple InfraEnv Create Page#2826rawagner wants to merge 1 commit intoopenshift-assisted:masterfrom
Conversation
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: rawagner The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
|
/hold |
WalkthroughThis update introduces a comprehensive refactor and feature expansion of the infrastructure environment (InfraEnv) and host management workflows. It adds new components for creating and managing InfraEnvs, centralizes resource creation and patching logic, internalizes modal and action handling, simplifies and unifies type definitions, and introduces new hooks for Kubernetes resource watching. Numerous translation keys, UI enhancements, and error handling improvements are also included. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant UI
participant Formik
participant K8sAPI
participant Router
User->>UI: Click "Create InfraEnv"
UI->>Formik: Initialize form
User->>Formik: Fill form fields and submit
Formik->>UI: Validate and collect values
UI->>K8sAPI: Dry-run create Secret, InfraEnv, (optional) Role
K8sAPI-->>UI: Dry-run response
UI->>K8sAPI: Create Secret, InfraEnv, (optional) Role
K8sAPI-->>UI: Creation response
UI->>Router: Navigate to InfraEnv details page
sequenceDiagram
participant User
participant UI
participant Modal
participant K8sAPI
User->>UI: Click "Delete Host"
UI->>Modal: Open DeleteHostModal
User->>Modal: Confirm deletion
Modal->>K8sAPI: Delete Agent/BMH/NMState, adjust provision requirements
K8sAPI-->>Modal: Success/Error
Modal->>UI: Close modal, refresh view
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
libs/ui-lib/lib/cim/components/Agent/BMCForm.tsxOops! Something went wrong! :( ESLint: 8.57.1 ESLint couldn't find the config "@openshift-assisted/eslint-config" to extend from. Please check that the name of the config is correct. The config "@openshift-assisted/eslint-config" was referenced from the config file in "/libs/ui-lib/.eslintrc.cjs". If you still have problems, please stop by https://eslint.org/chat/help to chat with the team. libs/ui-lib/lib/cim/components/Agent/NoAgentsAlert.tsxOops! Something went wrong! :( ESLint: 8.57.1 ESLint couldn't find the config "@openshift-assisted/eslint-config" to extend from. Please check that the name of the config is correct. The config "@openshift-assisted/eslint-config" was referenced from the config file in "/libs/ui-lib/.eslintrc.cjs". If you still have problems, please stop by https://eslint.org/chat/help to chat with the team. libs/ui-lib/lib/cim/components/Agent/tableUtils.tsxOops! Something went wrong! :( ESLint: 8.57.1 ESLint couldn't find the config "@openshift-assisted/eslint-config" to extend from. Please check that the name of the config is correct. The config "@openshift-assisted/eslint-config" was referenced from the config file in "/libs/ui-lib/.eslintrc.cjs". If you still have problems, please stop by https://eslint.org/chat/help to chat with the team.
✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 21
🔭 Outside diff range comments (1)
libs/ui-lib/lib/cim/components/modals/EditBMHModal.tsx (1)
42-44: 💡 Verification agent🧩 Analysis chain
Document why error handling is suppressed.
Error handling in the secret fetch operation is suppressed with a commented-out console.error. It would be helpful to add a comment explaining why this approach was chosen.
🏁 Script executed:
#!/bin/bash # Check if this error handling pattern is consistent across the codebase # Look for similar patterns of commented-out error logging echo "Files with commented-out error logging:" rg -A 2 "console\.error.*\(.*\);" --type=ts | grep -B 1 "\/\/" # Count occurrences echo "Count of commented-out console.error occurrences:" rg "\/\/\s*console\.error" --type=ts | wc -lLength of output: 2441
Document suppressed error handling in EditBMHModal
Please add a brief comment above the silent catch block to explain why console.error is disabled—e.g. that failures fetching the secret are non-critical and the UI will fall back gracefully. Without this note, future readers may not understand the intent.
Affected location:
- libs/ui-lib/lib/cim/components/modals/EditBMHModal.tsx (around lines 42–44)
Suggested snippet:
} catch (err) { - // console.error(t('ai:Could not get secret'), err); + // Intentionally silencing fetch errors for the BMH secret. + // If the secret isn’t available we fall back to defaults without blocking the form. + // console.error(t('ai:Could not get secret'), err); }Consider applying a similar comment to other instances of commented-out
console.errorfor consistency.
🧹 Nitpick comments (32)
libs/ui-lib/lib/ocm/components/Routes.tsx (2)
17-22: Rename props type alias to avoid collision.Extracting the inline props into a named alias is a great refactor for clarity and reuse. However, naming the alias
UILibRoutes—the same as the component—can lead to confusion in IDEs and code navigation. Consider renaming the alias to something likeUILibRoutesPropsto clearly communicate its purpose and avoid shadowing the component name.
24-29: Review React.FC usage andchildrendeclaration.Using
React.FC<UILibRoutes>already provides an implicitchildrenprop, so the explicitchildren?: React.ReactNodein your alias is redundant. You can either:
- Remove
childrenfrom theUILibRoutesalias and keep theReact.FCannotation, or- Drop the
React.FCgeneric and annotate the component directly:export const UILibRoutes = ({ allEnabledFeatures, children, history, basename, }: UILibRoutesProps) => { ... }Aligning on one pattern will simplify the types and reduce duplication.
libs/ui-lib/lib/cim/hooks/useInfraEnvBMHs.ts (1)
6-29: Consider handling edge cases for empty infraEnv name and namespaceThe hook implementation looks solid and follows the custom hook pattern well. However, there are a couple of edge cases to consider:
- On line 17, if
infraEnv.metadata?.namespaceis undefined, this could cause issues with the watch.- On line 21, using
infraEnv?.metadata?.name || ''may match unintended resources if the name is empty.Consider adding additional validation:
export const useInfraEnvBMHs = ( infraEnv: InfraEnvK8sResource | undefined, ): WatchK8sResult<BareMetalHostK8sResource[]> => { const [bmhs, loaded, err] = useK8sWatchResource<BareMetalHostK8sResource[]>( - infraEnv + infraEnv && infraEnv.metadata?.name && infraEnv.metadata?.namespace ? { groupVersionKind: { kind: BMHModel.kind, version: BMHModel.apiVersion, group: BMHModel.apiGroup, }, namespace: infraEnv.metadata?.namespace, isList: true, selector: { matchLabels: { - [INFRAENV_AGENTINSTALL_LABEL_KEY]: infraEnv?.metadata?.name || '', + [INFRAENV_AGENTINSTALL_LABEL_KEY]: infraEnv.metadata.name, }, }, } : null, ); return [bmhs, loaded, err]; };libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/useInfraEnvResources.ts (2)
11-17: Consider using an object return type for better readability and maintainability.Currently, the hook returns a tuple with multiple heterogeneous values (arrays, boolean, unknown). While tuples are valid, an object with named properties would make the hook's API more self-documenting and less prone to usage errors.
-export const useInfraEnvResources = (): [ - string[], - OsImage[], - SecretK8sResource[], - boolean, - unknown, -] => { +export const useInfraEnvResources = (): { + usedNames: string[]; + osImages: OsImage[]; + credentials: SecretK8sResource[]; + isLoaded: boolean; + error: unknown; +} => {Then update the return statement accordingly:
- return [ - usedNames, - osImages, - credentials, - infraLoaded && agentLoaded && credsLoaded, - infraErr || agentErr || credsErr, - ]; + return { + usedNames, + osImages, + credentials, + isLoaded: infraLoaded && agentLoaded && credsLoaded, + error: infraErr || agentErr || credsErr, + };
1-10: Add JSDoc documentation for better developer experience.Since this hook provides key infrastructure environment resources that will be used by other components, adding documentation would improve usability and maintainability.
+/** + * A hook that watches and aggregates Kubernetes resources needed for Infrastructure Environment creation. + * + * @returns An array containing: + * - List of existing InfraEnv names (to prevent duplicates) + * - Available OS images from AgentServiceConfig + * - Secret credentials filtered by cluster type + * - A boolean indicating if all resources are loaded + * - Any errors encountered during loading + */ export const useInfraEnvResources = (): [libs/ui-lib/lib/cim/components/modals/EditBMHModal.tsx (2)
54-54: Clean up unnecessary dependencies in useEffect.The dependency array includes
hasDHCPandt(translation function), which aren't used within the effect function.- }, [bmhName, bmhNamespace, bmhSecret, hasDHCP, t]); + }, [bmhName, bmhNamespace, bmhSecret]);
35-44: Consider using useK8sWatchResource for consistency.You're using
k8sGetto fetch the secret, but the project is also introducing a newuseK8sWatchResourcehook. For consistency across components, consider using the new hook.- try { - const secretResult = await k8sGet({ - model: SecretModel, - name: bmhSecret, - ns: bmhNamespace, - }); - setSecret(secretResult); - } catch (err) { - // console.error(t('ai:Could not get secret'), err); - } + // Move this outside the effect + const [secret, secretLoaded, secretError] = useK8sWatchResource<SecretK8sResource>({ + groupVersionKind: { + kind: SecretModel.kind, + version: SecretModel.apiVersion, + }, + name: bmhSecret, + namespace: bmhNamespace, + }); + + React.useEffect(() => { + setLoading(!secretLoaded); + if (secretLoaded && !secretError) { + setSecret(secret); + }libs/ui-lib/lib/cim/components/helpers/agents.ts (1)
38-63: Add documentation to clarify function behavior.This function has complex logic for hostname updates, but lacks documentation explaining its behavior and expected usage.
+/** + * Creates a function to update hostnames for agents or bare metal hosts. + * + * @param agents - List of Agent resources to search + * @param bmhs - List of BareMetalHost resources to search + * @returns A function that takes a host and hostname and updates the appropriate resource + */ export const onAgentChangeHostname: OnAgentChangeHostname< AgentK8sResource, BareMetalHostK8sResource > = (agents, bmhs) => (host, hostname) => {libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts (2)
1-17: Add documentation explaining the purpose of this wrapper.This hook appears to be a simple typed wrapper around the console SDK's hook, but it's not clear why this wrapper exists rather than using the original hook directly.
+/** + * A typed wrapper around the OpenShift Console's useK8sWatchResource hook. + * + * This provides consistent typing for Kubernetes resource watching throughout + * the application and allows for potential future enhancements like error handling + * without requiring changes to component implementations. + * + * @param initResource - The resource configuration to watch + * @returns A tuple containing the resource(s), loading state, and any error + */ export const useK8sWatchResource: UseK8sWatchResource = (props) => consoleWatch(props);
7-14: Consider enhancing type safety for errors.The current type signature uses
unknownfor the error type. Consider defining a more specific error type to provide better type safety for error handling.+// Define a more specific error type +export interface K8sWatchError { + message: string; + code?: number; + [key: string]: any; +} export type WatchK8sResult<R extends K8sResourceCommon | K8sResourceCommon[]> = [ R, boolean, - unknown, + K8sWatchError | null, ];libs/ui-lib/lib/cim/hooks/useInfraEnvNMStates.ts (2)
7-18: Guard‐clause before iterating can avoid an unnecessary full-array scanWhen
infraEnvisundefinedor itsmatchLabelsselector is empty, we still runArray.prototype.filter, only to immediately return an empty array inside the callback.
Adding an early return keeps intent clearer and avoids the superfluous loop.export const getInfraEnvNMStates = ( nmStateConfigs: NMStateK8sResource[] = [], infraEnv?: InfraEnvK8sResource, ) => - nmStateConfigs.filter((nmStateConfig) => { + !infraEnv || + !Object.keys(infraEnv.spec?.nmStateConfigLabelSelector?.matchLabels ?? {}).length + ? [] + : nmStateConfigs.filter((nmStateConfig) => { … - }); + });
20-35: Passundefinedinstead ofnullto optional hooks for stricter typings
useK8sWatchResourceacceptsnull, but nearly every callsite within UI-lib passesundefined.
Using a single sentinel value helps TypeScript catch accidental truthy/falsy mistakes and avoids implicitanyoverloads.- : null, + : undefined,libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx (1)
217-221: Hard-coded router paths may drift from central route definitionsThe literal
/multicloud/infrastructure/clusters/details/...path duplicates logic that already lives in@console/dynamic-plugin-sdkroute helpers.
If the console URL structure changes, these links will silently break.Consider composing the URL with a helper such as
getClusterDetailsLink(hcNamespace, hcName)or at least wrapping the string construction in one exported util so the path exists in a single place.libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (3)
67-72: Avoid an unnecessaryFragmentinbodyContent
<></>is wrapping only a single child – the translated string – so the fragment is superfluous and flagged by Biome.
Removing it trims two extra nodes from the tree without changing behaviour.- <PopoverIcon - noVerticalAlign - bodyContent={ - <> - {t( - 'ai:This will determine for the infrastructure environment which kind of hosts would be able to be added. If the hosts that you want to add are using DHCP server, select this option, else, select the static IP.', - )} - </> - } + <PopoverIcon + noVerticalAlign + bodyContent={t( + 'ai:This will determine for the infrastructure environment which kind of hosts would be able to be added. If the hosts that you want to add are using DHCP server, select this option, else, select the static IP.', + )} />🧰 Tools
🪛 Biome (1.9.4)
[error] 68-72: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment(lint/complexity/noUselessFragments)
126-126: Guard against rendering the version dropdown whenosImagesis empty
!!osImageswill betruefor an empty array, which can surface a dropdown containing no items and confuse users.
Prefer an explicit length check:- {!!osImages && <InfraEnvOpenShiftVersionDropdown osImages={osImages} />} + {osImages?.length > 0 && ( + <InfraEnvOpenShiftVersionDropdown osImages={osImages} /> + )}
141-148: Wrapatobcalls with basic validation / try-catchIf a secret’s data value is not valid Base-64,
atobthrows aDOMException, breaking the whole form.
Adding a tiny helper keeps the UI resilient to malformed secrets:- setFieldValue( - 'pullSecret', - cred.data?.['pullSecret'] ? atob(cred.data['pullSecret']) : '', - ); + const safeDecode = (val?: string) => { + try { + return val ? atob(val) : ''; + } catch { + return ''; + } + }; + setFieldValue('pullSecret', safeDecode(cred.data?.['pullSecret']));(Do the same for the SSH key.)
libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostsDiscovery.tsx (1)
135-136: Memoise theonSavecallback to avoid unnecessary re-renders
onAgentChangeHostname(agents, bareMetalHosts)is re-executed on every render, producing a brand-new function each time.
This forcesEditAgentModalto re-receive a changedonSaveprop and can trigger avoidable renders.- {editAgent && ( + {editAgent && ( <EditAgentModal onClose={() => setEditAgent(undefined)} usedHostnames={usedHostnames} agent={editAgent} - onSave={onAgentChangeHostname(agents, bareMetalHosts)} + onSave={React.useMemo( + () => onAgentChangeHostname(agents, bareMetalHosts), + [agents, bareMetalHosts], + )} /> )}libs/ui-lib/lib/cim/components/InfraEnv/AddHostDropdown.tsx (1)
49-56: Stabilise theuseK8sWatchResourcedescriptorPassing a new object literal on every render can cause the watch hook to resubscribe repeatedly (depending on its internal implementation).
Memoising the descriptor eliminates unnecessary watch churn:- const [provisioningConfig, provisioningConfigLoaded, provisioningConfigError] = - useK8sWatchResource<K8sResourceCommon>({ - name: 'provisioning-configuration', - groupVersionKind: { - group: 'metal3.io', - version: 'v1alpha1', - kind: 'Provisioning', - }, - }); + const provisioningGvk = React.useMemo( + () => ({ + name: 'provisioning-configuration', + groupVersionKind: { group: 'metal3.io', version: 'v1alpha1', kind: 'Provisioning' }, + }), + [], + ); + const [provisioningConfig, provisioningConfigLoaded, provisioningConfigError] = + useK8sWatchResource<K8sResourceCommon>(provisioningGvk);libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/InfraEnvDetails.tsx (1)
42-50: RedundantuseParamsinvocation
InfraEnvDetailsContentcallsuseParams()even though its parent (InfraEnvDetails) already obtainednameandnamespace. Passing these two values as props avoids the extra hook call and makes the component easier to unit-test.-const { name, namespace } = useParams() as { name: string; namespace: string }; +// receive from parent +const { name, namespace } = props;This is a small clean-up but improves clarity and slightly reduces re-renders.
libs/ui-lib/lib/cim/components/modals/types.ts (1)
42-45:createSecretprobably wants to be optional.
EditPullSecretFormikValuesintroduces a non-optionalcreateSecret: boolean, but many existing forms invoke the modal in “edit-only” mode where no new secret is created.
Consider making it optional with a sensible default to preserve backwards compatibility.- createSecret: boolean; + createSecret?: boolean; // defaults to falselibs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/AgentsTab.tsx (2)
30-33: Unusednamevariable returned byuseParams().
const { namespace } = useParams() as { name: string; namespace: string };
nameis destructured but never used, which will trigger the eslintno-unused-varsrule.
Either remove the property or use it explicitly.
56-63: Aggregated error handling hides the actual failing resource.
if (nmError || amError || aciError) { return <ErrorState />; }You lose the information about which watch failed and why.
Consider passing the first non-undefined error toErrorState(or at least logging it) to ease troubleshooting.libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvPage.tsx (3)
68-85: Namespace existence check swallows unexpected errors.Only a 404 should flip
createNs = true; every other error is surfaced to the user, but the original stack trace is lost.
Forwarding the completeHttpError(or at least its.message) would make debugging cluster-side RBAC issues much easier.- setSubmitError( - t('ai:Failed to check if namespace {{namespace}} exists', { - namespace: infraEnv.metadata?.name, - }), - ); + setSubmitError( + `${t('ai:Failed to check if namespace {{namespace}} exists', { + namespace: infraEnv.metadata?.name, + })}: ${getErrorMessage(e)}` + );
176-183: Accessibility: main banner icon lacks alt text.SVGs rendered as
<MainIcon />are announced as “graphic” by screen readers.
Please wrap it with anaria-labelor provide analtattribute for better accessibility compliance.-<MainIcon /> +<MainIcon aria-label={t('ai:Infrastructure environment illustration')} />
187-190: Navigation on cancel may surprise users.
navigate(-1)relies on browser history; hitting cancel after a hard refresh could throw the user to an unrelated page.
Prefer an explicit path (e.g., environments list) for deterministic UX.libs/ui-lib/lib/cim/components/formik/CredentialsField.tsx (2)
32-55: Gracefully handle an empty credentials arrayWhen
credentials.length === 0, the Select opens with an empty list – this is confusing UX.
Consider adding a disabled placeholder option (or disabling the toggle) to inform the user there are no credentials to pick.-{credentials.map((p) => ( - <SelectOption key={p.metadata?.uid} value={p.metadata?.uid}> - {p.metadata?.name} - </SelectOption> -))} +{credentials.length > 0 ? ( + credentials.map((p) => ( + <SelectOption key={p.metadata?.uid} value={p.metadata?.uid}> + {p.metadata?.name} + </SelectOption> + )) +) : ( + <SelectOption isDisabled>{t('ai:No credentials found')}</SelectOption> +)}This avoids a blank dropdown and clarifies what the user should do next.
67-72:navigatecallback loses form stateNavigating away immediately on click can discard any unsaved data the user already entered in the InfraEnv form.
Consider opening the create-credential flow in a new tab or adding a confirmation prompt.-onClick={() => navigate('/multicloud/credentials/create?type=hostinventory')} +onClick={(e) => { + e.preventDefault(); + window.open( + '/multicloud/credentials/create?type=hostinventory', + '_blank', + 'noopener,noreferrer', + ); +}}This preserves the current form state and avoids accidental data loss.
libs/ui-lib/lib/cim/components/InfraEnv/EnvironmentDetails.tsx (1)
213-218: Show error state for pull-secret loading
isWarning={!pullSecret}silently marks the item as “warning” even when the watch errored.
Consider distinguishing “not configured” vs. “failed to load” to aid troubleshooting.- isWarning={!pullSecret} + isWarning={!!pullSecretError} + /* optionally add `isError` prop for dedicated styling */At minimum, surface
pullSecretErrorsomewhere in the UI so users understand why the pull secret status is unknown.libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsx (2)
162-166: Missing dependency:onApproveAgentis used insideuseMemobut not declared
agentStatusColumnreceivesonApprovefromonApproveAgent. Because the function is referenced insideuseMemo, it should be added to the dependency array to avoid stale closures when the import is re-created during HMR or tests.- bmhStatuses, - agentMachines, + bmhStatuses, + agentMachines, + onApproveAgent,
258-274: Side effect in render:onAgentChangeHostname([editAgent], …)
onAgentChangeHostnameis invoked on every render to create a new callback, which:
- Prevents
EditAgentModalfrom receiving a stable prop (causing unnecessary re-renders).- Executes eagerly if the helper contains internal side-effects.
Consider memoising the callback:
- onSave={onAgentChangeHostname([editAgent], bareMetalHosts)} + onSave={React.useMemo( + () => onAgentChangeHostname([editAgent], bareMetalHosts), + [editAgent, bareMetalHosts], + )}libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts (2)
129-136: Label parsing loses values containing=
values.labels.forEach((l) => { const label = l.split('='); … })
String.split('=')without a limit splits all occurrences, so a label likekey=a=bbecomes['key', 'a', 'b'], breaking the intendedk=vlogic.-const label = l.split('='); +const [key, ...rest] = l.split('='); +const value = rest.join('='); // preserves additional '='Also guard against empty keys to satisfy Kubernetes label constraints.
160-166:additionalNTPSourcesshould respectenableNtpSourcesflag
additionalNTPSourcesis set regardless ofenableNtpSources.
Either honour the flag or remove it from the form to keep behaviour consistent.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting
⛔ Files ignored due to path filters (2)
libs/ui-lib/lib/cim/logos/OnPremiseBannerIcon.svgis excluded by!**/*.svgyarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (55)
libs/locales/lib/en/translation.json(37 hunks)libs/ui-lib/lib/cim/components/Agent/BMCForm.tsx(3 hunks)libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx(2 hunks)libs/ui-lib/lib/cim/components/Agent/types.ts(0 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostDiscoveryTable.tsx(4 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostsDiscovery.tsx(1 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentWizard.tsx(1 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts(3 hunks)libs/ui-lib/lib/cim/components/InfraEnv/AddHostDropdown.tsx(4 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvPage.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/useInfraEnvResources.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/EnvironmentDetails.tsx(4 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsx(7 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/AgentsTab.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/DetailsTab.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/InfraEnvDetails.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvFormPage.tsx(0 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.css(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.tsx(2 hunks)libs/ui-lib/lib/cim/components/InfraEnv/index.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/infra-env.css(0 hunks)libs/ui-lib/lib/cim/components/InfraEnv/types.ts(1 hunks)libs/ui-lib/lib/cim/components/YamlPreview/useYAMLPreview.ts(3 hunks)libs/ui-lib/lib/cim/components/common/InfoAndTroubleshootingNotification.tsx(1 hunks)libs/ui-lib/lib/cim/components/formik/CredentialsField.tsx(1 hunks)libs/ui-lib/lib/cim/components/helpers/agents.ts(2 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostModal.tsx(0 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlForm.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/AddHostModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/DeleteHostModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/EditBMHModal.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/EditNtpSourcesModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/EditProxyModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/EditPullSecretModal.tsx(4 hunks)libs/ui-lib/lib/cim/components/modals/EditSSHKeyModal.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/MassApproveAgentModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/MassDeleteAgentModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/ScaleUpModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/UnbindHostModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/types.ts(3 hunks)libs/ui-lib/lib/cim/config/constants.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useInfraEnvAgents.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useInfraEnvBMHs.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useInfraEnvNMStates.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/multi-cluster-engine.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/nm-state.ts(1 hunks)libs/ui-lib/lib/cim/types/models.ts(1 hunks)libs/ui-lib/lib/cim/utils.ts(1 hunks)libs/ui-lib/lib/ocm/components/Routes.tsx(1 hunks)libs/ui-lib/package.json(2 hunks)
💤 Files with no reviewable changes (4)
- libs/ui-lib/lib/cim/components/modals/AddBmcHostModal.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/infra-env.css
- libs/ui-lib/lib/cim/components/Agent/types.ts
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvFormPage.tsx
🧰 Additional context used
🧬 Code Graph Analysis (27)
libs/ui-lib/lib/ocm/components/Routes.tsx (1)
libs/ui-lib/lib/common/features/featureGate.tsx (1)
FeatureListType(6-8)
libs/ui-lib/lib/cim/hooks/useInfraEnvAgents.ts (4)
libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts (1)
InfraEnvK8sResource(8-42)libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts (2)
WatchK8sResult(7-11)useK8sWatchResource(16-16)libs/ui-lib/lib/cim/types/k8s/agent.ts (1)
AgentK8sResource(32-74)libs/ui-lib/lib/cim/types/models.ts (1)
AgentModel(67-76)
libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlForm.tsx (2)
libs/ui-lib/lib/cim/components/modals/types.ts (1)
UploadActionModalProps(52-59)libs/ui-lib/lib/cim/types/models.ts (1)
BMHModel(78-87)
libs/ui-lib/lib/cim/components/modals/MassApproveAgentModal.tsx (1)
libs/ui-lib/lib/cim/utils.ts (1)
onApproveAgent(30-41)
libs/ui-lib/lib/cim/hooks/useInfraEnvNMStates.ts (4)
libs/ui-lib/lib/cim/types/k8s/nm-state.ts (1)
NMStateK8sResource(3-11)libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts (1)
InfraEnvK8sResource(8-42)libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts (2)
WatchK8sResult(7-11)useK8sWatchResource(16-16)libs/ui-lib/lib/cim/types/models.ts (1)
NMStateModel(89-98)
libs/ui-lib/lib/cim/components/modals/EditProxyModal.tsx (2)
libs/ui-lib/lib/cim/utils.ts (1)
appendPatch(20-28)libs/ui-lib/lib/cim/types/models.ts (1)
InfraEnvModel(24-33)
libs/ui-lib/lib/cim/components/modals/EditBMHModal.tsx (1)
libs/ui-lib/lib/cim/types/models.ts (1)
SecretModel(3-11)
libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/DetailsTab.tsx (4)
libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts (1)
InfraEnvK8sResource(8-42)libs/ui-lib/lib/cim/types/k8s/agent.ts (1)
AgentK8sResource(32-74)libs/ui-lib/lib/cim/components/InfraEnv/EnvironmentErrors.tsx (1)
EnvironmentErrors(16-56)libs/ui-lib/lib/cim/config/constants.ts (1)
DOC_VERSION(4-4)
libs/ui-lib/lib/cim/hooks/useInfraEnvBMHs.ts (4)
libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts (1)
InfraEnvK8sResource(8-42)libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts (2)
WatchK8sResult(7-11)useK8sWatchResource(16-16)libs/ui-lib/lib/cim/types/models.ts (1)
BMHModel(78-87)libs/ui-lib/lib/cim/components/common/constants.ts (1)
INFRAENV_AGENTINSTALL_LABEL_KEY(10-10)
libs/ui-lib/lib/cim/components/YamlPreview/useYAMLPreview.ts (1)
libs/ui-lib/lib/cim/types/models.ts (1)
SecretModel(3-11)
libs/ui-lib/lib/cim/components/modals/EditSSHKeyModal.tsx (2)
libs/ui-lib/lib/cim/utils.ts (1)
appendPatch(20-28)libs/ui-lib/lib/cim/types/models.ts (1)
InfraEnvModel(24-33)
libs/ui-lib/lib/cim/components/modals/ScaleUpModal.tsx (1)
libs/ui-lib/lib/cim/components/helpers/agents.ts (1)
onAgentChangeHostname(43-63)
libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx (1)
libs/ui-lib/lib/cim/utils.ts (1)
onDeleteHost(95-131)
libs/ui-lib/lib/cim/components/modals/MassDeleteAgentModal.tsx (1)
libs/ui-lib/lib/cim/utils.ts (1)
onDeleteHost(95-131)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (5)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts (1)
EnvironmentStepFormValues(15-34)libs/ui-lib/lib/common/hooks/index.ts (1)
useTranslation(3-3)libs/ui-lib/lib/common/config/docs_links.ts (1)
getOCPStaticIPDocLink(62-63)libs/ui-lib/lib/cim/config/constants.ts (1)
DOC_VERSION(4-4)libs/ui-lib/lib/common/components/ui/formik/LabelField.tsx (1)
LabelField(34-100)
libs/ui-lib/lib/cim/components/formik/CredentialsField.tsx (1)
libs/ui-lib/lib/common/hooks/index.ts (1)
useTranslation(3-3)
libs/ui-lib/lib/cim/components/modals/EditNtpSourcesModal.tsx (3)
libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts (1)
InfraEnvK8sResource(8-42)libs/ui-lib/lib/cim/utils.ts (1)
appendPatch(20-28)libs/ui-lib/lib/cim/types/models.ts (1)
InfraEnvModel(24-33)
libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/InfraEnvDetails.tsx (10)
libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts (1)
InfraEnvK8sResource(8-42)libs/ui-lib/lib/cim/types/k8s/agent.ts (1)
AgentK8sResource(32-74)libs/ui-lib/lib/common/hooks/index.ts (1)
useTranslation(3-3)libs/ui-lib/lib/cim/components/ClusterDeployment/helpers.ts (1)
getAgentsHostsNames(196-210)libs/ui-lib/lib/cim/config/constants.ts (1)
DOC_VERSION(4-4)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.tsx (1)
InfraEnvHostsTabAgentsWarning(13-16)libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts (1)
useK8sWatchResource(16-16)libs/ui-lib/lib/cim/types/models.ts (1)
InfraEnvModel(24-33)libs/ui-lib/lib/cim/hooks/useInfraEnvAgents.ts (1)
useInfraEnvAgents(6-33)libs/ui-lib/lib/cim/hooks/useInfraEnvBMHs.ts (1)
useInfraEnvBMHs(6-29)
libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostsDiscovery.tsx (1)
libs/ui-lib/lib/cim/components/helpers/agents.ts (1)
onAgentChangeHostname(43-63)
libs/ui-lib/lib/cim/components/InfraEnv/AddHostDropdown.tsx (1)
libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts (1)
useK8sWatchResource(16-16)
libs/ui-lib/lib/cim/components/modals/UnbindHostModal.tsx (5)
libs/ui-lib/lib/cim/types/k8s/agent.ts (1)
AgentK8sResource(32-74)libs/ui-lib/lib/cim/types/k8s/agent-cluster-install.ts (1)
AgentClusterInstallK8sResource(17-80)libs/ui-lib/lib/common/hooks/index.ts (1)
useTranslation(3-3)libs/ui-lib/lib/cim/utils.ts (2)
onUnbindHost(140-169)getAgentName(133-138)libs/ui-lib/lib/common/utils.ts (1)
getErrorMessage(13-21)
libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostDiscoveryTable.tsx (7)
libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts (1)
ClusterDeploymentHostDiscoveryTableProps(176-184)libs/ui-lib/lib/cim/types/k8s/agent.ts (1)
AgentK8sResource(32-74)libs/ui-lib/lib/cim/hooks/useInfraEnvNMStates.ts (1)
useInfraEnvNMStates(20-43)libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts (1)
useK8sWatchResource(16-16)libs/ui-lib/lib/cim/types/k8s/agent-cluster-install.ts (1)
AgentClusterInstallK8sResource(17-80)libs/ui-lib/lib/cim/types/models.ts (1)
AgentClusterInstallModel(111-120)libs/ui-lib/lib/cim/components/helpers/agents.ts (1)
onAgentChangeHostname(43-63)
libs/ui-lib/lib/cim/components/modals/AddHostModal.tsx (4)
libs/ui-lib/lib/common/components/clusterConfiguration/DiscoveryImageConfigForm.tsx (1)
DiscoveryImageFormValues(56-56)libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts (1)
InfraEnvK8sResource(8-42)libs/ui-lib/lib/cim/utils.ts (1)
appendPatch(20-28)libs/ui-lib/lib/cim/types/models.ts (1)
InfraEnvModel(24-33)
libs/ui-lib/lib/cim/components/modals/EditPullSecretModal.tsx (3)
libs/ui-lib/lib/common/utils.ts (1)
getErrorMessage(13-21)libs/ui-lib/lib/cim/components/modals/types.ts (1)
EditPullSecretFormikValues(42-45)libs/ui-lib/lib/cim/types/models.ts (1)
SecretModel(3-11)
libs/ui-lib/lib/cim/components/modals/types.ts (1)
libs/ui-lib/lib/cim/components/Agent/types.ts (1)
BMCFormProps(18-27)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts (3)
libs/ui-lib-tests/cypress/fixtures/infra-envs/openshift-versions.ts (2)
x86(8-8)s390x(10-10)libs/ui-lib/lib/common/components/ui/formik/validationSchemas.ts (7)
richNameValidationSchema(456-489)locationValidationSchema(654-679)pullSecretValidationSchema(143-162)sshPublicKeyValidationSchema(105-115)httpProxyValidationSchema(534-573)noProxyValidationSchema(587-602)ntpSourceValidationSchema(604-627)libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts (1)
InfraEnvK8sResource(8-42)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvPage.tsx (4)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/useInfraEnvResources.ts (1)
useInfraEnvResources(11-69)libs/ui-lib/lib/common/utils.ts (1)
getErrorMessage(13-21)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts (7)
initialValues(69-85)validationSchema(36-67)EnvironmentStepFormValues(15-34)getPullSecretSecret(87-100)getInfraEnv(102-169)getRole(171-187)getNamespace(189-197)libs/ui-lib/lib/cim/types/models.ts (4)
NamespaceModel(46-54)RoleModel(13-22)SecretModel(3-11)InfraEnvModel(24-33)
🪛 Biome (1.9.4)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx
[error] 68-72: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment
(lint/complexity/noUselessFragments)
⏰ Context from checks skipped due to timeout of 90000ms (6)
- GitHub Check: lint
- GitHub Check: translation-files
- GitHub Check: unit-tests
- GitHub Check: tests
- GitHub Check: circular-deps
- GitHub Check: format
🔇 Additional comments (65)
libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.css (1)
1-3: Approve CSS class addition
The new.cim-infra-env-hosts-tab-title__iconrule correctly applies the intended left margin using the PatternFly spacer token and aligns with the updated class usage in the component.libs/ui-lib/lib/cim/config/constants.ts (1)
4-4: Verify documentation version constant
IntroducingDOC_VERSIONcentralizes the documentation version and improves maintainability. Ensure this value is synchronized with any external documentation, automated docs generation, and relevant tests.libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.tsx (2)
11-11: Ensure CSS import is effective
The added import forInfraEnvHostsTabAgentsWarning.cssbrings in the new icon class. Confirm that global CSS loading in the build pipeline includes this file without conflicts.
58-58: Align component class with new CSS
Updated theclassNametocim-infra-env-hosts-tab-title__icon, matching the CSS file. This ensures the icon receives the correct styling.libs/ui-lib/package.json (3)
5-5: Review major SDK upgrade
Bumping@openshift-console/dynamic-plugin-sdkfrom0.xto1.4.0may introduce breaking changes. Verify that all dynamic-plugin-sdk APIs used (k8sCreate,k8sPatch, resource watches, etc.) remain compatible and that automated tests cover these interactions.
120-120: Include SVG assets in build
The updatedbuildscript now callsyarn copy:svgalongsidecopy:css, ensuring SVG assets are packaged for CJS output. This supports the new icon and image files used in the UI library.
125-125: Copy SVGs in build output
Thecopy:svgrsync invocation mirrors all SVG files fromlibtobuild/cjswhile preserving directory structure. Confirm that all required SVGs are covered and correctly referenced in the built module.libs/ui-lib/lib/cim/types/k8s/multi-cluster-engine.ts (1)
1-7: IntroduceMCEK8sResourcetype alias
The new type extendsK8sResourceCommonand adds an optionalspec.targetNamespace, aligning with the Multi-Cluster Engine model. It enhances type safety for resource interactions.libs/ui-lib/lib/cim/types/k8s/nm-state.ts (1)
5-5: Improved type safety by usingunknowninstead ofany.This change enhances type safety by using
unknowninstead ofanyfor theconfigproperty, requiring explicit type checking before usage. This is a good practice that aligns with modern TypeScript standards and helps prevent potential type-related bugs.libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlModal.tsx (1)
28-28: Simplified component interface by internalizing resource creation.Removing the
onCreateBmcByYamlprop simplifies the component interface and follows better React patterns by keeping the resource creation logic inside the form component itself. This reduces prop drilling and improves maintainability.libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts (1)
20-22: Made proxy configuration fields optional for greater flexibility.Making the proxy fields (
httpProxy,httpsProxy, andnoProxy) optional improves the type definition's accuracy and provides better flexibility when handling proxy configurations. This change supports cases where proxy information may not be provided and aligns with the refactored proxy handling components.libs/ui-lib/lib/cim/components/InfraEnv/index.ts (1)
2-3: Improved component organization with dedicated create and details pages.The exports have been updated to reflect a more modular architecture, replacing the previous components with dedicated
CreateInfraEnvPageandInfraEnvDetailscomponents from their respective subdirectories. This reorganization follows better React practices and aligns with the PR's goal of creating a cleaner, more maintainable code structure.libs/ui-lib/lib/cim/components/modals/MassDeleteAgentModal.tsx (2)
29-29: Import added for centralized deletion logic.The code now imports the
onDeleteHostutility function from../../utils, aligning with the PR's goal of centralizing resource operations. This change simplifies the component by removing the need for external callback props.
165-165: Using centralized deletion utility instead of callback prop.The component now directly uses the imported
onDeleteHostutility function instead of relying on a callback prop. This implementation correctly passes the agent, BMH, and nmStates parameters, maintaining the same functionality while reducing prop drilling.libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlForm.tsx (2)
31-32: Imports for direct Kubernetes API interaction.Added imports to support direct k8sCreate operations and K8s model definition, removing the need for external callback props. These additions align with the PR objective of decoupling components and centralizing resource operations.
34-34: Simplified component props by removing onCreateBmcByYaml callback.The component signature has been simplified to only require the
onCloseprop, removing the dependency on an external callback for BMC host creation. This change is consistent with the PR's goal of reducing prop drilling and centralizing resource operations.libs/ui-lib/lib/cim/components/modals/MassApproveAgentModal.tsx (2)
24-24: Import added for centralized agent approval logic.The code now imports the
onApproveAgentutility function from../../utils, aligning with the PR's goal of centralizing resource operations. This change simplifies the component by removing the need for external callback props.
115-115: Using centralized approval utility instead of callback prop.The component now directly uses the imported
onApproveAgentutility function instead of relying on a callback prop. The implementation maintains the same functionality while reducing prop drilling and centralizing the agent approval logic.libs/ui-lib/lib/cim/components/YamlPreview/useYAMLPreview.ts (4)
4-4: Updated SDK import for direct K8s resource interaction.The import now includes
k8sGetandK8sResourceCommonfrom the OpenShift dynamic plugin SDK, providing direct access to Kubernetes resources. This aligns with the PR's goal of centralizing resource operations.
10-10: Added import for SecretModel.The code now imports the
SecretModelfrom../../types/models, which is needed for direct interaction with Kubernetes Secret resources. This replaces the need for an external secret fetching callback.
53-57: Direct K8s resource fetching replaces callback.The hook now directly fetches the Secret resource using
k8sGetwith the appropriate model and parameters instead of relying on an external callback function. This implementation reduces prop drilling and centralizes Kubernetes resource management.
90-90: Updated useEffect dependencies.The dependency array no longer includes
fetchSecretas it's been replaced with directk8sGetcalls. The array correctly includes all dependencies used in the effect:cdNamespace,cdName,secretName,fetchManagedClusters, andfetchKlusterletAddonConfig.libs/ui-lib/lib/cim/hooks/useInfraEnvAgents.ts (1)
6-33: Well-implemented hook for watching InfraEnv agentsThis new hook effectively watches Agent resources associated with an InfraEnv by constructing the appropriate label selector from the InfraEnv's status and using the Kubernetes watch resource API. The implementation correctly handles the case when infraEnv is undefined by passing null to useK8sWatchResource.
libs/ui-lib/lib/cim/components/InfraEnv/types.ts (2)
3-3: LGTM: Import change aligns with type simplificationThe import change correctly aligns with the simplified props type, only importing what's needed after the callback props were removed.
7-12: Props interface simplification improves maintainabilitySimplifying the
AddHostDropdownPropstype by removing callback props (onSaveISOParams,onCreateBMH,onCreateBmcByYaml, andprovisioningConfigResult) aligns with the PR's goal of decoupling components and internalizing logic. This reduces prop drilling and makes the component API cleaner.libs/ui-lib/lib/cim/components/modals/ScaleUpModal.tsx (1)
182-182: Simplified onSave handler reduces prop drillingThe
onSaveprop no longer passes callbacks toonAgentChangeHostname, which is consistent with the pattern of internalizing logic rather than passing callbacks through props. This simplifies the component interface while maintaining the same functionality.libs/ui-lib/lib/cim/components/modals/EditProxyModal.tsx (2)
26-28: LGTM: New imports support direct K8s resource patchingThese imports enable the modal to directly interact with Kubernetes resources instead of relying on external callbacks, which aligns with the decoupling goals of the PR.
98-121: Improved implementation with direct K8s resource patchingThe form submission now handles K8s resource patching internally rather than delegating to an external callback. This approach:
- Constructs proxy settings based on form values
- Creates patches only for changed values using
appendPatch- Applies patches directly using
k8sPatch- Includes an optimization to avoid API calls when no changes are made (
patches.lengthcheck)This implementation is more self-contained and aligns with the PR's goal of decoupling components.
libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/DetailsTab.tsx (1)
1-33: Clean, well-structured component implementationThe
DetailsTabcomponent is well-organized and follows good React patterns. It clearly separates error handling from details display and properly passes derived boolean indicators to child components.libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentWizard.tsx (2)
107-107: Simplified conditional logic improves readabilityThe conditional was simplified to only check
isAIFlow(which is!!infraEnv), removing unnecessary checks. This is a good refactoring that makes the code clearer and aligns with the broader changes to internalize host management logic.
44-49: Removed fetchSecret from useYamlPreview hookThe
useYamlPreviewhook call no longer includes thefetchSecretparameter, matching the refactoring in other components to use direct Kubernetes resource watchers or SDK calls instead of passing down callbacks.libs/ui-lib/lib/cim/components/modals/EditSSHKeyModal.tsx (3)
21-23: Added necessary imports for direct K8s resource managementGood addition of the necessary imports to support direct Kubernetes resource patching instead of relying on external callbacks. This aligns with the broader refactoring goals.
52-52: Modal is now always open when renderedThe component now hardcodes
isOpen={true}, making it the parent component's responsibility to mount/unmount the entire component to control visibility. This pattern simplifies the modal interface and reduces prop drilling.
64-78: Direct Kubernetes resource patchingGood implementation of direct Kubernetes resource patching using the SDK. The code:
- Creates a patch only if the SSH key has changed
- Uses the utility function
appendPatchfor consistent patch construction- Only makes the API call if there are actual changes to apply
This approach centralizes resource management and reduces the need for external callback props.
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/useInfraEnvResources.ts (1)
60-60:Details
❓ Verification inconclusive
Potential issue with OS image extraction.
This assumes all required OS images are in the first AgentServiceConfig (
agentServiceConfigs?.[0]). If there are multiple configs with different images, you'll only get images from the first one.
🏁 Script executed:
#!/bin/bash # Check how many AgentServiceConfig resources typically exist and whether they contain different OS images # First, count how many AgentServiceConfig resources typically exist echo "Number of AgentServiceConfig resources:" ast-grep --pattern 'kind: AgentServiceConfig' | wc -l # Check if there are references to multiple AgentServiceConfig resources echo "References to multiple AgentServiceConfigs:" rg -A 2 'agentServiceConfigs' --type=tsLength of output: 956
🏁 Script executed:
#!/bin/bash # Find where AgentServiceConfigK8sResource is defined to understand the resource structure rg -C3 "type AgentServiceConfigK8sResource" -g "*.ts"Length of output: 676
🏁 Script executed:
#!/bin/bash # Show full spec definition including osImages in AgentServiceConfigK8sResource echo "=== AgentServiceConfigK8sResource spec definition ===" rg -A10 "spec:" -g "libs/ui-lib/lib/cim/types/k8s/agent-service-config.ts" # Show the parameters passed to useK8sWatchResource in useInfraEnvResources.ts echo "=== useK8sWatchResource call context ===" rg -C5 "useK8sWatchResource" -g "libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/useInfraEnvResources.ts"Length of output: 5594
Review OS image aggregation logic
The current implementation only readsosImagesfrom the firstAgentServiceConfigin the list:const osImages = agentServiceConfigs?.[0]?.spec.osImages || [];If your cluster ever contains more than one
AgentServiceConfig(for example, per‐region or per‐environment overrides), this will drop all but the first config’s images. Please verify whether:
- You always provision exactly one
AgentServiceConfig(in which case this is safe), or- You should instead aggregate across all configs, e.g.:
const osImages = agentServiceConfigs ?.flatMap(cfg => cfg.spec.osImages ?? []) .filter(Boolean) ?? [];Adjust as needed to ensure no images are accidentally omitted.
libs/ui-lib/lib/cim/components/modals/EditBMHModal.tsx (1)
59-59:Details
✅ Verification successful
Verify the isOpen behavior.
The
isOpenprop is now hardcoded totrue, which means the modal will always be rendered in an open state. This shifts visibility control to the parent component, which must conditionally render this modal only when needed.
🏁 Script executed:
#!/bin/bash # Check how this modal is rendered in parent components # Find components that import EditBMHModal echo "Components that import EditBMHModal:" rg "import.*EditBMHModal" --type=ts # Look for conditional rendering of EditBMHModal echo "Conditional rendering of EditBMHModal:" rg -A 2 -B 2 "<EditBMHModal" --type=tsxLength of output: 520
🏁 Script executed:
#!/bin/bash # Retry searching for EditBMHModal usage without relying on --type echo "Searching for <EditBMHModal usage in TSX files:" rg "<EditBMHModal" -A2 -B2 -g "*.tsx"Length of output: 1526
isOpen is always true; visibility’s handled by parent rendering
Both
InfraEnvAgentTable.tsxandClusterDeploymentHostsDiscovery.tsxwrap the modal in a conditional based oneditBMH, e.g.:
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsx
{editBMH && ( <EditBMHModal infraEnv={infraEnv} bmh={editBMH} … )}- libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostsDiscovery.tsx
{editBMH && ( <EditBMHModal infraEnv={infraEnv} bmh={editBMH} … )}Since the parent now controls whether the modal is rendered at all, hard-coding
isOpentotrueis appropriate and no further changes are needed.libs/ui-lib/lib/cim/components/helpers/agents.ts (1)
5-5: LGTM: Improved code organization.The explicit import of utility functions centralizes host/agent modification logic, which is a positive improvement that aligns with the broader refactoring effort.
libs/ui-lib/lib/cim/hooks/useInfraEnvNMStates.ts (1)
37-43: Memo dependency list is correct – good job!
infraEnvNMStatesis re-computed only when either the source list or the selector changes, avoiding unnecessary re-renders.libs/locales/lib/en/translation.json (1)
5-6: Consistency win – plural keys look tidyPlural & singular keys were unified, preventing the dreaded i18next “missing translation” warnings.
Also applies to: 9-16
libs/ui-lib/lib/cim/components/modals/EditNtpSourcesModal.tsx (2)
33-38: Modal title translation key casing
ai:Edit Ntp sources dialogmixes “Ntp”/“NTP”. For translation-key hygiene, use the acronym form everywhere (Edit NTP sources dialog).
[ suggest_nitpick ]
50-56:⚠️ Potential issue
removepatch may fail when the field is already absentWhen
additionalNTPSourcesis undefined, theremoveop raises422: path does not exist.
Guard before pushing:-if (infraEnv.spec?.additionalNTPSources) { - patches.push({ op: 'remove', path: '/spec/additionalNTPSources' }); -} +if (infraEnv.spec?.additionalNTPSources?.length) { + patches.push({ op: 'remove', path: '/spec/additionalNTPSources' }); +}Likely an incorrect or invalid review comment.
libs/ui-lib/lib/cim/components/modals/DeleteHostModal.tsx (5)
1-12: Well-structured imports with appropriate dependencies.The imports include all necessary components and utilities for implementing a host deletion modal, following a clean organization pattern with UI components, resources, utilities, and translation hooks properly grouped.
13-25: Good component props definition with appropriate typing.The component accepts clearly typed optional Kubernetes resources (
agent,bmh,agentClusterInstall,nmStates) and a requiredonClosecallback. The type structure follows best practices by using inline typings for clarity.
30-41: Well-implemented delete handler with proper error management.The
onDeletefunction correctly handles the async deletion process, including:
- Setting and clearing error state
- Managing loading state via
isDeleting- Using try/catch/finally for robust error handling
- Properly calling the shared
onDeleteHostutilityThis follows best practices for asynchronous operations in React components.
44-64: Properly configured modal with user-friendly UX during deletion.The modal implementation correctly:
- Prevents closing during active deletion operation
- Disables interaction with buttons during deletion
- Shows loading state on the confirm button
- Uses appropriate variants (danger for delete confirmation)
- Uses translated text for all UI elements
This creates a good user experience with clear feedback during operations.
65-75: Clear confirmation message with proper error display.The modal body shows the host name for clear identification and conditionally displays errors using the Alert component with appropriate styling. This provides users with clear information about what they're deleting and any issues that occur.
libs/ui-lib/lib/cim/components/modals/EditPullSecretModal.tsx (6)
22-24: Required imports added for the refactored implementation.The added imports support the removal of external callback dependencies by bringing in the necessary Kubernetes API functions from the OpenShift dynamic plugin SDK.
33-33: Broadened type for better error handling compatibility.Changing
pullSecretErrortype tounknown | undefinedaligns with the generic error handling approach usinggetErrorMessage.
77-77: Standardized error handling with reusable utility.Using
getErrorMessageprovides consistent error formatting across different error types, improving user experience.
122-122: Simplified component rendering pattern.Changed from a conditional
isOpenprop to a hardcodedisOpen={true}, meaning the component expects to be conditionally rendered by its parent rather than controlled via anisOpenprop. This simplifies the component's API and aligns with the pattern used in other modals.
130-131: Improved initial form state.Setting the initial
pullSecretvalue to an empty string provides a cleaner initial state. The actual value is properly set from the existing pull secret in theuseEffecthook.
135-169: Internalized Kubernetes operations with robust error handling.The form submission handler was refactored to:
- Directly handle Kubernetes resource operations rather than relying on an external callback
- Correctly choose between creating a new secret or patching an existing one
- Properly encode the pull secret data
- Handle errors consistently
- Close the modal on success
This change improves component independence and aligns with the refactoring goal of internalizing Kubernetes operations within components.
libs/ui-lib/lib/cim/components/modals/AddHostModal.tsx (3)
18-21: Required imports added for Kubernetes operations.The added imports provide the necessary functionality for performing Kubernetes patch operations and working with the InfraEnv model.
22-69: Well-structured utility function for ISO parameter management.The new
onSaveISOParamsfunction:
- Takes form values and an InfraEnv resource as parameters
- Constructs JSON patches for SSH key, proxy settings, and image type
- Handles all edge cases (add/replace/remove operations)
- Only executes patches when changes exist
This follows best practices by:
- Using the
appendPatchutility for consistent patch creation- Intelligently comparing existing and new values
- Handling presence/absence of optional fields
- Properly structuring the patch operations
Extracting this as an exported function also improves testability and reusability.
92-92: Simplified implementation by using the extracted utility function.Changed from an external callback to the new utility function, reducing prop dependencies and centralizing Kubernetes operations.
libs/ui-lib/lib/cim/components/common/InfoAndTroubleshootingNotification.tsx (3)
7-11: Required imports added for resource watching.The added imports support the refactored implementation that internalizes resource fetching.
33-48: Well-implemented resource watching hook.The
useAssistedServiceConfigMaphook correctly:
- Uses the namespace from the previous hook
- Conditionally watches the ConfigMap only when namespace is available
- Returns the result for use in the component
This follows best practices for Kubernetes resource watching in React components.
62-66: Proper early return when ConfigMap is not available.The component correctly:
- Uses the new hook to get the ConfigMap
- Returns null if the ConfigMap isn't loaded yet
- No longer requires an external prop
This prevents rendering the component with incomplete data and simplifies the component's API.
libs/ui-lib/lib/cim/components/modals/types.ts (1)
25-30: Confirm thathasDHCPis intentionally dropped fromAddBmcHostModalProps.
BMCFormPropsstill exposes thehasDHCPflag, but the newAddBmcHostModalPropsdrops it.
If the underlying modal logic still branches on DHCP support, the prop removal will surface as a runtimeundefinedor compilation error once you re-wire the component. Please double-check all callers of<AddBmcHostModal>.libs/ui-lib/lib/cim/components/InfraEnv/EnvironmentDetails.tsx (1)
98-112: Guardgroupfield for core resources
SecretModel.apiGroupisundefined, sogroupVersionKind.groupbecomesundefined.
Some helpers treatundefinedand''differently, leading to watch failures.
Explicitly pass an empty string for core resources:- group: SecretModel.apiGroup, + group: SecretModel.apiGroup ?? '',This guarantees a valid watch key.
libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsx (1)
97-103: Potential ID mismatch between table rows and k8s resources
onSelectstoreshost.idwhile subsequent look-ups compare the stored IDs withmetadata.uid.
Ifhost.id !== metadata.uidfor BMH rows (or for agents in edge-cases), the mass-action logic will silently skip the selected rows.Please double-check that
tableUtilsalways setshost.id = resource.metadata.uid.
If that guarantee does not hold, consider switching both the selection and the filters tometadata.uidto avoid hard-to-trace inconsistencies.libs/ui-lib/lib/cim/utils.ts (1)
124-130:⚠️ Potential issue
workerAgentscount can become negativeWhen deleting the last worker,
(current || 1) - 1results in0, which is fine, but if the field was already0or undefined the value becomes-1, violating the CRD schema.-const workerCount = (agentClusterInstall.spec?.provisionRequirements.workerAgents || 1) - 1; +const current = agentClusterInstall.spec?.provisionRequirements.workerAgents ?? 0; +const workerCount = Math.max(current - 1, 0);Likely an incorrect or invalid review comment.
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts (1)
69-85: CPU architecture enum value might be incorrect
initialValues.cpuArchitecture = CpuArchitecture.x86.The common enum (see
openshift-versions.ts) uses the literal'x86_64'. Using an unsupported enum member will make the form silently submit an invalid value and the CR creation will fail server-side.Verify the enum keys and default accordingly.
libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts (2)
167-174: Callbacks disappeared fromInfraEnvAgentTableProps– confirm intentThe table props now only contain data and no row-level action handlers (approve, delete, etc.).
Please verify that:
- The table component was refactored to manage these actions internally, and
- No callers still attempt to pass the old callbacks.
Otherwise this change will surface as TypeScript errors.
176-184:Details
❌ Incorrect review comment
onEditBMHstill exported but appears deprecatedThe PR description says
onEditBMHwas removed, yetClusterDeploymentHostDiscoveryTablePropsstill re-exports it. Keeping an unused prop invites confusion.If BMH editing is indeed deprecated, drop it from the pick list:
-export type ClusterDeploymentHostDiscoveryTableProps = Pick< - AgentTableActions, - 'onEditRole' | 'onEditHost' | 'onEditBMH' | 'onSetInstallationDiskId' +export type ClusterDeploymentHostDiscoveryTableProps = Pick< + AgentTableActions, + 'onEditRole' | 'onEditHost' | 'onSetInstallationDiskId' >Please double-check the implementation before merging.
🏁 Script executed:
#!/bin/bash set -e # Locate the definition of AgentTableActions and its properties rg "export (type|interface) AgentTableActions" -A10Length of output: 1415
🏁 Script executed:
#!/bin/bash set -e # Search for onEditBMH usage across the codebase rg -n "onEditBMH"Length of output: 1687
Ignore removal of onEditBMH – it’s still in active use
TheonEditBMHcallback remains defined inAgentTableActionsand passed through several components. Removing it would break existing functionality.
Key usages:
- libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostDiscoveryTable.tsx (props deconstruction at line 97)
- libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostsDiscovery.tsx (onEditBMH={setEditBMH})
- libs/ui-lib/lib/common/components/hosts/tableUtils.tsx and libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx
Please retain
onEditBMHinClusterDeploymentHostDiscoveryTableProps.Likely an incorrect or invalid review comment.
| return onDeleteHost({ agent, bmh }); | ||
| } |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Signature mismatch risk after refactor to object parameter
onDeleteHost({ agent, bmh }) assumes the callback now receives a single object.
libs/ui-lib/lib/cim/utils.ts (still) exports:
export const onDeleteHost = async (
agent?: AgentK8sResource,
bmh?: BareMetalHostK8sResource,
…
)If that util hasn’t been migrated, this call will raise a TypeScript error or, worse, a runtime failure when invoked from JS. Please verify all implementations & imports were updated, or add an adapter here:
-return onDeleteHost({ agent, bmh });
+return onDeleteHost(agent, bmh);🏁 Script executed:
#!/bin/bash
set -e
# Locate and display the definition of onDeleteHost in the utils.ts file
echo "=== onDeleteHost definition in libs/ui-lib/lib/cim/utils.ts ==="
rg -n "export (const|function) onDeleteHost" -A 5 libs/ui-lib/lib/cim/utils.ts || echo "No definition found in utils.ts"
# As a fallback, search the entire codebase for onDeleteHost signature
echo "=== onDeleteHost definitions across the codebase ==="
rg -n "onDeleteHost\s*\(" -A 3 .Length of output: 2479
Correct the onDeleteHost call to use positional parameters
The utility onDeleteHost is still defined to accept positional arguments (agent, bmh, …), but here it’s being invoked with a single object:
• File: libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx
• Lines: 431–432
Suggested fix:
- return onDeleteHost({ agent, bmh });
+ return onDeleteHost(agent, bmh);This brings the call site in line with the exported signature and avoids TypeScript errors or runtime failures.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| return onDeleteHost({ agent, bmh }); | |
| } | |
| return onDeleteHost(agent, bmh); | |
| } |
🤖 Prompt for AI Agents
In libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx at lines 431-432, the
call to onDeleteHost incorrectly passes a single object with properties agent
and bmh, but the onDeleteHost function is defined to accept positional
parameters. Fix this by changing the call to pass agent and bmh as separate
arguments instead of an object, aligning with the function's expected signature.
libs/ui-lib/lib/cim/components/common/InfoAndTroubleshootingNotification.tsx
Show resolved
Hide resolved
libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostDiscoveryTable.tsx
Show resolved
Hide resolved
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Ensure all consumers removed onDeleteHost from hostActions
ClusterDeploymentWizardProps.hostActions no longer exposes onDeleteHost. Any stale usage will now break type-checking or crash at run-time.
Quick verification script:
🏁 Script executed:
rg -n "hostActions.*onDeleteHost"Length of output: 35
To ensure there are no leftover references anywhere in the codebase, let’s broaden the search to any occurrence of onDeleteHost:
🏁 Script executed:
#!/bin/bash
# Search for any usage of onDeleteHost across the repo
rg -n "onDeleteHost"Length of output: 2644
Remove stale onDeleteHost from hostActions consumers
The hostActions type in
libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts
was updated to only include onEditHost | onEditRole | onSetInstallationDiskId. Any destructuring of onDeleteHost will now fail.
Please update the following components:
-
libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostDiscoveryTable.tsx (≈ line 97)
• RemoveonDeleteHost: setDeleteHostfrom thehostActionsdestructuring.
• Where you need deletion behavior, call the standaloneonDeleteHostutil imported from../../utils.ts. -
libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsx (≈ line 114)
• RemoveonDeleteHost: setDeleteHostfrom thehostActionsdestructuring.
• Swap in theonDeleteHostutil from../../utils.tsfor any delete-host UI actions.
🤖 Prompt for AI Agents
In libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts around lines
130-131, the hostActions type no longer includes onDeleteHost. Update all
consumers accordingly: in ClusterDeploymentHostDiscoveryTable.tsx near line 97
and InfraEnvAgentTable.tsx near line 114, remove onDeleteHost: setDeleteHost
from hostActions destructuring. Replace any usage of onDeleteHost with the
standalone onDeleteHost utility imported from ../../utils.ts to maintain
deletion functionality without type errors or runtime crashes.
| onDeleteHost: (host: { agent?: AgentK8sResource; bmh?: BareMetalHostK8sResource }) => void; | ||
| onSetInstallationDiskId: (agent: AgentK8sResource, diskId: string) => Promise<AgentK8sResource>; | ||
| // eslint-disable-next-line | ||
| onMassDeleteHost: (agent?: AgentK8sResource, bmh?: BareMetalHostK8sResource) => Promise<any>; | ||
| onMassDeleteHost: (agent?: AgentK8sResource, bmh?: BareMetalHostK8sResource) => Promise<unknown>; | ||
| onApprove: (agent: AgentK8sResource) => Promise<AgentK8sResource>; |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Unify delete APIs for a predictable caller experience
onDeleteHost now receives a single wrapper object, but onMassDeleteHost still takes two positional params. Two different calling conventions for the same conceptual action are error-prone and complicate refactors.
Proposed shape:
- onMassDeleteHost: (agent?: AgentK8sResource, bmh?: BareMetalHostK8sResource) => Promise<unknown>;
+ // Accept an array of the same wrapper used by `onDeleteHost`
+ onMassDeleteHost: (
+ hosts: { agent?: AgentK8sResource; bmh?: BareMetalHostK8sResource }[],
+ ) => Promise<unknown>;This keeps both callbacks symmetrical, makes “mass” semantics explicit, and prevents accidental param swap bugs.
I’d like to verify how these callbacks are used across the codebase to confirm the impact of unifying their signatures.
🏁 Script executed:
#!/bin/bash
set -e
echo "Definition in types.ts:"
rg -n 'onMassDeleteHost' libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts
rg -n 'onDeleteHost' libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts
echo -e "\nUsages of onMassDeleteHost across the repo:"
rg -n 'onMassDeleteHost'
echo -e "\nUsages of onDeleteHost across the repo:"
rg -n 'onDeleteHost'Length of output: 4270
Unify onMassDeleteHost signature for a consistent API
File: libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts
Lines: 30–33
The two callbacks for deleting hosts use different conventions—one takes a single wrapper object, the other two positional params—making callers prone to parameter-swap bugs. Let’s align them:
- onMassDeleteHost: (agent?: AgentK8sResource, bmh?: BareMetalHostK8sResource) => Promise<unknown>;
+ // Accepts an array of the same wrapper used by `onDeleteHost`
+ onMassDeleteHost: (
+ hosts: { agent?: AgentK8sResource; bmh?: BareMetalHostK8sResource }[],
+ ) => Promise<unknown>;Next, update all CIM callers to pass in a hosts array:
- In ClusterDeploymentHostDiscoveryTable.tsx: replace
onMassDeleteHost(agent, bmh)withonMassDeleteHost([{ agent, bmh }, …]). - In MassDeleteAgentModal.tsx: invoke the new
onMassDeleteHost(hosts)directly instead of looping with positional args.
This change makes “mass” semantics explicit and prevents accidental param swaps.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| onDeleteHost: (host: { agent?: AgentK8sResource; bmh?: BareMetalHostK8sResource }) => void; | |
| onSetInstallationDiskId: (agent: AgentK8sResource, diskId: string) => Promise<AgentK8sResource>; | |
| // eslint-disable-next-line | |
| onMassDeleteHost: (agent?: AgentK8sResource, bmh?: BareMetalHostK8sResource) => Promise<any>; | |
| onMassDeleteHost: (agent?: AgentK8sResource, bmh?: BareMetalHostK8sResource) => Promise<unknown>; | |
| onApprove: (agent: AgentK8sResource) => Promise<AgentK8sResource>; | |
| onDeleteHost: (host: { agent?: AgentK8sResource; bmh?: BareMetalHostK8sResource }) => void; | |
| onSetInstallationDiskId: (agent: AgentK8sResource, diskId: string) => Promise<AgentK8sResource>; | |
| // Accepts an array of the same wrapper used by `onDeleteHost` | |
| onMassDeleteHost: ( | |
| hosts: { agent?: AgentK8sResource; bmh?: BareMetalHostK8sResource }[], | |
| ) => Promise<unknown>; | |
| onApprove: (agent: AgentK8sResource) => Promise<AgentK8sResource>; |
🤖 Prompt for AI Agents
In libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts around lines 30 to
33, unify the onMassDeleteHost callback signature to accept a single array of
host objects, each with optional agent and bmh properties, matching the
onDeleteHost single wrapper object style. Update the type definition
accordingly, then refactor all CIM callers: in
ClusterDeploymentHostDiscoveryTable.tsx, change calls from
onMassDeleteHost(agent, bmh) to onMassDeleteHost([{ agent, bmh }, ...]), and in
MassDeleteAgentModal.tsx, modify the invocation to pass the hosts array directly
instead of looping with positional arguments. This ensures consistent API usage
and prevents parameter swap errors.
9cb23e9 to
8e0f20b
Compare
There was a problem hiding this comment.
Caution
Inline review comments failed to post. This is likely due to GitHub's limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.
Actionable comments posted: 1
♻️ Duplicate comments (5)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts (2)
18-34: 🛠️ Refactor suggestion
credentialsfield is still unusedThe
EnvironmentStepFormValuestype keeps thecredentialsproperty (line 18) but:
- It is not part of
validationSchema.- It is never consumed when building Kubernetes manifests (
getPullSecretSecret,getInfraEnv, …).Keeping dead form state confuses maintainers and bloats the bundle.
Either remove the field completely or wire it into validation and manifest generation.
141-152:⚠️ Potential issueEmpty proxy object still emitted when no URLs are provided
The prior review pointed out that creating
infraEnv.spec.proxy = {}while all three URL fields are empty violates the CRD schema.
This edge case is still present: the code adds an empty object as soon asenableProxy === true.- if (values.enableProxy) { - infraEnv.spec.proxy = {}; + if ( + values.enableProxy && + (values.httpProxy || values.httpsProxy || values.noProxy) + ) { + infraEnv.spec.proxy = {};This guards against producing an invalid InfraEnv manifest.
libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts (1)
30-33: 🛠️ Refactor suggestion
onMassDeleteHostsignature remains inconsistent
onDeleteHostnow takes a single wrapper object, yetonMassDeleteHoststill uses two positional params(agent?, bmh?).
For a predictable API and to avoid caller mishaps, please update the “mass” variant to accept the same wrapper array recommended earlier:- onMassDeleteHost: (agent?: AgentK8sResource, bmh?: BareMetalHostK8sResource) => Promise<unknown>; + onMassDeleteHost: ( + hosts: { agent?: AgentK8sResource; bmh?: BareMetalHostK8sResource }[], + ) => Promise<unknown>;All call sites (
MassDeleteAgentModal, discovery tables, etc.) should then pass one array instead of looping or swapping params.libs/ui-lib/lib/cim/utils.ts (2)
44-55:⚠️ Potential issue
replacefails when BMH hostname annotation is missing
onChangeBMHHostnamestill uses a hardreplacepatch.
If the annotation does not exist, the API returns 422.
ReuseappendPatch(already defined) so the op switches automatically betweenaddandreplace.-export const onChangeBMHHostname = (bmh: BareMetalHostK8sResource, hostname: string) => - k8sPatch({ - model: BMHModel, - resource: bmh, - data: [ - { - op: 'replace', - path: `/metadata/annotations/${BMH_HOSTNAME_ANNOTATION.replace('/', '~1')}`, - value: hostname, - }, - ], - }); +export const onChangeBMHHostname = (bmh: BareMetalHostK8sResource, hostname: string) => { + const patches: Patch[] = []; + appendPatch( + patches, + `/metadata/annotations/${BMH_HOSTNAME_ANNOTATION.replace('/', '~1')}`, + hostname, + bmh.metadata?.annotations?.[BMH_HOSTNAME_ANNOTATION], + ); + return k8sPatch({ model: BMHModel, resource: bmh, data: patches }); +};
112-118:⚠️ Potential issueGuard against negative
workerAgentscountsBoth
onDeleteHostandonUnbindHostdecrementworkerAgentswith
(current || 1) - 1, which can underflow to –1.-const workerCount = (agentClusterInstall.spec?.provisionRequirements.workerAgents || 1) - 1; +const current = agentClusterInstall.spec?.provisionRequirements.workerAgents ?? 0; +const workerCount = Math.max(current - 1, 0);Apply the same fix in
onUnbindHost.
🧹 Nitpick comments (5)
libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlForm.tsx (2)
125-141: Implemented direct K8s resource creationReplaced the external callback with direct K8s resource creation logic. The implementation:
- Iterates through all YAML documents
- Attempts to extract GroupVersionKind for each document
- Uses the appropriate model to create resources
Consider adding error messaging for documents where GVK extraction fails rather than silently continuing to the next document.
if (yamlContent?.length) { for (const content of yamlContent) { let gvk: K8sGroupVersionKind | undefined = undefined; try { gvk = getGroupVersionKindForResource(content as K8sResourceCommon); - } catch (e) { + } catch (e) { + setError(`Failed to extract resource kind from document: ${getErrorMessage(e)}`); continue; } if (gvk) await k8sCreate({ model: models[`${gvk.group || 'core'}~${gvk.kind}~${gvk.version}`], data: content as K8sResourceCommon, }); + else { + setError('Could not determine resource type from YAML document. Please ensure the document includes kind, apiVersion, and metadata fields.'); + return; + } } }
137-140: Model lookup implementationThe model lookup uses a specific string format
${gvk.group || 'core'}~${gvk.kind}~${gvk.version}to identify the correct K8s model. Consider adding a comment to explain this format for future maintainers.if (gvk) await k8sCreate({ + // Models are keyed by "group~kind~version" in the models object provided by useK8sModels model: models[`${gvk.group || 'core'}~${gvk.kind}~${gvk.version}`], data: content as K8sResourceCommon, });libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (1)
68-72: Remove unnecessary FragmentThe Fragment wrapping the translation text is redundant since it only contains a single child element.
-<> {t( 'ai:This will determine for the infrastructure environment which kind of hosts would be able to be added. If the hosts that you want to add are using DHCP server, select this option, else, select the static IP.', )} -</>🧰 Tools
🪛 Biome (1.9.4)
[error] 68-72: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment(lint/complexity/noUselessFragments)
libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/InfraEnvDetails.tsx (2)
29-32: Route constants could be externalizedConsider moving these route constants to a separate constants file to improve reusability across components and centralize route definitions.
-const infraEnvironmentHosts = - '/multicloud/infrastructure/environments/details/:namespace/:name/hosts'; -const infraEnvironmentOverview = '/multicloud/infrastructure/environments/details/:namespace/:name';Create a new file
libs/ui-lib/lib/cim/config/routes.ts:export const ROUTES = { INFRA_ENV: { HOSTS: '/multicloud/infrastructure/environments/details/:namespace/:name/hosts', OVERVIEW: '/multicloud/infrastructure/environments/details/:namespace/:name', LIST: '/multicloud/infrastructure/environments' } };Then import and use these constants in this component.
89-96: Warning component nested in linkThe navigation includes an
InfraEnvHostsTabAgentsWarningcomponent inside a Link, which is an unconventional but functional approach. Consider refactoring to separate the warning from the navigation item for cleaner semantics.-<Link to={hostsPath}> - { - <> - <InfraEnvHostsTabAgentsWarning - infraAgents={infraAgents} - infraBMHs={infraBMHs} - /> - {t('ai:Hosts')} - </> - } -</Link> +<Link to={hostsPath}> + <span> + <InfraEnvHostsTabAgentsWarning + infraAgents={infraAgents} + infraBMHs={infraBMHs} + /> + {t('ai:Hosts')} + </span> +</Link>
🛑 Comments failed to post (1)
libs/ui-lib/lib/cim/utils.ts (1)
22-30: 🛠️ Refactor suggestion
appendPatchcannot remove existing valuesWhen
newValisundefined, the helper currently generates areplaceop withvalue: undefined, which the API rejects.
Emit aremoveoperation instead:- patches.push({ - op: existingVal ? 'replace' : 'add', - path, - value: newVal, - }); + patches.push( + newVal === undefined + ? { op: 'remove', path } + : { op: existingVal ? 'replace' : 'add', path, value: newVal }, + );This makes
appendPatchsafe for clearing optional fields.📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.export const appendPatch = <V>(patches: Patch[], path: string, newVal?: V, existingVal?: V) => { if (!isEqual(newVal, existingVal)) { patches.push( newVal === undefined ? { op: 'remove', path } : { op: existingVal ? 'replace' : 'add', path, value: newVal }, ); } };🤖 Prompt for AI Agents
In libs/ui-lib/lib/cim/utils.ts around lines 22 to 30, the appendPatch function incorrectly generates a 'replace' operation with value undefined when newVal is undefined, which the API rejects. Modify the function to emit a 'remove' operation instead of 'replace' or 'add' when newVal is undefined and existingVal is defined, ensuring it safely handles clearing optional fields.
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (3)
libs/ui-lib/lib/cim/utils.ts (2)
44-55:⚠️ Potential issue
/metadata/annotations/...patch should tolerate new annotationsWhen a BMH has no hostname annotation, the
replaceop fails. Swap toappendPatch.Apply this diff to fix the hostname annotation patch:
-export const onChangeBMHHostname = (bmh: BareMetalHostK8sResource, hostname: string) => - k8sPatch({ - model: BMHModel, - resource: bmh, - data: [ - { - op: 'replace', - path: `/metadata/annotations/${BMH_HOSTNAME_ANNOTATION.replace('/', '~1')}`, - value: hostname, - }, - ], - }); +export const onChangeBMHHostname = (bmh: BareMetalHostK8sResource, hostname: string) => { + const patches: Patch[] = []; + const annotationPath = `/metadata/annotations/${BMH_HOSTNAME_ANNOTATION.replace('/', '~1')}`; + const existingValue = bmh.metadata?.annotations?.[BMH_HOSTNAME_ANNOTATION]; + appendPatch(patches, annotationPath, hostname, existingValue); + return k8sPatch({ model: BMHModel, resource: bmh, data: patches }); +};
127-155:⚠️ Potential issuePrevent negative worker count in onUnbindHost
Similar to
onDeleteHost, this function decreasesworkerAgentswithout checking if the count goes below zero.Apply this diff to ensure the worker count doesn't go negative:
- const workerCount = (agentClusterInstall.spec?.provisionRequirements.workerAgents || 1) - 1; + const currentWorkers = agentClusterInstall.spec?.provisionRequirements.workerAgents || 1; + const workerCount = Math.max(0, currentWorkers - 1);libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts (1)
32-32: 🛠️ Refactor suggestionUnify
onMassDeleteHostsignature for a consistent APIThe two callbacks for deleting hosts use different conventions—one takes a single wrapper object, the other two positional params—making callers prone to parameter-swap bugs.
Align the signatures by updating
onMassDeleteHostto accept an array of host objects:- onMassDeleteHost: (agent?: AgentK8sResource, bmh?: BareMetalHostK8sResource) => Promise<unknown>; + // Accepts an array of the same wrapper used by `onDeleteHost` + onMassDeleteHost: ( + hosts: { agent?: AgentK8sResource; bmh?: BareMetalHostK8sResource }[], + ) => Promise<unknown>;
🧹 Nitpick comments (3)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (3)
68-72: Simplify by removing unnecessary FragmentThe Fragment wrapper here is redundant since it contains only a single child element. You can simplify this code by removing the Fragment tags.
- <> {t( 'ai:This will determine for the infrastructure environment which kind of hosts would be able to be added. If the hosts that you want to add are using DHCP server, select this option, else, select the static IP.', )} - </>🧰 Tools
🪛 Biome (1.9.4)
[error] 68-72: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment(lint/complexity/noUselessFragments)
126-126: Consider checking if osImages has itemsThe current check
!!osImageswill render the dropdown even if the array is empty. Consider checking for array length to avoid rendering the dropdown with no options.- {!!osImages && <InfraEnvOpenShiftVersionDropdown osImages={osImages} />} + {osImages && osImages.length > 0 && <InfraEnvOpenShiftVersionDropdown osImages={osImages} />}
100-114: Enhance security for external linkAdd
rel="noreferrer"to the window.open call for better security when opening external links.onClick={() => window.open( getOCPStaticIPDocLink(DOC_VERSION), '_blank', - 'noopener', + 'noopener noreferrer', ) }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting
⛔ Files ignored due to path filters (2)
libs/ui-lib/lib/cim/logos/OnPremiseBannerIcon.svgis excluded by!**/*.svgyarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (56)
libs/locales/lib/en/translation.json(38 hunks)libs/ui-lib/lib/cim/components/Agent/BMCForm.tsx(3 hunks)libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx(2 hunks)libs/ui-lib/lib/cim/components/Agent/types.ts(0 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostDiscoveryTable.tsx(4 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostsDiscovery.tsx(1 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentWizard.tsx(1 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts(3 hunks)libs/ui-lib/lib/cim/components/InfraEnv/AddHostDropdown.tsx(4 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvPage.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/useInfraEnvResources.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/EnvironmentDetails.tsx(4 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsx(7 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/AgentsTab.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/DetailsTab.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/InfraEnvDetails.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvFormPage.tsx(0 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.css(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.tsx(2 hunks)libs/ui-lib/lib/cim/components/InfraEnv/index.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/infra-env.css(0 hunks)libs/ui-lib/lib/cim/components/InfraEnv/types.ts(1 hunks)libs/ui-lib/lib/cim/components/YamlPreview/useYAMLPreview.ts(4 hunks)libs/ui-lib/lib/cim/components/common/InfoAndTroubleshootingNotification.tsx(1 hunks)libs/ui-lib/lib/cim/components/formik/CredentialsField.tsx(1 hunks)libs/ui-lib/lib/cim/components/helpers/agents.ts(2 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostModal.tsx(0 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlForm.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/AddHostModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/DeleteHostModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/EditBMHModal.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/EditNtpSourcesModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/EditProxyModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/EditPullSecretModal.tsx(4 hunks)libs/ui-lib/lib/cim/components/modals/EditSSHKeyModal.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/MassApproveAgentModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/MassDeleteAgentModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/ScaleUpModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/UnbindHostModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/types.ts(3 hunks)libs/ui-lib/lib/cim/config/constants.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useInfraEnvAgents.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useInfraEnvBMHs.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useInfraEnvNMStates.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts(1 hunks)libs/ui-lib/lib/cim/index.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/multi-cluster-engine.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/nm-state.ts(1 hunks)libs/ui-lib/lib/cim/types/models.ts(1 hunks)libs/ui-lib/lib/cim/utils.ts(1 hunks)libs/ui-lib/lib/ocm/components/Routes.tsx(1 hunks)libs/ui-lib/package.json(2 hunks)
💤 Files with no reviewable changes (4)
- libs/ui-lib/lib/cim/components/modals/AddBmcHostModal.tsx
- libs/ui-lib/lib/cim/components/Agent/types.ts
- libs/ui-lib/lib/cim/components/InfraEnv/infra-env.css
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvFormPage.tsx
✅ Files skipped from review due to trivial changes (2)
- libs/ui-lib/lib/cim/components/InfraEnv/types.ts
- libs/locales/lib/en/translation.json
🚧 Files skipped from review as they are similar to previous changes (47)
- libs/ui-lib/lib/cim/config/constants.ts
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/DetailsTab.tsx
- libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlForm.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.css
- libs/ui-lib/lib/cim/index.ts
- libs/ui-lib/lib/cim/components/helpers/agents.ts
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/index.ts
- libs/ui-lib/lib/cim/components/modals/EditProxyModal.tsx
- libs/ui-lib/lib/cim/types/k8s/nm-state.ts
- libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentWizard.tsx
- libs/ui-lib/package.json
- libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlModal.tsx
- libs/ui-lib/lib/cim/components/modals/EditBMHModal.tsx
- libs/ui-lib/lib/cim/hooks/useInfraEnvNMStates.ts
- libs/ui-lib/lib/ocm/components/Routes.tsx
- libs/ui-lib/lib/cim/hooks/useInfraEnvBMHs.ts
- libs/ui-lib/lib/cim/types/k8s/multi-cluster-engine.ts
- libs/ui-lib/lib/cim/components/modals/MassDeleteAgentModal.tsx
- libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx
- libs/ui-lib/lib/cim/hooks/useInfraEnvAgents.ts
- libs/ui-lib/lib/cim/components/YamlPreview/useYAMLPreview.ts
- libs/ui-lib/lib/cim/components/formik/CredentialsField.tsx
- libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts
- libs/ui-lib/lib/cim/components/modals/EditSSHKeyModal.tsx
- libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostsDiscovery.tsx
- libs/ui-lib/lib/cim/components/modals/EditPullSecretModal.tsx
- libs/ui-lib/lib/cim/components/modals/DeleteHostModal.tsx
- libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts
- libs/ui-lib/lib/cim/components/modals/ScaleUpModal.tsx
- libs/ui-lib/lib/cim/components/modals/MassApproveAgentModal.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/useInfraEnvResources.ts
- libs/ui-lib/lib/cim/components/modals/EditNtpSourcesModal.tsx
- libs/ui-lib/lib/cim/components/modals/AddHostModal.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/AddHostDropdown.tsx
- libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostDiscoveryTable.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/InfraEnvDetails.tsx
- libs/ui-lib/lib/cim/components/common/InfoAndTroubleshootingNotification.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts
- libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvPage.tsx
- libs/ui-lib/lib/cim/components/modals/types.ts
- libs/ui-lib/lib/cim/components/modals/UnbindHostModal.tsx
- libs/ui-lib/lib/cim/components/Agent/BMCForm.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/EnvironmentDetails.tsx
- libs/ui-lib/lib/cim/types/models.ts
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/AgentsTab.tsx
🧰 Additional context used
🧬 Code Graph Analysis (3)
libs/ui-lib/lib/cim/utils.ts (7)
libs/ui-lib/lib/cim/types/k8s/shared.ts (1)
StatusCondition(1-8)libs/ui-lib/lib/cim/types/k8s/agent.ts (1)
AgentK8sResource(32-74)libs/ui-lib/lib/cim/types/models.ts (4)
AgentModel(67-76)BMHModel(78-87)AgentClusterInstallModel(111-120)NMStateModel(89-98)libs/ui-lib/lib/cim/components/common/constants.ts (2)
BMH_HOSTNAME_ANNOTATION(20-20)AGENT_BMH_NAME_LABEL_KEY(12-12)libs/ui-lib/lib/cim/types/k8s/agent-cluster-install.ts (1)
AgentClusterInstallK8sResource(17-80)libs/ui-lib/lib/cim/types/k8s/nm-state.ts (1)
NMStateK8sResource(3-11)libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts (1)
InfraEnvK8sResource(8-42)
libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts (5)
libs/ui-lib/lib/cim/types/k8s/agent.ts (1)
AgentK8sResource(32-74)libs/ui-lib/lib/cim/components/Hypershift/types.ts (1)
AgentMachineK8sResource(186-193)libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts (1)
InfraEnvK8sResource(8-42)libs/ui-lib/lib/cim/types/k8s/nm-state.ts (1)
NMStateK8sResource(3-11)libs/ui-lib/lib/cim/types/k8s/agent-cluster-install.ts (1)
AgentClusterInstallK8sResource(17-80)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (4)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts (1)
EnvironmentStepFormValues(15-34)libs/ui-lib/lib/common/config/docs_links.ts (1)
getOCPStaticIPDocLink(62-63)libs/ui-lib/lib/cim/config/constants.ts (1)
DOC_VERSION(4-4)libs/ui-lib/lib/common/components/ui/formik/LabelField.tsx (1)
LabelField(34-100)
🪛 Biome (1.9.4)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx
[error] 68-72: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment
(lint/complexity/noUselessFragments)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: tests
🔇 Additional comments (10)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (1)
45-181: Good component structure and user experienceThe form is well-structured with appropriate helper texts, validation messages, and contextual information through popovers. The layout is clean and the use of conditional rendering for optional fields (like NTP sources) is effective.
🧰 Tools
🪛 Biome (1.9.4)
[error] 68-72: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment(lint/complexity/noUselessFragments)
libs/ui-lib/lib/cim/utils.ts (5)
22-30: Well-designed utility for conditional patchingThe
appendPatchutility is a clean approach that conditionally adds patches based on whether values exist and have changed, handling both 'add' and 'replace' operations appropriately. This will help prevent unnecessary updates and handle both new and existing fields consistently.
32-36: Good use of appendPatch for spec.approvedThe implementation correctly uses
appendPatchto handle both adding and replacing theapprovedfield, preventing potential 422 errors when the field doesn't exist.
38-42: Good use of appendPatch for hostname patchingThe implementation correctly uses
appendPatchto handle both adding and replacing the hostname, preventing potential errors when the field doesn't exist.
157-169: Good utility for filtering NMState resourcesThis function efficiently filters NMState resources based on label matching with InfraEnv's NMState label selector, which is a clean approach for finding associated resources.
171-172: Helpful platform detection utilityThe
isBMPlatformfunction provides a simple way to check if an infrastructure's platform is one of the supported bare metal types, which will be useful for conditional logic throughout the application.libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts (4)
30-30: Improved onDeleteHost signature with clearer parameter structureThe updated signature using a single object parameter with optional properties improves clarity and flexibility.
130-130: Simplified hostActions interface aligns with refactored componentsRemoving
onDeleteHostfromhostActionsreflects the wider refactoring where host deletion is now handled by the standaloneonDeleteHostutility function rather than through props.
165-172: Simplified InfraEnvAgentTableProps reflects internal state managementThe significant simplification of this type, removing many callback props, aligns with the broader refactoring approach where components now handle these actions internally using the centralized utility functions.
176-176: Simplified table props for better component encapsulationRemoving
onDeleteHostfrom the picked actions reflects the refactoring approach where deletion functionality is now handled internally using the dedicated utility functions.
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx
Show resolved
Hide resolved
f944c6f to
9167fcc
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (5)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (1)
140-148:atob()may throw → wrap intry/catchor validate upfront
atobraises aDOMExceptionon malformed base-64 strings (user may store arbitrary secrets).
The previous review already highlighted this – it is still unfixed.-onSelect={(cred) => { - setFieldValue( - 'pullSecret', - cred.data?.['pullSecret'] ? atob(cred.data['pullSecret']) : '', - ); - setFieldValue( - 'sshPublicKey', - cred.data?.['ssh-publickey'] ? atob(cred.data['ssh-publickey']) : '', - ); -}} +onSelect={(cred) => { + try { + setFieldValue( + 'pullSecret', + cred.data?.['pullSecret'] ? atob(cred.data['pullSecret']) : '', + ); + setFieldValue( + 'sshPublicKey', + cred.data?.['ssh-publickey'] ? atob(cred.data['ssh-publickey']) : '', + ); + } catch (e) { + console.error('Failed to decode credential data', e); + setFieldValue('pullSecret', ''); + setFieldValue('sshPublicKey', ''); + } +}}libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostDiscoveryTable.tsx (2)
206-213: GateDeleteHostModalrendering on watch completionRender the modal only when all required resources are loaded.
-{deleteHost && ( - <DeleteHostModal - {...deleteHost} - onClose={() => setDeleteHost(undefined)} - nmStates={nmStates} - agentClusterInstall={agentClusterInstall} - /> -)} +{deleteHost && nmStatesLoaded && aciLoaded && ( + <DeleteHostModal + {...deleteHost} + onClose={() => setDeleteHost(undefined)} + nmStates={nmStates} + agentClusterInstall={agentClusterInstall} + /> +)}
67-78: 🛠️ Refactor suggestionIgnore-loaded flags from watch hooks → modal can receive
undefineddataBoth hooks return
[data, loaded, error], but onlydatais captured.
If the user clicks “delete” before the watch finishes,DeleteHostModalreceives
undefinedresources and may crash.-const [nmStates] = useInfraEnvNMStates(infraEnv); -const [agentClusterInstall] = useK8sWatchResource<AgentClusterInstallK8sResource>({ +const [nmStates, nmStatesLoaded] = useInfraEnvNMStates(infraEnv); +const [agentClusterInstall, aciLoaded] = + useK8sWatchResource<AgentClusterInstallK8sResource>({libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts (1)
31-32:onMassDeleteHostsignature still inconsistent withonDeleteHostPrevious review suggested accepting a single hosts array (same wrapper object
used byonDeleteHost) to avoid parameter-swap bugs and simplify callers.
Consider aligning the APIs for consistency.libs/ui-lib/lib/cim/utils.ts (1)
44-55:⚠️ Potential issueFix
/metadata/annotations/...patch to handle new annotationsWhen a BMH has no hostname annotation, the
replaceoperation will fail. UseappendPatchto ensure the patch succeeds whether or not the annotation is present.Apply this diff to fix the issue:
-export const onChangeBMHHostname = (bmh: BareMetalHostK8sResource, hostname: string) => - k8sPatch({ - model: BMHModel, - resource: bmh, - data: [ - { - op: 'replace', - path: `/metadata/annotations/${BMH_HOSTNAME_ANNOTATION.replace('/', '~1')}`, - value: hostname, - }, - ], - }); +export const onChangeBMHHostname = (bmh: BareMetalHostK8sResource, hostname: string) => { + const patches: Patch[] = []; + const annotationPath = `/metadata/annotations/${BMH_HOSTNAME_ANNOTATION.replace('/', '~1')}`; + const currentValue = bmh.metadata?.annotations?.[BMH_HOSTNAME_ANNOTATION]; + appendPatch(patches, annotationPath, hostname, currentValue); + return k8sPatch({ + model: BMHModel, + resource: bmh, + data: patches, + }); +};
🧹 Nitpick comments (3)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (1)
68-74: Remove redundant fragment to satisfy linter and reduce DOM depth
<> … </>contains a single child, therefore the wrapper is unnecessary and triggersnoUselessFragmentsfrom Biome.
Keeping the text node directly is sufficient.-<> - {t( - 'ai:This will determine for the infrastructure environment which kind of hosts would be able to be added. If the hosts that you want to add are using DHCP server, select this option, else, select the static IP.', - )} -</> +{t( + 'ai:This will determine for the infrastructure environment which kind of hosts would be able to be added. If the hosts that you want to add are using DHCP server, select this option, else, select the static IP.', +)}🧰 Tools
🪛 Biome (1.9.4)
[error] 68-72: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment(lint/complexity/noUselessFragments)
libs/ui-lib/lib/cim/utils.ts (2)
57-81: Consider using appendPatch for individual propertiesCurrently, the function replaces the entire provisionRequirements object, which could overwrite other properties that might be present but not explicitly managed here.
Consider refactoring to use appendPatch for individual properties:
const setProvisionRequirements = ( agentClusterInstall: AgentClusterInstallK8sResource, workerCount: number | undefined, masterCount: number | undefined, ) => { - const provisionRequirements = { ...(agentClusterInstall.spec?.provisionRequirements || {}) }; - if (workerCount !== undefined) { - provisionRequirements.workerAgents = workerCount; - } - if (masterCount !== undefined) { - provisionRequirements.controlPlaneAgents = masterCount; - } - - return k8sPatch({ - model: AgentClusterInstallModel, - resource: agentClusterInstall, - data: [ - { - op: agentClusterInstall.spec?.provisionRequirements ? 'replace' : 'add', - path: '/spec/provisionRequirements', - value: provisionRequirements, - }, - ], - }); + const patches: Patch[] = []; + + // Ensure provisionRequirements exists + if (!agentClusterInstall.spec?.provisionRequirements) { + patches.push({ + op: 'add', + path: '/spec/provisionRequirements', + value: {}, + }); + } + + if (workerCount !== undefined) { + appendPatch( + patches, + '/spec/provisionRequirements/workerAgents', + workerCount, + agentClusterInstall.spec?.provisionRequirements?.workerAgents + ); + } + + if (masterCount !== undefined) { + appendPatch( + patches, + '/spec/provisionRequirements/controlPlaneAgents', + masterCount, + agentClusterInstall.spec?.provisionRequirements?.controlPlaneAgents + ); + } + + return k8sPatch({ + model: AgentClusterInstallModel, + resource: agentClusterInstall, + data: patches, + }); };
112-112: Consider clarifying or addressing the TODO commentThe TODO comment about handling mass delete lacks context and implementation plans.
Consider either:
- Adding more details about what mass delete should handle
- Creating a separate tracking issue/ticket for this TODO
- Implementing the mass delete functionality if it's needed
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting
⛔ Files ignored due to path filters (2)
libs/ui-lib/lib/cim/logos/OnPremiseBannerIcon.svgis excluded by!**/*.svgyarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (57)
libs/locales/lib/en/translation.json(38 hunks)libs/ui-lib-tests/cypress/integration/storage/storage-step-disk-holders.cy.ts(1 hunks)libs/ui-lib/lib/cim/components/Agent/BMCForm.tsx(3 hunks)libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx(2 hunks)libs/ui-lib/lib/cim/components/Agent/types.ts(0 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostDiscoveryTable.tsx(4 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostsDiscovery.tsx(1 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentWizard.tsx(1 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts(3 hunks)libs/ui-lib/lib/cim/components/InfraEnv/AddHostDropdown.tsx(4 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvPage.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/useInfraEnvResources.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/EnvironmentDetails.tsx(4 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsx(7 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/AgentsTab.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/DetailsTab.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/InfraEnvDetails.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvFormPage.tsx(0 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.css(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.tsx(2 hunks)libs/ui-lib/lib/cim/components/InfraEnv/index.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/infra-env.css(0 hunks)libs/ui-lib/lib/cim/components/InfraEnv/types.ts(1 hunks)libs/ui-lib/lib/cim/components/YamlPreview/useYAMLPreview.ts(4 hunks)libs/ui-lib/lib/cim/components/common/InfoAndTroubleshootingNotification.tsx(1 hunks)libs/ui-lib/lib/cim/components/formik/CredentialsField.tsx(1 hunks)libs/ui-lib/lib/cim/components/helpers/agents.ts(2 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostModal.tsx(0 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlForm.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/AddHostModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/DeleteHostModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/EditBMHModal.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/EditNtpSourcesModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/EditProxyModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/EditPullSecretModal.tsx(4 hunks)libs/ui-lib/lib/cim/components/modals/EditSSHKeyModal.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/MassApproveAgentModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/MassDeleteAgentModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/ScaleUpModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/UnbindHostModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/types.ts(2 hunks)libs/ui-lib/lib/cim/config/constants.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useInfraEnvAgents.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useInfraEnvBMHs.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useInfraEnvNMStates.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts(1 hunks)libs/ui-lib/lib/cim/index.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/multi-cluster-engine.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/nm-state.ts(1 hunks)libs/ui-lib/lib/cim/types/models.ts(1 hunks)libs/ui-lib/lib/cim/utils.ts(1 hunks)libs/ui-lib/lib/ocm/components/Routes.tsx(1 hunks)libs/ui-lib/package.json(2 hunks)
💤 Files with no reviewable changes (4)
- libs/ui-lib/lib/cim/components/modals/AddBmcHostModal.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/infra-env.css
- libs/ui-lib/lib/cim/components/Agent/types.ts
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvFormPage.tsx
✅ Files skipped from review due to trivial changes (3)
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.tsx
- libs/ui-lib/lib/cim/hooks/useInfraEnvBMHs.ts
- libs/ui-lib-tests/cypress/integration/storage/storage-step-disk-holders.cy.ts
🚧 Files skipped from review as they are similar to previous changes (45)
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.css
- libs/ui-lib/lib/cim/config/constants.ts
- libs/ui-lib/lib/cim/types/k8s/multi-cluster-engine.ts
- libs/ui-lib/package.json
- libs/ui-lib/lib/cim/types/k8s/nm-state.ts
- libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlModal.tsx
- libs/ui-lib/lib/cim/index.ts
- libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts
- libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx
- libs/ui-lib/lib/ocm/components/Routes.tsx
- libs/ui-lib/lib/cim/components/modals/ScaleUpModal.tsx
- libs/ui-lib/lib/cim/components/modals/MassDeleteAgentModal.tsx
- libs/ui-lib/lib/cim/components/modals/MassApproveAgentModal.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/DetailsTab.tsx
- libs/ui-lib/lib/cim/components/modals/EditSSHKeyModal.tsx
- libs/ui-lib/lib/cim/components/modals/AddHostModal.tsx
- libs/ui-lib/lib/cim/hooks/useInfraEnvNMStates.ts
- libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/useInfraEnvResources.ts
- libs/ui-lib/lib/cim/components/modals/EditBMHModal.tsx
- libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentWizard.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/types.ts
- libs/ui-lib/lib/cim/hooks/useInfraEnvAgents.ts
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/AgentsTab.tsx
- libs/ui-lib/lib/cim/components/YamlPreview/useYAMLPreview.ts
- libs/ui-lib/lib/cim/components/modals/DeleteHostModal.tsx
- libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts
- libs/ui-lib/lib/cim/components/modals/EditPullSecretModal.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvPage.tsx
- libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlForm.tsx
- libs/ui-lib/lib/cim/components/modals/UnbindHostModal.tsx
- libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostsDiscovery.tsx
- libs/ui-lib/lib/cim/components/formik/CredentialsField.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/AddHostDropdown.tsx
- libs/ui-lib/lib/cim/components/helpers/agents.ts
- libs/ui-lib/lib/cim/components/common/InfoAndTroubleshootingNotification.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/InfraEnvDetails.tsx
- libs/ui-lib/lib/cim/components/modals/EditNtpSourcesModal.tsx
- libs/ui-lib/lib/cim/components/Agent/BMCForm.tsx
- libs/ui-lib/lib/cim/components/modals/EditProxyModal.tsx
- libs/ui-lib/lib/cim/components/modals/types.ts
- libs/ui-lib/lib/cim/components/InfraEnv/EnvironmentDetails.tsx
- libs/ui-lib/lib/cim/types/models.ts
- libs/locales/lib/en/translation.json
- libs/ui-lib/lib/cim/components/InfraEnv/index.ts
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsx
🧰 Additional context used
🧬 Code Graph Analysis (3)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts (3)
libs/ui-lib-tests/cypress/fixtures/infra-envs/openshift-versions.ts (2)
x86(8-8)s390x(10-10)libs/ui-lib/lib/common/components/ui/formik/validationSchemas.ts (7)
richNameValidationSchema(456-489)locationValidationSchema(654-679)pullSecretValidationSchema(143-162)sshPublicKeyValidationSchema(105-115)httpProxyValidationSchema(534-573)noProxyValidationSchema(587-602)ntpSourceValidationSchema(604-627)libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts (1)
InfraEnvK8sResource(8-42)
libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts (5)
libs/ui-lib/lib/cim/types/k8s/agent.ts (1)
AgentK8sResource(32-74)libs/ui-lib/lib/cim/components/Hypershift/types.ts (1)
AgentMachineK8sResource(186-193)libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts (1)
InfraEnvK8sResource(8-42)libs/ui-lib/lib/cim/types/k8s/nm-state.ts (1)
NMStateK8sResource(3-11)libs/ui-lib/lib/cim/types/k8s/agent-cluster-install.ts (1)
AgentClusterInstallK8sResource(17-80)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (4)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts (1)
EnvironmentStepFormValues(15-34)libs/ui-lib/lib/common/config/docs_links.ts (1)
getOCPStaticIPDocLink(62-63)libs/ui-lib/lib/cim/config/constants.ts (1)
DOC_VERSION(4-4)libs/ui-lib/lib/common/components/ui/formik/LabelField.tsx (1)
LabelField(34-100)
🪛 Biome (1.9.4)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx
[error] 68-72: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment
(lint/complexity/noUselessFragments)
⏰ Context from checks skipped due to timeout of 90000ms (2)
- GitHub Check: tests
- GitHub Check: lint
🔇 Additional comments (1)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts (1)
110-117:locationstring is used as a Kubernetes label value – verify it meets the label RFC
metadata.labels['agentclusterinstalls.extensions.hive.openshift.io/location'] = values.locationKubernetes label values must match
[a-z0-9A-Z]([-a-z0-9A-Z_.]*[a-z0-9A-Z])?and ≤ 63 chars.
IflocationValidationSchemaallows spaces or uppercase characters, resource
creation will fail.Please ensure the schema enforces the label value constraints or transform the
value (e.g. slugify / lowercase / replace spaces).
There was a problem hiding this comment.
Actionable comments posted: 1
🔭 Outside diff range comments (1)
libs/ui-lib/lib/cim/utils.ts (1)
1-177:⚠️ Potential issueMissing onMassDeleteHost implementation
The
onMassDeleteHostfunction is defined in the types file but missing from this utility file. This could lead to runtime errors.Add an implementation of
onMassDeleteHostthat accepts an array of host objects:export const onMassDeleteHost = async ( hosts: { agent?: AgentK8sResource; bmh?: BareMetalHostK8sResource }[], agentClusterInstall?: AgentClusterInstallK8sResource, nmStates: NMStateK8sResource[] = [], ) => { for (const host of hosts) { await onDeleteHost(host.agent, host.bmh, agentClusterInstall, nmStates); } };Ensure you also update all calling code to use the new signature.
♻️ Duplicate comments (4)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (1)
140-148:⚠️ Potential issueAdd error handling for base64 decoding.
The
atob()function can throw exceptions if the input isn't properly base64-encoded. Add try-catch blocks to handle potential decoding errors.onSelect={(cred) => { - setFieldValue( - 'pullSecret', - cred.data?.['pullSecret'] ? atob(cred.data['pullSecret']) : '', - ); - setFieldValue( - 'sshPublicKey', - cred.data?.['ssh-publickey'] ? atob(cred.data['ssh-publickey']) : '', - ); + try { + setFieldValue( + 'pullSecret', + cred.data?.['pullSecret'] ? atob(cred.data['pullSecret']) : '', + ); + setFieldValue( + 'sshPublicKey', + cred.data?.['ssh-publickey'] ? atob(cred.data['ssh-publickey']) : '', + ); + } catch (error) { + console.error('Failed to decode credential data:', error); + // Consider showing a user-friendly error message here + } }}libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostDiscoveryTable.tsx (1)
211-218:⚠️ Potential issueConditional rendering of DeleteHostModal needs loading check.
The DeleteHostModal should only be rendered when both resources are fully loaded to avoid passing undefined values to the modal.
- {deleteHost && ( + {deleteHost && nmLoaded && aciLoaded && ( <DeleteHostModal {...deleteHost} onClose={() => setDeleteHost(undefined)} nmStates={nmStates} agentClusterInstall={agentClusterInstall} /> )}libs/ui-lib/lib/cim/utils.ts (2)
44-55: 🛠️ Refactor suggestionUse appendPatch for BMH hostname annotation
The current implementation uses a direct 'replace' operation which will fail if the annotation doesn't exist. Use
appendPatchfor consistency and to avoid potential errors.export const onChangeBMHHostname = (bmh: BareMetalHostK8sResource, hostname: string) => k8sPatch({ model: BMHModel, resource: bmh, - data: [ - { - op: 'replace', - path: `/metadata/annotations/${BMH_HOSTNAME_ANNOTATION.replace('/', '~1')}`, - value: hostname, - }, - ], + data: (() => { + const patches: Patch[] = []; + const annotationPath = `/metadata/annotations/${BMH_HOSTNAME_ANNOTATION.replace('/', '~1')}`; + const currentValue = bmh.metadata?.annotations?.[BMH_HOSTNAME_ANNOTATION]; + appendPatch(patches, annotationPath, hostname, currentValue); + return patches; + })(), });
127-159: 🛠️ Refactor suggestionRefactor onUnbindHost to use appendPatch
The current implementation uses direct 'replace' operations which could fail if properties don't exist. Use
appendPatchfor consistency and to avoid potential errors.export const onUnbindHost = async ( agent: AgentK8sResource, agentClusterInstall?: AgentClusterInstallK8sResource, ) => { if (agent.spec?.clusterDeploymentName?.name) { if (agentClusterInstall) { const masterCount = undefined; /* Only workers can be removed */ const workerCount = agentClusterInstall.spec?.provisionRequirements.workerAgents || 1; await setProvisionRequirements( agentClusterInstall, Math.max(0, workerCount - 1), masterCount, ); } - await k8sPatch({ - model: AgentModel, - resource: agent, - data: [ - { - op: 'replace', - path: '/spec/clusterDeploymentName', - value: null, - }, - { - op: 'replace', - path: '/spec/role', - value: '', - }, - ], - }); + const patches: Patch[] = []; + appendPatch(patches, '/spec/clusterDeploymentName', null, agent.spec.clusterDeploymentName); + appendPatch(patches, '/spec/role', '', agent.spec.role); + + await k8sPatch({ + model: AgentModel, + resource: agent, + data: patches, + }); } };
🧹 Nitpick comments (8)
libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts (6)
13-19: The hook changes the loading behavior when errors occur.The implementation overrides the
loadedstate totruewhen an error is present. This means consumers cannot distinguish between "successfully loaded" and "errored" states by checking theloadedvalue alone - they must also check theerrorvalue.Consider whether this behavior is intentional and well-documented for consumers of this hook.
export const useK8sWatchResource = <R extends K8sResourceCommon | K8sResourceCommon[]>( props: WatchK8sResource | null, ): WatchK8sResult<R> => { // eslint-disable-next-line const [data, loaded, error] = consoleWatch<R>(props); - return [data, !!error ? true : loaded, error as unknown]; + return [data, loaded, error as unknown]; // Or if the override is intentional, consider adding a comment explaining why: // return [data, !!error ? true : loaded, error as unknown]; // Force loaded=true when error exists to prevent loading indicators when we can show error state };🧰 Tools
🪛 Biome (1.9.4)
[error] 18-18: Avoid redundant double-negation.
It is not necessary to use double-negation when a value will already be coerced to a boolean.
Unsafe fix: Remove redundant double-negation(lint/complexity/noExtraBooleanCast)
16-17: Remove or clarify the ESLint disable comment.The ESLint disable comment doesn't specify which rule is being disabled. For better maintainability, either specify the exact rule being disabled or add a comment explaining why the disable is necessary.
- // eslint-disable-next-line + // eslint-disable-next-line @typescript-eslint/no-explicit-any const [data, loaded, error] = consoleWatch<R>(props);
18-18: Simplify boolean conversion.The double negation (
!!error) is redundant in the ternary expression as the expression will coerce to a boolean anyway.- return [data, !!error ? true : loaded, error as unknown]; + return [data, error ? true : loaded, error as unknown];🧰 Tools
🪛 Biome (1.9.4)
[error] 18-18: Avoid redundant double-negation.
It is not necessary to use double-negation when a value will already be coerced to a boolean.
Unsafe fix: Remove redundant double-negation(lint/complexity/noExtraBooleanCast)
1-19: Consider adding documentation.This hook performs a specialized function with some behavioral nuances (like changing loading state when errors occur). Adding JSDoc comments would help users understand its purpose and behavior clearly.
+/** + * A typed wrapper around the OpenShift Console SDK's useK8sWatchResource hook. + * @param props - The resource configuration to watch, or null + * @returns A tuple containing: + * - The watched resource data + * - A boolean indicating if data is loaded (true if error is present) + * - Any error that occurred during the watch + */ export const useK8sWatchResource = <R extends K8sResourceCommon | K8sResourceCommon[]>( props: WatchK8sResource | null, ): WatchK8sResult<R> => {🧰 Tools
🪛 Biome (1.9.4)
[error] 18-18: Avoid redundant double-negation.
It is not necessary to use double-negation when a value will already be coerced to a boolean.
Unsafe fix: Remove redundant double-negation(lint/complexity/noExtraBooleanCast)
7-11: Add JSDoc to the exported type.Since this type is exported, adding documentation would improve its usability for other developers.
+/** + * Represents the result of watching a Kubernetes resource. + * @template R - The type of resource being watched + */ export type WatchK8sResult<R extends K8sResourceCommon | K8sResourceCommon[]> = [ R, boolean, unknown, ];
3-5: Consider re-exporting the imported types.Since these types are used in the hook's signature, consider re-exporting them to make them available to consumers of this module without requiring them to import from the OpenShift SDK directly.
import { useK8sWatchResource as consoleWatch, K8sResourceCommon, WatchK8sResource, } from '@openshift-console/dynamic-plugin-sdk'; +export { K8sResourceCommon, WatchK8sResource };libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (1)
68-72: Remove unnecessary Fragment.This Fragment is redundant as it contains only one child element and can be removed.
- <> {t( 'ai:This will determine for the infrastructure environment which kind of hosts would be able to be added. If the hosts that you want to add are using DHCP server, select this option, else, select the static IP.', )} - </>🧰 Tools
🪛 Biome (1.9.4)
[error] 68-72: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment(lint/complexity/noUselessFragments)
libs/ui-lib/lib/cim/utils.ts (1)
112-112: Remove stale TODO commentThe TODO comment about handling mass delete is now addressed by implementing the
onMassDeleteHostfunction.- // TODO handle mass delete
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting
⛔ Files ignored due to path filters (2)
libs/ui-lib/lib/cim/logos/OnPremiseBannerIcon.svgis excluded by!**/*.svgyarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (57)
libs/locales/lib/en/translation.json(38 hunks)libs/ui-lib-tests/cypress/integration/storage/storage-step-disk-holders.cy.ts(1 hunks)libs/ui-lib/lib/cim/components/Agent/BMCForm.tsx(3 hunks)libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx(2 hunks)libs/ui-lib/lib/cim/components/Agent/types.ts(0 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostDiscoveryTable.tsx(6 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostsDiscovery.tsx(1 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentWizard.tsx(1 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts(3 hunks)libs/ui-lib/lib/cim/components/InfraEnv/AddHostDropdown.tsx(4 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvPage.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/useInfraEnvResources.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/EnvironmentDetails.tsx(4 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsx(7 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/AgentsTab.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/DetailsTab.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/InfraEnvDetails.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvFormPage.tsx(0 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.css(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.tsx(2 hunks)libs/ui-lib/lib/cim/components/InfraEnv/index.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/infra-env.css(0 hunks)libs/ui-lib/lib/cim/components/InfraEnv/types.ts(1 hunks)libs/ui-lib/lib/cim/components/YamlPreview/useYAMLPreview.ts(4 hunks)libs/ui-lib/lib/cim/components/common/InfoAndTroubleshootingNotification.tsx(1 hunks)libs/ui-lib/lib/cim/components/formik/CredentialsField.tsx(1 hunks)libs/ui-lib/lib/cim/components/helpers/agents.ts(2 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostModal.tsx(0 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlForm.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/AddHostModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/DeleteHostModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/EditBMHModal.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/EditNtpSourcesModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/EditProxyModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/EditPullSecretModal.tsx(4 hunks)libs/ui-lib/lib/cim/components/modals/EditSSHKeyModal.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/MassApproveAgentModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/MassDeleteAgentModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/ScaleUpModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/UnbindHostModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/types.ts(2 hunks)libs/ui-lib/lib/cim/config/constants.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useInfraEnvAgents.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useInfraEnvBMHs.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useInfraEnvNMStates.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts(1 hunks)libs/ui-lib/lib/cim/index.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/multi-cluster-engine.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/nm-state.ts(1 hunks)libs/ui-lib/lib/cim/types/models.ts(1 hunks)libs/ui-lib/lib/cim/utils.ts(1 hunks)libs/ui-lib/lib/ocm/components/Routes.tsx(1 hunks)libs/ui-lib/package.json(2 hunks)
💤 Files with no reviewable changes (4)
- libs/ui-lib/lib/cim/components/InfraEnv/infra-env.css
- libs/ui-lib/lib/cim/components/modals/AddBmcHostModal.tsx
- libs/ui-lib/lib/cim/components/Agent/types.ts
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvFormPage.tsx
✅ Files skipped from review due to trivial changes (3)
- libs/ui-lib-tests/cypress/integration/storage/storage-step-disk-holders.cy.ts
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.tsx
- libs/locales/lib/en/translation.json
🚧 Files skipped from review as they are similar to previous changes (43)
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.css
- libs/ui-lib/lib/cim/config/constants.ts
- libs/ui-lib/lib/cim/types/k8s/nm-state.ts
- libs/ui-lib/lib/cim/components/modals/AddHostModal.tsx
- libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlModal.tsx
- libs/ui-lib/package.json
- libs/ui-lib/lib/cim/components/modals/EditNtpSourcesModal.tsx
- libs/ui-lib/lib/cim/index.ts
- libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts
- libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/useInfraEnvResources.ts
- libs/ui-lib/lib/cim/hooks/useInfraEnvAgents.ts
- libs/ui-lib/lib/cim/types/k8s/multi-cluster-engine.ts
- libs/ui-lib/lib/cim/hooks/useInfraEnvNMStates.ts
- libs/ui-lib/lib/cim/components/InfraEnv/index.ts
- libs/ui-lib/lib/cim/components/modals/EditBMHModal.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/types.ts
- libs/ui-lib/lib/cim/hooks/useInfraEnvBMHs.ts
- libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx
- libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentWizard.tsx
- libs/ui-lib/lib/ocm/components/Routes.tsx
- libs/ui-lib/lib/cim/components/modals/EditSSHKeyModal.tsx
- libs/ui-lib/lib/cim/components/modals/MassDeleteAgentModal.tsx
- libs/ui-lib/lib/cim/components/modals/MassApproveAgentModal.tsx
- libs/ui-lib/lib/cim/components/common/InfoAndTroubleshootingNotification.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/AgentsTab.tsx
- libs/ui-lib/lib/cim/components/Agent/BMCForm.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/DetailsTab.tsx
- libs/ui-lib/lib/cim/components/modals/EditProxyModal.tsx
- libs/ui-lib/lib/cim/components/helpers/agents.ts
- libs/ui-lib/lib/cim/components/InfraEnv/AddHostDropdown.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts
- libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostsDiscovery.tsx
- libs/ui-lib/lib/cim/components/modals/ScaleUpModal.tsx
- libs/ui-lib/lib/cim/types/models.ts
- libs/ui-lib/lib/cim/components/formik/CredentialsField.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvPage.tsx
- libs/ui-lib/lib/cim/components/YamlPreview/useYAMLPreview.ts
- libs/ui-lib/lib/cim/components/modals/UnbindHostModal.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/InfraEnvDetails.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsx
- libs/ui-lib/lib/cim/components/modals/EditPullSecretModal.tsx
- libs/ui-lib/lib/cim/components/modals/types.ts
- libs/ui-lib/lib/cim/components/InfraEnv/EnvironmentDetails.tsx
🧰 Additional context used
🧬 Code Graph Analysis (2)
libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts (5)
libs/ui-lib/lib/cim/types/k8s/agent.ts (1)
AgentK8sResource(32-74)libs/ui-lib/lib/cim/components/Hypershift/types.ts (1)
AgentMachineK8sResource(186-193)libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts (1)
InfraEnvK8sResource(8-42)libs/ui-lib/lib/cim/types/k8s/nm-state.ts (1)
NMStateK8sResource(3-11)libs/ui-lib/lib/cim/types/k8s/agent-cluster-install.ts (1)
AgentClusterInstallK8sResource(17-80)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (5)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts (1)
EnvironmentStepFormValues(15-34)libs/ui-lib/lib/common/hooks/index.ts (1)
useTranslation(3-3)libs/ui-lib/lib/common/config/docs_links.ts (1)
getOCPStaticIPDocLink(62-63)libs/ui-lib/lib/cim/config/constants.ts (1)
DOC_VERSION(4-4)libs/ui-lib/lib/common/components/ui/formik/LabelField.tsx (1)
LabelField(34-100)
🪛 Biome (1.9.4)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx
[error] 68-72: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment
(lint/complexity/noUselessFragments)
libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts
[error] 18-18: Avoid redundant double-negation.
It is not necessary to use double-negation when a value will already be coerced to a boolean.
Unsafe fix: Remove redundant double-negation
(lint/complexity/noExtraBooleanCast)
⏰ Context from checks skipped due to timeout of 90000ms (3)
- GitHub Check: tests
- GitHub Check: lint
- GitHub Check: format
🔇 Additional comments (26)
libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlForm.tsx (4)
23-29: Good job refactoring to use the OpenShift Console SDK directly.The imports from the dynamic plugin SDK are appropriate for the new internal resource creation approach, providing a more direct implementation.
39-39: Props interface simplified appropriately.Removing the
onCreateBmcByYamlcallback prop simplifies the component interface, aligning with the PR objective to decouple components and centralize resource creation logic.
44-44: Type change ensures correct handling of multiple YAML documents.Good adjustment of the
yamlContentstate type to explicitly handle an array of parsed YAML documents.
120-140:Details
✅ Verification successful
Resource creation implementation handles multiple document types efficiently.
The direct resource creation approach with group-version-kind detection is an improvement over the previous callback approach. This implementation correctly:
- Extracts the GVK information from each document
- Uses the appropriate model from the models collection
- Handles potential errors gracefully for each document
🏁 Script executed:
#!/bin/bash # Verify error handling across similar resource creation workflows in the codebase # Look for similar k8sCreate patterns in the codebase to ensure consistent approach rg "k8sCreate\s*\(\s*\{" --type=tsx --type=ts -C 2 libs/ui-libLength of output: 92
🏁 Script executed:
#!/bin/bash # Re-run search for k8sCreate usage without type restrictions to ensure we catch tsx files too rg "k8sCreate\s*\(\s*\{" -n libs/ui-libLength of output: 888
🏁 Script executed:
#!/bin/bash # Inspect k8sCreate usage and surrounding error handling in BMCForm.tsx rg -n -C 5 "await k8sCreate" libs/ui-lib/lib/cim/components/Agent/BMCForm.tsx # Inspect k8sCreate usage and surrounding error handling in CreateInfraEnvPage.tsx rg -n -C 5 "await k8sCreate" libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvPage.tsxLength of output: 1343
🏁 Script executed:
#!/bin/bash # Inspect handleSubmit and error handling in BMCForm.tsx rg -n -C 10 "handleSubmit" libs/ui-lib/lib/cim/components/Agent/BMCForm.tsx # Search for try/catch blocks wrapping k8sCreate in BMCForm.tsx rg -n -C 10 "try" libs/ui-lib/lib/cim/components/Agent/BMCForm.tsxLength of output: 2131
🏁 Script executed:
#!/bin/bash # Inspect the handleSubmit implementation and error handling in AddBmcHostYamlForm.tsx rg -n -C 10 "const handleSubmit" libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlForm.tsx # Look for catch blocks to confirm error handling strategy rg -n -C 5 "catch" libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlForm.tsxLength of output: 2529
Approve multi-document resource creation flow
The AddBmcHostYamlForm implementation aligns with existing k8sCreate patterns in the codebase—extracting GVK per document, selecting the correct model, and wrapping operations in a global try/catch (with a fine-grained getGroupVersionKindForResource guard). This matches error-handling in BMCForm.tsx and CreateInfraEnvPage.tsx, so no further changes are needed.libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (2)
36-40: Type definition for component props is well structured.The props interface clearly defines the required data for the form component, making it easy to understand what inputs are needed.
107-115: Good documentation link handling with version from constants.Using the DOC_VERSION constant from config ensures consistent documentation references across the application. This approach makes it easier to update documentation links when new versions are released.
libs/ui-lib/lib/cim/components/modals/DeleteHostModal.tsx (4)
13-25: Well-defined props interface for the modal.The component defines a clear interface with optional and required props, properly typed for type safety. Using optional types for agent and bmh accommodates different deletion scenarios.
30-41: Properly implemented deletion workflow with error handling.The deletion process includes:
- Setting initial state (clearing errors and setting deleting status)
- Try-catch block for error handling
- Proper cleanup in the finally block
This ensures robust error handling and consistent UI state management.
43-63: Modal actions are disabled during deletion.Good UX implementation by disabling both confirm and cancel buttons during deletion, preventing multiple submissions. Using
isLoadingon the confirm button provides visual feedback during the operation.
67-67: Use the agent or bmh name for deletion confirmation.The modal correctly displays the name of the resource being deleted by using the
getAgentNameutility function, which handles both agent and BMH resources.libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostDiscoveryTable.tsx (5)
38-48: Appropriate imports for resource handling and routing.The added imports support the component's new responsibility for fetching and managing resources directly rather than relying on callbacks.
60-63: Well-typed state for host deletion.The deletion state properly captures either an agent or BMH resource to be deleted, supporting both host types.
68-78: Directly fetches required resources using hooks.Good use of hooks to fetch NMStates and AgentClusterInstall resources. The component correctly extracts loaded states from the hooks for use in rendering conditions.
98-98: Simplified table hook configuration with internal deletion handler.Good refactoring of the useAgentsTable hook configuration to use the internal state setter for deletion instead of an external callback.
199-199: Simplified hostname change handling.Direct use of the onAgentChangeHostname utility function eliminates unnecessary callback prop passing, aligning with the overall component decoupling objective.
libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts (4)
129-129: LGTM: Reduced prop surface simplifies component integrationThe
hostActionsproperty now only includes essential editing actions, which simplifies the component interface. This is consistent with moving host deletion functionality to the centralized utility functions.
164-171: LGTM: Simplified InfraEnvAgentTableProps with direct property listingRemoving the
Pick<AgentTableActions>inheritance in favor of directly listing required properties makes the component's dependencies more explicit and easier to understand.
173-176: LGTM: Narrowed table props to essential actionsRemoving deletion-related actions from the table props aligns with the centralization of deletion logic in utility functions.
29-31:Details
❓ Verification inconclusive
Inconsistent parameter patterns between related functions
The
onDeleteHostfunction now accepts a wrapper object{ agent?, bmh? }whileonMassDeleteHoststill uses separate parameters. This inconsistency makes the API less predictable and could lead to parameter-swap errors.onDeleteHost: (host: { agent?: AgentK8sResource; bmh?: BareMetalHostK8sResource }) => void; onSetInstallationDiskId: (agent: AgentK8sResource, diskId: string) => Promise<AgentK8sResource>; - onMassDeleteHost: (agent?: AgentK8sResource, bmh?: BareMetalHostK8sResource) => Promise<unknown>; + onMassDeleteHost: (hosts: { agent?: AgentK8sResource; bmh?: BareMetalHostK8sResource }[]) => Promise<unknown>;
🏁 Script executed:
#!/bin/bash # Verify how onMassDeleteHost is called in the codebase rg -n "onMassDeleteHost\(" --type tsLength of output: 38
Inconsistent parameter patterns between onDeleteHost and onMassDeleteHost
We’ve updatedonDeleteHostto accept a single object{ agent?, bmh? }, butonMassDeleteHoststill takes two separate parameters—this asymmetry can lead to swapped-argument bugs. To keep the API predictable, align both signatures:onDeleteHost: (host: { agent?: AgentK8sResource; bmh?: BareMetalHostK8sResource }) => void; onSetInstallationDiskId: (agent: AgentK8sResource, diskId: string) => Promise<AgentK8sResource>; - onMassDeleteHost: (agent?: AgentK8sResource, bmh?: BareMetalHostK8sResource) => Promise<unknown>; + onMassDeleteHost: (hosts: { agent?: AgentK8sResource; bmh?: BareMetalHostK8sResource }[]) => Promise<unknown>;Please verify and update all call sites of
onMassDeleteHostto match this new signature and ensure no regressions.libs/ui-lib/lib/cim/utils.ts (7)
1-14: LGTM: Well-organized imports with clear separationThe imports are well organized with clear separation between SDK imports, local type imports, and external utilities.
22-30: LGTM: Useful utility for conditional patchingThe
appendPatchfunction intelligently chooses between 'add' and 'replace' operations based on whether the value already exists, preventing common K8s API errors.
32-36: LGTM: Robust agent approval implementationUsing
appendPatchensures the function works correctly regardless of whetherspec.approvedalready exists in the agent resource.
38-42: LGTM: Hostname change function with proper patchingUsing
appendPatchensures the function works correctly regardless of whetherspec.hostnamealready exists in the agent resource.
83-118: LGTM: Comprehensive host deletion with safeguardsThe
onDeleteHostfunction properly handles:
- Agent resource deletion
- BareMetalHost resource deletion
- Associated NMState resources cleanup
- Worker count adjustment with protection against negative values
This centralized utility simplifies component implementations.
161-173: LGTM: Well-implemented NMState filtering utilityThe
getInfraEnvNMStatesfunction correctly handles null cases and usesisMatchfor proper label selector matching.
175-176: LGTM: Simple platform detection utilityThe
isBMPlatformfunction provides a clean way to check for bare metal-related platforms.
libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostDiscoveryTable.tsx
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (5)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (1)
140-148:⚠️ Potential issueAdd error handling for base64 decoding
The
atob()function can throw exceptions if the input isn't properly base64-encoded. Consider adding try/catch blocks to handle potential decoding errors.onSelect={(cred) => { - setFieldValue( - 'pullSecret', - cred.data?.['pullSecret'] ? atob(cred.data['pullSecret']) : '', - ); - setFieldValue( - 'sshPublicKey', - cred.data?.['ssh-publickey'] ? atob(cred.data['ssh-publickey']) : '', - ); + try { + setFieldValue( + 'pullSecret', + cred.data?.['pullSecret'] ? atob(cred.data['pullSecret']) : '', + ); + setFieldValue( + 'sshPublicKey', + cred.data?.['ssh-publickey'] ? atob(cred.data['ssh-publickey']) : '', + ); + } catch (error) { + console.error('Failed to decode credential data:', error); + // Consider showing a user-friendly error message here + } }}libs/ui-lib/lib/cim/utils.ts (2)
44-55:⚠️ Potential issue
/metadata/annotations/...patch should tolerate new annotationsWhen a BMH has no hostname annotation, the
replaceop fails. Swap toappendPatch.Apply this pattern to ensure the patch works whether or not the annotation exists:
-export const onChangeBMHHostname = (bmh: BareMetalHostK8sResource, hostname: string) => - k8sPatch({ - model: BMHModel, - resource: bmh, - data: [ - { - op: 'replace', - path: `/metadata/annotations/${BMH_HOSTNAME_ANNOTATION.replace('/', '~1')}`, - value: hostname, - }, - ], - }); +export const onChangeBMHHostname = (bmh: BareMetalHostK8sResource, hostname: string) => { + const patches: Patch[] = []; + const annotationPath = `/metadata/annotations/${BMH_HOSTNAME_ANNOTATION.replace('/', '~1')}`; + const hasAnnotation = bmh.metadata?.annotations && BMH_HOSTNAME_ANNOTATION in bmh.metadata.annotations; + + patches.push({ + op: hasAnnotation ? 'replace' : 'add', + path: annotationPath, + value: hostname, + }); + + return k8sPatch({ + model: BMHModel, + resource: bmh, + data: patches, + }); +};
127-159: 🛠️ Refactor suggestionRefactor onUnbindHost to use appendPatch
The current implementation uses direct 'replace' operations which could fail if properties don't exist. Also, the two patches could be combined into a single array.
Apply this diff to improve the function:
export const onUnbindHost = async ( agent: AgentK8sResource, agentClusterInstall?: AgentClusterInstallK8sResource, ) => { if (agent.spec?.clusterDeploymentName?.name) { if (agentClusterInstall) { const masterCount = undefined; /* Only workers can be removed */ const workerCount = agentClusterInstall.spec?.provisionRequirements.workerAgents || 1; await setProvisionRequirements( agentClusterInstall, Math.max(0, workerCount - 1), masterCount, ); } - await k8sPatch({ - model: AgentModel, - resource: agent, - data: [ - { - op: 'replace', - path: '/spec/clusterDeploymentName', - value: null, - }, - { - op: 'replace', - path: '/spec/role', - value: '', - }, - ], - }); + const patches: Patch[] = []; + appendPatch(patches, '/spec/clusterDeploymentName', null, agent.spec.clusterDeploymentName); + appendPatch(patches, '/spec/role', '', agent.spec.role); + + await k8sPatch({ + model: AgentModel, + resource: agent, + data: patches, + }); } };libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts (2)
129-129: SimplifiedhostActionsinterfaceThe
hostActionsproperty inClusterDeploymentWizardPropshas been correctly narrowed to only include the necessary actions. This is a good simplification that reduces the API surface.
31-31: 🛠️ Refactor suggestionUnify API signatures between
onDeleteHostandonMassDeleteHostWhile
onDeleteHostnow accepts a single wrapper object,onMassDeleteHoststill uses two positional parameters. These inconsistent signatures for similar operations could lead to confusion and errors.Consider aligning these signatures by changing
onMassDeleteHostto accept an array of the same wrapper objects:- onMassDeleteHost: (agent?: AgentK8sResource, bmh?: BareMetalHostK8sResource) => Promise<unknown>; + onMassDeleteHost: ( + hosts: { agent?: AgentK8sResource; bmh?: BareMetalHostK8sResource }[] + ) => Promise<unknown>;This matches the previous review comment and makes the API more consistent and robust.
🧹 Nitpick comments (3)
libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts (1)
18-18: Simplify the boolean expressionThe double negation
!!erroris redundant in a boolean context.- return [data, !!error ? true : loaded, error as unknown]; + return [data, error ? true : loaded, error as unknown];🧰 Tools
🪛 Biome (1.9.4)
[error] 18-18: Avoid redundant double-negation.
It is not necessary to use double-negation when a value will already be coerced to a boolean.
Unsafe fix: Remove redundant double-negation(lint/complexity/noExtraBooleanCast)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (2)
68-72: Remove unnecessary FragmentThe Fragment is redundant as it contains only one child element.
- <> {t( 'ai:This will determine for the infrastructure environment which kind of hosts would be able to be added. If the hosts that you want to add are using DHCP server, select this option, else, select the static IP.', )} - </>🧰 Tools
🪛 Biome (1.9.4)
[error] 68-72: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment(lint/complexity/noUselessFragments)
106-111: Apply a consistent pattern for the ternary structureThe structure of the ternary conditional for determining whether to watch a resource could be more readable with consistent formatting.
- infraEnv.spec?.pullSecretRef?.name - ? { - groupVersionKind: { - kind: SecretModel.kind, - version: SecretModel.apiVersion, - group: SecretModel.apiGroup, - }, - name: infraEnv.spec?.pullSecretRef?.name, - namespace: infraEnv.metadata?.namespace, - isList: false, - } - : null, + infraEnv.spec?.pullSecretRef?.name ? { + groupVersionKind: { + kind: SecretModel.kind, + version: SecretModel.apiVersion, + group: SecretModel.apiGroup, + }, + name: infraEnv.spec?.pullSecretRef?.name, + namespace: infraEnv.metadata?.namespace, + isList: false, + } : null,
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting
⛔ Files ignored due to path filters (2)
libs/ui-lib/lib/cim/logos/OnPremiseBannerIcon.svgis excluded by!**/*.svgyarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (57)
libs/locales/lib/en/translation.json(11 hunks)libs/ui-lib-tests/cypress/integration/storage/storage-step-disk-holders.cy.ts(1 hunks)libs/ui-lib/lib/cim/components/Agent/BMCForm.tsx(3 hunks)libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx(2 hunks)libs/ui-lib/lib/cim/components/Agent/types.ts(0 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostDiscoveryTable.tsx(6 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostsDiscovery.tsx(1 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentWizard.tsx(1 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts(3 hunks)libs/ui-lib/lib/cim/components/InfraEnv/AddHostDropdown.tsx(4 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvPage.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/useInfraEnvResources.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/EnvironmentDetails.tsx(4 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsx(7 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/AgentsTab.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/DetailsTab.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/InfraEnvDetails.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvFormPage.tsx(0 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.css(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.tsx(2 hunks)libs/ui-lib/lib/cim/components/InfraEnv/index.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/infra-env.css(0 hunks)libs/ui-lib/lib/cim/components/InfraEnv/types.ts(1 hunks)libs/ui-lib/lib/cim/components/YamlPreview/useYAMLPreview.ts(4 hunks)libs/ui-lib/lib/cim/components/common/InfoAndTroubleshootingNotification.tsx(1 hunks)libs/ui-lib/lib/cim/components/formik/CredentialsField.tsx(1 hunks)libs/ui-lib/lib/cim/components/helpers/agents.ts(2 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostModal.tsx(0 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlForm.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/AddHostModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/DeleteHostModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/EditBMHModal.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/EditNtpSourcesModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/EditProxyModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/EditPullSecretModal.tsx(4 hunks)libs/ui-lib/lib/cim/components/modals/EditSSHKeyModal.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/MassApproveAgentModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/MassDeleteAgentModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/ScaleUpModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/UnbindHostModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/types.ts(2 hunks)libs/ui-lib/lib/cim/config/constants.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useInfraEnvAgents.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useInfraEnvBMHs.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useInfraEnvNMStates.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts(1 hunks)libs/ui-lib/lib/cim/index.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/multi-cluster-engine.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/nm-state.ts(1 hunks)libs/ui-lib/lib/cim/types/models.ts(1 hunks)libs/ui-lib/lib/cim/utils.ts(1 hunks)libs/ui-lib/lib/ocm/components/Routes.tsx(1 hunks)libs/ui-lib/package.json(2 hunks)
💤 Files with no reviewable changes (4)
- libs/ui-lib/lib/cim/components/modals/AddBmcHostModal.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/infra-env.css
- libs/ui-lib/lib/cim/components/Agent/types.ts
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvFormPage.tsx
✅ Files skipped from review due to trivial changes (3)
- libs/ui-lib/lib/cim/config/constants.ts
- libs/ui-lib-tests/cypress/integration/storage/storage-step-disk-holders.cy.ts
- libs/locales/lib/en/translation.json
🚧 Files skipped from review as they are similar to previous changes (45)
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.tsx
- libs/ui-lib/package.json
- libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx
- libs/ui-lib/lib/cim/types/k8s/multi-cluster-engine.ts
- libs/ui-lib/lib/cim/index.ts
- libs/ui-lib/lib/cim/components/helpers/agents.ts
- libs/ui-lib/lib/cim/types/k8s/nm-state.ts
- libs/ui-lib/lib/ocm/components/Routes.tsx
- libs/ui-lib/lib/cim/components/modals/EditSSHKeyModal.tsx
- libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlModal.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.css
- libs/ui-lib/lib/cim/components/modals/EditPullSecretModal.tsx
- libs/ui-lib/lib/cim/components/modals/DeleteHostModal.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/useInfraEnvResources.ts
- libs/ui-lib/lib/cim/components/modals/MassDeleteAgentModal.tsx
- libs/ui-lib/lib/cim/hooks/useInfraEnvBMHs.ts
- libs/ui-lib/lib/cim/components/modals/EditNtpSourcesModal.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/index.ts
- libs/ui-lib/lib/cim/components/modals/ScaleUpModal.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvPage.tsx
- libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts
- libs/ui-lib/lib/cim/components/formik/CredentialsField.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/DetailsTab.tsx
- libs/ui-lib/lib/cim/hooks/useInfraEnvAgents.ts
- libs/ui-lib/lib/cim/components/modals/EditProxyModal.tsx
- libs/ui-lib/lib/cim/components/modals/MassApproveAgentModal.tsx
- libs/ui-lib/lib/cim/components/modals/EditBMHModal.tsx
- libs/ui-lib/lib/cim/components/modals/AddHostModal.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/types.ts
- libs/ui-lib/lib/cim/components/InfraEnv/AddHostDropdown.tsx
- libs/ui-lib/lib/cim/components/Agent/BMCForm.tsx
- libs/ui-lib/lib/cim/hooks/useInfraEnvNMStates.ts
- libs/ui-lib/lib/cim/components/common/InfoAndTroubleshootingNotification.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/AgentsTab.tsx
- libs/ui-lib/lib/cim/components/YamlPreview/useYAMLPreview.ts
- libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlForm.tsx
- libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostsDiscovery.tsx
- libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostDiscoveryTable.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/InfraEnvDetails.tsx
- libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentWizard.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsx
- libs/ui-lib/lib/cim/components/modals/UnbindHostModal.tsx
- libs/ui-lib/lib/cim/components/modals/types.ts
- libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts
- libs/ui-lib/lib/cim/types/models.ts
🧰 Additional context used
🧬 Code Graph Analysis (2)
libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts (5)
libs/ui-lib/lib/cim/types/k8s/agent.ts (1)
AgentK8sResource(32-74)libs/ui-lib/lib/cim/components/Hypershift/types.ts (1)
AgentMachineK8sResource(186-193)libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts (1)
InfraEnvK8sResource(8-42)libs/ui-lib/lib/cim/types/k8s/nm-state.ts (1)
NMStateK8sResource(3-11)libs/ui-lib/lib/cim/types/k8s/agent-cluster-install.ts (1)
AgentClusterInstallK8sResource(17-80)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (5)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts (1)
EnvironmentStepFormValues(15-34)libs/ui-lib/lib/common/hooks/index.ts (1)
useTranslation(3-3)libs/ui-lib/lib/common/config/docs_links.ts (1)
getOCPStaticIPDocLink(62-63)libs/ui-lib/lib/cim/config/constants.ts (1)
DOC_VERSION(4-4)libs/ui-lib/lib/common/components/ui/formik/LabelField.tsx (1)
LabelField(34-100)
🪛 Biome (1.9.4)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx
[error] 68-72: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment
(lint/complexity/noUselessFragments)
libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts
[error] 18-18: Avoid redundant double-negation.
It is not necessary to use double-negation when a value will already be coerced to a boolean.
Unsafe fix: Remove redundant double-negation
(lint/complexity/noExtraBooleanCast)
⏰ Context from checks skipped due to timeout of 90000ms (6)
- GitHub Check: translation-files
- GitHub Check: format
- GitHub Check: unit-tests
- GitHub Check: circular-deps
- GitHub Check: tests
- GitHub Check: lint
🔇 Additional comments (6)
libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts (2)
13-19: Nice implementation of the typed wrapper hookThe hook provides a type-safe wrapper around the console's watch resource functionality, with a well-defined return type signature.
🧰 Tools
🪛 Biome (1.9.4)
[error] 18-18: Avoid redundant double-negation.
It is not necessary to use double-negation when a value will already be coerced to a boolean.
Unsafe fix: Remove redundant double-negation(lint/complexity/noExtraBooleanCast)
17-18: Consider the loaded=true when error exists behaviorSetting
loaded=truewhen an error occurs might mask loading states during errors. Consumers might incorrectly assume the data is ready when it's actually errored. Consider whether this is the intended behavior or if it would be better to preserve the original loading state.🧰 Tools
🪛 Biome (1.9.4)
[error] 18-18: Avoid redundant double-negation.
It is not necessary to use double-negation when a value will already be coerced to a boolean.
Unsafe fix: Remove redundant double-negation(lint/complexity/noExtraBooleanCast)
libs/ui-lib/lib/cim/components/InfraEnv/EnvironmentDetails.tsx (2)
98-111: Good use of the new useK8sWatchResource hookThe refactoring to use the useK8sWatchResource hook improves code consistency and follows React's patterns better than manual fetching with useEffect.
230-240: Well-structured modal rendering patternThe conditionally rendered modals with internal state management is a clean pattern that reduces prop drilling and simplifies the component interface.
libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts (2)
29-29: ImprovedonDeleteHostparameter typingThe signature change to use a single object parameter with optional properties is a good improvement. This makes the API more flexible and less prone to parameter order mistakes.
175-175:Details
✅ Verification successful
Ensure removal of
onDeleteHostis consistentThe
ClusterDeploymentHostDiscoveryTablePropsno longer includesonDeleteHostfromAgentTableActions, which is consistent with the changes in other parts of the file. Make sure all consumers of this type have been updated accordingly.
🏁 Script executed:
#!/bin/bash # Check if there are any remaining references to onDeleteHost in associated components echo "Checking for onDeleteHost usage in ClusterDeploymentHostDiscoveryTable.tsx:" rg -n "onDeleteHost.*ClusterDeploymentHostDiscoveryTable" -A 5 -B 5 echo -e "\nChecking if any consumer is destructuring onDeleteHost from hostActions:" rg -n "hostActions.*onDeleteHost" -A 3 -B 3Length of output: 437
Removal of
onDeleteHostis ConsistentI’ve verified there are no remaining references to
onDeleteHostin:
ClusterDeploymentHostDiscoveryTable.tsx- Any destructuring of
hostActionsApproving these changes.
There was a problem hiding this comment.
Actionable comments posted: 3
♻️ Duplicate comments (3)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (1)
140-148: Add error handling for base64 decodingThe
atob()function can throw exceptions if the input isn't properly base64-encoded. Consider adding try/catch blocks to handle potential decoding errors.onSelect={(cred) => { - setFieldValue( - 'pullSecret', - cred.data?.['pullSecret'] ? atob(cred.data['pullSecret']) : '', - ); - setFieldValue( - 'sshPublicKey', - cred.data?.['ssh-publickey'] ? atob(cred.data['ssh-publickey']) : '', - ); + try { + setFieldValue( + 'pullSecret', + cred.data?.['pullSecret'] ? atob(cred.data['pullSecret']) : '', + ); + setFieldValue( + 'sshPublicKey', + cred.data?.['ssh-publickey'] ? atob(cred.data['ssh-publickey']) : '', + ); + } catch (error) { + console.error('Failed to decode credential data:', error); + // Consider showing a user-friendly error message here + } }}libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostDiscoveryTable.tsx (1)
211-218:⚠️ Potential issueGuard modal rendering on loading state.
The DeleteHostModal is rendered when deleteHost is set, but it should also check that the required resources are loaded to avoid potential runtime errors from undefined data.
-{deleteHost && ( +{deleteHost && nmLoaded && aciLoaded && ( <DeleteHostModal {...deleteHost} onClose={() => setDeleteHost(undefined)} nmStates={nmStates} agentClusterInstall={agentClusterInstall} /> )}libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts (1)
31-31: 🛠️ Refactor suggestionUnify
onMassDeleteHostsignature for consistencyThe
onMassDeleteHostsignature is still using separate parameters whileonDeleteHostnow uses a wrapper object pattern. This inconsistency makes the API harder to use correctly.- onMassDeleteHost: (agent?: AgentK8sResource, bmh?: BareMetalHostK8sResource) => Promise<unknown>; + onMassDeleteHost: ( + hosts: { agent?: AgentK8sResource; bmh?: BareMetalHostK8sResource }[] + ) => Promise<unknown>;This keeps both deletion callbacks symmetrical, makes "mass" semantics explicit, and prevents accidental parameter swap bugs.
🧹 Nitpick comments (5)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (3)
68-72: Remove unnecessary FragmentThe Fragment wrapper is redundant since it contains only a single child element. React doesn't require fragments when there's only one child element.
- <> {t( 'ai:This will determine for the infrastructure environment which kind of hosts would be able to be added. If the hosts that you want to add are using DHCP server, select this option, else, select the static IP.', )} - </>🧰 Tools
🪛 Biome (1.9.4)
[error] 68-72: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment(lint/complexity/noUselessFragments)
126-126: Consider simplifying conditional checkSince
osImagesis a required prop (based onInfraEnvFormProps), the!!osImagescheck may be redundant. The component should always receive this prop.- {!!osImages && <InfraEnvOpenShiftVersionDropdown osImages={osImages} />} + <InfraEnvOpenShiftVersionDropdown osImages={osImages} />If there's a concern that
osImagesmight be empty, consider checking for array length instead:- {!!osImages && <InfraEnvOpenShiftVersionDropdown osImages={osImages} />} + {osImages.length > 0 && <InfraEnvOpenShiftVersionDropdown osImages={osImages} />}
105-111: Add rel="noreferrer" for security when opening external linksWhen using
window.open()with_blank, it's recommended to includerel="noreferrer"(along with the existingnoopener) to prevent potential security issues where the opened page could access yourwindow.openerobject.onClick={() => window.open( getOCPStaticIPDocLink(DOC_VERSION), '_blank', - 'noopener', + 'noopener noreferrer', ) }libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts (1)
18-18: Consider simplifying the double negation.The double negation (
!!error) can be simplified since you're already coercing to a boolean with the ternary operator.- return [data, !!error ? true : loaded, error as unknown]; + return [data, error ? true : loaded, error as unknown];🧰 Tools
🪛 Biome (1.9.4)
[error] 18-18: Avoid redundant double-negation.
It is not necessary to use double-negation when a value will already be coerced to a boolean.
Unsafe fix: Remove redundant double-negation(lint/complexity/noExtraBooleanCast)
libs/ui-lib/lib/cim/utils.ts (1)
111-111: Address the TODO for mass deleteThere's a TODO comment to handle mass deletion, but the implementation is not provided. This should be implemented to support the
onMassDeleteHostfunction.- // TODO handle mass delete + // Implement mass delete by accepting an array of hosts and calling onDeleteHost for each one + // This would support the onMassDeleteHost function defined in the AgentTableActions typeWould you like me to propose an implementation for the mass delete functionality?
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting
⛔ Files ignored due to path filters (2)
libs/ui-lib/lib/cim/logos/OnPremiseBannerIcon.svgis excluded by!**/*.svgyarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (57)
libs/locales/lib/en/translation.json(11 hunks)libs/ui-lib-tests/cypress/integration/storage/storage-step-disk-holders.cy.ts(1 hunks)libs/ui-lib/lib/cim/components/Agent/BMCForm.tsx(3 hunks)libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx(2 hunks)libs/ui-lib/lib/cim/components/Agent/types.ts(0 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostDiscoveryTable.tsx(6 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostsDiscovery.tsx(1 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentWizard.tsx(1 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts(3 hunks)libs/ui-lib/lib/cim/components/InfraEnv/AddHostDropdown.tsx(4 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvPage.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/useInfraEnvResources.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/EnvironmentDetails.tsx(4 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsx(7 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/AgentsTab.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/DetailsTab.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/InfraEnvDetails.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvFormPage.tsx(0 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.css(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.tsx(2 hunks)libs/ui-lib/lib/cim/components/InfraEnv/index.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/infra-env.css(0 hunks)libs/ui-lib/lib/cim/components/InfraEnv/types.ts(1 hunks)libs/ui-lib/lib/cim/components/YamlPreview/useYAMLPreview.ts(4 hunks)libs/ui-lib/lib/cim/components/common/InfoAndTroubleshootingNotification.tsx(1 hunks)libs/ui-lib/lib/cim/components/formik/CredentialsField.tsx(1 hunks)libs/ui-lib/lib/cim/components/helpers/agents.ts(2 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostModal.tsx(0 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlForm.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/AddHostModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/DeleteHostModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/EditBMHModal.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/EditNtpSourcesModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/EditProxyModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/EditPullSecretModal.tsx(4 hunks)libs/ui-lib/lib/cim/components/modals/EditSSHKeyModal.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/MassApproveAgentModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/MassDeleteAgentModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/ScaleUpModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/UnbindHostModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/types.ts(2 hunks)libs/ui-lib/lib/cim/config/constants.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useInfraEnvAgents.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useInfraEnvBMHs.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useInfraEnvNMStates.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts(1 hunks)libs/ui-lib/lib/cim/index.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/multi-cluster-engine.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/nm-state.ts(1 hunks)libs/ui-lib/lib/cim/types/models.ts(1 hunks)libs/ui-lib/lib/cim/utils.ts(1 hunks)libs/ui-lib/lib/ocm/components/Routes.tsx(1 hunks)libs/ui-lib/package.json(2 hunks)
💤 Files with no reviewable changes (4)
- libs/ui-lib/lib/cim/components/modals/AddBmcHostModal.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/infra-env.css
- libs/ui-lib/lib/cim/components/Agent/types.ts
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvFormPage.tsx
✅ Files skipped from review due to trivial changes (2)
- libs/ui-lib-tests/cypress/integration/storage/storage-step-disk-holders.cy.ts
- libs/ui-lib/lib/cim/config/constants.ts
🚧 Files skipped from review as they are similar to previous changes (44)
- libs/ui-lib/package.json
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.css
- libs/ui-lib/lib/cim/components/modals/MassDeleteAgentModal.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.tsx
- libs/ui-lib/lib/cim/types/k8s/nm-state.ts
- libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostsDiscovery.tsx
- libs/ui-lib/lib/cim/types/k8s/multi-cluster-engine.ts
- libs/ui-lib/lib/cim/index.ts
- libs/ui-lib/lib/cim/components/InfraEnv/index.ts
- libs/ui-lib/lib/ocm/components/Routes.tsx
- libs/ui-lib/lib/cim/components/modals/EditProxyModal.tsx
- libs/ui-lib/lib/cim/components/formik/CredentialsField.tsx
- libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts
- libs/ui-lib/lib/cim/components/modals/AddHostModal.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/useInfraEnvResources.ts
- libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx
- libs/ui-lib/lib/cim/components/modals/EditBMHModal.tsx
- libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlModal.tsx
- libs/ui-lib/lib/cim/hooks/useInfraEnvAgents.ts
- libs/ui-lib/lib/cim/components/InfraEnv/types.ts
- libs/ui-lib/lib/cim/hooks/useInfraEnvNMStates.ts
- libs/ui-lib/lib/cim/hooks/useInfraEnvBMHs.ts
- libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlForm.tsx
- libs/ui-lib/lib/cim/components/modals/EditNtpSourcesModal.tsx
- libs/ui-lib/lib/cim/components/helpers/agents.ts
- libs/ui-lib/lib/cim/components/modals/MassApproveAgentModal.tsx
- libs/ui-lib/lib/cim/components/YamlPreview/useYAMLPreview.ts
- libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvPage.tsx
- libs/ui-lib/lib/cim/components/modals/types.ts
- libs/ui-lib/lib/cim/components/modals/DeleteHostModal.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/AddHostDropdown.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/DetailsTab.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/InfraEnvDetails.tsx
- libs/ui-lib/lib/cim/components/modals/UnbindHostModal.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/AgentsTab.tsx
- libs/ui-lib/lib/cim/components/modals/ScaleUpModal.tsx
- libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentWizard.tsx
- libs/ui-lib/lib/cim/components/common/InfoAndTroubleshootingNotification.tsx
- libs/ui-lib/lib/cim/types/models.ts
- libs/ui-lib/lib/cim/components/modals/EditSSHKeyModal.tsx
- libs/locales/lib/en/translation.json
- libs/ui-lib/lib/cim/components/Agent/BMCForm.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts
🧰 Additional context used
🧬 Code Graph Analysis (3)
libs/ui-lib/lib/cim/components/modals/EditPullSecretModal.tsx (3)
libs/ui-lib/lib/common/utils.ts (1)
getErrorMessage(13-21)libs/ui-lib/lib/cim/components/modals/types.ts (1)
EditPullSecretFormikValues(41-44)libs/ui-lib/lib/cim/types/models.ts (1)
SecretModel(3-11)
libs/ui-lib/lib/cim/utils.ts (7)
libs/ui-lib/lib/cim/types/k8s/shared.ts (1)
StatusCondition(1-8)libs/ui-lib/lib/cim/types/k8s/agent.ts (1)
AgentK8sResource(32-74)libs/ui-lib/lib/cim/types/models.ts (4)
AgentModel(67-76)BMHModel(78-87)AgentClusterInstallModel(111-120)NMStateModel(89-98)libs/ui-lib/lib/cim/components/common/constants.ts (2)
BMH_HOSTNAME_ANNOTATION(20-20)AGENT_BMH_NAME_LABEL_KEY(12-12)libs/ui-lib/lib/cim/types/k8s/agent-cluster-install.ts (1)
AgentClusterInstallK8sResource(17-80)libs/ui-lib/lib/cim/types/k8s/nm-state.ts (1)
NMStateK8sResource(3-11)libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts (1)
InfraEnvK8sResource(8-42)
libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts (5)
libs/ui-lib/lib/cim/types/k8s/agent.ts (1)
AgentK8sResource(32-74)libs/ui-lib/lib/cim/components/Hypershift/types.ts (1)
AgentMachineK8sResource(186-193)libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts (1)
InfraEnvK8sResource(8-42)libs/ui-lib/lib/cim/types/k8s/nm-state.ts (1)
NMStateK8sResource(3-11)libs/ui-lib/lib/cim/types/k8s/agent-cluster-install.ts (1)
AgentClusterInstallK8sResource(17-80)
🪛 Biome (1.9.4)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx
[error] 68-72: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment
(lint/complexity/noUselessFragments)
libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts
[error] 18-18: Avoid redundant double-negation.
It is not necessary to use double-negation when a value will already be coerced to a boolean.
Unsafe fix: Remove redundant double-negation
(lint/complexity/noExtraBooleanCast)
⏰ Context from checks skipped due to timeout of 90000ms (6)
- GitHub Check: format
- GitHub Check: lint
- GitHub Check: translation-files
- GitHub Check: tests
- GitHub Check: unit-tests
- GitHub Check: circular-deps
🔇 Additional comments (17)
libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts (1)
1-19: LGTM! A well-designed wrapper hook for Kubernetes resource watching.This is a clean, typed wrapper around the OpenShift console's watch resource hook that provides type safety for consumers. The loading boolean override to return true when an error exists is a good UX decision that simplifies error state handling for consumers.
🧰 Tools
🪛 Biome (1.9.4)
[error] 18-18: Avoid redundant double-negation.
It is not necessary to use double-negation when a value will already be coerced to a boolean.
Unsafe fix: Remove redundant double-negation(lint/complexity/noExtraBooleanCast)
libs/ui-lib/lib/cim/components/modals/EditPullSecretModal.tsx (3)
111-181: LGTM! Good refactoring to internalize resource operations.The modal now handles its own resource operations using the OpenShift dynamic plugin SDK's
k8sCreateandk8sPatchfunctions, which is a cleaner approach than delegating to external callbacks. The error handling is robust, utilizing thegetErrorMessageutility to normalize different error types.
122-122: Modal isOpen prop hardcoded to true.The
isOpenprop is hardcoded to true, which indicates this component is meant to be conditionally rendered by its parent rather than controlled via props. This is consistent with the pattern used across other modals in this PR.
135-168: Solid implementation of resource creation/patching.The conditional logic to either create a new secret or patch an existing one is well-structured. The code correctly handles base64 encoding of the pull secret and properly constructs the patch operation when updating an existing secret.
libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostDiscoveryTable.tsx (2)
152-154: Fixed loading state condition.The loading condition has been corrected to show loading state when either NMStates or AgentClusterInstall resources are not loaded, which addresses a previous issue where it was showing loading when AgentClusterInstall was loaded.
59-78: LGTM! Good refactoring to use resource watching hooks.The component now properly uses hooks for watching Kubernetes resources, which is a cleaner approach than passing resources through props. The destructuring of both the resource and loading state from the hooks is well implemented.
libs/ui-lib/lib/cim/components/InfraEnv/EnvironmentDetails.tsx (2)
98-111: LGTM! Good refactoring to use K8s resource watching.The component now uses
useK8sWatchResourceto reactively watch the pull secret, which is a cleaner approach than manual fetching. The conditional watch based on whetherpullSecretRef.nameexists is a good pattern.
230-252: Clean modal rendering pattern.The modals are now conditionally rendered based on local state flags instead of being controlled via
isOpenprops, which is a more concise pattern and aligns with the broader refactoring in this PR.libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts (2)
164-171: InfraEnvAgentTableProps now decoupled from actionsThis is a good refactoring that separates data from actions, making the component more reusable. Instead of receiving callbacks through props, the component can now import utility functions directly from
utils.ts.
173-176: ClusterDeploymentHostDiscoveryTableProps no longer includesonDeleteHostRemoving
onDeleteHostfrom the picked properties is consistent with the changes inhostActionsand the pattern of using utility functions directly fromutils.ts.libs/ui-lib/lib/cim/utils.ts (7)
22-30: Good implementation ofappendPatchutilityThe
appendPatchfunction is a helpful utility that simplifies patch operations by handling both 'add' and 'replace' operations based on whether the target path already exists.
32-36: Robust implementation ofonApproveAgentUsing the
appendPatchhelper ensures the patch operation will work correctly whetherspec.approvedalready exists or not.
38-42: Well-implemented hostname change utilitiesBoth
onChangeHostnameandonChangeBMHHostnameuse theappendPatchhelper to handle patching correctly. The BMH implementation properly escapes the annotation path withreplace('/', '~1').Also applies to: 44-54
119-124: Helpful utility for agent nameThe
getAgentNamefunction provides a consistent way to extract names from different resource types, with appropriate fallbacks.
126-150: Well-implementedonUnbindHostfunctionThe
onUnbindHostfunction correctly uses theappendPatchhelper to ensure patches work whether the properties exist or not, and prevents negative worker counts withMath.max(0, workerCount - 1).
152-164: Useful utility for filtering NMStates by InfraEnvThe
getInfraEnvNMStatesfunction provides a clean way to filter NMState resources based on the label selector in an InfraEnv resource.
166-167: Clear platform type helperThe
isBMPlatformfunction provides a simple way to check if the infrastructure is one of the bare metal compatible platforms.
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Verify consumers no longer use onDeleteHost from hostActions
The hostActions type no longer includes onDeleteHost, which means components using this prop need to be updated to use the standalone utility function.
Let's verify there are no stale usages:
🏁 Script executed:
#!/bin/bash
# Search for any usage of hostActions.onDeleteHost in the codebase
rg -n "hostActions.*onDeleteHost"
# Check components that previously used this pattern
grep -n "onDeleteHost" libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostDiscoveryTable.tsx
grep -n "onDeleteHost" libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsxLength of output: 473
Update onDeleteHost References to Use the Standalone Utility
The hostActions type no longer includes onDeleteHost, so all consumers must be updated to import and call the new standalone delete-host utility instead of pulling onDeleteHost out of hostActions.
Please update the following locations:
-
libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostDiscoveryTable.tsx
• RemoveonDeleteHost: setDeleteHostfrom thehostActionsdestructure (around line 98).
• Import the standalone delete-host handler and invoke it where you currently callsetDeleteHost. -
libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsx
• RemoveonDeleteHost: setDeleteHostfrom the props destructure (line 114).
• Replace the<DeleteHostAction … onDeleteHost={() => setMassDeleteOpen(…)} />usage (around line 211) to call the standalone delete-host utility directly.
This ensures no lingering references to hostActions.onDeleteHost and aligns with the updated hostActions type.
🤖 Prompt for AI Agents
In libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts at line 129, the
hostActions type no longer includes onDeleteHost. Update all consumers by
removing onDeleteHost from hostActions destructuring in
ClusterDeploymentHostDiscoveryTable.tsx around line 98 and
InfraEnvAgentTable.tsx around line 114. Import the standalone delete-host
utility function in these files and replace all calls to
hostActions.onDeleteHost or setDeleteHost with calls to this standalone
function, including the DeleteHostAction usage near line 211 in
InfraEnvAgentTable.tsx.
libs/ui-lib/lib/cim/utils.ts
Outdated
There was a problem hiding this comment.
onDeleteHost signature doesn't match its type definition
The implementation of onDeleteHost takes separate parameters instead of the single wrapper object defined in the AgentTableActions type. This mismatch will cause type errors.
-export const onDeleteHost = async (
- agent?: AgentK8sResource,
- bmh?: BareMetalHostK8sResource,
- agentClusterInstall?: AgentClusterInstallK8sResource,
- nmStates: NMStateK8sResource[] = [],
-) => {
+export const onDeleteHost = async (
+ host: { agent?: AgentK8sResource; bmh?: BareMetalHostK8sResource },
+ agentClusterInstall?: AgentClusterInstallK8sResource,
+ nmStates: NMStateK8sResource[] = [],
+) => {
- if (agent) {
+ if (host.agent) {
await k8sDelete({
model: AgentModel,
- resource: agent,
+ resource: host.agent,
});
}
- if (bmh) {
+ if (host.bmh) {
await k8sDelete({
model: BMHModel,
- resource: bmh,
+ resource: host.bmh,
});
const bmhNMStates = (nmStates || []).filter(
- (nm) => nm.metadata?.labels?.[AGENT_BMH_NAME_LABEL_KEY] === bmh.metadata?.name,
+ (nm) => nm.metadata?.labels?.[AGENT_BMH_NAME_LABEL_KEY] === host.bmh.metadata?.name,
);This change ensures the implementation matches the type definition in AgentTableActions.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| export const onDeleteHost = async ( | |
| agent?: AgentK8sResource, | |
| bmh?: BareMetalHostK8sResource, | |
| agentClusterInstall?: AgentClusterInstallK8sResource, | |
| nmStates: NMStateK8sResource[] = [], | |
| ) => { | |
| if (agent) { | |
| await k8sDelete({ | |
| model: AgentModel, | |
| resource: agent, | |
| }); | |
| } | |
| if (bmh) { | |
| await k8sDelete({ | |
| model: BMHModel, | |
| resource: bmh, | |
| }); | |
| const bmhNMStates = (nmStates || []).filter( | |
| (nm) => nm.metadata?.labels?.[AGENT_BMH_NAME_LABEL_KEY] === bmh.metadata?.name, | |
| ); | |
| for (const nmState of bmhNMStates) { | |
| await k8sDelete({ | |
| model: NMStateModel, | |
| resource: nmState, | |
| }); | |
| } | |
| } | |
| // TODO handle mass delete | |
| if (agentClusterInstall) { | |
| const masterCount = undefined; /* Only workers can be removed */ | |
| const workerCount = agentClusterInstall.spec?.provisionRequirements.workerAgents || 1; | |
| await setProvisionRequirements(agentClusterInstall, Math.max(0, workerCount - 1), masterCount); | |
| } | |
| }; | |
| export const onDeleteHost = async ( | |
| host: { agent?: AgentK8sResource; bmh?: BareMetalHostK8sResource }, | |
| agentClusterInstall?: AgentClusterInstallK8sResource, | |
| nmStates: NMStateK8sResource[] = [], | |
| ) => { | |
| if (host.agent) { | |
| await k8sDelete({ | |
| model: AgentModel, | |
| resource: host.agent, | |
| }); | |
| } | |
| if (host.bmh) { | |
| await k8sDelete({ | |
| model: BMHModel, | |
| resource: host.bmh, | |
| }); | |
| const bmhNMStates = (nmStates || []).filter( | |
| (nm) => | |
| nm.metadata?.labels?.[AGENT_BMH_NAME_LABEL_KEY] === | |
| host.bmh!.metadata?.name, | |
| ); | |
| for (const nmState of bmhNMStates) { | |
| await k8sDelete({ | |
| model: NMStateModel, | |
| resource: nmState, | |
| }); | |
| } | |
| } | |
| // TODO handle mass delete | |
| if (agentClusterInstall) { | |
| const masterCount = undefined; /* Only workers can be removed */ | |
| const workerCount = | |
| agentClusterInstall.spec?.provisionRequirements.workerAgents || 1; | |
| await setProvisionRequirements( | |
| agentClusterInstall, | |
| Math.max(0, workerCount - 1), | |
| masterCount, | |
| ); | |
| } | |
| }; |
🤖 Prompt for AI Agents
In libs/ui-lib/lib/cim/utils.ts around lines 82 to 117, the onDeleteHost
function currently takes multiple separate parameters, but its type definition
in AgentTableActions expects a single object parameter. To fix this, refactor
onDeleteHost to accept one object argument containing the properties agent, bmh,
agentClusterInstall, and nmStates, then destructure these inside the function.
This will align the function signature with its type definition and prevent type
errors.
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (4)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (1)
140-148: Add error handling for base64 decodingThe
atob()function can throw exceptions if the input isn't properly base64-encoded. Consider adding try/catch blocks to handle potential decoding errors.onSelect={(cred) => { - setFieldValue( - 'pullSecret', - cred.data?.['pullSecret'] ? atob(cred.data['pullSecret']) : '', - ); - setFieldValue( - 'sshPublicKey', - cred.data?.['ssh-publickey'] ? atob(cred.data['ssh-publickey']) : '', - ); + try { + setFieldValue( + 'pullSecret', + cred.data?.['pullSecret'] ? atob(cred.data['pullSecret']) : '', + ); + setFieldValue( + 'sshPublicKey', + cred.data?.['ssh-publickey'] ? atob(cred.data['ssh-publickey']) : '', + ); + } catch (error) { + console.error('Failed to decode credential data:', error); + // Consider showing a user-friendly error message here + } }}libs/ui-lib/lib/cim/utils.ts (1)
82-117:⚠️ Potential issueParameter signature inconsistency with type definition
The
onDeleteHostimplementation accepts separate parameters, but its type definition inClusterDeployment/types.tsexpects a single wrapper object. This mismatch will cause type errors when using the utility function.-export const onDeleteHost = async ( - agent?: AgentK8sResource, - bmh?: BareMetalHostK8sResource, - agentClusterInstall?: AgentClusterInstallK8sResource, - nmStates: NMStateK8sResource[] = [], -) => { +export const onDeleteHost = async ( + host: { agent?: AgentK8sResource; bmh?: BareMetalHostK8sResource }, + agentClusterInstall?: AgentClusterInstallK8sResource, + nmStates: NMStateK8sResource[] = [], +) => { - if (agent) { + if (host.agent) { await k8sDelete({ model: AgentModel, - resource: agent, + resource: host.agent, }); } - if (bmh) { + if (host.bmh) { await k8sDelete({ model: BMHModel, - resource: bmh, + resource: host.bmh, }); const bmhNMStates = (nmStates || []).filter( - (nm) => nm.metadata?.labels?.[AGENT_BMH_NAME_LABEL_KEY] === bmh.metadata?.name, + (nm) => nm.metadata?.labels?.[AGENT_BMH_NAME_LABEL_KEY] === host.bmh.metadata?.name, );libs/ui-lib/lib/cim/components/Agent/BMCForm.tsx (1)
239-330:⚠️ Potential issueMissing BMH creation during Add Host flow
The
onCreateBMHfunction does not create a new BareMetalHost whenbmhis undefined (during "Add host" flow). It currently only creates/patches Secrets and NMState resources, leaving orphaned credentials & NMState objects and producing a silent failure.if (bmh) { const patches: Patch[] = []; appendPatch( patches, `/metadata/annotations/${BMH_HOSTNAME_ANNOTATION.replace('/', '~1')}`, values.hostname, bmh.metadata?.annotations?.[BMH_HOSTNAME_ANNOTATION], ); appendPatch(patches, '/spec/bmc/address', values.bmcAddress, bmh.spec?.bmc?.address); appendPatch( patches, '/spec/bmc/disableCertificateVerification', values.disableCertificateVerification, bmh.spec?.bmc?.disableCertificateVerification, ); appendPatch(patches, '/spec/bootMACAddress', values.bootMACAddress, bmh.spec?.bootMACAddress); appendPatch(patches, '/spec/online', values.online, bmh.spec?.online); if (newSecret) { appendPatch( patches, '/spec/bmc/credentialsName', newSecret.metadata?.name, bmh.spec?.bmc?.credentialsName, ); } if (patches.length) { await k8sPatch({ model: BMHModel, resource: bmh, data: patches, }); } + } else { + // Create new BMH + const newBmh: BareMetalHostK8sResource = { + apiVersion: 'metal3.io/v1alpha1', + kind: 'BareMetalHost', + metadata: { + name: values.name, + namespace: infraEnv.metadata?.namespace, + labels: { + [INFRAENV_AGENTINSTALL_LABEL_KEY]: infraEnv.metadata?.name || '', + }, + annotations: { + [BMH_HOSTNAME_ANNOTATION]: values.hostname, + }, + }, + spec: { + bmc: { + address: values.bmcAddress, + credentialsName: (newSecret ?? secret)?.metadata?.name ?? '', + disableCertificateVerification: values.disableCertificateVerification, + }, + bootMACAddress: values.bootMACAddress, + online: values.online, + }, + }; + + await k8sCreate<BareMetalHostK8sResource>({ + model: BMHModel, + data: newBmh, + }); }libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts (1)
30-31: 🛠️ Refactor suggestionInconsistent deletion API patterns
While
onDeleteHostnow uses a wrapper object,onMassDeleteHoststill uses separate parameters. This inconsistency makes the API less predictable and more error-prone.- onMassDeleteHost: (agent?: AgentK8sResource, bmh?: BareMetalHostK8sResource) => Promise<unknown>; + onMassDeleteHost: ( + hosts: { agent?: AgentK8sResource; bmh?: BareMetalHostK8sResource }[], + ) => Promise<unknown>;
🧹 Nitpick comments (4)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (3)
68-72: Simplify unnecessary FragmentRemove the unnecessary Fragment wrapper since it contains only one child element. This simplification will reduce DOM nesting and improve code readability.
- <> - {t( - 'ai:This will determine for the infrastructure environment which kind of hosts would be able to be added. If the hosts that you want to add are using DHCP server, select this option, else, select the static IP.', - )} - </> + {t( + 'ai:This will determine for the infrastructure environment which kind of hosts would be able to be added. If the hosts that you want to add are using DHCP server, select this option, else, select the static IP.', + )}🧰 Tools
🪛 Biome (1.9.4)
[error] 68-72: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment(lint/complexity/noUselessFragments)
126-126: Improve conditional rendering for better readabilityThe OpenShift version dropdown conditional rendering could be more explicit. While
!!osImagesworks correctly, it might be clearer to check for array length.- {!!osImages && <InfraEnvOpenShiftVersionDropdown osImages={osImages} />} + {osImages.length > 0 && <InfraEnvOpenShiftVersionDropdown osImages={osImages} />}
41-182: Consider extracting form sections into smaller componentsThe form is fairly large and contains multiple logical sections (basic info, network settings, credentials, proxy settings, NTP settings). Consider extracting these into smaller, focused components to improve maintainability and readability.
// Example of how this could look: const CreateInfraEnvForm: React.FC<InfraEnvFormProps> = ({ credentials, osImages }) => { const { values } = useFormikContext<EnvironmentStepFormValues>(); const { t } = useTranslation(); return ( <Stack hasGutter> <StackItem>{t('ai:Infrastructure environments are used...')}</StackItem> <StackItem> <Form> <BasicInfoSection /> <NetworkConfigSection /> <CredentialsSection credentials={credentials} /> <ProxyConfigSection /> <NTPConfigSection /> </Form> </StackItem> </Stack> ); };🧰 Tools
🪛 Biome (1.9.4)
[error] 68-72: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment(lint/complexity/noUselessFragments)
libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts (1)
17-18: Simplify boolean coercionThe double negation (
!!error) is redundant when the value will already be coerced to a boolean in this context.- return [data, !!error ? true : loaded, error as unknown]; + return [data, error ? true : loaded, error as unknown];🧰 Tools
🪛 Biome (1.9.4)
[error] 18-18: Avoid redundant double-negation.
It is not necessary to use double-negation when a value will already be coerced to a boolean.
Unsafe fix: Remove redundant double-negation(lint/complexity/noExtraBooleanCast)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting
⛔ Files ignored due to path filters (2)
libs/ui-lib/lib/cim/logos/OnPremiseBannerIcon.svgis excluded by!**/*.svgyarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (57)
libs/locales/lib/en/translation.json(11 hunks)libs/ui-lib/lib/cim/components/Agent/BMCForm.tsx(3 hunks)libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx(2 hunks)libs/ui-lib/lib/cim/components/Agent/types.ts(0 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostDiscoveryTable.tsx(6 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostsDiscovery.tsx(1 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentWizard.tsx(1 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts(3 hunks)libs/ui-lib/lib/cim/components/InfraEnv/AddHostDropdown.tsx(4 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvPage.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/useInfraEnvResources.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/EnvironmentDetails.tsx(4 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsx(7 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/AgentsTab.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/DetailsTab.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/InfraEnvDetails.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvFormPage.tsx(0 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.css(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.tsx(2 hunks)libs/ui-lib/lib/cim/components/InfraEnv/index.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/infra-env.css(0 hunks)libs/ui-lib/lib/cim/components/InfraEnv/types.ts(1 hunks)libs/ui-lib/lib/cim/components/YamlPreview/useYAMLPreview.ts(4 hunks)libs/ui-lib/lib/cim/components/common/InfoAndTroubleshootingNotification.tsx(1 hunks)libs/ui-lib/lib/cim/components/formik/CredentialsField.tsx(1 hunks)libs/ui-lib/lib/cim/components/helpers/agents.ts(2 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostModal.tsx(0 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlForm.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/AddHostModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/DeleteHostModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/EditBMHModal.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/EditNtpSourcesModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/EditProxyModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/EditPullSecretModal.tsx(4 hunks)libs/ui-lib/lib/cim/components/modals/EditSSHKeyModal.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/MassApproveAgentModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/MassDeleteAgentModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/ScaleUpModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/UnbindHostModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/types.ts(2 hunks)libs/ui-lib/lib/cim/config/constants.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useInfraEnvAgents.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useInfraEnvBMHs.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useInfraEnvNMStates.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts(1 hunks)libs/ui-lib/lib/cim/index.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/multi-cluster-engine.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/nm-state.ts(1 hunks)libs/ui-lib/lib/cim/types/models.ts(1 hunks)libs/ui-lib/lib/cim/utils.ts(1 hunks)libs/ui-lib/lib/common/components/clusterConfiguration/FormatDiskWarning.tsx(1 hunks)libs/ui-lib/lib/ocm/components/Routes.tsx(1 hunks)libs/ui-lib/package.json(2 hunks)
💤 Files with no reviewable changes (4)
- libs/ui-lib/lib/cim/components/InfraEnv/infra-env.css
- libs/ui-lib/lib/cim/components/modals/AddBmcHostModal.tsx
- libs/ui-lib/lib/cim/components/Agent/types.ts
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvFormPage.tsx
✅ Files skipped from review due to trivial changes (2)
- libs/ui-lib/lib/common/components/clusterConfiguration/FormatDiskWarning.tsx
- libs/ui-lib/lib/cim/config/constants.ts
🚧 Files skipped from review as they are similar to previous changes (46)
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.tsx
- libs/ui-lib/lib/cim/types/k8s/multi-cluster-engine.ts
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.css
- libs/ui-lib/lib/cim/types/k8s/nm-state.ts
- libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlModal.tsx
- libs/ui-lib/lib/ocm/components/Routes.tsx
- libs/ui-lib/lib/cim/index.ts
- libs/ui-lib/package.json
- libs/ui-lib/lib/cim/hooks/useInfraEnvAgents.ts
- libs/ui-lib/lib/cim/components/modals/EditProxyModal.tsx
- libs/ui-lib/lib/cim/components/modals/ScaleUpModal.tsx
- libs/ui-lib/lib/cim/components/modals/MassDeleteAgentModal.tsx
- libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts
- libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx
- libs/ui-lib/lib/cim/components/modals/EditPullSecretModal.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/index.ts
- libs/ui-lib/lib/cim/hooks/useInfraEnvNMStates.ts
- libs/ui-lib/lib/cim/hooks/useInfraEnvBMHs.ts
- libs/ui-lib/lib/cim/components/InfraEnv/AddHostDropdown.tsx
- libs/ui-lib/lib/cim/components/modals/EditNtpSourcesModal.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/DetailsTab.tsx
- libs/ui-lib/lib/cim/components/modals/DeleteHostModal.tsx
- libs/ui-lib/lib/cim/components/modals/AddHostModal.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/useInfraEnvResources.ts
- libs/ui-lib/lib/cim/components/YamlPreview/useYAMLPreview.ts
- libs/ui-lib/lib/cim/components/helpers/agents.ts
- libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlForm.tsx
- libs/ui-lib/lib/cim/components/modals/UnbindHostModal.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvPage.tsx
- libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostsDiscovery.tsx
- libs/ui-lib/lib/cim/components/common/InfoAndTroubleshootingNotification.tsx
- libs/ui-lib/lib/cim/components/modals/MassApproveAgentModal.tsx
- libs/ui-lib/lib/cim/components/formik/CredentialsField.tsx
- libs/ui-lib/lib/cim/components/modals/EditSSHKeyModal.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/AgentsTab.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/InfraEnvDetails.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/types.ts
- libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentWizard.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/EnvironmentDetails.tsx
- libs/ui-lib/lib/cim/components/modals/types.ts
- libs/locales/lib/en/translation.json
- libs/ui-lib/lib/cim/components/modals/EditBMHModal.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts
- libs/ui-lib/lib/cim/types/models.ts
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsx
- libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostDiscoveryTable.tsx
🧰 Additional context used
🪛 Biome (1.9.4)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx
[error] 68-72: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment
(lint/complexity/noUselessFragments)
libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts
[error] 18-18: Avoid redundant double-negation.
It is not necessary to use double-negation when a value will already be coerced to a boolean.
Unsafe fix: Remove redundant double-negation
(lint/complexity/noExtraBooleanCast)
⏰ Context from checks skipped due to timeout of 90000ms (6)
- GitHub Check: circular-deps
- GitHub Check: unit-tests
- GitHub Check: tests
- GitHub Check: translation-files
- GitHub Check: format
- GitHub Check: lint
🔇 Additional comments (12)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (3)
127-136: Location field implementation looks greatThe location field is well-implemented with appropriate validation messages, required flag, and helpful descriptive text that explains the purpose of the field to users.
77-123: Well-structured network type selectionThe network type selection is well-implemented with appropriate radio buttons, spacing, and helpful documentation popovers. The link to external documentation for static IP configuration is particularly helpful for users.
155-177: Well-implemented conditional rendering for NTP sourcesThe NTP sources configuration uses effective conditional rendering based on the checkbox state. The implementation properly wraps the additional fields in a Grid container when enabled, providing good structure and layout.
libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts (1)
13-19: Well-structured resource watching hook with improved loading state handlingThis hook provides a strongly typed wrapper around the console's resource watching hook with a useful improvement to the loading state logic. By marking loading as true when an error is present, it prevents components from attempting to render data during error states.
🧰 Tools
🪛 Biome (1.9.4)
[error] 18-18: Avoid redundant double-negation.
It is not necessary to use double-negation when a value will already be coerced to a boolean.
Unsafe fix: Remove redundant double-negation(lint/complexity/noExtraBooleanCast)
libs/ui-lib/lib/cim/utils.ts (4)
22-30: Clean appendPatch helper to avoid redundant API callsThe
appendPatchutility is well-designed. It only adds patches when there's an actual difference between values and correctly selects between 'add' and 'replace' operations based on the existence of the target path.
32-36: Robust agent approval implementationUsing
appendPatchfor approving agents ensures the operation works correctly regardless of whether the agent already has an approval status set, preventing potential 422 errors from the API server.
152-164: Well-designed filter function with proper type handlingThe
getInfraEnvNMStatesfunction effectively filters NMState configs based on label matching and handles potential missing label selectors gracefully.
166-167: Platform detection handles all bare metal scenariosThe
isBMPlatformfunction covers all relevant platform types that might represent bare metal infrastructure, making it robust for different deployment scenarios.libs/ui-lib/lib/cim/components/Agent/BMCForm.tsx (1)
344-354: Form submission now uses the centralized creation utilityThe form submission handler has been refactored to use the exported
onCreateBMHfunction, removing the need for a callback prop and centralizing the resource creation logic. This is a good pattern for maintainability.libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts (3)
129-129: Simplified hostActions interface reduces prop drillingThe
hostActionstype now only includes core editing capabilities, removing deletion operations that are now handled by standalone utilities. This aligns with the internal refactoring to reduce prop drilling and centralize resource operations.
164-171: Streamlined InfraEnvAgentTableProps removes callback dependenciesThe revised
InfraEnvAgentTablePropsfocuses solely on data resources, eliminating callbacks entirely. This is a clean approach that allows the component to manage its own state and actions internally.
173-176: Reduced ClusterDeploymentHostDiscoveryTableProps dependenciesThe properties picked from
AgentTableActionsnow exclude deletion operations, which aligns with the broader refactoring to use centralized utilities for these operations instead of passing callbacks.
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (5)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (1)
140-148:⚠️ Potential issueAddress the unresolved base64 decoding safety issue.
Despite being marked as addressed in previous commits, the
atob()calls are still not wrapped in try/catch blocks. This can cause runtime exceptions if the credential data contains invalid base64.Apply this fix to safely handle base64 decoding:
onSelect={(cred) => { - setFieldValue( - 'pullSecret', - cred.data?.['pullSecret'] ? atob(cred.data['pullSecret']) : '', - ); - setFieldValue( - 'sshPublicKey', - cred.data?.['ssh-publickey'] ? atob(cred.data['ssh-publickey']) : '', - ); + try { + setFieldValue( + 'pullSecret', + cred.data?.['pullSecret'] ? atob(cred.data['pullSecret']) : '', + ); + setFieldValue( + 'sshPublicKey', + cred.data?.['ssh-publickey'] ? atob(cred.data['ssh-publickey']) : '', + ); + } catch (error) { + console.error('Failed to decode credential data:', error); + setFieldValue('pullSecret', ''); + setFieldValue('sshPublicKey', ''); + } }}libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsx (2)
113-118: Handler signature mismatch persists - async actions expected but setters providedThe
useAgentsTablehook is receiving state setters (setDeleteHost,setEditBMH,setEditAgent,setUnbindHost) where it may expect async callback functions. If the hook internally awaits these handlers or expects them to return promises, passing state setters could cause the table to remain in a loading state.Verify that
useAgentsTableaccepts these setter functions. If async functions are required, wrap the setters:-onDeleteHost: setDeleteHost, -onEditBMH: setEditBMH, -onEditHost: setEditAgent, -onUnbindHost: setUnbindHost, +onDeleteHost: (params) => setDeleteHost(params), +onEditBMH: (bmh) => setEditBMH(bmh), +onEditHost: (agent) => setEditAgent(agent), +onUnbindHost: (agent) => setUnbindHost(agent),
215-215: Missing bareMetalHosts in hostname calculationThe
getAgentsHostsNamesutility function accepts both agents and BMHs to extract all hostnames, but only agents are being passed. This could result in hostname conflicts with bare metal hosts.- const usedHostnames = React.useMemo(() => getAgentsHostsNames(agents), [agents]); + const usedHostnames = React.useMemo(() => getAgentsHostsNames(agents, bareMetalHosts), [agents, bareMetalHosts]);libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/InfraEnvDetails.tsx (1)
95-106: Fix unnecessary curly braces in JSX fragmentThe JSX structure has unnecessary curly braces around the React fragment, which could cause rendering issues.
<NavItem isActive={location.pathname === hostsPath}> <Link to={hostsPath}> - { - <> - <InfraEnvHostsTabAgentsWarning - infraAgents={infraAgents} - infraBMHs={infraBMHs} - /> - {t('ai:Hosts')} - </> - } + <> + <InfraEnvHostsTabAgentsWarning + infraAgents={infraAgents} + infraBMHs={infraBMHs} + /> + {t('ai:Hosts')} + </> </Link> </NavItem>libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts (1)
29-32: Inconsistent parameter styles between delete operationsThe
onDeleteHostcallback uses a wrapper object whileonMassDeleteHoststill uses positional parameters. This inconsistency makes the API error-prone and harder to maintain.- onDeleteHost: (host: { agent?: AgentK8sResource; bmh?: BareMetalHostK8sResource }) => void; - onSetInstallationDiskId: (agent: AgentK8sResource, diskId: string) => Promise<AgentK8sResource>; - onMassDeleteHost: (agent?: AgentK8sResource, bmh?: BareMetalHostK8sResource) => Promise<unknown>; + onDeleteHost: (host: { agent?: AgentK8sResource; bmh?: BareMetalHostK8sResource }) => void; + onSetInstallationDiskId: (agent: AgentK8sResource, diskId: string) => Promise<AgentK8sResource>; + onMassDeleteHost: ( + hosts: { agent?: AgentK8sResource; bmh?: BareMetalHostK8sResource }[], + ) => Promise<unknown>;
🧹 Nitpick comments (2)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (1)
68-72: Remove unnecessary Fragment wrapper.The Fragment is redundant since it contains only one child element.
bodyContent={ - <> - {t( - 'ai:This will determine for the infrastructure environment which kind of hosts would be able to be added. If the hosts that you want to add are using DHCP server, select this option, else, select the static IP.', - )} - </> + t( + 'ai:This will determine for the infrastructure environment which kind of hosts would be able to be added. If the hosts that you want to add are using DHCP server, select this option, else, select the static IP.', + ) }🧰 Tools
🪛 Biome (1.9.4)
[error] 68-72: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment(lint/complexity/noUselessFragments)
libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/InfraEnvDetails.tsx (1)
176-178: Enhance error handling with specific error contextThe current error handling shows a generic error state without indicating which resource failed to load (InfraEnv, Agents, or BMHs).
if (error) { - return <ErrorState title={getErrorMessage(error)} />; + const errorMessage = infraErr + ? t('ai:Failed to load infrastructure environment') + : agentsErr + ? t('ai:Failed to load agents') + : t('ai:Failed to load bare metal hosts'); + + return <ErrorState + title={errorMessage} + content={t('ai:Please try refreshing the page or contact support if the issue persists.')} + />; }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
libs/ui-lib/lib/cim/logos/OnPremiseBannerIcon.svgis excluded by!**/*.svgyarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (74)
libs/locales/lib/en/translation.json(21 hunks)libs/ui-lib/lib/cim/components/Agent/BMCForm.tsx(4 hunks)libs/ui-lib/lib/cim/components/Agent/NoAgentsAlert.tsx(1 hunks)libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx(3 hunks)libs/ui-lib/lib/cim/components/Agent/types.ts(0 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostDiscoveryTable.tsx(6 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostsDiscovery.tsx(1 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentWizard.tsx(1 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts(3 hunks)libs/ui-lib/lib/cim/components/Hypershift/DetailsPage/NodePoolsTable.tsx(2 hunks)libs/ui-lib/lib/cim/components/InfraEnv/AddHostDropdown.tsx(5 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvPage.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/useInfraEnvResources.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/EnvironmentDetails.tsx(4 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsx(7 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/AgentsTab.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/DetailsTab.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/InfraEnvDetails.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvFormPage.tsx(0 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.css(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.tsx(2 hunks)libs/ui-lib/lib/cim/components/InfraEnv/index.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/infra-env.css(0 hunks)libs/ui-lib/lib/cim/components/InfraEnv/types.ts(1 hunks)libs/ui-lib/lib/cim/components/YamlEditor/Theme.ts(1 hunks)libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.css(1 hunks)libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.tsx(1 hunks)libs/ui-lib/lib/cim/components/YamlEditor/utils.ts(1 hunks)libs/ui-lib/lib/cim/components/YamlPreview/useYAMLPreview.ts(5 hunks)libs/ui-lib/lib/cim/components/common/InfoAndTroubleshootingNotification.tsx(1 hunks)libs/ui-lib/lib/cim/components/formik/CredentialsField.tsx(1 hunks)libs/ui-lib/lib/cim/components/helpers/agents.ts(3 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostModal.tsx(0 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlForm.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/AddHostModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/CimConfiguration/CimConfigProgressAlert.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/CimConfiguration/utils.ts(1 hunks)libs/ui-lib/lib/cim/components/modals/DeleteHostModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/EditBMHModal.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/EditNtpSourcesModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/EditProxyModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/EditPullSecretModal.tsx(4 hunks)libs/ui-lib/lib/cim/components/modals/EditSSHKeyModal.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/MassApproveAgentModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/MassDeleteAgentModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/ScaleUpModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/UnbindHostModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/types.ts(2 hunks)libs/ui-lib/lib/cim/components/modals/utils.ts(2 hunks)libs/ui-lib/lib/cim/config/constants.ts(1 hunks)libs/ui-lib/lib/cim/hooks/types.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useAgentClusterInstall.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useAgentMachines.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useAgents.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useBMHs.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useConfigMap.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useInfraEnvs.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useNMStates.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useProvisioningConfig.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useSecret.ts(1 hunks)libs/ui-lib/lib/cim/index.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/klusterlet.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/multi-cluster-engine.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/nm-state.ts(1 hunks)libs/ui-lib/lib/cim/types/models.ts(1 hunks)libs/ui-lib/lib/cim/utils.ts(1 hunks)libs/ui-lib/lib/common/components/clusterConfiguration/FormatDiskWarning.tsx(1 hunks)libs/ui-lib/lib/ocm/components/Routes.tsx(1 hunks)libs/ui-lib/package.json(2 hunks)
💤 Files with no reviewable changes (4)
- libs/ui-lib/lib/cim/components/Agent/types.ts
- libs/ui-lib/lib/cim/components/modals/AddBmcHostModal.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvFormPage.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/infra-env.css
✅ Files skipped from review due to trivial changes (5)
- libs/ui-lib/lib/cim/hooks/useInfraEnvs.ts
- libs/ui-lib/lib/cim/components/Agent/NoAgentsAlert.tsx
- libs/ui-lib/lib/cim/hooks/types.ts
- libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/useInfraEnvResources.ts
- libs/ui-lib/lib/cim/hooks/useAgentClusterInstall.ts
🚧 Files skipped from review as they are similar to previous changes (50)
- libs/ui-lib/lib/cim/components/modals/EditProxyModal.tsx
- libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostsDiscovery.tsx
- libs/ui-lib/lib/cim/types/k8s/klusterlet.ts
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.css
- libs/ui-lib/lib/cim/types/k8s/multi-cluster-engine.ts
- libs/ui-lib/lib/cim/index.ts
- libs/ui-lib/lib/common/components/clusterConfiguration/FormatDiskWarning.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/DetailsTab.tsx
- libs/ui-lib/lib/cim/types/k8s/nm-state.ts
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.tsx
- libs/ui-lib/lib/cim/components/modals/MassDeleteAgentModal.tsx
- libs/ui-lib/lib/cim/components/Hypershift/DetailsPage/NodePoolsTable.tsx
- libs/ui-lib/lib/cim/components/modals/MassApproveAgentModal.tsx
- libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlModal.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/index.ts
- libs/ui-lib/lib/cim/components/formik/CredentialsField.tsx
- libs/ui-lib/package.json
- libs/ui-lib/lib/cim/components/modals/EditBMHModal.tsx
- libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.css
- libs/ui-lib/lib/cim/config/constants.ts
- libs/ui-lib/lib/cim/components/modals/ScaleUpModal.tsx
- libs/ui-lib/lib/ocm/components/Routes.tsx
- libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts
- libs/ui-lib/lib/cim/components/modals/EditPullSecretModal.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/AddHostDropdown.tsx
- libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.tsx
- libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentWizard.tsx
- libs/ui-lib/lib/cim/components/modals/EditNtpSourcesModal.tsx
- libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts
- libs/ui-lib/lib/cim/components/modals/AddHostModal.tsx
- libs/ui-lib/lib/cim/components/YamlPreview/useYAMLPreview.ts
- libs/ui-lib/lib/cim/components/YamlEditor/utils.ts
- libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvPage.tsx
- libs/ui-lib/lib/cim/components/modals/EditSSHKeyModal.tsx
- libs/ui-lib/lib/cim/components/YamlEditor/Theme.ts
- libs/ui-lib/lib/cim/components/common/InfoAndTroubleshootingNotification.tsx
- libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts
- libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostDiscoveryTable.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/types.ts
- libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlForm.tsx
- libs/ui-lib/lib/cim/components/modals/DeleteHostModal.tsx
- libs/ui-lib/lib/cim/utils.ts
- libs/ui-lib/lib/cim/components/modals/types.ts
- libs/ui-lib/lib/cim/types/models.ts
- libs/ui-lib/lib/cim/components/InfraEnv/EnvironmentDetails.tsx
- libs/ui-lib/lib/cim/components/Agent/BMCForm.tsx
- libs/ui-lib/lib/cim/components/helpers/agents.ts
- libs/ui-lib/lib/cim/components/modals/UnbindHostModal.tsx
- libs/locales/lib/en/translation.json
🧰 Additional context used
🧬 Code Graph Analysis (12)
libs/ui-lib/lib/cim/components/modals/CimConfiguration/utils.ts (1)
libs/ui-lib/lib/cim/types/k8s/shared.ts (1)
StatusCondition(1-8)
libs/ui-lib/lib/cim/hooks/useAgentMachines.ts (4)
libs/ui-lib/lib/cim/hooks/types.ts (1)
K8sWatchHookListProps(3-3)libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts (1)
useK8sWatchResource(13-19)libs/ui-lib/lib/cim/components/Hypershift/types.ts (1)
AgentMachineK8sResource(186-193)libs/ui-lib/lib/cim/types/models.ts (1)
AgentMachineModel(100-109)
libs/ui-lib/lib/cim/hooks/useProvisioningConfig.ts (1)
libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts (1)
useK8sWatchResource(13-19)
libs/ui-lib/lib/cim/hooks/useSecret.ts (2)
libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts (1)
useK8sWatchResource(13-19)libs/ui-lib/lib/cim/types/models.ts (1)
SecretModel(3-11)
libs/ui-lib/lib/cim/hooks/useBMHs.ts (3)
libs/ui-lib/lib/cim/hooks/types.ts (1)
K8sWatchHookListProps(3-3)libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts (1)
useK8sWatchResource(13-19)libs/ui-lib/lib/cim/types/models.ts (1)
BMHModel(78-87)
libs/ui-lib/lib/cim/hooks/useAgents.ts (4)
libs/ui-lib/lib/cim/hooks/types.ts (1)
K8sWatchHookListProps(3-3)libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts (1)
useK8sWatchResource(13-19)libs/ui-lib/lib/cim/types/k8s/agent.ts (1)
AgentK8sResource(32-74)libs/ui-lib/lib/cim/types/models.ts (1)
AgentModel(67-76)
libs/ui-lib/lib/cim/hooks/useNMStates.ts (4)
libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts (1)
InfraEnvK8sResource(8-42)libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts (2)
WatchK8sResult(7-11)useK8sWatchResource(13-19)libs/ui-lib/lib/cim/types/k8s/nm-state.ts (1)
NMStateK8sResource(3-11)libs/ui-lib/lib/cim/types/models.ts (1)
NMStateModel(89-98)
libs/ui-lib/lib/cim/hooks/useConfigMap.ts (2)
libs/ui-lib/lib/cim/hooks/types.ts (1)
K8sWatchHookProps(4-4)libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts (1)
useK8sWatchResource(13-19)
libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsx (4)
libs/ui-lib/lib/cim/types/k8s/agent.ts (1)
AgentK8sResource(32-74)libs/ui-lib/lib/cim/utils.ts (1)
onApproveAgent(20-24)libs/ui-lib/lib/cim/components/ClusterDeployment/helpers.ts (1)
getAgentsHostsNames(196-210)libs/ui-lib/lib/cim/components/helpers/agents.ts (1)
onAgentChangeHostname(49-84)
libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/InfraEnvDetails.tsx (10)
libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts (1)
InfraEnvK8sResource(8-42)libs/ui-lib/lib/cim/types/k8s/agent.ts (1)
AgentK8sResource(32-74)libs/ui-lib/lib/cim/components/ClusterDeployment/helpers.ts (1)
getAgentsHostsNames(196-210)libs/ui-lib/lib/cim/config/constants.ts (1)
DOC_VERSION(4-4)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.tsx (1)
InfraEnvHostsTabAgentsWarning(13-16)libs/ui-lib/lib/cim/hooks/useInfraEnvs.ts (1)
useInfraEnv(6-14)libs/ui-lib/lib/cim/hooks/useAgents.ts (1)
useAgents(6-19)libs/ui-lib/lib/cim/hooks/useBMHs.ts (1)
useBMHs(6-19)libs/ui-lib/lib/cim/components/common/constants.ts (1)
INFRAENV_AGENTINSTALL_LABEL_KEY(10-10)libs/ui-lib/lib/common/utils.ts (1)
getErrorMessage(13-21)
libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts (5)
libs/ui-lib/lib/cim/types/k8s/agent.ts (1)
AgentK8sResource(32-74)libs/ui-lib/lib/cim/components/Hypershift/types.ts (1)
AgentMachineK8sResource(186-193)libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts (1)
InfraEnvK8sResource(8-42)libs/ui-lib/lib/cim/types/k8s/nm-state.ts (1)
NMStateK8sResource(3-11)libs/ui-lib/lib/cim/types/k8s/agent-cluster-install.ts (1)
AgentClusterInstallK8sResource(17-80)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (4)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts (1)
EnvironmentStepFormValues(15-34)libs/ui-lib/lib/common/config/docs_links.ts (1)
getOCPStaticIPDocLink(62-63)libs/ui-lib/lib/cim/config/constants.ts (1)
DOC_VERSION(4-4)libs/ui-lib/lib/common/components/ui/formik/LabelField.tsx (1)
LabelField(34-100)
🪛 Biome (1.9.4)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx
[error] 68-72: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment
(lint/complexity/noUselessFragments)
🔇 Additional comments (20)
libs/ui-lib/lib/cim/hooks/useConfigMap.ts (1)
1-16: LGTM! Well-implemented resource watch hook.This hook follows excellent practices:
- Defensive programming: The conditional logic prevents unnecessary API calls when required parameters are missing
- Correct resource specification: ConfigMap is properly defined as a core v1 resource (no group field needed)
- Type safety: Properly typed with
ConfigMapK8sResourceandK8sWatchHookProps- Consistent pattern: Follows the established pattern used by other resource watch hooks in this refactor
The implementation correctly handles edge cases where name or namespace might be undefined, null, or empty strings by returning null to disable the watch.
libs/ui-lib/lib/cim/components/modals/CimConfiguration/utils.ts (2)
3-7: LGTM: Import changes are appropriate.The addition of
StatusConditionto the imports is necessary for the new local function definition and follows the existing import patterns.
12-18:Details
✅ Verification successful
Function implementation is correct, but verify for code duplication.
The
getConditionByTypefunction is well-implemented with proper generics and type safety. However, since this was moved from a shared utility module, ensure no other modules have duplicated this functionality.
🏁 Script executed:
#!/bin/bash # Description: Check for potential duplicate implementations of getConditionByType function # Expected: Should find minimal occurrences, ideally only in this file and potentially the original shared module echo "Searching for getConditionByType function definitions..." ast-grep --pattern 'export const getConditionByType = $$$' echo -e "\nSearching for any getConditionByType references..." rg -A 3 'getConditionByType.*=' --type ts --type tsx echo -e "\nSearching for imports of getConditionByType from other modules..." rg 'import.*getConditionByType' --type ts --type tsxLength of output: 1241
🏁 Script executed:
#!/bin/bash # Comprehensive search for all occurrences of getConditionByType in the repository echo "Searching for all instances of getConditionByType..." rg -n 'getConditionByType' .Length of output: 1113
No duplicate implementation found – approving changes.
Search across the repo shows only one
getConditionByTypedefinition (in utils.ts) and its expected imports/references, with no other copies elsewhere. Feel free to proceed with this implementation.libs/ui-lib/lib/cim/components/modals/CimConfiguration/CimConfigProgressAlert.tsx (1)
15-15:Details
✅ Verification successful
Verify that the function move doesn't introduce code duplication.
The import consolidation looks good for code organization. However, please verify that moving
getConditionByTypefrom the shared utils (../../../utils) to local utils (./utils) doesn't create code duplication if other components were using this function.
🏁 Script executed:
#!/bin/bash # Description: Check if getConditionByType is used elsewhere in the codebase # Expected: Should only find usage in the current file and the new local utils file echo "Searching for getConditionByType usage across the codebase..." rg -A 2 "getConditionByType" --type ts --type tsx echo -e "\nSearching for imports from the old shared utils location..." rg "from ['\"].*?/utils['\"]" --type ts --type tsx -A 1 -B 1Length of output: 440
🏁 Script executed:
#!/bin/bash # Retry searching without relying on rg’s built-in --type flags echo "🔍 Searching for getConditionByType usage across .ts/.tsx files..." rg -A2 "getConditionByType" -g '*.ts' -g '*.tsx' || true echo -e "\n🔍 Searching for imports from the old shared utils location..." rg -A2 "from ['\"][^'\"]*/utils['\"]" -g '*.ts' -g '*.tsx' || trueLength of output: 61659
Consolidation Safe: No Duplication Detected
Search results confirm that
getConditionByTypeis defined only in
libs/ui-lib/lib/cim/components/modals/CimConfiguration/utils.ts
and imported only bylibs/ui-lib/lib/cim/components/modals/CimConfiguration/CimConfigProgressAlert.tsx.There are no remaining imports of
getConditionByTypefrom any shared “../../../utils” location. Consolidating it locally does not introduce duplication or break other components—this change is safe to approve.libs/ui-lib/lib/cim/hooks/useProvisioningConfig.ts (1)
4-12: LGTM! Clean implementation following established patterns.The hook correctly configures the watch for the metal3.io Provisioning resource and follows the same pattern as other resource-specific hooks in the codebase.
libs/ui-lib/lib/cim/hooks/useSecret.ts (1)
5-19: Well-structured conditional logic and parameter handling.The hook properly handles the optional parameters and conditionally enables/disables the watch based on whether a name is provided. The parameter structure and typing are correct for watching individual Secret resources.
libs/ui-lib/lib/cim/hooks/useAgentMachines.ts (1)
6-15: LGTM! Consistent implementation following established patterns.The hook correctly configures list watching for AgentMachine resources, properly uses the spread operator to merge props while ensuring
isList: true, and follows the same pattern as other list-watching hooks in the codebase.libs/ui-lib/lib/cim/hooks/useBMHs.ts (1)
6-19: LGTM! Proper implementation with correct conditional logic.The hook follows the established pattern for optional list watching, correctly uses the BMHModel configuration, and properly handles the conditional watch enabling/disabling based on the props parameter.
libs/ui-lib/lib/cim/hooks/useAgents.ts (1)
6-19: LGTM! Clean implementation of typed Agent resource watcher.The hook follows the established pattern and correctly configures the watch with AgentModel metadata. The conditional watching and proper typing make this a solid addition to the resource watching utilities.
libs/ui-lib/lib/cim/hooks/useNMStates.ts (1)
7-39: LGTM! Well-designed hook with proper filtering and memoization.The hook correctly watches NMState resources and filters them based on the InfraEnv's label selector. The use of
React.useMemowith appropriate dependencies ensures efficient re-filtering, and the lodashisMatchfunction provides robust label matching.libs/ui-lib/lib/cim/components/modals/utils.ts (1)
98-132: LGTM! Comprehensive host deletion orchestration.The function properly handles the complete deletion workflow including agent, BMH, associated NMState resources, and provision requirement updates. The bounds checking for worker count and the filtering logic for NMState resources are well-implemented.
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (1)
41-181: Well-structured form component with comprehensive UI elements.The form implementation is well-organized with proper Formik integration, PatternFly components, and comprehensive field coverage for infrastructure environment creation. The conditional rendering and validation setup demonstrate good practices.
🧰 Tools
🪛 Biome (1.9.4)
[error] 68-72: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment(lint/complexity/noUselessFragments)
libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsx (2)
34-50: Clean imports organizationThe new modal imports and utilities are well-organized and support the internalization refactor effectively.
258-288: Well-structured modal state managementThe conditional rendering of modals based on internal state is clean and follows React best practices. Each modal receives the appropriate data and close handlers.
libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/AgentsTab.tsx (3)
21-45: Well-designed custom hook for resource aggregationThe
useAgentTabResourceshook effectively combines multiple resource watchers and provides unified loading/error states. The hook correctly handles the namespace parameter and returns a clean interface.
47-77: Proper async state handlingThe
AgentsTabcomponent correctly handles loading and error states before rendering content, following React best practices for async data fetching.
79-124: Clean UI structure with PatternFly componentsThe
AgentsTabContentcomponent is well-structured using PatternFly layout components and properly passes all required data to theInfraEnvAgentTable.libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/InfraEnvDetails.tsx (1)
120-167: Excellent resource management with label selectorsThe
useInfraEnvResourceshook demonstrates proper Kubernetes resource watching with appropriate label selectors for filtering agents and BMHs. The logic correctly builds selectors from the InfraEnv status.libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts (2)
164-171: Excellent simplification of component propsThe
InfraEnvAgentTablePropstype has been significantly simplified by removing external callback dependencies. This supports the refactoring goal of internalizing host and agent management logic.
129-129:Details
❓ Verification inconclusive
Verify all hostActions consumers are updated
The
hostActionstype has been reduced to only include specific actions. Ensure all components using this type have been updated to handle the removed callbacks internally.
🏁 Script executed:
#!/bin/bash # Description: Verify no components are still destructuring removed hostActions properties # Search for any remaining references to removed hostActions properties rg -n "hostActions.*onDeleteHost|hostActions.*onApprove|hostActions.*onChangeHostname" # Check for destructuring patterns that might include removed properties rg -n "onDeleteHost.*hostActions|onApprove.*hostActions|onChangeHostname.*hostActions"Length of output: 177
Verify removal of deprecated hostActions callbacks
No matches were found for the removed callbacks (
onDeleteHost,onApprove,onChangeHostname) when searching the codebase. Please manually review any components or destructuring patterns that consumehostActionsto confirm they no longer expect these callbacks and correctly handle only the remaining actions (onEditHost,onEditRole,onSetInstallationDiskId).
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Verify the apiGroup reference for core Kubernetes resources.
The SecretModel in the relevant snippets doesn't include an apiGroup field. For core Kubernetes resources like Secrets, the API group is typically empty. Referencing SecretModel.apiGroup (line 12) will result in group: undefined, which may work but could be problematic.
🏁 Script executed:
#!/bin/bash
# Check if SecretModel includes apiGroup field
ast-grep --pattern $'export const SecretModel: K8sModel = {
$$$
}'Length of output: 592
Handle undefined apiGroup for core Secret resources
The SecretModel in libs/ui-lib/lib/cim/types/models.ts doesn’t define an apiGroup, so SecretModel.apiGroup is undefined. This leads to:
// libs/ui-lib/lib/cim/hooks/useSecret.ts:12
group: SecretModel.apiGroup, // → undefinedKubernetes core resources must use an empty string for the group. You’ll need to choose one of the following fixes:
• In models.ts, add an explicit empty apiGroup property:
export const SecretModel: K8sModel = {
apiGroup: '',
apiVersion: 'v1',
…
};• Or in useSecret.ts, provide a fallback when building groupVersionKind:
-group: SecretModel.apiGroup,
+group: SecretModel.apiGroup ?? '',Either change will ensure group is correctly set to '' instead of undefined.
🤖 Prompt for AI Agents
In libs/ui-lib/lib/cim/hooks/useSecret.ts around lines 9 to 13, the group field
is set to SecretModel.apiGroup, which is undefined for core Kubernetes resources
like Secrets. To fix this, update the code to provide a fallback empty string
for the group field when SecretModel.apiGroup is undefined, ensuring group is
set to '' instead of undefined. Alternatively, add an explicit apiGroup: ''
property to SecretModel in libs/ui-lib/lib/cim/types/models.ts.
ff846eb to
b9e36d2
Compare
|
@rawagner: This pull request references ACM-20968 which is a valid jira issue. Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.20.0" version, but no target version was set. DetailsIn response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository. |
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (5)
libs/ui-lib/lib/cim/hooks/useSecret.ts (2)
20-24: Handle undefined apiGroup for core Secret resources.The
SecretModeldoesn't define anapiGroup, soSecretModel.apiGroupisundefined. For core Kubernetes resources like Secrets, the group should be an empty string.Apply this fix:
groupVersionKind: { kind: SecretModel.kind, version: SecretModel.apiVersion, - group: SecretModel.apiGroup, + group: SecretModel.apiGroup ?? '', },
6-14: 🛠️ Refactor suggestionInconsistent group handling between hooks.
The
useSecretshook doesn't specify agroupfield, whileuseSecretdoes. For consistency and correctness with core Kubernetes resources, both should handle the group field the same way.Apply this diff to make the hooks consistent:
export const useSecrets = (props: K8sWatchHookListProps) => useK8sWatchResource<SecretK8sResource[]>({ groupVersionKind: { kind: SecretModel.kind, version: SecretModel.apiVersion, + group: SecretModel.apiGroup ?? '', }, ...props, isList: true, });libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (1)
140-148:⚠️ Potential issueAdd error handling for base64 decoding.
The
atob()function can throw exceptions if the input isn't properly base64-encoded. Despite being marked as addressed in previous reviews, this issue still exists.Apply this diff to add proper error handling:
onSelect={(cred) => { - setFieldValue( - 'pullSecret', - cred.data?.['pullSecret'] ? atob(cred.data['pullSecret']) : '', - ); - setFieldValue( - 'sshPublicKey', - cred.data?.['ssh-publickey'] ? atob(cred.data['ssh-publickey']) : '', - ); + try { + setFieldValue( + 'pullSecret', + cred.data?.['pullSecret'] ? atob(cred.data['pullSecret']) : '', + ); + setFieldValue( + 'sshPublicKey', + cred.data?.['ssh-publickey'] ? atob(cred.data['ssh-publickey']) : '', + ); + } catch (error) { + console.error('Failed to decode credential data:', error); + setFieldValue('pullSecret', ''); + setFieldValue('sshPublicKey', ''); + } }}libs/ui-lib/lib/cim/components/modals/EditPullSecretModal.tsx (1)
151-151:⚠️ Potential issueAdd error handling for base64 encoding
The
btoa()function can throw exceptions when input contains non-ASCII characters. Consider adding try/catch blocks to handle potential encoding errors.Apply this fix at both locations (lines 151 and 164):
- '.dockerconfigjson': btoa(values.pullSecret), + '.dockerconfigjson': (() => { + try { + return btoa(values.pullSecret); + } catch (error) { + console.error('Failed to encode pull secret:', error); + throw new Error('Pull secret contains invalid characters that cannot be encoded'); + } + })(),Also applies to: 164-164
libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts (1)
29-31: 🛠️ Refactor suggestionFix inconsistent parameter signatures between delete functions
The
onDeleteHostfunction uses a single wrapper object parameter, whileonMassDeleteHoststill uses two separate parameters. This inconsistency makes the API error-prone and was flagged in previous reviews.Apply this fix to unify the API:
- onMassDeleteHost: (agent?: AgentK8sResource, bmh?: BareMetalHostK8sResource) => Promise<unknown>; + onMassDeleteHost: ( + hosts: { agent?: AgentK8sResource; bmh?: BareMetalHostK8sResource }[], + ) => Promise<unknown>;This change will:
- Make "mass" semantics explicit with an array parameter
- Prevent parameter swap bugs
- Provide consistent calling conventions
🧹 Nitpick comments (1)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (1)
68-72: Remove unnecessary Fragment wrapper.The Fragment is redundant since it only contains a single child element.
Apply this diff:
- <> {t( 'ai:This will determine for the infrastructure environment which kind of hosts would be able to be added. If the hosts that you want to add are using DHCP server, select this option, else, select the static IP.', )} - </>🧰 Tools
🪛 Biome (1.9.4)
[error] 68-72: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment(lint/complexity/noUselessFragments)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
libs/ui-lib/lib/cim/logos/OnPremiseBannerIcon.svgis excluded by!**/*.svgyarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (75)
libs/locales/lib/en/translation.json(21 hunks)libs/ui-lib/lib/cim/components/Agent/BMCForm.tsx(4 hunks)libs/ui-lib/lib/cim/components/Agent/NoAgentsAlert.tsx(1 hunks)libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx(3 hunks)libs/ui-lib/lib/cim/components/Agent/types.ts(0 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostDiscoveryTable.tsx(6 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostsDiscovery.tsx(1 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentWizard.tsx(1 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts(3 hunks)libs/ui-lib/lib/cim/components/Hypershift/DetailsPage/NodePoolsTable.tsx(2 hunks)libs/ui-lib/lib/cim/components/InfraEnv/AddHostDropdown.tsx(5 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvPage.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/useInfraEnvResources.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/EnvironmentDetails.tsx(4 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsx(7 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/AgentsTab.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/DetailsTab.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/InfraEnvDetails.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvFormPage.tsx(0 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.css(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.tsx(2 hunks)libs/ui-lib/lib/cim/components/InfraEnv/index.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/infra-env.css(0 hunks)libs/ui-lib/lib/cim/components/InfraEnv/types.ts(1 hunks)libs/ui-lib/lib/cim/components/YamlEditor/Theme.ts(1 hunks)libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.css(1 hunks)libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.tsx(1 hunks)libs/ui-lib/lib/cim/components/YamlEditor/utils.ts(1 hunks)libs/ui-lib/lib/cim/components/YamlPreview/useYAMLPreview.ts(5 hunks)libs/ui-lib/lib/cim/components/common/InfoAndTroubleshootingNotification.tsx(1 hunks)libs/ui-lib/lib/cim/components/formik/CredentialsField.tsx(1 hunks)libs/ui-lib/lib/cim/components/helpers/agents.ts(3 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostModal.tsx(0 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlForm.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/AddHostModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/CimConfiguration/CimConfigProgressAlert.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/CimConfiguration/utils.ts(1 hunks)libs/ui-lib/lib/cim/components/modals/DeleteHostModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/EditBMHModal.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/EditNtpSourcesModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/EditProxyModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/EditPullSecretModal.tsx(4 hunks)libs/ui-lib/lib/cim/components/modals/EditSSHKeyModal.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/MassApproveAgentModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/MassDeleteAgentModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/ScaleUpModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/UnbindHostModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/types.ts(2 hunks)libs/ui-lib/lib/cim/components/modals/utils.ts(2 hunks)libs/ui-lib/lib/cim/config/constants.ts(1 hunks)libs/ui-lib/lib/cim/hooks/types.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useAgentClusterInstall.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useAgentMachines.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useAgentServiceConfig.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useAgents.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useBMHs.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useConfigMap.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useInfraEnvs.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useNMStates.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useProvisioningConfig.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useSecret.ts(1 hunks)libs/ui-lib/lib/cim/index.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/klusterlet.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/multi-cluster-engine.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/nm-state.ts(1 hunks)libs/ui-lib/lib/cim/types/models.ts(1 hunks)libs/ui-lib/lib/cim/utils.ts(1 hunks)libs/ui-lib/lib/common/components/clusterConfiguration/FormatDiskWarning.tsx(1 hunks)libs/ui-lib/lib/ocm/components/Routes.tsx(1 hunks)libs/ui-lib/package.json(2 hunks)
💤 Files with no reviewable changes (4)
- libs/ui-lib/lib/cim/components/InfraEnv/infra-env.css
- libs/ui-lib/lib/cim/components/Agent/types.ts
- libs/ui-lib/lib/cim/components/modals/AddBmcHostModal.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvFormPage.tsx
✅ Files skipped from review due to trivial changes (2)
- libs/ui-lib/lib/cim/hooks/useAgentMachines.ts
- libs/ui-lib/lib/cim/hooks/useAgentClusterInstall.ts
🚧 Files skipped from review as they are similar to previous changes (61)
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.css
- libs/ui-lib/lib/cim/config/constants.ts
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.tsx
- libs/ui-lib/lib/common/components/clusterConfiguration/FormatDiskWarning.tsx
- libs/ui-lib/lib/cim/types/k8s/multi-cluster-engine.ts
- libs/ui-lib/lib/cim/index.ts
- libs/ui-lib/lib/cim/components/modals/CimConfiguration/CimConfigProgressAlert.tsx
- libs/ui-lib/package.json
- libs/ui-lib/lib/cim/components/InfraEnv/types.ts
- libs/ui-lib/lib/cim/hooks/useProvisioningConfig.ts
- libs/ui-lib/lib/cim/components/modals/MassApproveAgentModal.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/index.ts
- libs/ui-lib/lib/cim/types/k8s/klusterlet.ts
- libs/ui-lib/lib/cim/hooks/useBMHs.ts
- libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlModal.tsx
- libs/ui-lib/lib/cim/hooks/useNMStates.ts
- libs/ui-lib/lib/cim/components/modals/utils.ts
- libs/ui-lib/lib/cim/components/modals/AddHostModal.tsx
- libs/ui-lib/lib/cim/hooks/useConfigMap.ts
- libs/ui-lib/lib/cim/components/modals/CimConfiguration/utils.ts
- libs/ui-lib/lib/cim/components/Hypershift/DetailsPage/NodePoolsTable.tsx
- libs/ui-lib/lib/cim/components/modals/EditProxyModal.tsx
- libs/ui-lib/lib/cim/components/YamlEditor/Theme.ts
- libs/ui-lib/lib/cim/hooks/useAgents.ts
- libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/useInfraEnvResources.ts
- libs/ui-lib/lib/cim/hooks/types.ts
- libs/ui-lib/lib/cim/components/modals/ScaleUpModal.tsx
- libs/ui-lib/lib/cim/components/modals/MassDeleteAgentModal.tsx
- libs/ui-lib/lib/cim/components/modals/EditBMHModal.tsx
- libs/ui-lib/lib/cim/types/k8s/nm-state.ts
- libs/ui-lib/lib/cim/components/modals/EditNtpSourcesModal.tsx
- libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentWizard.tsx
- libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.css
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/DetailsTab.tsx
- libs/ui-lib/lib/cim/components/YamlEditor/utils.ts
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/InfraEnvDetails.tsx
- libs/ui-lib/lib/cim/components/modals/EditSSHKeyModal.tsx
- libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx
- libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostsDiscovery.tsx
- libs/ui-lib/lib/cim/components/modals/types.ts
- libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlForm.tsx
- libs/ui-lib/lib/cim/components/modals/DeleteHostModal.tsx
- libs/ui-lib/lib/cim/components/YamlPreview/useYAMLPreview.ts
- libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts
- libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.tsx
- libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts
- libs/ui-lib/lib/cim/components/helpers/agents.ts
- libs/ui-lib/lib/cim/components/common/InfoAndTroubleshootingNotification.tsx
- libs/ui-lib/lib/ocm/components/Routes.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/AddHostDropdown.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/EnvironmentDetails.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsx
- libs/ui-lib/lib/cim/components/formik/CredentialsField.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvPage.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/AgentsTab.tsx
- libs/ui-lib/lib/cim/components/Agent/NoAgentsAlert.tsx
- libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostDiscoveryTable.tsx
- libs/ui-lib/lib/cim/components/modals/UnbindHostModal.tsx
- libs/ui-lib/lib/cim/types/models.ts
- libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts
- libs/locales/lib/en/translation.json
🧰 Additional context used
🧬 Code Graph Analysis (5)
libs/ui-lib/lib/cim/hooks/useInfraEnvs.ts (4)
libs/ui-lib/lib/cim/hooks/types.ts (2)
K8sWatchHookListProps(3-3)K8sWatchHookProps(4-4)libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts (1)
useK8sWatchResource(13-19)libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts (1)
InfraEnvK8sResource(8-42)libs/ui-lib/lib/cim/types/models.ts (1)
InfraEnvModel(24-33)
libs/ui-lib/lib/cim/hooks/useAgentServiceConfig.ts (4)
libs/ui-lib/lib/cim/hooks/types.ts (1)
K8sWatchHookListProps(3-3)libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts (1)
useK8sWatchResource(13-19)libs/ui-lib/lib/cim/types/k8s/agent-service-config.ts (1)
AgentServiceConfigK8sResource(23-33)libs/ui-lib/lib/cim/types/models.ts (1)
AgentServiceConfigModel(35-44)
libs/ui-lib/lib/cim/hooks/useSecret.ts (3)
libs/ui-lib/lib/cim/hooks/types.ts (2)
K8sWatchHookListProps(3-3)K8sWatchHookProps(4-4)libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts (1)
useK8sWatchResource(13-19)libs/ui-lib/lib/cim/types/models.ts (1)
SecretModel(3-11)
libs/ui-lib/lib/cim/components/modals/EditPullSecretModal.tsx (3)
libs/ui-lib/lib/common/utils.ts (1)
getErrorMessage(13-21)libs/ui-lib/lib/cim/components/modals/types.ts (1)
EditPullSecretFormikValues(41-44)libs/ui-lib/lib/cim/types/models.ts (1)
SecretModel(3-11)
libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts (5)
libs/ui-lib/lib/cim/types/k8s/agent.ts (1)
AgentK8sResource(32-74)libs/ui-lib/lib/cim/components/Hypershift/types.ts (1)
AgentMachineK8sResource(186-193)libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts (1)
InfraEnvK8sResource(8-42)libs/ui-lib/lib/cim/types/k8s/nm-state.ts (1)
NMStateK8sResource(3-11)libs/ui-lib/lib/cim/types/k8s/agent-cluster-install.ts (1)
AgentClusterInstallK8sResource(17-80)
🪛 Biome (1.9.4)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx
[error] 68-72: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment
(lint/complexity/noUselessFragments)
🔇 Additional comments (8)
libs/ui-lib/lib/cim/hooks/useAgentServiceConfig.ts (1)
6-15: LGTM! Clean and consistent hook implementation.The hook follows the established pattern for Kubernetes resource watching hooks and correctly configures the AgentServiceConfig resource type with proper typing.
libs/ui-lib/lib/cim/hooks/useInfraEnvs.ts (2)
6-15: LGTM! Well-structured list hook implementation.The
useInfraEnvshook correctly implements the list pattern with proper typing and configuration.
17-25: LGTM! Clean single resource hook implementation.The
useInfraEnvhook follows the correct pattern for watching single Kubernetes resources.libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (1)
36-184: Well-structured form component with comprehensive features.The component provides a good user experience with proper validation, internationalization, helpful popovers, and logical field organization. The integration with Formik and PatternFly components is well-executed.
🧰 Tools
🪛 Biome (1.9.4)
[error] 68-72: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment(lint/complexity/noUselessFragments)
libs/ui-lib/lib/cim/utils.ts (1)
1-58: Well-structured utility functions for K8s resource managementThe refactored utilities provide a clean foundation for Kubernetes resource operations. The
appendPatchfunction correctly handles the undefined vs falsy value distinction, and the specialized functions (onApproveAgent,setProvisionRequirements,getAgentName) follow consistent patterns for their respective use cases.libs/ui-lib/lib/cim/components/Agent/BMCForm.tsx (2)
238-335: Excellent centralization of resource management logicThe new
onCreateBMHfunction effectively consolidates the creation and patching of BMH, Secret, and NMState resources. The implementation correctly uses theappendPatchutility for safe patching operations and handles both create and update scenarios appropriately.
455-455: Good practice using void to suppress async lint warningsThe arrow function wrapper with
voidproperly handles the asyncsubmitForm()call and suppresses linting warnings about unhandled promises.libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts (1)
164-192: Type simplifications align well with architectural improvementsThe removal of numerous callback properties from these type definitions successfully reduces prop drilling and external dependencies. This aligns perfectly with the broader refactoring effort to internalize host and agent management operations within components.
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (3)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (1)
140-148: The atob() decoding issue still exists.The previous review comment about adding error handling for base64 decoding was marked as addressed, but the code still contains unprotected
atob()calls that can throw exceptions with invalid input.libs/ui-lib/lib/cim/components/modals/EditPullSecretModal.tsx (1)
151-151: Add error handling for base64 encoding.The
btoa()function can throw exceptions when input contains non-ASCII characters. Consider adding try/catch blocks to handle potential encoding errors.- '.dockerconfigjson': btoa(values.pullSecret), + '.dockerconfigjson': (() => { + try { + return btoa(values.pullSecret); + } catch (error) { + console.error('Failed to encode pull secret:', error); + throw new Error('Pull secret contains invalid characters that cannot be encoded'); + } + })(),Also applies to: 164-164
libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts (1)
29-31: Inconsistent delete API signatures create developer confusion.While
onDeleteHostwas updated to use a wrapper object parameter,onMassDeleteHoststill uses two positional parameters. This inconsistency makes the API error-prone and complicates refactoring.- onMassDeleteHost: (agent?: AgentK8sResource, bmh?: BareMetalHostK8sResource) => Promise<unknown>; + onMassDeleteHost: ( + hosts: { agent?: AgentK8sResource; bmh?: BareMetalHostK8sResource }[], + ) => Promise<unknown>;This would unify the API style, make "mass" semantics explicit, and prevent parameter swap bugs.
🧹 Nitpick comments (1)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (1)
68-72: Remove unnecessary Fragment.The Fragment is redundant since it only contains a single child element.
-bodyContent={ - <> - {t( - 'ai:This will determine for the infrastructure environment which kind of hosts would be able to be added. If the hosts that you want to add are using DHCP server, select this option, else, select the static IP.', - )} - </> -} +bodyContent={t( + 'ai:This will determine for the infrastructure environment which kind of hosts would be able to be added. If the hosts that you want to add are using DHCP server, select this option, else, select the static IP.', +)}🧰 Tools
🪛 Biome (1.9.4)
[error] 68-72: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment(lint/complexity/noUselessFragments)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
libs/ui-lib/lib/cim/logos/OnPremiseBannerIcon.svgis excluded by!**/*.svgyarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (75)
libs/locales/lib/en/translation.json(21 hunks)libs/ui-lib/lib/cim/components/Agent/BMCForm.tsx(4 hunks)libs/ui-lib/lib/cim/components/Agent/NoAgentsAlert.tsx(1 hunks)libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx(3 hunks)libs/ui-lib/lib/cim/components/Agent/types.ts(0 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostDiscoveryTable.tsx(6 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostsDiscovery.tsx(1 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentWizard.tsx(1 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts(3 hunks)libs/ui-lib/lib/cim/components/Hypershift/DetailsPage/NodePoolsTable.tsx(2 hunks)libs/ui-lib/lib/cim/components/InfraEnv/AddHostDropdown.tsx(5 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvPage.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/useInfraEnvResources.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/EnvironmentDetails.tsx(4 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsx(7 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/AgentsTab.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/DetailsTab.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/InfraEnvDetails.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvFormPage.tsx(0 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.css(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.tsx(2 hunks)libs/ui-lib/lib/cim/components/InfraEnv/index.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/infra-env.css(0 hunks)libs/ui-lib/lib/cim/components/InfraEnv/types.ts(1 hunks)libs/ui-lib/lib/cim/components/YamlEditor/Theme.ts(1 hunks)libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.css(1 hunks)libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.tsx(1 hunks)libs/ui-lib/lib/cim/components/YamlEditor/utils.ts(1 hunks)libs/ui-lib/lib/cim/components/YamlPreview/useYAMLPreview.ts(5 hunks)libs/ui-lib/lib/cim/components/common/InfoAndTroubleshootingNotification.tsx(1 hunks)libs/ui-lib/lib/cim/components/formik/CredentialsField.tsx(1 hunks)libs/ui-lib/lib/cim/components/helpers/agents.ts(3 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostModal.tsx(0 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlForm.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/AddHostModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/CimConfiguration/CimConfigProgressAlert.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/CimConfiguration/utils.ts(1 hunks)libs/ui-lib/lib/cim/components/modals/DeleteHostModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/EditBMHModal.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/EditNtpSourcesModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/EditProxyModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/EditPullSecretModal.tsx(4 hunks)libs/ui-lib/lib/cim/components/modals/EditSSHKeyModal.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/MassApproveAgentModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/MassDeleteAgentModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/ScaleUpModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/UnbindHostModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/types.ts(2 hunks)libs/ui-lib/lib/cim/components/modals/utils.ts(2 hunks)libs/ui-lib/lib/cim/config/constants.ts(1 hunks)libs/ui-lib/lib/cim/hooks/types.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useAgentClusterInstall.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useAgentMachines.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useAgentServiceConfig.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useAgents.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useBMHs.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useConfigMap.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useInfraEnvs.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useNMStates.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useProvisioningConfig.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useSecret.ts(1 hunks)libs/ui-lib/lib/cim/index.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/klusterlet.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/multi-cluster-engine.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/nm-state.ts(1 hunks)libs/ui-lib/lib/cim/types/models.ts(1 hunks)libs/ui-lib/lib/cim/utils.ts(1 hunks)libs/ui-lib/lib/common/components/clusterConfiguration/FormatDiskWarning.tsx(1 hunks)libs/ui-lib/lib/ocm/components/Routes.tsx(1 hunks)libs/ui-lib/package.json(2 hunks)
💤 Files with no reviewable changes (4)
- libs/ui-lib/lib/cim/components/Agent/types.ts
- libs/ui-lib/lib/cim/components/InfraEnv/infra-env.css
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvFormPage.tsx
- libs/ui-lib/lib/cim/components/modals/AddBmcHostModal.tsx
✅ Files skipped from review due to trivial changes (4)
- libs/ui-lib/lib/cim/components/modals/CimConfiguration/CimConfigProgressAlert.tsx
- libs/ui-lib/lib/cim/hooks/useAgentServiceConfig.ts
- libs/ui-lib/lib/cim/components/modals/MassDeleteAgentModal.tsx
- libs/ui-lib/lib/cim/hooks/types.ts
🚧 Files skipped from review as they are similar to previous changes (62)
- libs/ui-lib/lib/common/components/clusterConfiguration/FormatDiskWarning.tsx
- libs/ui-lib/lib/cim/components/Agent/NoAgentsAlert.tsx
- libs/ui-lib/lib/cim/types/k8s/multi-cluster-engine.ts
- libs/ui-lib/lib/cim/index.ts
- libs/ui-lib/lib/cim/config/constants.ts
- libs/ui-lib/lib/cim/components/InfraEnv/index.ts
- libs/ui-lib/lib/cim/components/modals/MassApproveAgentModal.tsx
- libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.css
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.tsx
- libs/ui-lib/lib/cim/components/modals/EditBMHModal.tsx
- libs/ui-lib/lib/cim/hooks/useBMHs.ts
- libs/ui-lib/lib/ocm/components/Routes.tsx
- libs/ui-lib/lib/cim/components/modals/CimConfiguration/utils.ts
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/DetailsTab.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.css
- libs/ui-lib/lib/cim/hooks/useInfraEnvs.ts
- libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlModal.tsx
- libs/ui-lib/lib/cim/components/modals/EditProxyModal.tsx
- libs/ui-lib/lib/cim/hooks/useProvisioningConfig.ts
- libs/ui-lib/lib/cim/components/YamlEditor/Theme.ts
- libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/useInfraEnvResources.ts
- libs/ui-lib/lib/cim/components/Hypershift/DetailsPage/NodePoolsTable.tsx
- libs/ui-lib/lib/cim/types/k8s/nm-state.ts
- libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts
- libs/ui-lib/lib/cim/hooks/useConfigMap.ts
- libs/ui-lib/lib/cim/components/YamlEditor/utils.ts
- libs/ui-lib/lib/cim/components/modals/ScaleUpModal.tsx
- libs/ui-lib/lib/cim/hooks/useAgentMachines.ts
- libs/ui-lib/lib/cim/types/k8s/klusterlet.ts
- libs/ui-lib/lib/cim/components/modals/EditNtpSourcesModal.tsx
- libs/ui-lib/lib/cim/components/formik/CredentialsField.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvPage.tsx
- libs/ui-lib/lib/cim/hooks/useAgentClusterInstall.ts
- libs/ui-lib/lib/cim/components/common/InfoAndTroubleshootingNotification.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/AddHostDropdown.tsx
- libs/ui-lib/package.json
- libs/ui-lib/lib/cim/hooks/useAgents.ts
- libs/ui-lib/lib/cim/components/InfraEnv/types.ts
- libs/ui-lib/lib/cim/components/modals/EditSSHKeyModal.tsx
- libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostDiscoveryTable.tsx
- libs/ui-lib/lib/cim/hooks/useSecret.ts
- libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostsDiscovery.tsx
- libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentWizard.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsx
- libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.tsx
- libs/ui-lib/lib/cim/hooks/useNMStates.ts
- libs/ui-lib/lib/cim/components/helpers/agents.ts
- libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlForm.tsx
- libs/ui-lib/lib/cim/components/modals/DeleteHostModal.tsx
- libs/ui-lib/lib/cim/components/YamlPreview/useYAMLPreview.ts
- libs/ui-lib/lib/cim/components/modals/types.ts
- libs/ui-lib/lib/cim/components/Agent/BMCForm.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/AgentsTab.tsx
- libs/ui-lib/lib/cim/components/modals/AddHostModal.tsx
- libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts
- libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts
- libs/ui-lib/lib/cim/types/models.ts
- libs/ui-lib/lib/cim/components/InfraEnv/EnvironmentDetails.tsx
- libs/ui-lib/lib/cim/components/modals/UnbindHostModal.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/InfraEnvDetails.tsx
- libs/locales/lib/en/translation.json
🧰 Additional context used
🧬 Code Graph Analysis (5)
libs/ui-lib/lib/cim/utils.ts (2)
libs/ui-lib/lib/cim/types/k8s/agent.ts (1)
AgentK8sResource(32-74)libs/ui-lib/lib/cim/types/models.ts (1)
AgentModel(67-76)
libs/ui-lib/lib/cim/components/modals/EditPullSecretModal.tsx (3)
libs/ui-lib/lib/common/utils.ts (1)
getErrorMessage(13-21)libs/ui-lib/lib/cim/components/modals/types.ts (1)
EditPullSecretFormikValues(41-44)libs/ui-lib/lib/cim/types/models.ts (1)
SecretModel(3-11)
libs/ui-lib/lib/cim/components/modals/utils.ts (5)
libs/ui-lib/lib/cim/types/k8s/agent-cluster-install.ts (1)
AgentClusterInstallK8sResource(17-80)libs/ui-lib/lib/cim/types/models.ts (4)
AgentClusterInstallModel(111-120)AgentModel(67-76)BMHModel(78-87)NMStateModel(89-98)libs/ui-lib/lib/cim/types/k8s/agent.ts (1)
AgentK8sResource(32-74)libs/ui-lib/lib/cim/types/k8s/nm-state.ts (1)
NMStateK8sResource(3-11)libs/ui-lib/lib/cim/components/common/constants.ts (1)
AGENT_BMH_NAME_LABEL_KEY(12-12)
libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts (4)
libs/ui-lib/lib/cim/types/k8s/agent.ts (1)
AgentK8sResource(32-74)libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts (1)
InfraEnvK8sResource(8-42)libs/ui-lib/lib/cim/types/k8s/nm-state.ts (1)
NMStateK8sResource(3-11)libs/ui-lib/lib/cim/types/k8s/agent-cluster-install.ts (1)
AgentClusterInstallK8sResource(17-80)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (4)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts (1)
EnvironmentStepFormValues(15-34)libs/ui-lib/lib/common/config/docs_links.ts (1)
getOCPStaticIPDocLink(62-63)libs/ui-lib/lib/cim/config/constants.ts (1)
DOC_VERSION(4-4)libs/ui-lib/lib/common/components/ui/formik/LabelField.tsx (1)
LabelField(34-100)
🪛 Biome (1.9.4)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx
[error] 68-72: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment
(lint/complexity/noUselessFragments)
🔇 Additional comments (6)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (1)
45-181: Well-structured form component.The component follows React best practices with proper use of Formik context, PatternFly components, and accessibility considerations. The form layout is logical and user-friendly with appropriate validation, helper text, and conditional rendering.
🧰 Tools
🪛 Biome (1.9.4)
[error] 68-72: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment(lint/complexity/noUselessFragments)
libs/ui-lib/lib/cim/utils.ts (1)
1-20: Well-implemented patching utilities with proper error handling.The
appendPatchandonApproveAgentfunctions correctly address the issues raised in previous reviews. The conditional logicexistingVal === undefined ? 'add' : 'replace'properly distinguishes between adding new paths and replacing existing ones, preventing 422 errors. The deep equality check withisEqualensures patches are only applied when necessary.libs/ui-lib/lib/cim/components/modals/EditPullSecretModal.tsx (1)
134-174: Good refactoring to internalize modal logic.The modal now properly manages its own submission state and resource operations, eliminating the need for external callbacks. The conditional creation vs patching logic is sound, and error handling is appropriately managed through the local error state.
libs/ui-lib/lib/cim/components/modals/utils.ts (2)
97-121: Well-structured provision requirements patching.The
setProvisionRequirementsfunction properly handles both worker and master count updates with appropriate conditional logic for the add vs replace patch operation.
159-164: Clean utility for extracting agent names.The
getAgentNamefunction provides a reliable fallback hierarchy for extracting meaningful names from resources, handling both Agent and BMH types appropriately.libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts (1)
129-129: Good simplification of component interfaces.The reduction of callback properties in
hostActionsandClusterDeploymentHostDiscoveryTablePropsappropriately reflects the internalization of host management logic, reducing prop drilling and improving component cohesion.Also applies to: 175-175
| const workerCount = agentClusterInstall.spec?.provisionRequirements.workerAgents || 1; | ||
| await setProvisionRequirements(agentClusterInstall, Math.max(0, workerCount - 1), masterCount); |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Fix worker count defaulting logic.
Defaulting workerAgents to 1 when undefined may cause incorrect counts. If the actual initial value should have been 0, this logic subtracts an extra unit and can yield incorrect worker counts.
- const workerCount = agentClusterInstall.spec?.provisionRequirements.workerAgents || 1;
+ const workerCount = agentClusterInstall.spec?.provisionRequirements.workerAgents ?? 0;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const workerCount = agentClusterInstall.spec?.provisionRequirements.workerAgents || 1; | |
| await setProvisionRequirements(agentClusterInstall, Math.max(0, workerCount - 1), masterCount); | |
| const workerCount = agentClusterInstall.spec?.provisionRequirements.workerAgents ?? 0; | |
| await setProvisionRequirements(agentClusterInstall, Math.max(0, workerCount - 1), masterCount); |
🤖 Prompt for AI Agents
In libs/ui-lib/lib/cim/components/modals/utils.ts around lines 154 to 155, the
workerAgents count defaults to 1 if undefined, which can cause incorrect worker
counts when subtracting one. Change the default value from 1 to 0 to correctly
reflect the initial worker count and avoid subtracting an extra unit, ensuring
accurate worker count calculations.
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (4)
libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/InfraEnvDetails.tsx (2)
95-106: Fix incorrect JSX structure in NavItemThe JSX fragment structure looks incorrect. The Link component's children should be properly formatted:
<NavItem isActive={location.pathname === hostsPath}> <Link to={hostsPath}> - { - <> - <InfraEnvHostsTabAgentsWarning - infraAgents={infraAgents} - infraBMHs={infraBMHs} - /> - {t('ai:Hosts')} - </> - } + <> + <InfraEnvHostsTabAgentsWarning + infraAgents={infraAgents} + infraBMHs={infraBMHs} + /> + {t('ai:Hosts')} + </> </Link> </NavItem>The extra curly braces around the fragment are unnecessary and could cause rendering issues.
176-178: Enhance error handling with specific error messagesThe current error handling shows a generic error state without distinguishing between different error sources:
if (error) { - return <ErrorState title={getErrorMessage(error)} />; + const errorMessage = infraErr + ? t('ai:Failed to load infrastructure environment') + : agentsErr + ? t('ai:Failed to load agents') + : bmhsErr + ? t('ai:Failed to load bare metal hosts') + : t('ai:An unexpected error occurred'); + + return <ErrorState + title={errorMessage} + content={t('ai:Please try refreshing the page or contact support if the issue persists.')} + />; }This provides users with more context about what failed and potential next steps.
libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts (2)
21-23: Inconsistent parameter style foronMassDeleteHostWhile
onDeleteHostwas updated to use a wrapper object,onMassDeleteHoststill uses two positional parameters which is inconsistent and error-prone.- onMassDeleteHost: (agent?: AgentK8sResource, bmh?: BareMetalHostK8sResource) => Promise<unknown>; + onMassDeleteHost: ( + hosts: { agent?: AgentK8sResource; bmh?: BareMetalHostK8sResource }[], + ) => Promise<unknown>;This would unify the API style, make "mass" semantics explicit, and prevent parameter swap bugs.
121-121: Update onDeleteHost References to Use the Standalone UtilityThe
hostActionstype no longer includesonDeleteHost, so all consumers must be updated to import and call the new standalone delete-host utility instead of pullingonDeleteHostout ofhostActions.Please update the following locations:
libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostDiscoveryTable.tsx
• RemoveonDeleteHost: setDeleteHostfrom thehostActionsdestructure (around line 98).
• Import the standalone delete-host handler and invoke it where you currently callsetDeleteHost.libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsx
• RemoveonDeleteHost: setDeleteHostfrom the props destructure (line 114).
• Replace the<DeleteHostAction … onDeleteHost={() => setMassDeleteOpen(…)} />usage (around line 211) to call the standalone delete-host utility directly.This ensures no lingering references to
hostActions.onDeleteHostand aligns with the updatedhostActionstype.
🧹 Nitpick comments (2)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (1)
68-72: Remove unnecessary Fragment wrapper.The Fragment wrapper around the single translation call is redundant and can be removed for cleaner code.
bodyContent={ - <> - {t( - 'ai:This will determine for the infrastructure environment which kind of hosts would be able to be added. If the hosts that you want to add are using DHCP server, select this option, else, select the static IP.', - )} - </> + t( + 'ai:This will determine for the infrastructure environment which kind of hosts would be able to be added. If the hosts that you want to add are using DHCP server, select this option, else, select the static IP.', + ) }🧰 Tools
🪛 Biome (1.9.4)
[error] 68-72: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment(lint/complexity/noUselessFragments)
libs/ui-lib/lib/cim/components/modals/types.ts (1)
34-34: Consider using a more descriptive type for pullSecretThe
pullSecretfield uses a genericstringtype. Consider using a more specific type or adding validation constraints if this represents structured data like JSON.- pullSecret: string; + pullSecret: string; // Consider: JsonString or add validation constraints
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
libs/ui-lib/lib/cim/logos/OnPremiseBannerIcon.svgis excluded by!**/*.svgyarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (77)
libs/locales/lib/en/translation.json(21 hunks)libs/ui-lib/lib/cim/components/Agent/BMCForm.tsx(4 hunks)libs/ui-lib/lib/cim/components/Agent/NoAgentsAlert.tsx(1 hunks)libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx(3 hunks)libs/ui-lib/lib/cim/components/Agent/types.ts(0 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostDiscoveryTable.tsx(6 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostsDiscovery.tsx(2 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentWizard.tsx(1 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts(3 hunks)libs/ui-lib/lib/cim/components/Hypershift/DetailsPage/NodePoolsTable.tsx(2 hunks)libs/ui-lib/lib/cim/components/InfraEnv/AddHostDropdown.tsx(4 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvPage.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/useInfraEnvResources.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/EnvironmentDetails.tsx(4 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsx(6 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/AgentsTab.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/DetailsTab.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/InfraEnvDetails.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvFormPage.tsx(0 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.css(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.tsx(2 hunks)libs/ui-lib/lib/cim/components/InfraEnv/index.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/infra-env.css(0 hunks)libs/ui-lib/lib/cim/components/InfraEnv/types.ts(1 hunks)libs/ui-lib/lib/cim/components/YamlEditor/Theme.ts(1 hunks)libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.css(1 hunks)libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.tsx(1 hunks)libs/ui-lib/lib/cim/components/YamlEditor/utils.ts(1 hunks)libs/ui-lib/lib/cim/components/YamlPreview/useYAMLPreview.ts(5 hunks)libs/ui-lib/lib/cim/components/common/InfoAndTroubleshootingNotification.tsx(1 hunks)libs/ui-lib/lib/cim/components/formik/CredentialsField.tsx(1 hunks)libs/ui-lib/lib/cim/components/helpers/agents.ts(3 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostModal.tsx(0 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlForm.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/AddHostModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/CimConfiguration/CimConfigProgressAlert.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/CimConfiguration/utils.ts(1 hunks)libs/ui-lib/lib/cim/components/modals/DeleteHostModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/EditAgentModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/EditBMHModal.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/EditNtpSourcesModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/EditProxyModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/EditPullSecretModal.tsx(4 hunks)libs/ui-lib/lib/cim/components/modals/EditSSHKeyModal.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/MassApproveAgentModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/MassDeleteAgentModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/ProvisioningConfigErrorAlert.tsx(0 hunks)libs/ui-lib/lib/cim/components/modals/ScaleUpModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/UnbindHostModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/types.ts(1 hunks)libs/ui-lib/lib/cim/components/modals/utils.ts(2 hunks)libs/ui-lib/lib/cim/config/constants.ts(1 hunks)libs/ui-lib/lib/cim/hooks/types.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useAgentClusterInstall.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useAgentMachines.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useAgentServiceConfig.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useAgents.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useBMHs.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useConfigMap.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useInfraEnvs.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useNMStates.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useProvisioningConfig.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useSecret.ts(1 hunks)libs/ui-lib/lib/cim/index.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/klusterlet.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/multi-cluster-engine.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/nm-state.ts(1 hunks)libs/ui-lib/lib/cim/types/models.ts(1 hunks)libs/ui-lib/lib/cim/utils.ts(1 hunks)libs/ui-lib/lib/common/components/clusterConfiguration/FormatDiskWarning.tsx(1 hunks)libs/ui-lib/lib/ocm/components/Routes.tsx(1 hunks)libs/ui-lib/package.json(2 hunks)
💤 Files with no reviewable changes (5)
- libs/ui-lib/lib/cim/components/modals/ProvisioningConfigErrorAlert.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/infra-env.css
- libs/ui-lib/lib/cim/components/Agent/types.ts
- libs/ui-lib/lib/cim/components/modals/AddBmcHostModal.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvFormPage.tsx
✅ Files skipped from review due to trivial changes (5)
- libs/ui-lib/lib/cim/components/Agent/NoAgentsAlert.tsx
- libs/ui-lib/lib/cim/hooks/useAgentServiceConfig.ts
- libs/ui-lib/lib/cim/components/modals/MassDeleteAgentModal.tsx
- libs/ui-lib/lib/cim/hooks/types.ts
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.tsx
🚧 Files skipped from review as they are similar to previous changes (60)
- libs/ui-lib/lib/cim/types/k8s/klusterlet.ts
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.css
- libs/ui-lib/lib/cim/components/modals/CimConfiguration/CimConfigProgressAlert.tsx
- libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.css
- libs/ui-lib/lib/cim/components/InfraEnv/index.ts
- libs/ui-lib/lib/cim/hooks/useAgents.ts
- libs/ui-lib/lib/common/components/clusterConfiguration/FormatDiskWarning.tsx
- libs/ui-lib/lib/cim/types/k8s/multi-cluster-engine.ts
- libs/ui-lib/lib/cim/components/modals/ScaleUpModal.tsx
- libs/ui-lib/lib/cim/index.ts
- libs/ui-lib/lib/ocm/components/Routes.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/AddHostDropdown.tsx
- libs/ui-lib/package.json
- libs/ui-lib/lib/cim/config/constants.ts
- libs/ui-lib/lib/cim/hooks/useProvisioningConfig.ts
- libs/ui-lib/lib/cim/hooks/useAgentMachines.ts
- libs/ui-lib/lib/cim/types/k8s/nm-state.ts
- libs/ui-lib/lib/cim/components/modals/CimConfiguration/utils.ts
- libs/ui-lib/lib/cim/components/formik/CredentialsField.tsx
- libs/ui-lib/lib/cim/hooks/useConfigMap.ts
- libs/ui-lib/lib/cim/components/modals/EditProxyModal.tsx
- libs/ui-lib/lib/cim/components/YamlEditor/Theme.ts
- libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts
- libs/ui-lib/lib/cim/hooks/useBMHs.ts
- libs/ui-lib/lib/cim/components/modals/EditSSHKeyModal.tsx
- libs/ui-lib/lib/cim/components/modals/MassApproveAgentModal.tsx
- libs/ui-lib/lib/cim/hooks/useInfraEnvs.ts
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/DetailsTab.tsx
- libs/ui-lib/lib/cim/components/modals/DeleteHostModal.tsx
- libs/ui-lib/lib/cim/components/modals/EditNtpSourcesModal.tsx
- libs/ui-lib/lib/cim/hooks/useNMStates.ts
- libs/ui-lib/lib/cim/components/modals/EditPullSecretModal.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/types.ts
- libs/ui-lib/lib/cim/hooks/useSecret.ts
- libs/ui-lib/lib/cim/components/modals/EditBMHModal.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/useInfraEnvResources.ts
- libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx
- libs/ui-lib/lib/cim/components/modals/AddHostModal.tsx
- libs/ui-lib/lib/cim/components/YamlPreview/useYAMLPreview.ts
- libs/ui-lib/lib/cim/components/Hypershift/DetailsPage/NodePoolsTable.tsx
- libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentWizard.tsx
- libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostsDiscovery.tsx
- libs/ui-lib/lib/cim/components/helpers/agents.ts
- libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.tsx
- libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlForm.tsx
- libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts
- libs/ui-lib/lib/cim/components/common/InfoAndTroubleshootingNotification.tsx
- libs/ui-lib/lib/cim/components/YamlEditor/utils.ts
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsx
- libs/ui-lib/lib/cim/components/modals/utils.ts
- libs/ui-lib/lib/cim/hooks/useAgentClusterInstall.ts
- libs/ui-lib/lib/cim/components/Agent/BMCForm.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/AgentsTab.tsx
- libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlModal.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvPage.tsx
- libs/ui-lib/lib/cim/components/modals/UnbindHostModal.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/EnvironmentDetails.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts
- libs/ui-lib/lib/cim/types/models.ts
- libs/locales/lib/en/translation.json
🧰 Additional context used
🧬 Code Graph Analysis (3)
libs/ui-lib/lib/cim/utils.ts (2)
libs/ui-lib/lib/cim/types/k8s/agent.ts (1)
AgentK8sResource(32-74)libs/ui-lib/lib/cim/types/models.ts (1)
AgentModel(67-76)
libs/ui-lib/lib/cim/components/modals/types.ts (1)
libs/ui-lib/lib/cim/components/Agent/types.ts (1)
BMCFormProps(18-27)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (5)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts (1)
EnvironmentStepFormValues(16-35)libs/ui-lib/lib/common/hooks/index.ts (1)
useTranslation(3-3)libs/ui-lib/lib/common/config/docs_links.ts (1)
getOCPStaticIPDocLink(62-63)libs/ui-lib/lib/cim/config/constants.ts (1)
DOC_VERSION(4-4)libs/ui-lib/lib/common/components/ui/formik/LabelField.tsx (1)
LabelField(34-100)
🪛 Biome (1.9.4)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx
[error] 68-72: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment
(lint/complexity/noUselessFragments)
🔇 Additional comments (13)
libs/ui-lib/lib/cim/utils.ts (2)
6-14: LGTM! Well-designed utility for conditional patching.The
appendPatchfunction demonstrates excellent practices:
- Uses deep equality comparison with
isEqualto avoid unnecessary patches- Correctly handles undefined values by choosing appropriate JSON Patch operations
- Generic typing provides good type safety
16-20: Clean implementation of agent approval logic.The
onApproveAgentfunction properly uses theappendPatchutility and follows the established pattern for Kubernetes resource updates. Good encapsulation of the approval workflow.libs/ui-lib/lib/cim/components/modals/EditAgentModal.tsx (2)
8-13: Excellent refactoring to explicit prop types.Defining explicit props instead of using spread operators improves type safety and makes the component's interface clearer. Good architectural improvement.
15-18: Good internalization of hostname change logic.Computing
usedHostnamesinternally and obtaining theonSavefunction from the helper reduces external dependencies and makes the component more self-contained. This aligns well with the broader refactoring effort.libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (2)
100-114: Well-implemented documentation link integration.The external documentation link for static IP configuration is well-implemented with proper security attributes (
noopener) and good UX with the external link icon.
140-149: Good credential integration with form state.The credentials selection properly updates form fields by decoding base64 data. The implementation handles the credential data structure correctly.
libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostDiscoveryTable.tsx (4)
50-60: Well-designed resource loading hook.The
useTableResourceshook properly abstracts the loading of related Kubernetes resources and combines their loading states. Good encapsulation of the async resource fetching logic.
72-75: Good internalization of deletion state.Moving the deletion state management inside the component reduces external dependencies and simplifies the component's interface. The explicit typing for the deleteHost state provides good type safety.
154-156: Proper loading state guard.The loading guard ensures the table doesn't render with undefined resources, preventing potential runtime errors. Good defensive programming practice.
213-220: Safe conditional rendering of DeleteHostModal.The modal is only rendered when
deleteHostis set and the resources are loaded, ensuring the modal receives properly initialized data. This prevents the runtime errors that were flagged in previous reviews.libs/ui-lib/lib/cim/components/modals/types.ts (1)
24-27: LGTM: Clean type composition using Pick utilityThe use of
Pickto select specific properties fromBMCFormPropsis a good pattern for type composition and aligns with the refactoring to remove external callbacks.libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/InfraEnvDetails.tsx (1)
120-167: Well-structured custom hook for resource aggregationThe
useInfraEnvResourceshook effectively aggregates related resources with proper selector mapping and loading state management. The hook correctly derives selectors from the InfraEnv status and handles the loading states appropriately.libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts (1)
156-163: Clean type simplification aligns with refactoring goalsThe simplified
InfraEnvAgentTablePropsremoves external callback dependencies, which aligns well with the broader refactoring to internalize component logic and reduce prop drilling.
896fb00 to
f70636a
Compare
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (3)
libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsx (1)
113-118: Verify handler signatures match useAgentsTable expectations.The handlers passed to
useAgentsTableare state setters rather than async callback functions. IfuseAgentsTableexpects async functions that return promises, this could cause the table to remain in a loading state.#!/bin/bash # Search for useAgentsTable implementation to verify expected handler signatures ast-grep --pattern 'function useAgentsTable($$$) { $$$ }' # Also search for the hook definition rg -A 10 "export.*useAgentsTable" -t tslibs/ui-lib/lib/cim/components/ClusterDeployment/types.ts (2)
121-121: Verify all consumers updated for removedonDeleteHostfromhostActionsThe
hostActionstype no longer includesonDeleteHost, which is a breaking change. Components that previously destructuredonDeleteHostfromhostActionswill now fail at compile time or runtime.Based on past reviews, the following components need updates:
ClusterDeploymentHostDiscoveryTable.tsx(removeonDeleteHost: setDeleteHostfrom destructuring)InfraEnvAgentTable.tsx(removeonDeleteHost: setDeleteHostfrom destructuring)These components should import and use the standalone delete-host utility instead.
23-23: 🛠️ Refactor suggestionUnify the API signature for consistency
The
onMassDeleteHostfunction still uses two positional parameters whileonDeleteHostwas updated to use a single wrapper object. This inconsistency makes the API error-prone and harder to maintain.Consider updating to match the
onDeleteHostpattern:- onMassDeleteHost: (agent?: AgentK8sResource, bmh?: BareMetalHostK8sResource) => Promise<unknown>; + onMassDeleteHost: ( + hosts: { agent?: AgentK8sResource; bmh?: BareMetalHostK8sResource }[], + ) => Promise<unknown>;This change would make the "mass" semantics explicit and prevent parameter order confusion.
🧹 Nitpick comments (1)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (1)
68-72: Remove unnecessary Fragment.The Fragment wrapper is redundant here since it only contains a single text element.
- <> - {t( - 'ai:This will determine for the infrastructure environment which kind of hosts would be able to be added. If the hosts that you want to add are using DHCP server, select this option, else, select the static IP.', - )} - </> + {t( + 'ai:This will determine for the infrastructure environment which kind of hosts would be able to be added. If the hosts that you want to add are using DHCP server, select this option, else, select the static IP.', + )}🧰 Tools
🪛 Biome (1.9.4)
[error] 68-72: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment(lint/complexity/noUselessFragments)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
libs/ui-lib/lib/cim/logos/OnPremiseBannerIcon.svgis excluded by!**/*.svgyarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (77)
libs/locales/lib/en/translation.json(21 hunks)libs/ui-lib/lib/cim/components/Agent/BMCForm.tsx(4 hunks)libs/ui-lib/lib/cim/components/Agent/NoAgentsAlert.tsx(1 hunks)libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx(3 hunks)libs/ui-lib/lib/cim/components/Agent/types.ts(0 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostDiscoveryTable.tsx(6 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostsDiscovery.tsx(3 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentWizard.tsx(3 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts(3 hunks)libs/ui-lib/lib/cim/components/Hypershift/DetailsPage/NodePoolsTable.tsx(2 hunks)libs/ui-lib/lib/cim/components/InfraEnv/AddHostDropdown.tsx(4 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvPage.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/useInfraEnvResources.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/EnvironmentDetails.tsx(4 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsx(6 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/AgentsTab.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/DetailsTab.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/InfraEnvDetails.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvFormPage.tsx(0 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.css(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.tsx(2 hunks)libs/ui-lib/lib/cim/components/InfraEnv/index.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/infra-env.css(0 hunks)libs/ui-lib/lib/cim/components/InfraEnv/types.ts(1 hunks)libs/ui-lib/lib/cim/components/YamlEditor/Theme.ts(1 hunks)libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.css(1 hunks)libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.tsx(1 hunks)libs/ui-lib/lib/cim/components/YamlEditor/utils.ts(1 hunks)libs/ui-lib/lib/cim/components/YamlPreview/useYAMLPreview.ts(5 hunks)libs/ui-lib/lib/cim/components/common/InfoAndTroubleshootingNotification.tsx(1 hunks)libs/ui-lib/lib/cim/components/formik/CredentialsField.tsx(1 hunks)libs/ui-lib/lib/cim/components/helpers/agents.ts(3 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostModal.tsx(0 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlForm.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/AddHostModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/CimConfiguration/CimConfigProgressAlert.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/CimConfiguration/utils.ts(1 hunks)libs/ui-lib/lib/cim/components/modals/DeleteHostModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/EditAgentModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/EditBMHModal.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/EditNtpSourcesModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/EditProxyModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/EditPullSecretModal.tsx(4 hunks)libs/ui-lib/lib/cim/components/modals/EditSSHKeyModal.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/MassApproveAgentModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/MassDeleteAgentModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/ProvisioningConfigErrorAlert.tsx(0 hunks)libs/ui-lib/lib/cim/components/modals/ScaleUpModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/UnbindHostModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/types.ts(1 hunks)libs/ui-lib/lib/cim/components/modals/utils.ts(2 hunks)libs/ui-lib/lib/cim/config/constants.ts(1 hunks)libs/ui-lib/lib/cim/hooks/types.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useAgentClusterInstall.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useAgentMachines.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useAgentServiceConfig.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useAgents.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useBMHs.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useConfigMap.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useInfraEnvs.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useNMStates.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useProvisioningConfig.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useSecret.ts(1 hunks)libs/ui-lib/lib/cim/index.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/klusterlet.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/multi-cluster-engine.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/nm-state.ts(1 hunks)libs/ui-lib/lib/cim/types/models.ts(1 hunks)libs/ui-lib/lib/cim/utils.ts(1 hunks)libs/ui-lib/lib/common/components/clusterConfiguration/FormatDiskWarning.tsx(1 hunks)libs/ui-lib/lib/ocm/components/Routes.tsx(1 hunks)libs/ui-lib/package.json(2 hunks)
💤 Files with no reviewable changes (5)
- libs/ui-lib/lib/cim/components/InfraEnv/infra-env.css
- libs/ui-lib/lib/cim/components/Agent/types.ts
- libs/ui-lib/lib/cim/components/modals/AddBmcHostModal.tsx
- libs/ui-lib/lib/cim/components/modals/ProvisioningConfigErrorAlert.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvFormPage.tsx
✅ Files skipped from review due to trivial changes (4)
- libs/ui-lib/lib/cim/components/Agent/NoAgentsAlert.tsx
- libs/ui-lib/package.json
- libs/ui-lib/lib/cim/hooks/types.ts
- libs/ui-lib/lib/cim/components/modals/DeleteHostModal.tsx
🚧 Files skipped from review as they are similar to previous changes (63)
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.css
- libs/ui-lib/lib/cim/config/constants.ts
- libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.css
- libs/ui-lib/lib/cim/types/k8s/multi-cluster-engine.ts
- libs/ui-lib/lib/common/components/clusterConfiguration/FormatDiskWarning.tsx
- libs/ui-lib/lib/cim/types/k8s/klusterlet.ts
- libs/ui-lib/lib/cim/index.ts
- libs/ui-lib/lib/cim/types/k8s/nm-state.ts
- libs/ui-lib/lib/cim/components/modals/CimConfiguration/CimConfigProgressAlert.tsx
- libs/ui-lib/lib/cim/components/modals/MassApproveAgentModal.tsx
- libs/ui-lib/lib/cim/hooks/useProvisioningConfig.ts
- libs/ui-lib/lib/cim/hooks/useAgentMachines.ts
- libs/ui-lib/lib/cim/hooks/useConfigMap.ts
- libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts
- libs/ui-lib/lib/cim/components/modals/CimConfiguration/utils.ts
- libs/ui-lib/lib/cim/components/modals/MassDeleteAgentModal.tsx
- libs/ui-lib/lib/cim/hooks/useBMHs.ts
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/DetailsTab.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/index.ts
- libs/ui-lib/lib/cim/components/InfraEnv/types.ts
- libs/ui-lib/lib/ocm/components/Routes.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.tsx
- libs/ui-lib/lib/cim/hooks/useInfraEnvs.ts
- libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlModal.tsx
- libs/ui-lib/lib/cim/components/modals/EditProxyModal.tsx
- libs/ui-lib/lib/cim/hooks/useAgents.ts
- libs/ui-lib/lib/cim/components/modals/ScaleUpModal.tsx
- libs/ui-lib/lib/cim/hooks/useSecret.ts
- libs/ui-lib/lib/cim/components/modals/EditNtpSourcesModal.tsx
- libs/ui-lib/lib/cim/components/Hypershift/DetailsPage/NodePoolsTable.tsx
- libs/ui-lib/lib/cim/components/YamlEditor/Theme.ts
- libs/ui-lib/lib/cim/hooks/useAgentServiceConfig.ts
- libs/ui-lib/lib/cim/hooks/useAgentClusterInstall.ts
- libs/ui-lib/lib/cim/components/YamlPreview/useYAMLPreview.ts
- libs/ui-lib/lib/cim/components/modals/EditPullSecretModal.tsx
- libs/ui-lib/lib/cim/components/YamlEditor/utils.ts
- libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts
- libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostDiscoveryTable.tsx
- libs/ui-lib/lib/cim/hooks/useNMStates.ts
- libs/ui-lib/lib/cim/components/formik/CredentialsField.tsx
- libs/ui-lib/lib/cim/components/modals/utils.ts
- libs/ui-lib/lib/cim/components/modals/EditSSHKeyModal.tsx
- libs/ui-lib/lib/cim/components/modals/AddHostModal.tsx
- libs/ui-lib/lib/cim/components/modals/EditAgentModal.tsx
- libs/ui-lib/lib/cim/components/helpers/agents.ts
- libs/ui-lib/lib/cim/components/InfraEnv/AddHostDropdown.tsx
- libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/AgentsTab.tsx
- libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlForm.tsx
- libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostsDiscovery.tsx
- libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/InfraEnvDetails.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvPage.tsx
- libs/ui-lib/lib/cim/components/modals/EditBMHModal.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/EnvironmentDetails.tsx
- libs/ui-lib/lib/cim/types/models.ts
- libs/ui-lib/lib/cim/components/modals/UnbindHostModal.tsx
- libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentWizard.tsx
- libs/ui-lib/lib/cim/components/modals/types.ts
- libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts
- libs/ui-lib/lib/cim/components/common/InfoAndTroubleshootingNotification.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/useInfraEnvResources.ts
- libs/locales/lib/en/translation.json
🧰 Additional context used
🧬 Code Graph Analysis (4)
libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsx (5)
libs/ui-lib/lib/cim/types/k8s/agent.ts (1)
AgentK8sResource(32-74)libs/ui-lib/lib/cim/components/modals/utils.ts (1)
deleteHost(123-157)libs/ui-lib/lib/cim/utils.ts (1)
onApproveAgent(16-20)libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx (1)
clusterColumn(188-230)libs/ui-lib/lib/cim/components/helpers/agents.ts (1)
onAgentChangeHostname(49-84)
libs/ui-lib/lib/cim/components/Agent/BMCForm.tsx (7)
libs/ui-lib/lib/cim/components/Agent/types.ts (1)
AddBmcValues(5-16)libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts (1)
InfraEnvK8sResource(8-42)libs/ui-lib/lib/cim/types/k8s/nm-state.ts (1)
NMStateK8sResource(3-11)libs/ui-lib/lib/cim/utils.ts (1)
appendPatch(6-14)libs/ui-lib/lib/cim/types/models.ts (3)
SecretModel(3-11)NMStateModel(89-98)BMHModel(78-87)libs/ui-lib/lib/cim/components/modals/utils.ts (2)
getBareMetalHostCredentialsSecret(18-37)getBareMetalHost(39-77)libs/ui-lib/lib/cim/components/common/constants.ts (1)
BMH_HOSTNAME_ANNOTATION(20-20)
libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts (5)
libs/ui-lib/lib/cim/types/k8s/agent.ts (1)
AgentK8sResource(32-74)libs/ui-lib/lib/cim/components/Hypershift/types.ts (1)
AgentMachineK8sResource(186-193)libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts (1)
InfraEnvK8sResource(8-42)libs/ui-lib/lib/cim/types/k8s/nm-state.ts (1)
NMStateK8sResource(3-11)libs/ui-lib/lib/cim/types/k8s/agent-cluster-install.ts (1)
AgentClusterInstallK8sResource(17-80)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (4)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts (1)
EnvironmentStepFormValues(16-35)libs/ui-lib/lib/common/config/docs_links.ts (1)
getOCPStaticIPDocLink(62-63)libs/ui-lib/lib/cim/config/constants.ts (1)
DOC_VERSION(4-4)libs/ui-lib/lib/common/components/ui/formik/LabelField.tsx (1)
LabelField(34-100)
🪛 Biome (1.9.4)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx
[error] 68-72: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment
(lint/complexity/noUselessFragments)
⏰ Context from checks skipped due to timeout of 90000ms (6)
- GitHub Check: format
- GitHub Check: unit-tests
- GitHub Check: circular-deps
- GitHub Check: translation-files
- GitHub Check: lint
- GitHub Check: tests
🔇 Additional comments (7)
libs/ui-lib/lib/cim/utils.ts (2)
6-14: LGTM! Clean utility function for conditional patching.The
appendPatchfunction correctly handles the undefined check and uses deep equality comparison to avoid unnecessary patches. This addresses the previous issues with falsely-valued but defined properties.
16-20: Excellent pattern for agent approval.The
onApproveAgentfunction properly uses theappendPatchutility to avoid redundant operations and returns a promise for the patch operation. This centralizes agent approval logic effectively.libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (1)
140-148: Base64 decoding is properly handled.The credential selection logic correctly decodes base64 data from the selected credentials. The error handling concerns from previous reviews have been addressed.
libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsx (1)
256-287: Well-structured modal rendering.The conditional modal rendering is clean and properly manages the state through the
onClosehandlers. Each modal receives the appropriate props and data.libs/ui-lib/lib/cim/components/Agent/BMCForm.tsx (3)
238-335: Excellent centralized resource management.The
onCreateBMHfunction properly handles all three resource types (Secret, NMState, BareMetalHost) with appropriate create/patch logic. The function correctly creates a new BMH when one doesn't exist, addressing the previous review concern.
353-359: Clean function integration.The form submission now properly calls the internal
onCreateBMHfunction with all required parameters, removing the dependency on external callbacks.
455-455: Good practice for void return.Using
voidwithsubmitForm()properly suppresses the lint warning about unused promise return values.
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (3)
libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts (2)
23-23: Unify API signature for consistencyThe
onMassDeleteHostfunction still uses positional parameters whileonDeleteHostnow uses a wrapper object. This inconsistency makes the API error-prone and harder to maintain.Consider updating to use an array of the same wrapper objects:
- onMassDeleteHost: (agent?: AgentK8sResource, bmh?: BareMetalHostK8sResource) => Promise<unknown>; + onMassDeleteHost: ( + hosts: { agent?: AgentK8sResource; bmh?: BareMetalHostK8sResource }[], + ) => Promise<unknown>;This would make the "mass" semantics explicit and prevent parameter swap bugs.
121-121: Verify consumers handle reduced hostActions interfaceThe
hostActionstype now only includes'onEditRole' | 'onSetInstallationDiskId', removing several callback properties includingonDeleteHost. This simplification aligns with the refactoring goals but requires verification that all consumers have been updated.Based on past reviews, ensure the following components have been updated to use standalone utilities instead of extracting callbacks from
hostActions:
ClusterDeploymentHostDiscoveryTable.tsxInfraEnvAgentTable.tsx#!/bin/bash # Verify no stale references to removed hostActions properties rg -n "hostActions\.(onDeleteHost|onApproveAgent|onEditBMH|onUnbindHost)" --type ts --type tsxlibs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (1)
140-148: The base64 decoding error handling issue remains unaddressed.This matches the previous review feedback about adding try/catch blocks around
atob()calls. The current implementation can still throw exceptions if the credential data isn't properly base64-encoded.
🧹 Nitpick comments (1)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (1)
68-72: Remove unnecessary Fragment wrapper.The Fragment is redundant since it only contains a single child element.
bodyContent={ - <> - {t( - 'ai:This will determine for the infrastructure environment which kind of hosts would be able to be added. If the hosts that you want to add are using DHCP server, select this option, else, select the static IP.', - )} - </> + t( + 'ai:This will determine for the infrastructure environment which kind of hosts would be able to be added. If the hosts that you want to add are using DHCP server, select this option, else, select the static IP.', + ) }🧰 Tools
🪛 Biome (1.9.4)
[error] 68-72: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment(lint/complexity/noUselessFragments)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
libs/ui-lib/lib/cim/logos/OnPremiseBannerIcon.svgis excluded by!**/*.svgyarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (77)
libs/locales/lib/en/translation.json(21 hunks)libs/ui-lib/lib/cim/components/Agent/BMCForm.tsx(4 hunks)libs/ui-lib/lib/cim/components/Agent/NoAgentsAlert.tsx(1 hunks)libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx(3 hunks)libs/ui-lib/lib/cim/components/Agent/types.ts(0 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostDiscoveryTable.tsx(6 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostsDiscovery.tsx(3 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentWizard.tsx(3 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts(3 hunks)libs/ui-lib/lib/cim/components/Hypershift/DetailsPage/NodePoolsTable.tsx(2 hunks)libs/ui-lib/lib/cim/components/InfraEnv/AddHostDropdown.tsx(4 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvPage.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/useInfraEnvResources.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/EnvironmentDetails.tsx(4 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsx(6 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/AgentsTab.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/DetailsTab.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/InfraEnvDetails.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvFormPage.tsx(0 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.css(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.tsx(2 hunks)libs/ui-lib/lib/cim/components/InfraEnv/index.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/infra-env.css(0 hunks)libs/ui-lib/lib/cim/components/InfraEnv/types.ts(1 hunks)libs/ui-lib/lib/cim/components/YamlEditor/Theme.ts(1 hunks)libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.css(1 hunks)libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.tsx(1 hunks)libs/ui-lib/lib/cim/components/YamlEditor/utils.ts(1 hunks)libs/ui-lib/lib/cim/components/YamlPreview/useYAMLPreview.ts(5 hunks)libs/ui-lib/lib/cim/components/common/InfoAndTroubleshootingNotification.tsx(1 hunks)libs/ui-lib/lib/cim/components/formik/CredentialsField.tsx(1 hunks)libs/ui-lib/lib/cim/components/helpers/agents.ts(3 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostModal.tsx(0 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlForm.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/AddHostModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/CimConfiguration/CimConfigProgressAlert.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/CimConfiguration/utils.ts(1 hunks)libs/ui-lib/lib/cim/components/modals/DeleteHostModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/EditAgentModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/EditBMHModal.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/EditNtpSourcesModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/EditProxyModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/EditPullSecretModal.tsx(4 hunks)libs/ui-lib/lib/cim/components/modals/EditSSHKeyModal.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/MassApproveAgentModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/MassDeleteAgentModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/ProvisioningConfigErrorAlert.tsx(0 hunks)libs/ui-lib/lib/cim/components/modals/ScaleUpModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/UnbindHostModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/types.ts(1 hunks)libs/ui-lib/lib/cim/components/modals/utils.ts(2 hunks)libs/ui-lib/lib/cim/config/constants.ts(1 hunks)libs/ui-lib/lib/cim/hooks/types.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useAgentClusterInstall.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useAgentMachines.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useAgentServiceConfig.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useAgents.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useBMHs.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useConfigMap.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useInfraEnvs.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useNMStates.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useProvisioningConfig.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useSecret.ts(1 hunks)libs/ui-lib/lib/cim/index.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/klusterlet.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/multi-cluster-engine.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/nm-state.ts(1 hunks)libs/ui-lib/lib/cim/types/models.ts(1 hunks)libs/ui-lib/lib/cim/utils.ts(1 hunks)libs/ui-lib/lib/common/components/clusterConfiguration/FormatDiskWarning.tsx(1 hunks)libs/ui-lib/lib/ocm/components/Routes.tsx(1 hunks)libs/ui-lib/package.json(2 hunks)
💤 Files with no reviewable changes (5)
- libs/ui-lib/lib/cim/components/InfraEnv/infra-env.css
- libs/ui-lib/lib/cim/components/Agent/types.ts
- libs/ui-lib/lib/cim/components/modals/AddBmcHostModal.tsx
- libs/ui-lib/lib/cim/components/modals/ProvisioningConfigErrorAlert.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvFormPage.tsx
✅ Files skipped from review due to trivial changes (2)
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.tsx
- libs/ui-lib/lib/cim/hooks/types.ts
🚧 Files skipped from review as they are similar to previous changes (64)
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.css
- libs/ui-lib/lib/cim/config/constants.ts
- libs/ui-lib/lib/cim/types/k8s/multi-cluster-engine.ts
- libs/ui-lib/lib/cim/components/modals/CimConfiguration/utils.ts
- libs/ui-lib/lib/cim/types/k8s/klusterlet.ts
- libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.css
- libs/ui-lib/lib/cim/components/modals/CimConfiguration/CimConfigProgressAlert.tsx
- libs/ui-lib/lib/common/components/clusterConfiguration/FormatDiskWarning.tsx
- libs/ui-lib/lib/cim/hooks/useConfigMap.ts
- libs/ui-lib/lib/cim/hooks/useAgentServiceConfig.ts
- libs/ui-lib/lib/cim/hooks/useProvisioningConfig.ts
- libs/ui-lib/lib/cim/components/InfraEnv/index.ts
- libs/ui-lib/lib/cim/components/modals/EditBMHModal.tsx
- libs/ui-lib/package.json
- libs/ui-lib/lib/cim/components/modals/MassApproveAgentModal.tsx
- libs/ui-lib/lib/cim/hooks/useAgentMachines.ts
- libs/ui-lib/lib/ocm/components/Routes.tsx
- libs/ui-lib/lib/cim/components/Hypershift/DetailsPage/NodePoolsTable.tsx
- libs/ui-lib/lib/cim/components/Agent/NoAgentsAlert.tsx
- libs/ui-lib/lib/cim/hooks/useAgents.ts
- libs/ui-lib/lib/cim/index.ts
- libs/ui-lib/lib/cim/components/modals/EditAgentModal.tsx
- libs/ui-lib/lib/cim/types/k8s/nm-state.ts
- libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts
- libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/useInfraEnvResources.ts
- libs/ui-lib/lib/cim/components/modals/MassDeleteAgentModal.tsx
- libs/ui-lib/lib/cim/hooks/useNMStates.ts
- libs/ui-lib/lib/cim/components/YamlEditor/Theme.ts
- libs/ui-lib/lib/cim/hooks/useAgentClusterInstall.ts
- libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlForm.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/DetailsTab.tsx
- libs/ui-lib/lib/cim/hooks/useBMHs.ts
- libs/ui-lib/lib/cim/components/modals/EditProxyModal.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/types.ts
- libs/ui-lib/lib/cim/components/modals/EditSSHKeyModal.tsx
- libs/ui-lib/lib/cim/components/formik/CredentialsField.tsx
- libs/ui-lib/lib/cim/components/modals/DeleteHostModal.tsx
- libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlModal.tsx
- libs/ui-lib/lib/cim/hooks/useInfraEnvs.ts
- libs/ui-lib/lib/cim/components/modals/AddHostModal.tsx
- libs/ui-lib/lib/cim/components/YamlPreview/useYAMLPreview.ts
- libs/ui-lib/lib/cim/components/modals/EditNtpSourcesModal.tsx
- libs/ui-lib/lib/cim/utils.ts
- libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts
- libs/ui-lib/lib/cim/components/modals/ScaleUpModal.tsx
- libs/ui-lib/lib/cim/components/modals/EditPullSecretModal.tsx
- libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/AddHostDropdown.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/AgentsTab.tsx
- libs/ui-lib/lib/cim/components/modals/UnbindHostModal.tsx
- libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx
- libs/ui-lib/lib/cim/components/modals/types.ts
- libs/ui-lib/lib/cim/components/YamlEditor/utils.ts
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/InfraEnvDetails.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts
- libs/ui-lib/lib/cim/components/InfraEnv/EnvironmentDetails.tsx
- libs/ui-lib/lib/cim/components/modals/utils.ts
- libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvPage.tsx
- libs/ui-lib/lib/cim/components/helpers/agents.ts
- libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostsDiscovery.tsx
- libs/ui-lib/lib/cim/hooks/useSecret.ts
- libs/ui-lib/lib/cim/types/models.ts
- libs/locales/lib/en/translation.json
- libs/ui-lib/lib/cim/components/common/InfoAndTroubleshootingNotification.tsx
🧰 Additional context used
🧬 Code Graph Analysis (3)
libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsx (5)
libs/ui-lib/lib/cim/types/k8s/agent.ts (1)
AgentK8sResource(32-74)libs/ui-lib/lib/cim/components/modals/utils.ts (1)
deleteHost(123-157)libs/ui-lib/lib/cim/utils.ts (1)
onApproveAgent(16-20)libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx (1)
clusterColumn(188-230)libs/ui-lib/lib/cim/components/helpers/agents.ts (1)
onAgentChangeHostname(49-84)
libs/ui-lib/lib/cim/components/Agent/BMCForm.tsx (7)
libs/ui-lib/lib/cim/components/Agent/types.ts (1)
AddBmcValues(5-16)libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts (1)
InfraEnvK8sResource(8-42)libs/ui-lib/lib/cim/types/k8s/nm-state.ts (1)
NMStateK8sResource(3-11)libs/ui-lib/lib/cim/utils.ts (1)
appendPatch(6-14)libs/ui-lib/lib/cim/types/models.ts (3)
SecretModel(3-11)NMStateModel(89-98)BMHModel(78-87)libs/ui-lib/lib/cim/components/modals/utils.ts (2)
getBareMetalHostCredentialsSecret(18-37)getBareMetalHost(39-77)libs/ui-lib/lib/cim/components/common/constants.ts (1)
BMH_HOSTNAME_ANNOTATION(20-20)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (5)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts (1)
EnvironmentStepFormValues(16-35)libs/ui-lib/lib/common/hooks/index.ts (1)
useTranslation(3-3)libs/ui-lib/lib/common/config/docs_links.ts (1)
getOCPStaticIPDocLink(62-63)libs/ui-lib/lib/cim/config/constants.ts (1)
DOC_VERSION(4-4)libs/ui-lib/lib/common/components/ui/formik/LabelField.tsx (1)
LabelField(34-100)
🪛 Biome (1.9.4)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx
[error] 68-72: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment
(lint/complexity/noUselessFragments)
⏰ Context from checks skipped due to timeout of 90000ms (6)
- GitHub Check: format
- GitHub Check: unit-tests
- GitHub Check: circular-deps
- GitHub Check: tests
- GitHub Check: translation-files
- GitHub Check: lint
🔇 Additional comments (11)
libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostDiscoveryTable.tsx (2)
50-60: Well-implemented resource loading hookThe
useTableResourceshook properly encapsulates the loading logic for both NMStates and AgentClusterInstall, returning a combined loaded state. This ensures the component waits for all required data before rendering.
72-76: Good internalization of delete modal stateThe component now manages delete operations internally through the
deleteHoststate, eliminating the need for external callbacks. The modal is properly rendered whendeleteHostis set, and the close handler correctly resets the state.Also applies to: 213-220
libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsx (2)
79-93: Successful internalization of modal state managementThe component now manages all host/agent editing operations through internal state (
editBMH,editAgent,deleteHost,unbindHost) instead of external callbacks. This significantly simplifies the component interface and centralizes state management.Also applies to: 113-118
256-287: Clean modal rendering with internal stateAll modals are now conditionally rendered based on internal state with proper cleanup handlers. The modals receive necessary data directly without requiring external callbacks.
libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentWizard.tsx (1)
42-42: Good adoption of internal modal state patternThe component successfully adopts the same pattern as other components in this refactor - managing modal state internally with
editAgentand conditionally renderingEditAgentModal. The direct passing ofsetEditAgentto child components is consistent with the broader refactoring approach.Also applies to: 130-130, 161-168
libs/ui-lib/lib/cim/components/Agent/BMCForm.tsx (2)
238-335: Excellent centralization of BMH resource managementThe
onCreateBMHfunction provides a comprehensive solution for handling both creation and updates of BMH-related resources. It correctly:
- Handles Secret creation/patching with base64-encoded credentials
- Manages NMState resource lifecycle based on form data
- Creates new BMH when in "add" mode or patches existing BMH in "edit" mode
- Uses the
appendPatchutility for conditional patching, avoiding unnecessary API callsThis centralized approach eliminates the need for external callbacks and provides consistent resource management across the application.
353-359: Clean integration of centralized resource managementThe form submission handler cleanly integrates with the new
onCreateBMHfunction, passing all necessary parameters. This removes the dependency on external callbacks and simplifies the component interface.libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts (3)
21-21: Good: Wrapper object signature improves API consistencyThe change to use a wrapper object with optional
agentandbmhproperties is more maintainable than positional parameters and reduces the risk of parameter order mistakes.
155-162: Clean type definition for InfraEnv componentsThe
InfraEnvAgentTablePropstype definition includes all necessary resources for agent table functionality. The inclusion ofnmStatesdirectly in props is appropriate for this component's scope.
164-172: Appropriate action subset for host discoveryThe
ClusterDeploymentHostDiscoveryTablePropscorrectly picks only the essential actions fromAgentTableActions, maintaining a focused interface for the host discovery table component.libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (1)
41-184: Well-structured component with good practices.The component follows React best practices with proper:
- TypeScript typing for props and form values
- Internationalization using translation hooks
- Accessibility with proper form labels and field IDs
- PatternFly component usage for consistent UI
- Form validation and helper text
- Security considerations (noopener for external links)
🧰 Tools
🪛 Biome (1.9.4)
[error] 68-72: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment(lint/complexity/noUselessFragments)
| </Flex> | ||
| </FormGroup> | ||
| <CpuArchitectureDropdown /> | ||
| {!!osImages && <InfraEnvOpenShiftVersionDropdown osImages={osImages} />} |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Improve osImages array validation.
The current check !!osImages will pass for empty arrays, which might not be the intended behavior. Consider checking if the array has content.
-{!!osImages && <InfraEnvOpenShiftVersionDropdown osImages={osImages} />}
+{osImages && osImages.length > 0 && <InfraEnvOpenShiftVersionDropdown osImages={osImages} />}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| {!!osImages && <InfraEnvOpenShiftVersionDropdown osImages={osImages} />} | |
| {osImages && osImages.length > 0 && <InfraEnvOpenShiftVersionDropdown osImages={osImages} />} |
🤖 Prompt for AI Agents
In libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx
at line 126, the condition rendering InfraEnvOpenShiftVersionDropdown uses
`!!osImages`, which evaluates true even for empty arrays. Update the condition
to check that osImages is not only defined but also has a length greater than
zero, ensuring the dropdown only renders when the array contains elements.
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (3)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (2)
126-126: osImages array validation issue remains unaddressed.The condition
!!osImageswill evaluate to true for empty arrays, which may not be the intended behavior. The dropdown should only render when there are actual OS images to display.-{!!osImages && <InfraEnvOpenShiftVersionDropdown osImages={osImages} />} +{osImages && osImages.length > 0 && <InfraEnvOpenShiftVersionDropdown osImages={osImages} />}
140-148: Base64 decoding error handling is still missing.Despite the past review comment being marked as addressed, the
atob()function calls still lack error handling. These functions can throw exceptions if the input isn't properly base64-encoded, potentially causing runtime crashes.onSelect={(cred) => { - setFieldValue( - 'pullSecret', - cred.data?.['pullSecret'] ? atob(cred.data['pullSecret']) : '', - ); - setFieldValue( - 'sshPublicKey', - cred.data?.['ssh-publickey'] ? atob(cred.data['ssh-publickey']) : '', - ); + try { + setFieldValue( + 'pullSecret', + cred.data?.['pullSecret'] ? atob(cred.data['pullSecret']) : '', + ); + setFieldValue( + 'sshPublicKey', + cred.data?.['ssh-publickey'] ? atob(cred.data['ssh-publickey']) : '', + ); + } catch (error) { + console.error('Failed to decode credential data:', error); + setFieldValue('pullSecret', ''); + setFieldValue('sshPublicKey', ''); + } }}libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts (1)
23-23: 🛠️ Refactor suggestionConsider unifying onMassDeleteHost signature for consistency.
While
onDeleteHostwas updated to use a wrapper object,onMassDeleteHoststill uses two positional parameters. This inconsistency could lead to confusion and parameter swap errors.Consider updating to match the pattern:
- onMassDeleteHost: (agent?: AgentK8sResource, bmh?: BareMetalHostK8sResource) => Promise<unknown>; + onMassDeleteHost: ( + hosts: { agent?: AgentK8sResource; bmh?: BareMetalHostK8sResource }[] + ) => Promise<unknown>;This would make the "mass" semantics explicit and maintain API consistency.
🧹 Nitpick comments (1)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (1)
68-72: Remove unnecessary Fragment wrapper.The Fragment wrapper around the single translation text is redundant and can be simplified.
-bodyContent={ - <> - {t( - 'ai:This will determine for the infrastructure environment which kind of hosts would be able to be added. If the hosts that you want to add are using DHCP server, select this option, else, select the static IP.', - )} - </> -} +bodyContent={t( + 'ai:This will determine for the infrastructure environment which kind of hosts would be able to be added. If the hosts that you want to add are using DHCP server, select this option, else, select the static IP.', +)}🧰 Tools
🪛 Biome (1.9.4)
[error] 68-72: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment(lint/complexity/noUselessFragments)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
libs/ui-lib/lib/cim/logos/OnPremiseBannerIcon.svgis excluded by!**/*.svgyarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (77)
libs/locales/lib/en/translation.json(21 hunks)libs/ui-lib/lib/cim/components/Agent/BMCForm.tsx(4 hunks)libs/ui-lib/lib/cim/components/Agent/NoAgentsAlert.tsx(1 hunks)libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx(3 hunks)libs/ui-lib/lib/cim/components/Agent/types.ts(0 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostDiscoveryTable.tsx(6 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostsDiscovery.tsx(3 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentWizard.tsx(3 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts(3 hunks)libs/ui-lib/lib/cim/components/Hypershift/DetailsPage/NodePoolsTable.tsx(2 hunks)libs/ui-lib/lib/cim/components/InfraEnv/AddHostDropdown.tsx(4 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvPage.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/useInfraEnvResources.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/EnvironmentDetails.tsx(4 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsx(6 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/AgentsTab.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/DetailsTab.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/InfraEnvDetails.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvFormPage.tsx(0 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.css(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.tsx(2 hunks)libs/ui-lib/lib/cim/components/InfraEnv/index.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/infra-env.css(0 hunks)libs/ui-lib/lib/cim/components/InfraEnv/types.ts(1 hunks)libs/ui-lib/lib/cim/components/YamlEditor/Theme.ts(1 hunks)libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.css(1 hunks)libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.tsx(1 hunks)libs/ui-lib/lib/cim/components/YamlEditor/utils.ts(1 hunks)libs/ui-lib/lib/cim/components/YamlPreview/useYAMLPreview.ts(5 hunks)libs/ui-lib/lib/cim/components/common/InfoAndTroubleshootingNotification.tsx(1 hunks)libs/ui-lib/lib/cim/components/formik/CredentialsField.tsx(1 hunks)libs/ui-lib/lib/cim/components/helpers/agents.ts(3 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostModal.tsx(0 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlForm.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/AddHostModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/CimConfiguration/CimConfigProgressAlert.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/CimConfiguration/utils.ts(1 hunks)libs/ui-lib/lib/cim/components/modals/DeleteHostModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/EditAgentModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/EditBMHModal.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/EditNtpSourcesModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/EditProxyModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/EditPullSecretModal.tsx(4 hunks)libs/ui-lib/lib/cim/components/modals/EditSSHKeyModal.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/MassApproveAgentModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/MassDeleteAgentModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/ProvisioningConfigErrorAlert.tsx(0 hunks)libs/ui-lib/lib/cim/components/modals/ScaleUpModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/UnbindHostModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/types.ts(1 hunks)libs/ui-lib/lib/cim/components/modals/utils.ts(2 hunks)libs/ui-lib/lib/cim/config/constants.ts(1 hunks)libs/ui-lib/lib/cim/hooks/types.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useAgentClusterInstall.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useAgentMachines.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useAgentServiceConfig.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useAgents.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useBMHs.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useConfigMap.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useInfraEnvs.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useNMStates.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useProvisioningConfig.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useSecret.ts(1 hunks)libs/ui-lib/lib/cim/index.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/klusterlet.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/multi-cluster-engine.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/nm-state.ts(1 hunks)libs/ui-lib/lib/cim/types/models.ts(1 hunks)libs/ui-lib/lib/cim/utils.ts(1 hunks)libs/ui-lib/lib/common/components/clusterConfiguration/FormatDiskWarning.tsx(1 hunks)libs/ui-lib/lib/ocm/components/Routes.tsx(1 hunks)libs/ui-lib/package.json(2 hunks)
💤 Files with no reviewable changes (5)
- libs/ui-lib/lib/cim/components/Agent/types.ts
- libs/ui-lib/lib/cim/components/InfraEnv/infra-env.css
- libs/ui-lib/lib/cim/components/modals/AddBmcHostModal.tsx
- libs/ui-lib/lib/cim/components/modals/ProvisioningConfigErrorAlert.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvFormPage.tsx
✅ Files skipped from review due to trivial changes (4)
- libs/ui-lib/lib/cim/components/modals/CimConfiguration/CimConfigProgressAlert.tsx
- libs/ui-lib/lib/cim/components/Agent/NoAgentsAlert.tsx
- libs/ui-lib/lib/cim/hooks/useProvisioningConfig.ts
- libs/ui-lib/lib/cim/hooks/useAgentClusterInstall.ts
🚧 Files skipped from review as they are similar to previous changes (63)
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.css
- libs/ui-lib/lib/cim/types/k8s/multi-cluster-engine.ts
- libs/ui-lib/lib/common/components/clusterConfiguration/FormatDiskWarning.tsx
- libs/ui-lib/lib/cim/config/constants.ts
- libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.css
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.tsx
- libs/ui-lib/lib/cim/components/modals/MassDeleteAgentModal.tsx
- libs/ui-lib/lib/cim/hooks/useAgentMachines.ts
- libs/ui-lib/lib/cim/components/InfraEnv/index.ts
- libs/ui-lib/lib/cim/hooks/useInfraEnvs.ts
- libs/ui-lib/lib/cim/hooks/useAgentServiceConfig.ts
- libs/ui-lib/lib/cim/types/k8s/nm-state.ts
- libs/ui-lib/lib/cim/types/k8s/klusterlet.ts
- libs/ui-lib/lib/cim/components/YamlEditor/Theme.ts
- libs/ui-lib/lib/cim/hooks/useAgents.ts
- libs/ui-lib/lib/cim/hooks/useConfigMap.ts
- libs/ui-lib/lib/cim/components/Hypershift/DetailsPage/NodePoolsTable.tsx
- libs/ui-lib/package.json
- libs/ui-lib/lib/cim/components/modals/MassApproveAgentModal.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/useInfraEnvResources.ts
- libs/ui-lib/lib/cim/index.ts
- libs/ui-lib/lib/cim/components/InfraEnv/AddHostDropdown.tsx
- libs/ui-lib/lib/cim/utils.ts
- libs/ui-lib/lib/cim/components/modals/EditNtpSourcesModal.tsx
- libs/ui-lib/lib/ocm/components/Routes.tsx
- libs/ui-lib/lib/cim/components/modals/EditProxyModal.tsx
- libs/ui-lib/lib/cim/hooks/useBMHs.ts
- libs/ui-lib/lib/cim/components/modals/EditSSHKeyModal.tsx
- libs/ui-lib/lib/cim/components/modals/CimConfiguration/utils.ts
- libs/ui-lib/lib/cim/hooks/useNMStates.ts
- libs/ui-lib/lib/cim/components/modals/EditBMHModal.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/DetailsTab.tsx
- libs/ui-lib/lib/cim/components/modals/AddHostModal.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/types.ts
- libs/ui-lib/lib/cim/hooks/types.ts
- libs/ui-lib/lib/cim/components/YamlPreview/useYAMLPreview.ts
- libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlForm.tsx
- libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts
- libs/ui-lib/lib/cim/components/modals/EditAgentModal.tsx
- libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.tsx
- libs/ui-lib/lib/cim/components/modals/EditPullSecretModal.tsx
- libs/ui-lib/lib/cim/components/formik/CredentialsField.tsx
- libs/ui-lib/lib/cim/components/modals/utils.ts
- libs/ui-lib/lib/cim/components/modals/ScaleUpModal.tsx
- libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlModal.tsx
- libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx
- libs/ui-lib/lib/cim/components/YamlEditor/utils.ts
- libs/ui-lib/lib/cim/components/common/InfoAndTroubleshootingNotification.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts
- libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostsDiscovery.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvPage.tsx
- libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts
- libs/ui-lib/lib/cim/hooks/useSecret.ts
- libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentWizard.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/EnvironmentDetails.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/InfraEnvDetails.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/AgentsTab.tsx
- libs/ui-lib/lib/cim/components/modals/DeleteHostModal.tsx
- libs/ui-lib/lib/cim/components/modals/types.ts
- libs/ui-lib/lib/cim/types/models.ts
- libs/ui-lib/lib/cim/components/modals/UnbindHostModal.tsx
- libs/locales/lib/en/translation.json
- libs/ui-lib/lib/cim/components/Agent/BMCForm.tsx
🧰 Additional context used
🧬 Code Graph Analysis (3)
libs/ui-lib/lib/cim/components/helpers/agents.ts (3)
libs/ui-lib/lib/cim/components/common/constants.ts (2)
AGENT_BMH_NAME_LABEL_KEY(12-12)BMH_HOSTNAME_ANNOTATION(20-20)libs/ui-lib/lib/cim/utils.ts (1)
appendPatch(6-14)libs/ui-lib/lib/cim/types/models.ts (2)
AgentModel(67-76)BMHModel(78-87)
libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsx (5)
libs/ui-lib/lib/cim/types/k8s/agent.ts (1)
AgentK8sResource(32-74)libs/ui-lib/lib/cim/components/modals/utils.ts (1)
deleteHost(123-157)libs/ui-lib/lib/cim/utils.ts (1)
onApproveAgent(16-20)libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx (1)
clusterColumn(188-230)libs/ui-lib/lib/cim/components/helpers/agents.ts (1)
onAgentChangeHostname(49-84)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (4)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts (1)
EnvironmentStepFormValues(16-35)libs/ui-lib/lib/common/config/docs_links.ts (1)
getOCPStaticIPDocLink(62-63)libs/ui-lib/lib/cim/config/constants.ts (1)
DOC_VERSION(4-4)libs/ui-lib/lib/common/components/ui/formik/LabelField.tsx (1)
LabelField(34-100)
🪛 Biome (1.9.4)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx
[error] 68-72: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment
(lint/complexity/noUselessFragments)
⏰ Context from checks skipped due to timeout of 90000ms (6)
- GitHub Check: tests
- GitHub Check: circular-deps
- GitHub Check: unit-tests
- GitHub Check: translation-files
- GitHub Check: format
- GitHub Check: lint
🔇 Additional comments (10)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (1)
41-182: Well-structured form component with comprehensive functionality.The component effectively implements a complex infrastructure environment creation form with proper validation, internationalization, and user experience considerations. The integration with Formik provides good state management, and the use of PatternFly components ensures consistent UI patterns.
🧰 Tools
🪛 Biome (1.9.4)
[error] 68-72: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment(lint/complexity/noUselessFragments)
libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostDiscoveryTable.tsx (3)
50-60: Well-designed resource loading hook.The
useTableResourceshook properly encapsulates the loading logic for both NMStates and AgentClusterInstall resources, returning a combined loading state. This ensures dependent components only render when all required data is available.
154-156: Proper loading state management.The loading check prevents rendering the table until all resources are loaded, which addresses the previous issues with modals receiving partially-initialized data.
213-220: Safe modal rendering with complete data.The
DeleteHostModalis only rendered whendeleteHostis set and the loading state ensures all resources (nmStates,agentClusterInstall) are fully loaded before rendering, preventing runtime errors.libs/ui-lib/lib/cim/components/helpers/agents.ts (1)
49-84: Excellent centralization of hostname update logic.The refactored
onAgentChangeHostnamefunction properly:
- Handles both Agent and BareMetalHost hostname updates
- Uses correct JSON Patch path escaping for BMH annotations (line 79)
- Centralizes Kubernetes patch operations instead of relying on external callbacks
- Returns proper Promise types for async operations
This change significantly improves maintainability and reduces coupling.
libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsx (3)
113-118: Well-implemented internalization of action handlers.The refactored approach using internal state setters (
setDeleteHost,setEditBMH, etc.) for theuseAgentsTablehandlers is clean and reduces external coupling. The handlers now manage modal state internally rather than requiring external callbacks.
256-287: Comprehensive modal state management.The conditional rendering of modals based on internal state (
editBMH,editAgent,deleteHost,unbindHost) is well-organized and provides all necessary data to each modal component. This approach eliminates the need for external modal management.
299-299: Proper usage of refactored hostname change function.The call to
onAgentChangeHostname(agents, bareMetalHosts)correctly provides both agents and BMHs to the hostname change handler, ensuring all hostname updates are handled properly.libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts (2)
21-21: Good refactoring of onDeleteHost signature.The wrapper object approach
{ agent?: AgentK8sResource; bmh?: BareMetalHostK8sResource }is much cleaner than separate parameters and reduces the chance of parameter order errors.
121-121: Excellent simplification of hostActions interface.Reducing
hostActionsto only the essential actions (onEditRole,onSetInstallationDiskId) makes the interface much cleaner and reduces coupling. The removal of deletion and hostname change callbacks aligns well with the internal state management approach.
There was a problem hiding this comment.
Actionable comments posted: 3
♻️ Duplicate comments (4)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (2)
126-126: Improve osImages array validation.The condition
!!osImagesevaluates to true even for empty arrays. The dropdown should only render when the array contains elements.-{!!osImages && <InfraEnvOpenShiftVersionDropdown osImages={osImages} />} +{osImages && osImages.length > 0 && <InfraEnvOpenShiftVersionDropdown osImages={osImages} />}
140-148: Add error handling for base64 decoding.The
atob()function can throw exceptions if the input isn't properly base64-encoded. This issue from previous reviews still needs to be addressed.onSelect={(cred) => { - setFieldValue( - 'pullSecret', - cred.data?.['pullSecret'] ? atob(cred.data['pullSecret']) : '', - ); - setFieldValue( - 'sshPublicKey', - cred.data?.['ssh-publickey'] ? atob(cred.data['ssh-publickey']) : '', - ); + try { + setFieldValue( + 'pullSecret', + cred.data?.['pullSecret'] ? atob(cred.data['pullSecret']) : '', + ); + setFieldValue( + 'sshPublicKey', + cred.data?.['ssh-publickey'] ? atob(cred.data['ssh-publickey']) : '', + ); + } catch (error) { + console.error('Failed to decode credential data:', error); + // Consider showing a user-friendly error message here + } }}libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts (2)
21-23: API inconsistency between delete operations remains unaddressedThe
onDeleteHostsignature was updated to use a wrapper object, butonMassDeleteHoststill uses two positional parameters, creating an inconsistent API that increases the risk of parameter swap bugs.Consider unifying the signatures:
- onMassDeleteHost: (agent?: AgentK8sResource, bmh?: BareMetalHostK8sResource) => Promise<unknown>; + onMassDeleteHost: ( + hosts: { agent?: AgentK8sResource; bmh?: BareMetalHostK8sResource }[], + ) => Promise<unknown>;This would make the "mass" semantics explicit and prevent accidental parameter ordering errors.
121-121: Verify all consumers updated for reduced hostActions interfaceThe
hostActionstype now only includes'onEditRole' | 'onSetInstallationDiskId', removing'onEditHost'and'onDeleteHost'. Based on past review comments, this appears to have been addressed, but ensure all consuming components have been updated to handle these operations through alternative means.
🧹 Nitpick comments (3)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (1)
68-72: Remove unnecessary Fragment wrapper.The Fragment is redundant since it contains only one child element.
-bodyContent={ - <> - {t( - 'ai:This will determine for the infrastructure environment which kind of hosts would be able to be added. If the hosts that you want to add are using DHCP server, select this option, else, select the static IP.', - )} - </> -} +bodyContent={ + t( + 'ai:This will determine for the infrastructure environment which kind of hosts would be able to be added. If the hosts that you want to add are using DHCP server, select this option, else, select the static IP.', + ) +}🧰 Tools
🪛 Biome (1.9.4)
[error] 68-72: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment(lint/complexity/noUselessFragments)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts (2)
161-163: Add conditional check for cpuArchitecture assignment.The current code assigns
cpuArchitectureeven when it might be undefined or empty, which could create unnecessary spec fields.-if (values.cpuArchitecture) { +if (values.cpuArchitecture && values.cpuArchitecture !== '') { infraEnv.spec.cpuArchitecture = values.cpuArchitecture; }
175-191: Consider parameterizing the role name.The hardcoded role name
'capi-provider-role'might conflict if multiple InfraEnvs are created in the same namespace. Consider making it unique per InfraEnv.-export const getRole = (namespace: string) => { +export const getRole = (namespace: string, infraEnvName?: string) => { return { kind: RoleModel.kind, apiVersion: `${RoleModel.apiGroup || ''}/${RoleModel.apiVersion}`, metadata: { - name: 'capi-provider-role', + name: infraEnvName ? `capi-provider-role-${infraEnvName}` : 'capi-provider-role', namespace, },
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
libs/ui-lib/lib/cim/logos/OnPremiseBannerIcon.svgis excluded by!**/*.svgyarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (77)
libs/locales/lib/en/translation.json(21 hunks)libs/ui-lib/lib/cim/components/Agent/BMCForm.tsx(4 hunks)libs/ui-lib/lib/cim/components/Agent/NoAgentsAlert.tsx(1 hunks)libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx(3 hunks)libs/ui-lib/lib/cim/components/Agent/types.ts(0 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostDiscoveryTable.tsx(6 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostsDiscovery.tsx(3 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentWizard.tsx(3 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts(3 hunks)libs/ui-lib/lib/cim/components/Hypershift/DetailsPage/NodePoolsTable.tsx(2 hunks)libs/ui-lib/lib/cim/components/InfraEnv/AddHostDropdown.tsx(4 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvPage.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/useInfraEnvResources.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/EnvironmentDetails.tsx(4 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsx(6 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/AgentsTab.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/DetailsTab.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/InfraEnvDetails.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvFormPage.tsx(0 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.css(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.tsx(2 hunks)libs/ui-lib/lib/cim/components/InfraEnv/index.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/infra-env.css(0 hunks)libs/ui-lib/lib/cim/components/InfraEnv/types.ts(1 hunks)libs/ui-lib/lib/cim/components/YamlEditor/Theme.ts(1 hunks)libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.css(1 hunks)libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.tsx(1 hunks)libs/ui-lib/lib/cim/components/YamlEditor/utils.ts(1 hunks)libs/ui-lib/lib/cim/components/YamlPreview/useYAMLPreview.ts(5 hunks)libs/ui-lib/lib/cim/components/common/InfoAndTroubleshootingNotification.tsx(1 hunks)libs/ui-lib/lib/cim/components/formik/CredentialsField.tsx(1 hunks)libs/ui-lib/lib/cim/components/helpers/agents.ts(3 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostModal.tsx(0 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlForm.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/AddHostModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/CimConfiguration/CimConfigProgressAlert.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/CimConfiguration/utils.ts(1 hunks)libs/ui-lib/lib/cim/components/modals/DeleteHostModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/EditAgentModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/EditBMHModal.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/EditNtpSourcesModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/EditProxyModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/EditPullSecretModal.tsx(4 hunks)libs/ui-lib/lib/cim/components/modals/EditSSHKeyModal.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/MassApproveAgentModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/MassDeleteAgentModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/ProvisioningConfigErrorAlert.tsx(0 hunks)libs/ui-lib/lib/cim/components/modals/ScaleUpModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/UnbindHostModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/types.ts(2 hunks)libs/ui-lib/lib/cim/components/modals/utils.ts(2 hunks)libs/ui-lib/lib/cim/config/constants.ts(1 hunks)libs/ui-lib/lib/cim/hooks/types.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useAgentClusterInstall.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useAgentMachines.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useAgentServiceConfig.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useAgents.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useBMHs.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useConfigMap.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useInfraEnvs.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useNMStates.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useProvisioningConfig.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useSecret.ts(1 hunks)libs/ui-lib/lib/cim/index.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/klusterlet.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/multi-cluster-engine.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/nm-state.ts(1 hunks)libs/ui-lib/lib/cim/types/models.ts(1 hunks)libs/ui-lib/lib/cim/utils.ts(1 hunks)libs/ui-lib/lib/common/components/clusterConfiguration/FormatDiskWarning.tsx(1 hunks)libs/ui-lib/lib/ocm/components/Routes.tsx(1 hunks)libs/ui-lib/package.json(2 hunks)
💤 Files with no reviewable changes (5)
- libs/ui-lib/lib/cim/components/Agent/types.ts
- libs/ui-lib/lib/cim/components/modals/AddBmcHostModal.tsx
- libs/ui-lib/lib/cim/components/modals/ProvisioningConfigErrorAlert.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvFormPage.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/infra-env.css
✅ Files skipped from review due to trivial changes (3)
- libs/ui-lib/lib/cim/index.ts
- libs/ui-lib/lib/cim/hooks/types.ts
- libs/ui-lib/lib/cim/components/modals/DeleteHostModal.tsx
🚧 Files skipped from review as they are similar to previous changes (62)
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.css
- libs/ui-lib/lib/cim/components/modals/CimConfiguration/CimConfigProgressAlert.tsx
- libs/ui-lib/lib/cim/config/constants.ts
- libs/ui-lib/lib/cim/components/Agent/NoAgentsAlert.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.tsx
- libs/ui-lib/lib/cim/types/k8s/klusterlet.ts
- libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.css
- libs/ui-lib/lib/common/components/clusterConfiguration/FormatDiskWarning.tsx
- libs/ui-lib/lib/cim/types/k8s/multi-cluster-engine.ts
- libs/ui-lib/package.json
- libs/ui-lib/lib/cim/components/modals/MassApproveAgentModal.tsx
- libs/ui-lib/lib/cim/types/k8s/nm-state.ts
- libs/ui-lib/lib/cim/hooks/useProvisioningConfig.ts
- libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts
- libs/ui-lib/lib/cim/hooks/useAgentServiceConfig.ts
- libs/ui-lib/lib/cim/components/modals/CimConfiguration/utils.ts
- libs/ui-lib/lib/cim/hooks/useAgentMachines.ts
- libs/ui-lib/lib/cim/components/YamlEditor/Theme.ts
- libs/ui-lib/lib/cim/components/InfraEnv/types.ts
- libs/ui-lib/lib/cim/components/Hypershift/DetailsPage/NodePoolsTable.tsx
- libs/ui-lib/lib/ocm/components/Routes.tsx
- libs/ui-lib/lib/cim/hooks/useAgents.ts
- libs/ui-lib/lib/cim/components/modals/MassDeleteAgentModal.tsx
- libs/ui-lib/lib/cim/components/YamlEditor/utils.ts
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/DetailsTab.tsx
- libs/ui-lib/lib/cim/hooks/useConfigMap.ts
- libs/ui-lib/lib/cim/hooks/useInfraEnvs.ts
- libs/ui-lib/lib/cim/components/modals/EditBMHModal.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/useInfraEnvResources.ts
- libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlModal.tsx
- libs/ui-lib/lib/cim/hooks/useBMHs.ts
- libs/ui-lib/lib/cim/components/modals/EditProxyModal.tsx
- libs/ui-lib/lib/cim/components/modals/AddHostModal.tsx
- libs/ui-lib/lib/cim/components/modals/EditSSHKeyModal.tsx
- libs/ui-lib/lib/cim/hooks/useNMStates.ts
- libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.tsx
- libs/ui-lib/lib/cim/components/helpers/agents.ts
- libs/ui-lib/lib/cim/components/formik/CredentialsField.tsx
- libs/ui-lib/lib/cim/components/modals/ScaleUpModal.tsx
- libs/ui-lib/lib/cim/components/modals/EditNtpSourcesModal.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/index.ts
- libs/ui-lib/lib/cim/components/YamlPreview/useYAMLPreview.ts
- libs/ui-lib/lib/cim/components/common/InfoAndTroubleshootingNotification.tsx
- libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts
- libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostsDiscovery.tsx
- libs/ui-lib/lib/cim/hooks/useAgentClusterInstall.ts
- libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlForm.tsx
- libs/ui-lib/lib/cim/components/modals/utils.ts
- libs/ui-lib/lib/cim/hooks/useSecret.ts
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/InfraEnvDetails.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/AddHostDropdown.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvPage.tsx
- libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx
- libs/ui-lib/lib/cim/components/modals/EditAgentModal.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/AgentsTab.tsx
- libs/ui-lib/lib/cim/components/modals/EditPullSecretModal.tsx
- libs/ui-lib/lib/cim/components/modals/UnbindHostModal.tsx
- libs/ui-lib/lib/cim/types/models.ts
- libs/ui-lib/lib/cim/components/InfraEnv/EnvironmentDetails.tsx
- libs/ui-lib/lib/cim/components/modals/types.ts
- libs/locales/lib/en/translation.json
🧰 Additional context used
🧬 Code Graph Analysis (4)
libs/ui-lib/lib/cim/utils.ts (2)
libs/ui-lib/lib/cim/types/k8s/agent.ts (1)
AgentK8sResource(32-74)libs/ui-lib/lib/cim/types/models.ts (1)
AgentModel(67-76)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts (4)
libs/ui-lib-tests/cypress/fixtures/infra-envs/openshift-versions.ts (2)
x86(8-8)s390x(10-10)libs/ui-lib/lib/common/components/ui/formik/validationSchemas.ts (7)
richNameValidationSchema(456-489)locationValidationSchema(654-679)pullSecretValidationSchema(143-162)sshPublicKeyValidationSchema(105-115)httpProxyValidationSchema(534-573)noProxyValidationSchema(587-602)ntpSourceValidationSchema(604-627)libs/ui-lib/lib/cim/types/models.ts (3)
SecretModel(3-11)InfraEnvModel(24-33)RoleModel(13-22)libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts (1)
InfraEnvK8sResource(8-42)
libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts (5)
libs/ui-lib/lib/cim/types/k8s/agent.ts (1)
AgentK8sResource(32-74)libs/ui-lib/lib/cim/components/Hypershift/types.ts (1)
AgentMachineK8sResource(186-193)libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts (1)
InfraEnvK8sResource(8-42)libs/ui-lib/lib/cim/types/k8s/nm-state.ts (1)
NMStateK8sResource(3-11)libs/ui-lib/lib/cim/types/k8s/agent-cluster-install.ts (1)
AgentClusterInstallK8sResource(17-80)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (4)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts (1)
EnvironmentStepFormValues(16-35)libs/ui-lib/lib/common/config/docs_links.ts (1)
getOCPStaticIPDocLink(62-63)libs/ui-lib/lib/cim/config/constants.ts (1)
DOC_VERSION(4-4)libs/ui-lib/lib/common/components/ui/formik/LabelField.tsx (1)
LabelField(34-100)
🪛 Biome (1.9.4)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx
[error] 68-72: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment
(lint/complexity/noUselessFragments)
⏰ Context from checks skipped due to timeout of 90000ms (6)
- GitHub Check: unit-tests
- GitHub Check: translation-files
- GitHub Check: tests
- GitHub Check: circular-deps
- GitHub Check: lint
- GitHub Check: format
🔇 Additional comments (7)
libs/ui-lib/lib/cim/utils.ts (1)
6-20: Well-implemented utility functions.The
appendPatchhelper correctly handles the add/replace logic with proper undefined checks, andonApproveAgentprovides a clean abstraction for agent approval. These utilities effectively centralize patch creation logic.libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostDiscoveryTable.tsx (2)
50-60: Clean resource loading abstraction.The
useTableResourceshook provides a clean abstraction for loading the required resources and properly combines the loading states. This prevents rendering with partially loaded data.
213-220: Proper conditional rendering of DeleteHostModal.The modal is only rendered when
deleteHostis set, and it receives all necessary props including the loadednmStatesandagentClusterInstall. This avoids the runtime errors that could occur with undefined data.libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentWizard.tsx (1)
42-42: Good internalization of modal state management.The
editAgentstate and conditionalEditAgentModalrendering properly internalizes the agent editing workflow, eliminating the need for external callbacks.Also applies to: 161-168
libs/ui-lib/lib/cim/components/Agent/BMCForm.tsx (1)
353-359: Good internalization of BMH creation logic.The direct call to
onCreateBMHwith all necessary parameters properly internalizes the resource creation logic, eliminating the need for external callbacks.libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts (2)
155-162: New InfraEnvAgentTableProps type looks well-structuredThe type definition properly includes all necessary Kubernetes resource types for agent table functionality and follows consistent naming conventions with other prop types in the file.
166-166: Consistent property selection from AgentTableActionsThe
ClusterDeploymentHostDiscoveryTablePropscorrectly picks only the required actions fromAgentTableActions, maintaining a clean interface that excludes mass deletion and approval operations which aren't needed for this component.
| values.labels.forEach((l) => { | ||
| const label = l.split('='); | ||
| if (label.length && infraEnv.metadata?.labels) { | ||
| infraEnv.metadata.labels[label[0]] = label.length === 2 ? label[1] : ''; | ||
| } | ||
| }); |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Fix potential issue with empty label keys.
The current logic could create labels with empty keys when label.length is 1 but still processes the label.
values.labels.forEach((l) => {
const label = l.split('=');
- if (label.length && infraEnv.metadata?.labels) {
- infraEnv.metadata.labels[label[0]] = label.length === 2 ? label[1] : '';
+ if (label.length >= 2 && label[0].trim() && infraEnv.metadata?.labels) {
+ infraEnv.metadata.labels[label[0].trim()] = label.slice(1).join('=').trim();
}
});📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| values.labels.forEach((l) => { | |
| const label = l.split('='); | |
| if (label.length && infraEnv.metadata?.labels) { | |
| infraEnv.metadata.labels[label[0]] = label.length === 2 ? label[1] : ''; | |
| } | |
| }); | |
| values.labels.forEach((l) => { | |
| const label = l.split('='); | |
| if (label.length >= 2 && label[0].trim() && infraEnv.metadata?.labels) { | |
| infraEnv.metadata.labels[label[0].trim()] = label.slice(1).join('=').trim(); | |
| } | |
| }); |
🤖 Prompt for AI Agents
In libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts around lines
134 to 139, the code processes labels without checking if the label key is
empty, which can lead to creating labels with empty keys. Update the condition
to ensure that the label array has a non-empty first element before assigning it
as a key in infraEnv.metadata.labels. This prevents adding labels with empty
keys by verifying label[0] is not an empty string.
| labels: Yup.array() | ||
| .of(Yup.string()) | ||
| .test( | ||
| 'label-equals-validation', | ||
| 'Label selector needs to be in a `key=value` form', | ||
| (values) => | ||
| (values as string[]).every((value) => { | ||
| const parts = value.split('='); | ||
| return parts.length === 2; | ||
| }), | ||
| ), |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Improve label validation logic.
The current validation has several issues:
- It doesn't prevent empty keys or values (e.g., "=value" or "key=" would pass)
- The error message refers to "Label selector" but this validates metadata labels
- Labels with multiple
=characters are rejected but could be valid in some cases
labels: Yup.array()
.of(Yup.string())
.test(
- 'label-equals-validation',
- 'Label selector needs to be in a `key=value` form',
+ 'label-format-validation',
+ 'Labels must be in a `key=value` format with non-empty key and value',
(values) =>
(values as string[]).every((value) => {
const parts = value.split('=');
- return parts.length === 2;
+ return parts.length >= 2 && parts[0].trim() !== '' && parts.slice(1).join('=').trim() !== '';
}),
),📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| labels: Yup.array() | |
| .of(Yup.string()) | |
| .test( | |
| 'label-equals-validation', | |
| 'Label selector needs to be in a `key=value` form', | |
| (values) => | |
| (values as string[]).every((value) => { | |
| const parts = value.split('='); | |
| return parts.length === 2; | |
| }), | |
| ), | |
| labels: Yup.array() | |
| .of(Yup.string()) | |
| .test( | |
| 'label-format-validation', | |
| 'Labels must be in a `key=value` format with non-empty key and value', | |
| (values) => | |
| (values as string[]).every((value) => { | |
| const parts = value.split('='); | |
| return parts.length >= 2 && parts[0].trim() !== '' && parts.slice(1).join('=').trim() !== ''; | |
| }), | |
| ), |
🤖 Prompt for AI Agents
In libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts around lines
55 to 65, improve the Yup validation for labels by ensuring keys and values are
not empty (reject strings like "=value" or "key="), update the error message to
refer to "metadata labels" instead of "Label selector," and adjust the logic to
allow multiple '=' characters in values by only splitting on the first '=' and
validating that both key and value parts are non-empty.
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (5)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (2)
140-148:⚠️ Potential issueAdd error handling for base64 decoding
The
atob()calls can throw exceptions if the credential data isn't properly base64-encoded. This issue was flagged in previous reviews but hasn't been addressed.Wrap the decoding operations in try-catch blocks:
onSelect={(cred) => { - setFieldValue( - 'pullSecret', - cred.data?.['pullSecret'] ? atob(cred.data['pullSecret']) : '', - ); - setFieldValue( - 'sshPublicKey', - cred.data?.['ssh-publickey'] ? atob(cred.data['ssh-publickey']) : '', - ); + try { + setFieldValue( + 'pullSecret', + cred.data?.['pullSecret'] ? atob(cred.data['pullSecret']) : '', + ); + setFieldValue( + 'sshPublicKey', + cred.data?.['ssh-publickey'] ? atob(cred.data['ssh-publickey']) : '', + ); + } catch (error) { + console.error('Failed to decode credential data:', error); + setFieldValue('pullSecret', ''); + setFieldValue('sshPublicKey', ''); + } }}
126-126: 🛠️ Refactor suggestionImprove osImages array validation
The current check
!!osImagesevaluates to true even for empty arrays, which might not be the intended behavior.-{!!osImages && <InfraEnvOpenShiftVersionDropdown osImages={osImages} />} +{osImages && osImages.length > 0 && <InfraEnvOpenShiftVersionDropdown osImages={osImages} />}libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/InfraEnvDetails.tsx (2)
95-105: Fix incorrect JSX structure in NavItemThe JSX fragment structure has unnecessary curly braces around the fragment that could cause rendering issues.
Apply this fix:
<NavItem isActive={location.pathname === hostsPath}> <Link to={hostsPath}> - { - <> - <InfraEnvHostsTabAgentsWarning - infraAgents={infraAgents} - infraBMHs={infraBMHs} - /> - {t('ai:Hosts')} - </> - } + <> + <InfraEnvHostsTabAgentsWarning + infraAgents={infraAgents} + infraBMHs={infraBMHs} + /> + {t('ai:Hosts')} + </> </Link> </NavItem>
176-177: Enhance error handling with specific error messagesThe current error handling shows a generic error state without distinguishing between different error sources (InfraEnv, agents, or BMHs).
Consider implementing more specific error handling:
if (error) { - return <ErrorState title={getErrorMessage(error)} />; + const errorMessage = infraErr + ? t('ai:Failed to load infrastructure environment') + : agentsErr + ? t('ai:Failed to load agents') + : t('ai:Failed to load bare metal hosts'); + + return <ErrorState + title={errorMessage} + content={t('ai:Please try refreshing the page or contact support if the issue persists.')} + />; }libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts (1)
21-23: Inconsistent parameter style between delete methodsThe
onDeleteHostmethod now uses a wrapper object, butonMassDeleteHoststill uses two positional parameters, creating API inconsistency.Consider unifying the parameter style:
- onMassDeleteHost: (agent?: AgentK8sResource, bmh?: BareMetalHostK8sResource) => Promise<unknown>; + onMassDeleteHost: ( + hosts: { agent?: AgentK8sResource; bmh?: BareMetalHostK8sResource }[], + ) => Promise<unknown>;This would make the "mass" semantics explicit and prevent parameter swap bugs.
🧹 Nitpick comments (1)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (1)
68-72: Remove unnecessary FragmentThe Fragment wrapper is redundant when it contains only static content.
- bodyContent={ - <> - {t( - 'ai:This will determine for the infrastructure environment which kind of hosts would be able to be added. If the hosts that you want to add are using DHCP server, select this option, else, select the static IP.', - )} - </> - } + bodyContent={t( + 'ai:This will determine for the infrastructure environment which kind of hosts would be able to be added. If the hosts that you want to add are using DHCP server, select this option, else, select the static IP.', + )}🧰 Tools
🪛 Biome (1.9.4)
[error] 68-72: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment(lint/complexity/noUselessFragments)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
libs/ui-lib/lib/cim/logos/OnPremiseBannerIcon.svgis excluded by!**/*.svgyarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (77)
libs/locales/lib/en/translation.json(21 hunks)libs/ui-lib/lib/cim/components/Agent/BMCForm.tsx(4 hunks)libs/ui-lib/lib/cim/components/Agent/NoAgentsAlert.tsx(1 hunks)libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx(3 hunks)libs/ui-lib/lib/cim/components/Agent/types.ts(0 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostDiscoveryTable.tsx(6 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostsDiscovery.tsx(3 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentWizard.tsx(3 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts(3 hunks)libs/ui-lib/lib/cim/components/Hypershift/DetailsPage/NodePoolsTable.tsx(2 hunks)libs/ui-lib/lib/cim/components/InfraEnv/AddHostDropdown.tsx(4 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvPage.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/useInfraEnvResources.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/EnvironmentDetails.tsx(4 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsx(6 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/AgentsTab.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/DetailsTab.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/InfraEnvDetails.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvFormPage.tsx(0 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.css(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.tsx(2 hunks)libs/ui-lib/lib/cim/components/InfraEnv/index.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/infra-env.css(0 hunks)libs/ui-lib/lib/cim/components/InfraEnv/types.ts(1 hunks)libs/ui-lib/lib/cim/components/YamlEditor/Theme.ts(1 hunks)libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.css(1 hunks)libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.tsx(1 hunks)libs/ui-lib/lib/cim/components/YamlEditor/utils.ts(1 hunks)libs/ui-lib/lib/cim/components/YamlPreview/useYAMLPreview.ts(5 hunks)libs/ui-lib/lib/cim/components/common/InfoAndTroubleshootingNotification.tsx(1 hunks)libs/ui-lib/lib/cim/components/formik/CredentialsField.tsx(1 hunks)libs/ui-lib/lib/cim/components/helpers/agents.ts(3 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostModal.tsx(0 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlForm.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/AddHostModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/CimConfiguration/CimConfigProgressAlert.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/CimConfiguration/utils.ts(1 hunks)libs/ui-lib/lib/cim/components/modals/DeleteHostModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/EditAgentModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/EditBMHModal.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/EditNtpSourcesModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/EditProxyModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/EditPullSecretModal.tsx(4 hunks)libs/ui-lib/lib/cim/components/modals/EditSSHKeyModal.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/MassApproveAgentModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/MassDeleteAgentModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/ProvisioningConfigErrorAlert.tsx(0 hunks)libs/ui-lib/lib/cim/components/modals/ScaleUpModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/UnbindHostModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/types.ts(2 hunks)libs/ui-lib/lib/cim/components/modals/utils.ts(2 hunks)libs/ui-lib/lib/cim/config/constants.ts(1 hunks)libs/ui-lib/lib/cim/hooks/types.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useAgentClusterInstall.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useAgentMachines.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useAgentServiceConfig.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useAgents.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useBMHs.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useConfigMap.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useInfraEnvs.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useNMStates.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useProvisioningConfig.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useSecret.ts(1 hunks)libs/ui-lib/lib/cim/index.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/klusterlet.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/multi-cluster-engine.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/nm-state.ts(1 hunks)libs/ui-lib/lib/cim/types/models.ts(1 hunks)libs/ui-lib/lib/cim/utils.ts(1 hunks)libs/ui-lib/lib/common/components/clusterConfiguration/FormatDiskWarning.tsx(1 hunks)libs/ui-lib/lib/ocm/components/Routes.tsx(1 hunks)libs/ui-lib/package.json(2 hunks)
💤 Files with no reviewable changes (5)
- libs/ui-lib/lib/cim/components/InfraEnv/infra-env.css
- libs/ui-lib/lib/cim/components/Agent/types.ts
- libs/ui-lib/lib/cim/components/modals/ProvisioningConfigErrorAlert.tsx
- libs/ui-lib/lib/cim/components/modals/AddBmcHostModal.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvFormPage.tsx
✅ Files skipped from review due to trivial changes (5)
- libs/ui-lib/lib/cim/hooks/useAgentServiceConfig.ts
- libs/ui-lib/lib/cim/components/Agent/NoAgentsAlert.tsx
- libs/ui-lib/lib/cim/components/modals/MassDeleteAgentModal.tsx
- libs/ui-lib/lib/cim/hooks/types.ts
- libs/ui-lib/lib/cim/components/modals/DeleteHostModal.tsx
🚧 Files skipped from review as they are similar to previous changes (60)
- libs/ui-lib/lib/cim/index.ts
- libs/ui-lib/lib/common/components/clusterConfiguration/FormatDiskWarning.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.css
- libs/ui-lib/lib/cim/components/modals/CimConfiguration/CimConfigProgressAlert.tsx
- libs/ui-lib/lib/cim/hooks/useNMStates.ts
- libs/ui-lib/lib/cim/hooks/useAgentMachines.ts
- libs/ui-lib/lib/cim/types/k8s/multi-cluster-engine.ts
- libs/ui-lib/lib/cim/hooks/useConfigMap.ts
- libs/ui-lib/package.json
- libs/ui-lib/lib/ocm/components/Routes.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/index.ts
- libs/ui-lib/lib/cim/types/k8s/klusterlet.ts
- libs/ui-lib/lib/cim/components/InfraEnv/types.ts
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.tsx
- libs/ui-lib/lib/cim/components/modals/CimConfiguration/utils.ts
- libs/ui-lib/lib/cim/components/modals/EditSSHKeyModal.tsx
- libs/ui-lib/lib/cim/config/constants.ts
- libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.css
- libs/ui-lib/lib/cim/types/k8s/nm-state.ts
- libs/ui-lib/lib/cim/hooks/useBMHs.ts
- libs/ui-lib/lib/cim/hooks/useAgents.ts
- libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts
- libs/ui-lib/lib/cim/components/YamlEditor/Theme.ts
- libs/ui-lib/lib/cim/components/modals/EditPullSecretModal.tsx
- libs/ui-lib/lib/cim/components/modals/EditProxyModal.tsx
- libs/ui-lib/lib/cim/components/YamlPreview/useYAMLPreview.ts
- libs/ui-lib/lib/cim/components/common/InfoAndTroubleshootingNotification.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/useInfraEnvResources.ts
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/DetailsTab.tsx
- libs/ui-lib/lib/cim/components/modals/EditBMHModal.tsx
- libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostsDiscovery.tsx
- libs/ui-lib/lib/cim/components/modals/ScaleUpModal.tsx
- libs/ui-lib/lib/cim/utils.ts
- libs/ui-lib/lib/cim/components/InfraEnv/AddHostDropdown.tsx
- libs/ui-lib/lib/cim/components/Hypershift/DetailsPage/NodePoolsTable.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvPage.tsx
- libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlModal.tsx
- libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/EnvironmentDetails.tsx
- libs/ui-lib/lib/cim/components/Agent/BMCForm.tsx
- libs/ui-lib/lib/cim/hooks/useProvisioningConfig.ts
- libs/ui-lib/lib/cim/components/modals/MassApproveAgentModal.tsx
- libs/ui-lib/lib/cim/components/formik/CredentialsField.tsx
- libs/ui-lib/lib/cim/components/modals/AddHostModal.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/AgentsTab.tsx
- libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlForm.tsx
- libs/ui-lib/lib/cim/hooks/useInfraEnvs.ts
- libs/ui-lib/lib/cim/hooks/useSecret.ts
- libs/ui-lib/lib/cim/hooks/useAgentClusterInstall.ts
- libs/ui-lib/lib/cim/components/modals/utils.ts
- libs/ui-lib/lib/cim/types/models.ts
- libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx
- libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentWizard.tsx
- libs/ui-lib/lib/cim/components/YamlEditor/utils.ts
- libs/ui-lib/lib/cim/components/modals/EditAgentModal.tsx
- libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts
- libs/ui-lib/lib/cim/components/modals/UnbindHostModal.tsx
- libs/ui-lib/lib/cim/components/modals/types.ts
- libs/locales/lib/en/translation.json
- libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts
🧰 Additional context used
🧬 Code Graph Analysis (4)
libs/ui-lib/lib/cim/components/modals/EditNtpSourcesModal.tsx (3)
libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts (1)
InfraEnvK8sResource(8-42)libs/ui-lib/lib/cim/utils.ts (1)
appendPatch(6-14)libs/ui-lib/lib/cim/types/models.ts (1)
InfraEnvModel(24-33)
libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/InfraEnvDetails.tsx (10)
libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts (1)
InfraEnvK8sResource(8-42)libs/ui-lib/lib/cim/types/k8s/agent.ts (1)
AgentK8sResource(32-74)libs/ui-lib/lib/cim/components/ClusterDeployment/helpers.ts (1)
getAgentsHostsNames(196-210)libs/ui-lib/lib/cim/config/constants.ts (1)
DOC_VERSION(4-4)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.tsx (1)
InfraEnvHostsTabAgentsWarning(13-16)libs/ui-lib/lib/cim/hooks/useInfraEnvs.ts (1)
useInfraEnv(21-33)libs/ui-lib/lib/cim/hooks/useAgents.ts (1)
useAgents(6-19)libs/ui-lib/lib/cim/hooks/useBMHs.ts (1)
useBMHs(6-19)libs/ui-lib/lib/cim/components/common/constants.ts (1)
INFRAENV_AGENTINSTALL_LABEL_KEY(10-10)libs/ui-lib/lib/common/utils.ts (1)
getErrorMessage(13-21)
libs/ui-lib/lib/cim/components/helpers/agents.ts (3)
libs/ui-lib/lib/cim/components/common/constants.ts (2)
AGENT_BMH_NAME_LABEL_KEY(12-12)BMH_HOSTNAME_ANNOTATION(20-20)libs/ui-lib/lib/cim/utils.ts (1)
appendPatch(6-14)libs/ui-lib/lib/cim/types/models.ts (2)
AgentModel(67-76)BMHModel(78-87)
libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts (5)
libs/ui-lib/lib/cim/types/k8s/agent.ts (1)
AgentK8sResource(32-74)libs/ui-lib/lib/cim/components/Hypershift/types.ts (1)
AgentMachineK8sResource(186-193)libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts (1)
InfraEnvK8sResource(8-42)libs/ui-lib/lib/cim/types/k8s/nm-state.ts (1)
NMStateK8sResource(3-11)libs/ui-lib/lib/cim/types/k8s/agent-cluster-install.ts (1)
AgentClusterInstallK8sResource(17-80)
🪛 Biome (1.9.4)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx
[error] 68-72: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment
(lint/complexity/noUselessFragments)
⏰ Context from checks skipped due to timeout of 90000ms (6)
- GitHub Check: tests
- GitHub Check: unit-tests
- GitHub Check: translation-files
- GitHub Check: circular-deps
- GitHub Check: lint
- GitHub Check: format
🔇 Additional comments (8)
libs/ui-lib/lib/cim/components/modals/EditNtpSourcesModal.tsx (1)
20-22: LGTM: Well-implemented modal refactoring with proper K8s patchingThe refactoring successfully internalizes the submission logic and removes external dependencies. The K8s patch implementation correctly handles both removal of NTP sources (auto mode) and addition/update with properly filtered entries (filtering out empty strings as previously addressed).
Also applies to: 29-29, 36-36, 47-80
libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostDiscoveryTable.tsx (1)
27-27: LGTM: Excellent refactoring with proper resource loading and state managementThe refactoring successfully:
- Internalizes host deletion logic with proper state management
- Introduces proper loading state handling via
useTableResourceshook- Ensures modals are only rendered with fully loaded resources
- Addresses previous concerns about rendering modals with undefined data
The loading state logic and modal rendering are now correctly implemented.
Also applies to: 38-48, 50-60, 72-80, 154-156, 213-220
libs/ui-lib/lib/cim/components/helpers/agents.ts (1)
4-11: LGTM: Excellent consolidation of hostname update logicThe refactoring successfully:
- Removes external callback dependencies as mentioned in previous concerns
- Implements direct K8s patch operations for both Agent and BMH resources
- Correctly handles JSON Patch path escaping for BMH annotations (
BMH_HOSTNAME_ANNOTATION.replace('/', '~1'))- Provides clean separation between Agent-backed and BMH-backed hostname updates
The implementation is robust and follows K8s patch best practices.
Also applies to: 52-84
libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsx (1)
34-49: LGTM: Well-executed internalization of modal and action managementThe refactoring successfully:
- Internalizes host and agent management via React state hooks
- Removes external callback dependencies and simplifies component interface
- Properly sets up modal rendering with appropriate props and state management
- Uses direct utility functions (
onApproveAgent) instead of external callbacksThe state setter approach for handlers passed to
useAgentsTableis appropriate and maintains the expected function signature.Also applies to: 78-92, 112-117, 255-286, 298-298
libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/InfraEnvDetails.tsx (2)
130-136: Good implementation of selector constructionThe selector construction logic properly handles both
matchLabelsandmatchExpressionsfrom the InfraEnv status, ensuring comprehensive agent filtering.
147-158:Details
✅ Verification successful
Verify BMH selector label key constant
The BMH selector uses
INFRAENV_AGENTINSTALL_LABEL_KEYconstant. Ensure this label key correctly matches the labels applied to BMHs in the system.
🏁 Script executed:
#!/bin/bash # Verify the BMH label key constant usage echo "=== Checking INFRAENV_AGENTINSTALL_LABEL_KEY usage ===" rg -n "INFRAENV_AGENTINSTALL_LABEL_KEY" --type ts echo -e "\n=== Checking for BMH labeling patterns ===" rg -n "infraenvs\.agent-install\.openshift\.io" --type ts -A 2 -B 2Length of output: 4982
INFRAENV_AGENTINSTALL_LABEL_KEY matches BMH labels
Verified that the constant
INFRAENV_AGENTINSTALL_LABEL_KEYis defined as'infraenvs.agent-install.openshift.io'and is used consistently across BMH selectors and labeling patterns. No changes required.libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts (2)
121-121: Streamlined hostActions interface reduces prop drillingThe simplified
hostActionstype that only includesonEditRoleandonSetInstallationDiskIdaligns well with the broader refactoring to internalize action handling within components.This change reduces the API surface and moves toward better encapsulation by having components manage their own delete, approve, and other actions internally.
155-162: Simplified InfraEnvAgentTableProps improves component interfaceThe
InfraEnvAgentTablePropstype now focuses on data dependencies rather than callback props, which aligns with the pattern of internalizing action handling within components.This design reduces coupling and makes the component more self-contained.
4de56e5 to
2c5e978
Compare
|
PR needs rebase. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (8)
libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.tsx (1)
1-163: LGTM! Well-structured YAML editor component.The component demonstrates good practices:
- Proper use of
useStateSafelyfor state management- Clean separation of concerns with
submitYamlshandling validation- Appropriate error handling and user feedback
- Good accessibility with proper ARIA labels
Note: File upload functionality referenced in the UI text is still not implemented, but this appears to be a known limitation for future enhancement.
libs/ui-lib/lib/cim/components/modals/EditPullSecretModal.tsx (2)
151-151: Add error handling for base64 encoding.The
btoa()function can throw exceptions when input contains non-ASCII characters, which could crash the application.Apply this diff to handle encoding errors:
- '.dockerconfigjson': btoa(values.pullSecret), + '.dockerconfigjson': (() => { + try { + return btoa(values.pullSecret); + } catch (error) { + throw new Error('Pull secret contains invalid characters that cannot be encoded'); + } + })(),
164-164: Same base64 encoding issue in patch operation.Apply the same error handling pattern here as well.
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (2)
126-126: Improve osImages array validation.The current check
!!osImageswill pass for empty arrays, which might not be the intended behavior.Apply this diff:
-{!!osImages && <InfraEnvOpenShiftVersionDropdown osImages={osImages} />} +{osImages && osImages.length > 0 && <InfraEnvOpenShiftVersionDropdown osImages={osImages} />}
141-148: Add error handling for base64 decoding.The
atob()function can throw exceptions if the input isn't properly base64-encoded.Apply this diff to handle decoding errors:
onSelect={(cred) => { - setFieldValue( - 'pullSecret', - cred.data?.['pullSecret'] ? atob(cred.data['pullSecret']) : '', - ); - setFieldValue( - 'sshPublicKey', - cred.data?.['ssh-publickey'] ? atob(cred.data['ssh-publickey']) : '', - ); + try { + setFieldValue( + 'pullSecret', + cred.data?.['pullSecret'] ? atob(cred.data['pullSecret']) : '', + ); + setFieldValue( + 'sshPublicKey', + cred.data?.['ssh-publickey'] ? atob(cred.data['ssh-publickey']) : '', + ); + } catch (error) { + console.error('Failed to decode credential data:', error); + setFieldValue('pullSecret', ''); + setFieldValue('sshPublicKey', ''); + } }}libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts (2)
55-65: Consider improving label validation robustnessThe current label validation has some edge cases that could be improved:
- Empty keys/values are allowed (e.g.,
"=value"or"key="would pass)- Labels with multiple
=characters are rejected but could be validConsider this improvement to handle edge cases:
labels: Yup.array() .of(Yup.string()) .test( - 'label-equals-validation', - 'Label selector needs to be in a `key=value` form', + 'label-format-validation', + 'Labels must be in a `key=value` format with non-empty key and value', (values) => (values as string[]).every((value) => { const parts = value.split('='); - return parts.length === 2; + return parts.length >= 2 && parts[0].trim() !== '' && parts.slice(1).join('=').trim() !== ''; }), ),
134-139: Fix potential issue with empty label keysThe current logic could create labels with empty keys when processing malformed label strings.
Apply this fix to prevent empty label keys:
values.labels.forEach((l) => { const label = l.split('='); - if (label.length && infraEnv.metadata?.labels) { - infraEnv.metadata.labels[label[0]] = label.length === 2 ? label[1] : ''; + if (label.length >= 2 && label[0].trim() && infraEnv.metadata?.labels) { + infraEnv.metadata.labels[label[0].trim()] = label.slice(1).join('=').trim(); } });libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts (1)
21-23: Consider unifying callback signatures for consistencyWhile
onDeleteHostnow uses a wrapper object (good!),onMassDeleteHoststill uses positional parameters, creating inconsistent APIs.Consider aligning the signatures:
- onMassDeleteHost: (agent?: AgentK8sResource, bmh?: BareMetalHostK8sResource) => Promise<unknown>; + onMassDeleteHost: ( + hosts: { agent?: AgentK8sResource; bmh?: BareMetalHostK8sResource }[], + ) => Promise<unknown>;This would make the "mass" operation semantics explicit and prevent parameter swap errors.
🧹 Nitpick comments (1)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx (1)
68-72: Remove unnecessary Fragment wrapper.The Fragment contains only one child element and is redundant.
Apply this diff:
- bodyContent={ - <> - {t( - 'ai:This will determine for the infrastructure environment which kind of hosts would be able to be added. If the hosts that you want to add are using DHCP server, select this option, else, select the static IP.', - )} - </> - } + bodyContent={t( + 'ai:This will determine for the infrastructure environment which kind of hosts would be able to be added. If the hosts that you want to add are using DHCP server, select this option, else, select the static IP.', + )}
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
libs/ui-lib/lib/cim/logos/OnPremiseBannerIcon.svgis excluded by!**/*.svgyarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (77)
libs/locales/lib/en/translation.json(21 hunks)libs/ui-lib/lib/cim/components/Agent/BMCForm.tsx(4 hunks)libs/ui-lib/lib/cim/components/Agent/NoAgentsAlert.tsx(1 hunks)libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx(3 hunks)libs/ui-lib/lib/cim/components/Agent/types.ts(0 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostDiscoveryTable.tsx(6 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostsDiscovery.tsx(3 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentWizard.tsx(3 hunks)libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts(3 hunks)libs/ui-lib/lib/cim/components/Hypershift/DetailsPage/NodePoolsTable.tsx(2 hunks)libs/ui-lib/lib/cim/components/InfraEnv/AddHostDropdown.tsx(4 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvPage.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/useInfraEnvResources.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/EnvironmentDetails.tsx(4 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsx(6 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/AgentsTab.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/DetailsTab.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/InfraEnvDetails.tsx(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvFormPage.tsx(0 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.css(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.tsx(2 hunks)libs/ui-lib/lib/cim/components/InfraEnv/index.ts(1 hunks)libs/ui-lib/lib/cim/components/InfraEnv/infra-env.css(0 hunks)libs/ui-lib/lib/cim/components/InfraEnv/types.ts(1 hunks)libs/ui-lib/lib/cim/components/YamlEditor/Theme.ts(1 hunks)libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.css(1 hunks)libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.tsx(1 hunks)libs/ui-lib/lib/cim/components/YamlEditor/utils.ts(1 hunks)libs/ui-lib/lib/cim/components/YamlPreview/useYAMLPreview.ts(5 hunks)libs/ui-lib/lib/cim/components/common/InfoAndTroubleshootingNotification.tsx(1 hunks)libs/ui-lib/lib/cim/components/formik/CredentialsField.tsx(1 hunks)libs/ui-lib/lib/cim/components/helpers/agents.ts(3 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostModal.tsx(0 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlForm.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/AddHostModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/CimConfiguration/CimConfigProgressAlert.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/CimConfiguration/utils.ts(1 hunks)libs/ui-lib/lib/cim/components/modals/DeleteHostModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/EditAgentModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/EditBMHModal.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/EditNtpSourcesModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/EditProxyModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/EditPullSecretModal.tsx(4 hunks)libs/ui-lib/lib/cim/components/modals/EditSSHKeyModal.tsx(3 hunks)libs/ui-lib/lib/cim/components/modals/MassApproveAgentModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/MassDeleteAgentModal.tsx(2 hunks)libs/ui-lib/lib/cim/components/modals/ProvisioningConfigErrorAlert.tsx(0 hunks)libs/ui-lib/lib/cim/components/modals/ScaleUpModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/UnbindHostModal.tsx(1 hunks)libs/ui-lib/lib/cim/components/modals/types.ts(2 hunks)libs/ui-lib/lib/cim/components/modals/utils.ts(2 hunks)libs/ui-lib/lib/cim/config/constants.ts(1 hunks)libs/ui-lib/lib/cim/hooks/types.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useAgentClusterInstall.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useAgentMachines.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useAgentServiceConfig.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useAgents.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useBMHs.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useConfigMap.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useInfraEnvs.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useNMStates.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useProvisioningConfig.ts(1 hunks)libs/ui-lib/lib/cim/hooks/useSecret.ts(1 hunks)libs/ui-lib/lib/cim/index.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/klusterlet.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/multi-cluster-engine.ts(1 hunks)libs/ui-lib/lib/cim/types/k8s/nm-state.ts(1 hunks)libs/ui-lib/lib/cim/types/models.ts(1 hunks)libs/ui-lib/lib/cim/utils.ts(1 hunks)libs/ui-lib/lib/common/components/clusterConfiguration/FormatDiskWarning.tsx(1 hunks)libs/ui-lib/lib/ocm/components/Routes.tsx(1 hunks)libs/ui-lib/package.json(2 hunks)
💤 Files with no reviewable changes (5)
- libs/ui-lib/lib/cim/components/InfraEnv/infra-env.css
- libs/ui-lib/lib/cim/components/Agent/types.ts
- libs/ui-lib/lib/cim/components/modals/AddBmcHostModal.tsx
- libs/ui-lib/lib/cim/components/modals/ProvisioningConfigErrorAlert.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvFormPage.tsx
✅ Files skipped from review due to trivial changes (1)
- libs/ui-lib/lib/cim/hooks/useAgentServiceConfig.ts
🚧 Files skipped from review as they are similar to previous changes (62)
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.css
- libs/ui-lib/lib/cim/components/modals/CimConfiguration/CimConfigProgressAlert.tsx
- libs/ui-lib/lib/cim/config/constants.ts
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.tsx
- libs/ui-lib/lib/common/components/clusterConfiguration/FormatDiskWarning.tsx
- libs/ui-lib/lib/cim/types/k8s/multi-cluster-engine.ts
- libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.css
- libs/ui-lib/lib/cim/hooks/useProvisioningConfig.ts
- libs/ui-lib/lib/cim/types/k8s/klusterlet.ts
- libs/ui-lib/lib/cim/components/Agent/NoAgentsAlert.tsx
- libs/ui-lib/lib/cim/hooks/useConfigMap.ts
- libs/ui-lib/lib/cim/components/modals/MassApproveAgentModal.tsx
- libs/ui-lib/lib/ocm/components/Routes.tsx
- libs/ui-lib/lib/cim/types/k8s/nm-state.ts
- libs/ui-lib/lib/cim/hooks/useBMHs.ts
- libs/ui-lib/lib/cim/hooks/useAgentMachines.ts
- libs/ui-lib/lib/cim/components/modals/CimConfiguration/utils.ts
- libs/ui-lib/package.json
- libs/ui-lib/lib/cim/hooks/useAgents.ts
- libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts
- libs/ui-lib/lib/cim/components/InfraEnv/index.ts
- libs/ui-lib/lib/cim/components/modals/MassDeleteAgentModal.tsx
- libs/ui-lib/lib/cim/hooks/useNMStates.ts
- libs/ui-lib/lib/cim/components/InfraEnv/types.ts
- libs/ui-lib/lib/cim/components/YamlEditor/Theme.ts
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/DetailsTab.tsx
- libs/ui-lib/lib/cim/index.ts
- libs/ui-lib/lib/cim/components/modals/EditProxyModal.tsx
- libs/ui-lib/lib/cim/components/modals/ScaleUpModal.tsx
- libs/ui-lib/lib/cim/hooks/types.ts
- libs/ui-lib/lib/cim/components/Hypershift/DetailsPage/NodePoolsTable.tsx
- libs/ui-lib/lib/cim/hooks/useInfraEnvs.ts
- libs/ui-lib/lib/cim/components/modals/EditSSHKeyModal.tsx
- libs/ui-lib/lib/cim/components/modals/AddHostModal.tsx
- libs/ui-lib/lib/cim/components/modals/EditBMHModal.tsx
- libs/ui-lib/lib/cim/hooks/useSecret.ts
- libs/ui-lib/lib/cim/components/InfraEnv/AddHostDropdown.tsx
- libs/ui-lib/lib/cim/components/YamlPreview/useYAMLPreview.ts
- libs/ui-lib/lib/cim/components/modals/EditNtpSourcesModal.tsx
- libs/ui-lib/lib/cim/components/formik/CredentialsField.tsx
- libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlModal.tsx
- libs/ui-lib/lib/cim/components/modals/DeleteHostModal.tsx
- libs/ui-lib/lib/cim/components/YamlEditor/utils.ts
- libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx
- libs/ui-lib/lib/cim/components/modals/AddBmcHostYamlForm.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/useInfraEnvResources.ts
- libs/ui-lib/lib/cim/hooks/useAgentClusterInstall.ts
- libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvPage.tsx
- libs/ui-lib/lib/cim/components/modals/EditAgentModal.tsx
- libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostsDiscovery.tsx
- libs/ui-lib/lib/cim/components/helpers/agents.ts
- libs/ui-lib/lib/cim/components/common/InfoAndTroubleshootingNotification.tsx
- libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentWizard.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/AgentsTab.tsx
- libs/ui-lib/lib/cim/components/modals/utils.ts
- libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvDetails/InfraEnvDetails.tsx
- libs/ui-lib/lib/cim/components/Agent/BMCForm.tsx
- libs/ui-lib/lib/cim/components/modals/UnbindHostModal.tsx
- libs/ui-lib/lib/cim/components/InfraEnv/EnvironmentDetails.tsx
- libs/ui-lib/lib/cim/types/models.ts
- libs/ui-lib/lib/cim/components/modals/types.ts
- libs/locales/lib/en/translation.json
🧰 Additional context used
🧠 Learnings (3)
libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.tsx (3)
Learnt from: rawagner
PR: openshift-assisted/assisted-installer-ui#2826
File: libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.tsx:50-61
Timestamp: 2025-05-22T07:31:16.062Z
Learning: The YamlEditor component in libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.tsx already handles YAML validation through the submitYamls function in utils.ts, which validates YAML syntax and throws user-friendly error messages if parsing fails.
Learnt from: rawagner
PR: openshift-assisted/assisted-installer-ui#2826
File: libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.tsx:50-61
Timestamp: 2025-05-22T07:31:16.062Z
Learning: The `submitYamls` function in the YamlEditor component (libs/ui-lib/lib/cim/components/YamlEditor/utils.ts) already handles YAML validation with yaml.loadAll() and provides user-friendly error messages. Additional validation in the submit function would be redundant.
Learnt from: rawagner
PR: openshift-assisted/assisted-installer-ui#2899
File: libs/ui-lib/lib/ocm/components/clusterWizard/OperatorsSelect.tsx:32-55
Timestamp: 2025-04-14T09:11:08.834Z
Learning: In React components with asynchronous operations, `useStateSafely` custom hook should be used instead of `React.useState` to prevent state updates on unmounted components and avoid memory leaks.
libs/ui-lib/lib/cim/components/modals/EditPullSecretModal.tsx (2)
Learnt from: rawagner
PR: openshift-assisted/assisted-installer-ui#2826
File: libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.tsx:50-61
Timestamp: 2025-05-22T07:31:16.062Z
Learning: The `submitYamls` function in the YamlEditor component (libs/ui-lib/lib/cim/components/YamlEditor/utils.ts) already handles YAML validation with yaml.loadAll() and provides user-friendly error messages. Additional validation in the submit function would be redundant.
Learnt from: rawagner
PR: openshift-assisted/assisted-installer-ui#2826
File: libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.tsx:50-61
Timestamp: 2025-05-22T07:31:16.062Z
Learning: The YamlEditor component in libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.tsx already handles YAML validation through the submitYamls function in utils.ts, which validates YAML syntax and throws user-friendly error messages if parsing fails.
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts (2)
Learnt from: rawagner
PR: openshift-assisted/assisted-installer-ui#2826
File: libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.tsx:50-61
Timestamp: 2025-05-22T07:31:16.062Z
Learning: The YamlEditor component in libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.tsx already handles YAML validation through the submitYamls function in utils.ts, which validates YAML syntax and throws user-friendly error messages if parsing fails.
Learnt from: rawagner
PR: openshift-assisted/assisted-installer-ui#2826
File: libs/ui-lib/lib/cim/components/YamlEditor/YamlEditor.tsx:50-61
Timestamp: 2025-05-22T07:31:16.062Z
Learning: The `submitYamls` function in the YamlEditor component (libs/ui-lib/lib/cim/components/YamlEditor/utils.ts) already handles YAML validation with yaml.loadAll() and provides user-friendly error messages. Additional validation in the submit function would be redundant.
🧬 Code Graph Analysis (3)
libs/ui-lib/lib/cim/utils.ts (2)
libs/ui-lib/lib/cim/types/k8s/agent.ts (1)
AgentK8sResource(32-74)libs/ui-lib/lib/cim/types/models.ts (1)
AgentModel(67-76)
libs/ui-lib/lib/cim/components/modals/EditPullSecretModal.tsx (3)
libs/ui-lib/lib/common/utils.ts (1)
getErrorMessage(13-21)libs/ui-lib/lib/cim/components/modals/types.ts (1)
EditPullSecretFormikValues(29-32)libs/ui-lib/lib/cim/types/models.ts (1)
SecretModel(3-11)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts (4)
libs/ui-lib-tests/cypress/fixtures/infra-envs/openshift-versions.ts (2)
x86(8-8)s390x(10-10)libs/ui-lib/lib/common/components/ui/formik/validationSchemas.ts (7)
richNameValidationSchema(456-489)locationValidationSchema(654-679)pullSecretValidationSchema(143-162)sshPublicKeyValidationSchema(105-115)httpProxyValidationSchema(534-573)noProxyValidationSchema(587-602)ntpSourceValidationSchema(604-627)libs/ui-lib/lib/cim/types/models.ts (3)
SecretModel(3-11)InfraEnvModel(24-33)RoleModel(13-22)libs/ui-lib/lib/cim/types/k8s/infra-env-k8s-resource.ts (1)
InfraEnvK8sResource(8-42)
🪛 Biome (1.9.4)
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/CreateInfraEnvForm.tsx
[error] 68-72: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment
(lint/complexity/noUselessFragments)
🔇 Additional comments (6)
libs/ui-lib/lib/cim/hooks/useK8sWatchResource.ts (1)
1-27: LGTM! Solid typed wrapper implementation.The hook provides excellent type safety while maintaining the original behavior of the console's useK8sWatchResource. The error handling logic correctly prioritizes error state over loading state.
libs/ui-lib/lib/cim/utils.ts (1)
1-20: LGTM! Clean utility functions after thorough refinement.The implementation correctly handles:
- Proper distinction between
undefinedand falsy values inappendPatch- Safe patching operations that work regardless of existing field state
- Clean separation of concerns with reusable patch logic
libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentHostDiscoveryTable.tsx (1)
51-61: LGTM: Clean refactoring that internalizes state managementThe refactoring successfully removes external callback dependencies by:
- Adding internal
deleteHoststate management- Using
useTableResourceshook for resource watching with proper loading/error handling- Conditionally rendering
DeleteHostModalbased on internal stateThis aligns well with the broader PR objective of decoupling components and centralizing resource management.
Also applies to: 73-82, 218-225
libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsx (1)
78-92: LGTM: Consistent state internalization patternThe component successfully follows the same refactoring pattern as other components in this PR:
- Internal state hooks for
editBMH,editAgent,deleteHost, andunbindHost- Updated
useAgentsTableto use state setters instead of external callbacks- Conditional modal rendering based on internal state
This maintains consistency across the codebase while simplifying the component interface.
Also applies to: 112-117, 255-286
libs/ui-lib/lib/cim/components/InfraEnv/CreateInfraEnv/utils.ts (1)
88-104: LGTM: Well-structured resource generation functionsThe resource generation functions are well-implemented:
getPullSecretSecret: Correctly creates Kubernetes Secret with proper naminggetInfraEnv: Comprehensively builds InfraEnv resource with all optional fields handled appropriatelygetRole: Creates necessary RBAC Role for agent managementThe conditional field inclusion and resource structure align with Kubernetes best practices.
Also applies to: 106-173, 175-191
libs/ui-lib/lib/cim/components/ClusterDeployment/types.ts (1)
121-121: LGTM: Simplified type definitions align with refactoring goalsThe type simplification successfully reflects the internalization of callback management:
hostActionsreduced to core actions onlyInfraEnvAgentTablePropsno longer requires external callbacks- Component interfaces are cleaner and more focused
This aligns well with the PR's objective to decouple components and reduce external dependencies.
Also applies to: 155-162, 166-166
|
@rawagner: The following test failed, say
Full PR test history. Your PR dashboard. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here. |
Even though it looks like a lot of new code, this is actually mostly a refactoring of existing InfraEnv form. I've moved things around to create a nicer structure.
The new code is
CredentialsField.tsx, as that was previously done in ACM console, which we cannot do anymore.Another new code is
YamlEditor.tsx. It will need some more tweaking (ie makings sure it sizes properly). But that can be handled in a followup.See also stolostron/console#4307
Summary by CodeRabbit
New Features
Improvements
Bug Fixes
Style
Documentation
Chores