Skip to content

Fix React 18 types#3361

Merged
openshift-merge-bot[bot] merged 1 commit intoopenshift-assisted:masterfrom
rawagner:types_18
Jan 16, 2026
Merged

Fix React 18 types#3361
openshift-merge-bot[bot] merged 1 commit intoopenshift-assisted:masterfrom
rawagner:types_18

Conversation

@rawagner
Copy link
Member

@rawagner rawagner commented Jan 15, 2026

Replace/remove deprecated deps

Summary by CodeRabbit

  • New Features

    • Redesigned label editor with inline editable labels for easier key/value management.
  • Improvements

    • Improved responsive sizing for tables and YAML preview using a resize-observer approach.
    • Broadened component prop typings and stricter translation typing.
    • Updated locale text (simplified label guidance; added "New label").
  • Chores

    • Removed legacy tag-input and measurement utilities; cleaned package configuration and dependency housekeeping.

✏️ Tip: You can customize this high-level summary in your review settings.

@openshift-ci openshift-ci bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jan 15, 2026
@coderabbitai
Copy link

coderabbitai bot commented Jan 15, 2026

📝 Walkthrough

Walkthrough

Removed react-tagsinput and react-measure, added @react-hook/resize-observer, migrated Measure-based sizing to ResizeObserver in multiple UI components, refactored LabelField to use PatternFly LabelGroup, and applied widespread React PropsWithChildren and small typing/i18n fixes.

Changes

Cohort / File(s) Summary
Dependency & manifests
apps/assisted-disconnected-ui/package.json, apps/assisted-ui/package.json, libs/ui-lib/package.json, package.json
Removed react-tagsinput, removed react-measure and its types, added @react-hook/resize-observer, updated @types/react-dom, and removed resolutions forcing @types/react.
ResizeObserver migration
libs/ui-lib/lib/cim/components/.../ClusterDeploymentHostsDiscovery.tsx, libs/ui-lib/lib/cim/components/.../ClusterDeploymentHostsSelectionAdvanced.tsx, libs/ui-lib/lib/ClusterDeployment/components/ClusterDeploymentHostsSelectionAdvanced.tsx, libs/ui-lib/lib/cim/components/YamlPreview/YamlPreview.tsx
Replaced react-measure render-props with useResizeObserver + ref/state-based width/height measurement (tableRef/editorRef → tableWidth/editorHeight).
Label UI refactor
libs/ui-lib/lib/common/components/ui/formik/LabelField.tsx, libs/locales/lib/en/translation.json
Replaced TagsInput with PatternFly LabelGroup and inline editable control; new add/edit/delete handlers; updated locale strings and added ai:New label.
PropsWithChildren typing updates
multiple files (examples: apps/assisted-ui/src/components/App.tsx, libs/ui-lib/lib/.../InfraEnv/InfraEnvFormPage.tsx, libs/ui-lib/lib/common/components/..., libs/ui-lib/lib/ocm/components/...)
Many React.FC annotations changed to React.FC<React.PropsWithChildren<...>> to explicitly include children in props; no runtime behavior changes.
i18n and small typing fixes
libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx, libs/ui-lib/lib/cim/components/modals/*.tsx, libs/ui-lib/lib/common/components/hosts/tableUtils.tsx, libs/ui-lib/lib/common/components/storage/DisksTable.tsx
Added explicit t<string>(...) generics for translation calls and small type annotations/casts (e.g., (val: unknown), as HumanizedSortable).
Misc small changes
libs/ui-lib/lib/cim/components/ClusterDeployment/customManifests/ConfigMapForm.tsx, libs/ui-lib/lib/cim/components/modals/EditSSHKeyModal.tsx, libs/ui-lib/lib/common/components/ui/CustomToolbarFilter.tsx, libs/ui-lib/lib/ocm/store/slices/clusters/selectors.tsx, etc.
Minor logic/typing tweaks: boolean coercion (!!isError), tightened Formik render-prop typing, handler changed to () => void submitForm(), optional chaining for portal target, small selector typings.

Sequence Diagram(s)

(omitted)

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

lgtm

Suggested reviewers

  • ammont82
  • ElayAharoni

Poem

🐰
I nudged some types and watched widths bob—
swapped Measure for ResizeObserver’s job.
Tags hopped off, Labels took their place,
smaller deps, a tidier space.
A rabbit's cheer for cleaner code and pace.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Fix React 18 types' accurately captures the primary change in this PR, which involves widespread updates to React component type signatures and removal of React 18-incompatible dependencies.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@openshift-ci openshift-ci bot added the size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. label Jan 15, 2026
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
libs/ui-lib/lib/common/components/hosts/AITable.tsx (1)

228-236: Type signature mismatch with PatternFly's OnCollapse.

The _event parameter should be typed as React.MouseEvent, not unknown. PatternFly's OnCollapse type from @patternfly/react-table v6.4.0 expects: (event: React.MouseEvent, rowIndex: number, isOpen: boolean, rowData: IRowData, extraData: IExtraData) => void.

Using unknown actually reduces type safety compared to the proper React.MouseEvent type. While the implementation works (JavaScript allows unused parameters), the type signature should match the contract expected by PatternFly's Table component to maintain proper type checking.

libs/ui-lib/lib/common/components/ui/formik/InputField.tsx (1)

62-68: Typo in data-testid attribute.

There's a leading space in the test ID string which could cause test selectors to fail.

Proposed fix
             <HelperTextItem
               variant="indeterminate"
-              data-testid=" input-field-description-${fieldId}-helper-text"
+              data-testid={`input-field-description-${fieldId}-helper-text`}
             >
libs/ui-lib/lib/common/components/ui/StaticTextField.tsx (1)

66-77: Pass children to StaticField in FormikStaticField.

FormikStaticField accepts children via React.PropsWithChildren but doesn't pass them to StaticField. When destructuring, children must be explicitly extracted and forwarded. The component is currently being used with children (e.g., <VipStaticValue />) that are silently discarded. Update the component to match the pattern used in StaticTextField (line 83-93):

const FormikStaticField: React.FC<React.PropsWithChildren<FormikStaticFieldProps>> = ({
  value,
  children,
  ...props
}) => {
  // ...
  return <StaticField {...props}>{children}</StaticField>;
};
libs/ui-lib/lib/cim/components/ClusterDeployment/hostSelection/ClusterDeploymentHostsSelectionAdvanced.tsx (1)

1-107: Remove unused duplicate component in components directory.

The file at libs/ui-lib/lib/cim/components/ClusterDeployment/components/ClusterDeploymentHostsSelectionAdvanced.tsx is an unused duplicate. The active version is at libs/ui-lib/lib/cim/components/ClusterDeployment/hostSelection/ClusterDeploymentHostsSelectionAdvanced.tsx, which is the only one imported by ScaleUpForm.tsx and ClusterDeploymentHostsSelection.tsx. The components version is not exported from its directory's index file and has no usages in the codebase.

🤖 Fix all issues with AI agents
In `@libs/ui-lib/lib/common/components/ui/formik/LabelField.tsx`:
- Around line 90-99: LabelField currently renders HelperTextItem with an error
icon but never displays the actual errorMessage text; update the JSX where
HelperTextItem is used (inside FormHelperText) to pass errorMessage as its
children (e.g., <HelperTextItem ...>{errorMessage}</HelperTextItem>) so the
error text is visible to users; ensure you keep existing props like icon,
variant, id and data-testid when adding the children.
- Around line 57-63: The onEdit handler incorrectly checks label.length (always
>=1) and uses undefined for missing values causing inconsistency with onAdd;
update onEdit in LabelField.tsx so it extracts the split parts safely (e.g.,
check label.length > 1 or presence of label[1]) and assign value: '' (empty
string) when no right-hand side exists to match onAdd, then call
setLabels(newLabels, true).
- Line 29: The field value `labels` can be undefined and will cause
`labels.map()` to throw; update the code in LabelField to guard against that by
providing a default empty array for the field value or using a nullish fallback
when mapping. For example, adjust the useField destructure so the value defaults
to [] (e.g., [{ value: labels = [] }, ...]) or change the mapping site to use
(labels ?? []) before calling .map; keep existing names (`labels`, `useField`,
`setLabels`) so other logic is unchanged.
- Around line 17-20: Rename the local type "Label" to "LabelItem" to avoid
shadowing the imported PatternFly Label component: change the type declaration
"type Label = { key: string; value?: string }" to "type LabelItem = { key:
string; value?: string }" and update every usage of "Label" in this module
(e.g., the props, local variables, function signatures and array types that
currently reference Label) to use "LabelItem" instead so the PatternFly Label
import remains unshadowed.
🧹 Nitpick comments (5)
apps/assisted-ui/src/components/App.tsx (1)

12-16: Pragmatic workaround for React 18 type compatibility.

The double cast through any is a common pattern when library types predate React 18's change where React.FC no longer implicitly includes children. This is a type-only fix with no runtime impact.

Consider enhancing the comment to be more specific about the root cause for future maintainers:

📝 Suggested comment improvement
-// Add PropsWithChildren to bypass the React 18 type mismatch
+// react-router-dom v5 types predate React 18 where React.FC no longer includes children.
+// Wrap with PropsWithChildren to restore children prop typing.
 // eslint-disable-next-line
 const BrowserRouter18 = BrowserRouter as any as React.FC<
   React.PropsWithChildren<BrowserRouterProps>
 >;
libs/ui-lib/lib/common/components/ui/CustomToolbarFilter.tsx (1)

118-123: Optional chaining improvement looks good; consider consistent type handling for portals.

The refactor to use optional chaining is cleaner. However, the as React.ReactElement cast is applied here but not to the other createPortal calls at lines 133-134 and 135-137. If this cast is required to satisfy React 18's stricter typing for ReactPortal, consider applying it uniformly across all portal renderings in this component for consistency.

♻️ Optional: Apply consistent typing to other portals
           {showToolbarItem && <ToolbarItem {...props}>{children}</ToolbarItem>}
-            {labelContainerRef.current &&
-              ReactDOM.createPortal(labelGroup, labelContainerRef.current as Element)}
-            {expandableLabelContainerRef &&
-              expandableLabelContainerRef.current &&
-              ReactDOM.createPortal(labelGroup, expandableLabelContainerRef.current)}
+            {labelContainerRef.current
+              ? (ReactDOM.createPortal(labelGroup, labelContainerRef.current as Element) as React.ReactElement)
+              : null}
+            {expandableLabelContainerRef?.current
+              ? (ReactDOM.createPortal(labelGroup, expandableLabelContainerRef.current) as React.ReactElement)
+              : null}
libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx (1)

103-114: Consider applying t<string>() to remaining translation calls for consistency.

Within discoveryTypeColumn, the cell content uses t('ai:Unknown'), t('ai:BMC'), and t('ai:Discovery ISO') without the explicit string generic. While these may not cause type errors currently, applying the pattern consistently would improve maintainability.

♻️ Suggested consistency improvement
     cell: (host) => {
       const agent = agents.find((a) => a.metadata?.uid === host.id);
-      let discoveryType = t('ai:Unknown');
+      let discoveryType = t<string>('ai:Unknown');
       if (agent) {
         // eslint-disable-next-line no-prototype-builtins
         discoveryType = agent?.metadata?.labels?.hasOwnProperty(AGENT_BMH_NAME_LABEL_KEY)
-          ? t('ai:BMC')
-          : t('ai:Discovery ISO');
+          ? t<string>('ai:BMC')
+          : t<string>('ai:Discovery ISO');
       } else {
         const bmh = bareMetalHosts.find((bmh) => bmh.metadata?.uid === host.id);
         if (bmh) {
-          discoveryType = t('ai:BMC');
+          discoveryType = t<string>('ai:BMC');
         }
       }
libs/ui-lib/lib/common/components/hosts/tableUtils.tsx (1)

325-383: Consider adding i18n for hardcoded column headers.

The ipv4Column, ipv6Column, and macAddressColumn headers use hardcoded English strings ('IPv4 address', 'IPv6 address', 'MAC address') instead of translation keys. For consistency with other columns in this file, these should use the t<string>() pattern.

♻️ Suggested i18n improvement
-export const ipv4Column = (cluster: Cluster): TableRow<Host> => ({
+export const ipv4Column = (cluster: Cluster, t: TFunction): TableRow<Host> => ({
   header: {
-    title: 'IPv4 address',
+    title: t<string>('ai:IPv4 address'),
     sort: true,
   },
   // ... cell implementation
 });

-export const ipv6Column = (cluster: Cluster): TableRow<Host> => ({
+export const ipv6Column = (cluster: Cluster, t: TFunction): TableRow<Host> => ({
   header: {
-    title: 'IPv6 address',
+    title: t<string>('ai:IPv6 address'),
     sort: true,
   },
   // ... cell implementation
 });

-export const macAddressColumn = (cluster: Cluster): TableRow<Host> => ({
+export const macAddressColumn = (cluster: Cluster, t: TFunction): TableRow<Host> => ({
   header: {
-    title: 'MAC address',
+    title: t<string>('ai:MAC address'),
     sort: true,
   },
   // ... cell implementation
 });
libs/ui-lib/lib/cim/components/YamlPreview/YamlPreview.tsx (1)

56-60: Consider initial height measurement timing.

The useResizeObserver callback fires when the container resizes, but there's no initial measurement. The editor won't render until a resize event occurs. This may cause a brief delay before the editor appears.

Optional: Add initial height measurement
   const editorRef = React.useRef<HTMLDivElement>(null);
   const [editorHeight, setEditorHeight] = React.useState<number>();
+
+  React.useLayoutEffect(() => {
+    if (editorRef.current) {
+      setEditorHeight(editorRef.current.getBoundingClientRect().height);
+    }
+  }, []);
+
   useResizeObserver(editorRef, (entry) => {
     setEditorHeight(entry.contentRect.height);
   });
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8bb681c and 1d91189.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (42)
  • apps/assisted-disconnected-ui/package.json
  • apps/assisted-ui/package.json
  • apps/assisted-ui/src/components/App.tsx
  • libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx
  • libs/ui-lib/lib/cim/components/ClusterDeployment/components/ClusterDeploymentHostsSelectionAdvanced.tsx
  • libs/ui-lib/lib/cim/components/ClusterDeployment/customManifests/ConfigMapForm.tsx
  • libs/ui-lib/lib/cim/components/ClusterDeployment/hostDiscovery/ClusterDeploymentHostsDiscovery.tsx
  • libs/ui-lib/lib/cim/components/ClusterDeployment/hostSelection/ClusterDeploymentHostsSelectionAdvanced.tsx
  • libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvFormPage.tsx
  • libs/ui-lib/lib/cim/components/YamlPreview/YamlPreview.tsx
  • libs/ui-lib/lib/cim/components/modals/EditSSHKeyModal.tsx
  • libs/ui-lib/lib/cim/components/modals/MassApproveAgentModal.tsx
  • libs/ui-lib/lib/cim/components/modals/MassDeleteAgentModal.tsx
  • libs/ui-lib/lib/common/components/AddHosts/AddHostsContext.tsx
  • libs/ui-lib/lib/common/components/AlertsContextProvider.tsx
  • libs/ui-lib/lib/common/components/clusterWizard/ClusterWizardStepHeader.tsx
  • libs/ui-lib/lib/common/components/hosts/AITable.tsx
  • libs/ui-lib/lib/common/components/hosts/HostPropertyValidationPopover.tsx
  • libs/ui-lib/lib/common/components/hosts/HostStatus.tsx
  • libs/ui-lib/lib/common/components/hosts/HostsTableDetailContext.tsx
  • libs/ui-lib/lib/common/components/hosts/TableToolbar.tsx
  • libs/ui-lib/lib/common/components/hosts/tableUtils.tsx
  • libs/ui-lib/lib/common/components/storage/DisksTable.tsx
  • libs/ui-lib/lib/common/components/ui/CustomToolbarFilter.tsx
  • libs/ui-lib/lib/common/components/ui/GridGap.tsx
  • libs/ui-lib/lib/common/components/ui/StaticTextField.tsx
  • libs/ui-lib/lib/common/components/ui/Toolbar/ToolbarSecondaryGroup.tsx
  • libs/ui-lib/lib/common/components/ui/formik/CertificatesUploadField.tsx
  • libs/ui-lib/lib/common/components/ui/formik/InputField.tsx
  • libs/ui-lib/lib/common/components/ui/formik/LabelField.tsx
  • libs/ui-lib/lib/common/components/ui/formik/NumberInputField.tsx
  • libs/ui-lib/lib/common/components/ui/formik/SelectFieldWithSearch.tsx
  • libs/ui-lib/lib/common/components/ui/formik/TextAreaField.tsx
  • libs/ui-lib/lib/common/components/ui/formik/UploadField.tsx
  • libs/ui-lib/lib/common/features/featureGate.tsx
  • libs/ui-lib/lib/ocm/components/SentryErrorMonitorContextProvider.tsx
  • libs/ui-lib/lib/ocm/components/clusters/ClusterToolbar.tsx
  • libs/ui-lib/lib/ocm/components/hosts/ModalDialogsContext.tsx
  • libs/ui-lib/lib/ocm/components/ui/AssistedUILibVersion.tsx
  • libs/ui-lib/lib/ocm/store/slices/clusters/selectors.tsx
  • libs/ui-lib/package.json
  • package.json
💤 Files with no reviewable changes (3)
  • apps/assisted-ui/package.json
  • package.json
  • apps/assisted-disconnected-ui/package.json
🧰 Additional context used
🧠 Learnings (7)
📚 Learning: 2025-12-17T09:08:18.279Z
Learnt from: jgyselov
Repo: openshift-assisted/assisted-installer-ui PR: 3319
File: libs/ui-lib/lib/cim/components/helpers/toAssisted.ts:199-201
Timestamp: 2025-12-17T09:08:18.279Z
Learning: In libs/ui-lib/lib/cim/components/helpers/toAssisted.ts, the platformType field on agentClusterInstall.spec is guaranteed to always contain a valid PlatformType value (when lowercased), making the type assertion safe without additional runtime validation.

Applied to files:

  • libs/ui-lib/lib/ocm/components/ui/AssistedUILibVersion.tsx
  • libs/ui-lib/lib/ocm/store/slices/clusters/selectors.tsx
  • libs/ui-lib/lib/cim/components/modals/MassDeleteAgentModal.tsx
  • libs/ui-lib/lib/cim/components/ClusterDeployment/customManifests/ConfigMapForm.tsx
  • libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx
📚 Learning: 2025-10-21T04:40:36.292Z
Learnt from: linoyaslan
Repo: openshift-assisted/assisted-installer-ui PR: 3190
File: libs/ui-lib/lib/ocm/components/clusterConfiguration/networkConfiguration/AdvancedNetworkFields.tsx:55-63
Timestamp: 2025-10-21T04:40:36.292Z
Learning: In libs/ui-lib/lib/ocm/components/clusterConfiguration/networkConfiguration/AdvancedNetworkFields.tsx, the network reordering logic in the useEffect (swapping clusterNetworks and serviceNetworks based on the primary machine network's IP family) is for UI consistency only. Validation of empty or invalid CIDRs is handled separately by validation schemas, not by the reordering logic.

Applied to files:

  • libs/ui-lib/lib/cim/components/ClusterDeployment/hostDiscovery/ClusterDeploymentHostsDiscovery.tsx
  • libs/ui-lib/lib/cim/components/ClusterDeployment/hostSelection/ClusterDeploymentHostsSelectionAdvanced.tsx
  • libs/ui-lib/lib/ocm/store/slices/clusters/selectors.tsx
  • libs/ui-lib/lib/cim/components/ClusterDeployment/components/ClusterDeploymentHostsSelectionAdvanced.tsx
📚 Learning: 2025-12-17T09:16:41.439Z
Learnt from: jgyselov
Repo: openshift-assisted/assisted-installer-ui PR: 3319
File: libs/ui-lib/lib/common/components/hosts/utils.ts:208-210
Timestamp: 2025-12-17T09:16:41.439Z
Learning: In libs/ui-lib/lib/common/components/hosts/utils.ts, the nodeLabels field on Host objects is guaranteed to be valid JSON because it's always constructed using JSON.stringify in libs/ui-lib/lib/cim/components/helpers/toAssisted.ts, making direct JSON.parse safe without additional error handling.

Applied to files:

  • libs/ui-lib/lib/common/components/hosts/tableUtils.tsx
  • libs/ui-lib/lib/common/components/hosts/HostPropertyValidationPopover.tsx
📚 Learning: 2025-10-20T08:57:04.935Z
Learnt from: linoyaslan
Repo: openshift-assisted/assisted-installer-ui PR: 3190
File: libs/ui-lib/lib/ocm/components/clusterDetail/ClusterProperties.tsx:43-45
Timestamp: 2025-10-20T08:57:04.935Z
Learning: In the file `libs/ui-lib/lib/ocm/components/clusterDetail/ClusterProperties.tsx`, the `getStackTypeLabel` function returns 'Dual-stack' or 'IPv4' because the system currently only supports IPv4 single-stack clusters. IPv6-only single-stack clusters are not supported.

Applied to files:

  • libs/ui-lib/lib/common/components/hosts/tableUtils.tsx
📚 Learning: 2026-01-07T15:19:02.310Z
Learnt from: rawagner
Repo: openshift-assisted/assisted-installer-ui PR: 3350
File: apps/assisted-ui/package.json:26-27
Timestamp: 2026-01-07T15:19:02.310Z
Learning: The react-router-dom-v5-compat package is designed to work alongside react-router-dom v4 or v5, not replace it. It declares peer dependencies on react-router-dom "4 || 5" and allows incremental migration by providing React Router v6 APIs while the application continues to run on v5. Having both react-router-dom5.x and react-router-dom-v5-compat installed together is the correct and intended configuration.

Applied to files:

  • apps/assisted-ui/src/components/App.tsx
  • libs/ui-lib/package.json
📚 Learning: 2025-05-22T09:12:50.632Z
Learnt from: rawagner
Repo: openshift-assisted/assisted-installer-ui PR: 2942
File: libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentManifestsStep.tsx:93-97
Timestamp: 2025-05-22T09:12:50.632Z
Learning: When working with Formik's FieldArray, use the provided array helpers (like `remove()`, `push()`, etc.) instead of directly mutating the values array to ensure proper state tracking and re-rendering.

Applied to files:

  • libs/ui-lib/lib/common/components/ui/StaticTextField.tsx
  • libs/ui-lib/lib/common/components/ui/formik/LabelField.tsx
📚 Learning: 2025-05-22T07:31:16.062Z
Learnt from: rawagner
Repo: openshift-assisted/assisted-installer-ui PR: 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.

Applied to files:

  • libs/ui-lib/lib/cim/components/YamlPreview/YamlPreview.tsx
🧬 Code graph analysis (10)
libs/ui-lib/lib/common/components/ui/formik/NumberInputField.tsx (1)
libs/ui-lib/lib/common/components/ui/formik/types.ts (1)
  • NumberInputFieldProps (76-86)
libs/ui-lib/lib/cim/components/modals/MassApproveAgentModal.tsx (3)
libs/ui-lib/lib/common/components/hosts/tableUtils.tsx (1)
  • hostnameColumn (59-92)
libs/ui-lib/lib/cim/types/k8s/agent.ts (1)
  • AgentK8sResource (32-74)
libs/ui-lib/lib/common/components/hosts/AITable.tsx (1)
  • TableRow (24-28)
libs/ui-lib/lib/common/components/hosts/HostStatus.tsx (1)
libs/ui-lib/lib/common/components/hosts/types.ts (2)
  • HostStatus (81-83)
  • HostStatusProps (85-95)
libs/ui-lib/lib/common/components/ui/formik/TextAreaField.tsx (1)
libs/ui-lib/lib/common/components/ui/formik/types.ts (1)
  • TextAreaFieldProps (88-95)
apps/assisted-ui/src/components/App.tsx (2)
apps/assisted-ui/src/components/Header.tsx (1)
  • Header (6-24)
libs/ui-lib/lib/ocm/components/Routes.tsx (1)
  • UILibRoutes (25-61)
libs/ui-lib/lib/common/components/ui/formik/InputField.tsx (1)
libs/ui-lib/lib/common/components/ui/formik/types.ts (1)
  • InputFieldProps (66-74)
libs/ui-lib/lib/common/components/ui/formik/UploadField.tsx (1)
libs/ui-lib/lib/common/components/ui/formik/types.ts (1)
  • UploadFieldProps (97-106)
libs/ui-lib/lib/ocm/store/slices/clusters/selectors.tsx (1)
libs/ui-lib/lib/common/components/ui/table/utils.ts (1)
  • HumanizedSortable (7-11)
libs/ui-lib/lib/common/components/ui/formik/CertificatesUploadField.tsx (1)
libs/ui-lib/lib/common/components/ui/formik/types.ts (1)
  • UploadFieldProps (97-106)
libs/ui-lib/lib/cim/components/modals/EditSSHKeyModal.tsx (1)
libs/ui-lib/lib/cim/components/modals/types.ts (1)
  • EditSSHKeyFormikValues (52-54)
🪛 Biome (2.1.2)
libs/ui-lib/lib/common/components/ui/formik/LabelField.tsx

[error] 17-17: Shouldn't redeclare 'Label'. Consider to delete it or rename it.

'Label' is defined here:

(lint/suspicious/noRedeclare)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: unit-tests
  • GitHub Check: lint
  • GitHub Check: circular-deps
  • GitHub Check: tests
  • GitHub Check: translation-files
  • GitHub Check: format
🔇 Additional comments (69)
libs/ui-lib/lib/common/features/featureGate.tsx (1)

37-41: LGTM!

Correctly wraps props with React.PropsWithChildren to explicitly declare children support, which is required for React 18 types since React.FC no longer implicitly includes children in its props.

libs/ui-lib/lib/cim/components/modals/EditSSHKeyModal.tsx (2)

72-72: Correct type alignment for Formik render props.

The render-prop generic now correctly uses EditSSHKeyFormikValues (the actual form values type) instead of EditSSHKeyModalProps (the component props). This aligns with the Formik<EditSSHKeyFormikValues> generic on line 56.


90-90: Proper handling of async event handler.

Using () => void submitForm() is the correct pattern for React 18 types. The void operator explicitly discards the promise returned by submitForm, satisfying TypeScript's stricter return type checking for onClick handlers (which expect void, not Promise<void>).

libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvFormPage.tsx (2)

133-140: LGTM!

Correct use of React.PropsWithChildren to explicitly type children for React 18+, where React.FC no longer implicitly includes children. The component properly destructures and renders children.


289-297: LGTM!

Appropriate use of React.PropsWithChildren wrapper. The component correctly destructures children and passes them to the nested InfraEnvForm component.

libs/ui-lib/lib/common/components/hosts/HostStatus.tsx (2)

186-188: LGTM!

Correct React 18 typing fix. The component uses props.children (line 204), so wrapping with React.PropsWithChildren properly declares the implicit children prop that was removed from React.FC in React 18.


231-243: LGTM!

Proper React 18 typing update. The destructured children prop (line 238) and its usage (lines 282, 287) require explicit typing via React.PropsWithChildren. This aligns with the broader codebase standardization mentioned in the PR summary.

libs/ui-lib/lib/cim/components/ClusterDeployment/customManifests/ConfigMapForm.tsx (1)

220-228: LGTM!

The !!isError coercion ensures a boolean value is used for conditional rendering, which aligns with React 18's stricter TypeScript types and is consistent with the existing pattern on line 230 (!!alerts.length).

libs/ui-lib/lib/cim/components/modals/MassApproveAgentModal.tsx (3)

21-24: LGTM! Correct React 18 typing for children prop.

The use of React.PropsWithChildren<ApproveTableRowProps> is the proper approach for React 18, where children is no longer implicitly included in React.FC. The explicit destructuring and rendering of children is correct.


29-29: LGTM! Consistent with codebase patterns.

The explicit t<string>(...) generic matches the pattern used in tableUtils.tsx for header titles, ensuring proper type narrowing for the translation return value.


54-54: LGTM!

Consistent application of the t<string>(...) pattern for header titles.

apps/assisted-ui/src/components/App.tsx (2)

2-2: LGTM!

Clean import addition to support the type wrapper below.


18-27: LGTM!

The component structure remains intact with the wrapper cleanly applied. The routing hierarchy (BrowserRouter18 → CompatRouter → Page → UILibRoutes) correctly maintains the v5-compat migration pattern per the learned context.

libs/ui-lib/lib/common/components/storage/DisksTable.tsx (1)

42-44: LGTM!

The explicit t<string>() generic ensures type safety for the bodyContent prop, which is consistent with the PR-wide pattern of tightening i18n translation typings.

libs/ui-lib/lib/cim/components/modals/MassDeleteAgentModal.tsx (3)

33-33: LGTM!

Correct application of t<string>() for the header title type safety.


66-66: LGTM!

Consistent with the hostname column pattern above.


88-103: LGTM!

All Popover content strings and the interpolated translation on line 98 correctly use the t<string>() pattern. The interpolation syntax t<string>('ai:Go to cluster {{clusterName}}', { clusterName }) is properly preserved.

libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx (5)

48-48: LGTM!

The t<string>() pattern is correctly applied to the header title.


95-95: LGTM!

Consistent typing for the discovery type header.


149-149: LGTM!

Consistent typing for the status header.


197-197: LGTM!

Consistent typing for the cluster header.


237-237: LGTM!

Consistent typing for the infrastructure env header.

libs/ui-lib/lib/common/components/hosts/tableUtils.tsx (11)

67-67: LGTM!

Correct application of t<string>() for the hostname header.


103-103: LGTM!

Consistent typing for the role header.


135-135: LGTM!

Consistent typing for the status header.


172-172: LGTM!

Consistent typing for the discovered-on header.


191-191: LGTM!

Consistent typing for the CPU architecture header.


209-209: LGTM!

Consistent typing for the CPU cores header.


236-236: LGTM!

Consistent typing for the memory header.


261-261: LGTM!

Consistent typing for the total storage header.


286-286: LGTM!

Consistent typing for the GPUs header.


308-308: LGTM!

Consistent typing for the active NIC header.


387-387: LGTM!

Consistent typing for the labels header.

libs/ui-lib/lib/common/components/ui/formik/LabelField.tsx (2)

109-158: LGTM!

The EditableLabelControl follows common inline editing patterns with proper keyboard handling (Enter to confirm, Escape to discard) and accessibility support via translated aria-labels.


65-89: Good implementation of the LabelGroup with editable labels.

The rendering logic correctly handles the edit/delete flows and the key generation is appropriate for this use case.

libs/ui-lib/lib/common/components/ui/formik/SelectFieldWithSearch.tsx (1)

166-184: Type refinement is appropriate.

Typing val as unknown is a reasonable choice here since:

  1. The value originates from PatternFly's Select component which passes selection of varying types
  2. The useField<unknown | unknown[]> on line 51 already acknowledges the loosely-typed nature of the field value
  3. The callback body handles val defensively with truthy checks before use

The implementation correctly handles the unknown type throughout the callback logic.

libs/ui-lib/lib/common/components/AddHosts/AddHostsContext.tsx (1)

13-22: LGTM!

The update to React.PropsWithChildren<AddHostsContextType> is the correct approach for React 18 compatibility, where React.FC no longer implicitly includes children in its props type. The component correctly uses children and renders it within the provider.

libs/ui-lib/lib/ocm/store/slices/clusters/selectors.tsx (1)

62-71: LGTM!

The as HumanizedSortable type assertions on the baseDnsDomain and versionText cells are consistent with the other cells in this function and correctly match the HumanizedSortable interface structure (title, sortableValue, props).

libs/ui-lib/lib/common/components/hosts/TableToolbar.tsx (1)

38-46: LGTM!

The React.PropsWithChildren wrapper correctly addresses React 18's removal of implicit children from React.FC. The component destructures and renders children appropriately.

libs/ui-lib/lib/ocm/components/clusters/ClusterToolbar.tsx (1)

9-12: LGTM!

Correct React 18 typing update. The component renders children within ToolbarContent, so React.PropsWithChildren is necessary.

libs/ui-lib/lib/common/components/ui/formik/UploadField.tsx (1)

18-30: LGTM!

Correct React 18 typing update. The component renders children within the FormGroup (line 50), so React.PropsWithChildren is required to explicitly type the children prop.

libs/ui-lib/lib/ocm/components/ui/AssistedUILibVersion.tsx (1)

4-4: LGTM!

Correct fix for React 18 type compatibility. Since React.FC no longer implicitly includes children in React 18's type definitions, wrapping with React.PropsWithChildren is the appropriate pattern.

libs/ui-lib/lib/common/components/ui/GridGap.tsx (1)

7-9: LGTM!

Correct React 18 type fix. The component properly uses React.PropsWithChildren to explicitly type the children prop.

libs/ui-lib/lib/ocm/components/SentryErrorMonitorContextProvider.tsx (1)

11-13: LGTM!

Correct React 18 type fix for the context provider. Explicitly typing children with React.PropsWithChildren is the right approach for provider components in React 18.

libs/ui-lib/lib/ocm/components/hosts/ModalDialogsContext.tsx (1)

107-107: LGTM!

Correct React 18 type fix for the modal dialogs context provider. The explicit React.PropsWithChildren typing is appropriate since the component renders children within the context provider.

libs/ui-lib/lib/common/components/ui/formik/NumberInputField.tsx (1)

18-18: LGTM!

Correct React 18 type fix. Using React.PropsWithChildren<NumberInputFieldProps> properly extends the existing props interface with explicit children typing, which is necessary since the component renders children in line 84.

libs/ui-lib/lib/common/components/AlertsContextProvider.tsx (1)

21-21: LGTM!

Correct React 18 typing fix. Since React.FC no longer implicitly includes children, using React.PropsWithChildren is the appropriate pattern for components that render children.

libs/ui-lib/lib/common/components/ui/formik/TextAreaField.tsx (1)

14-14: LGTM!

Proper React 18 typing. The component renders children (line 48) inside the FormGroup, so wrapping TextAreaFieldProps with React.PropsWithChildren is the correct approach.

libs/ui-lib/lib/common/components/clusterWizard/ClusterWizardStepHeader.tsx (1)

4-4: LGTM!

Correct typing for React 18. The component renders children within the Content element, requiring explicit children prop typing.

libs/ui-lib/lib/common/components/ui/formik/CertificatesUploadField.tsx (1)

17-17: LGTM!

Correct React 18 typing. The component renders children (line 93) inside the FormGroup, so wrapping UploadFieldProps with React.PropsWithChildren is appropriate.

libs/ui-lib/lib/common/components/ui/Toolbar/ToolbarSecondaryGroup.tsx (1)

4-4: LGTM!

Correct typing for React 18. The component renders children within ToolbarGroup, requiring explicit children prop typing.

libs/ui-lib/lib/common/components/ui/formik/InputField.tsx (1)

17-21: LGTM! Correct React 18 type migration.

The React.PropsWithChildren wrapper correctly makes children explicit in the component's type signature, which is required in React 18 since React.FC no longer implicitly includes children.

libs/ui-lib/lib/common/components/hosts/HostsTableDetailContext.tsx (1)

15-29: LGTM! Correct React 18 type migration for context provider.

The React.PropsWithChildren wrapper is correctly applied to the provider component.

Minor observation: The type assertion as HostsTableDetailContextValue on line 25 appears redundant since context is already typed correctly, but this is an existing pattern and not introduced by this change.

libs/ui-lib/lib/common/components/hosts/HostPropertyValidationPopover.tsx (2)

18-22: LGTM! Correct React 18 type migration.

The React.PropsWithChildren wrapper is correctly applied, and children is properly destructured and used within the Button component.


54-64: LGTM! Consistent type migration pattern.

The React.PropsWithChildren wrapper follows the same correct pattern as ValidationPopover above, with children properly destructured and rendered in multiple conditional branches.

libs/ui-lib/lib/common/components/ui/StaticTextField.tsx (2)

22-30: LGTM! Correct React 18 type migration for StaticField.

The React.PropsWithChildren wrapper is correctly applied, with children properly destructured and rendered.


83-95: LGTM! Correct React 18 type migration for StaticTextField.

The React.PropsWithChildren wrapper is correctly applied, with children explicitly destructured and passed to the Content component.

libs/ui-lib/lib/cim/components/YamlPreview/YamlPreview.tsx (4)

2-4: Good migration from react-measure to useResizeObserver.

The imports correctly bring in the Monaco editor types and the resize observer hook, replacing the deprecated react-measure dependency as mentioned in the PR objectives.


17-33: LGTM! Well-typed Monaco theme definition.

The explicit editor.IStandaloneThemeData typing ensures type safety for the custom theme configuration.


88-100: Conditional rendering guards against zero-height editor.

The !!editorHeight check prevents rendering the Monaco editor before a valid height is determined, avoiding layout issues. This is the correct approach for resize-observer-based sizing.


41-46: LGTM! Correct React 18 type migration.

The React.PropsWithChildren wrapper is correctly applied, with children properly destructured and rendered in the readonly-editor-bar div.

libs/ui-lib/package.json (2)

13-13: LGTM! Good choice for replacing react-measure.

@react-hook/resize-observer is a lightweight, well-maintained library that provides a cleaner API using hooks, which aligns well with modern React patterns.


45-47: Type versions are aligned correctly.

Pinning @types/react-dom to 18.2.15 matches the pinned @types/react at 18.2.37, both corresponding to React 18.2.x types. This avoids potential type mismatches.

libs/ui-lib/lib/cim/components/ClusterDeployment/components/ClusterDeploymentHostsSelectionAdvanced.tsx (2)

61-65: Resize observer implementation looks correct.

Same pattern as the other file - tableWidth starts as undefined and gets populated after the observer fires. The implementation is functionally correct.


93-102: Clean refactor from Measure to ResizeObserver.

The wrapper div with ref and passing tableWidth to the table component is the correct approach for the resize observer pattern.

libs/ui-lib/lib/cim/components/ClusterDeployment/hostDiscovery/ClusterDeploymentHostsDiscovery.tsx (3)

3-3: LGTM!

Import is consistent with the other refactored components.


71-75: Consistent resize observer pattern.

Good to see the same pattern applied consistently across components. The hook correctly observes the container div and updates tableWidth state.


109-124: Clean migration from Measure to ResizeObserver.

The table is now wrapped in a div with a ref, and the observed width is passed down. This maintains the same width-driven behavior with a more modern and lightweight approach.

libs/ui-lib/lib/cim/components/ClusterDeployment/hostSelection/ClusterDeploymentHostsSelectionAdvanced.tsx (1)

61-65: No action needed — AgentsSelectionTable already handles undefined width gracefully.

The component defines width?: number (line 43) and uses the pattern const addAll = width && width > 700 (line 101) to safely check if width exists and exceeds 700. This defensive check prevents errors, and the conditional rendering logic (lines 113, 121) gracefully degrades by omitting certain columns when width is undefined. The table renders correctly in all cases.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
libs/ui-lib/lib/common/components/ui/formik/InputField.tsx (1)

64-64: Pre-existing typo in test ID.

The data-testid has a leading space: " input-field-description-...". This could cause test selector issues.

Proposed fix
-            data-testid=" input-field-description-${fieldId}-helper-text"
+            data-testid={`input-field-description-${fieldId}-helper-text`}

Note: The template literal also isn't being interpolated (missing backticks), so ${fieldId} appears literally in the output.

🤖 Fix all issues with AI agents
In `@libs/locales/lib/en/translation.json`:
- Line 974: The translation key "New label" is missing the required ai:
namespace; change the JSON key from "New label" to "ai:New label" (keeping the
value "New label") and ensure no duplicate "ai:New label" key already exists,
updating any code references if they expect the non-namespaced key so everything
remains consistent with other keys like "ai:Add label" and "ai:Add more".
- Line 2: Remove the duplicate un-prefixed JSON key "Add label" from the
translations so only the existing namespaced "ai:Add label": "Add label"
remains; locate the un-prefixed key "Add label" in the translations JSON and
delete that entry to avoid redundancy and key collisions.

In `@libs/ui-lib/lib/common/components/ui/formik/LabelField.tsx`:
- Around line 135-143: There’s a race where onBlur calls onConfirmAdd while
onKeyDown handling Escape calls onDiscardAdd; fix by adding a ref flag (e.g.,
isDiscardingRef) that onKeyDown sets when Escape is pressed and onDiscardAdd
runs, then check that ref in the onBlur handler before invoking onConfirmAdd
(and clear the ref after discard); update handlers referenced (onKeyDown,
onDiscardAdd, onBlur, onConfirmAdd) so blur is suppressed when isDiscardingRef
is true to prevent the confirm from firing.
♻️ Duplicate comments (3)
libs/ui-lib/lib/common/components/ui/formik/LabelField.tsx (3)

17-20: Rename the local Label type to avoid shadowing the PatternFly import.

The local type shadows the imported Label component from PatternFly (line 8). Rename to LabelItem or similar to avoid confusion and tooling issues.


29-29: Guard against undefined labels to prevent runtime errors.

If the form field isn't initialized, labels.map() at line 71 will throw. Provide a fallback:

-  const [{ value: labels }, { touched, error }, { setValue: setLabels }] = useField<Label[]>(name);
+  const [{ value }, { touched, error }, { setValue: setLabels }] = useField<Label[]>(name);
+  const labels = value ?? [];

57-63: Fix the condition and inconsistent value handling in onEdit.

Two issues:

  1. label.length ? label[1] : undefined — after split('='), the array always has length ≥ 1, so this condition is always truthy. Should be label.length > 1.
  2. Inconsistency: onAdd (line 47) sets value: split[1] or value: '', while onEdit sets value: undefined. This can cause subtle comparison bugs.
   const onEdit = (index: number, nextText: string) => {
     const label = nextText.split('=');
     const newLabels = [...labels];
-    newLabels.splice(index, 1, { key: label[0], value: label.length ? label[1] : undefined });
+    newLabels.splice(index, 1, { key: label[0], value: label.length > 1 ? label[1] : '' });

     setLabels(newLabels, true);
   };
🧹 Nitpick comments (3)
libs/ui-lib/lib/cim/components/YamlPreview/YamlPreview.tsx (1)

88-100: Consider edge case when container height is zero.

The !!editorHeight check will prevent rendering both when editorHeight is undefined (initial state) and when it's 0. If the container ever has a legitimate height of 0 (e.g., during CSS transitions or when collapsed), the editor won't render.

If this is intentional behavior, the current implementation is fine. Otherwise, consider explicitly checking for undefined:

♻️ Optional: Explicit undefined check
-          {!!editorHeight && (
+          {editorHeight !== undefined && (
apps/assisted-ui/src/components/App.tsx (1)

12-16: Reasonable workaround for React 18 type compatibility.

The double cast pattern is a pragmatic solution for the React 18 children type change when using react-router-dom v5 types. This approach maintains functionality during the incremental migration to v6.

Minor nit: consider making the eslint-disable more specific:

-// eslint-disable-next-line
+// eslint-disable-next-line `@typescript-eslint/no-explicit-any`
libs/ui-lib/lib/ocm/store/slices/clusters/selectors.tsx (1)

62-71: Type casts align with existing pattern - LGTM with minor suggestion.

The explicit as HumanizedSortable casts make these cells consistent with the others in the array.

One small note: on line 65, sortableValue: baseDnsDomain could be undefined (per line 34), but HumanizedSortable.sortableValue expects number | string. The cast works around this, but for better type safety, consider defaulting to an empty string:

Optional improvement
       {
         title: baseDnsDomain || DASH,
         props: { 'data-testid': `cluster-base-domain-${name}` },
-        sortableValue: baseDnsDomain,
+        sortableValue: baseDnsDomain || '',
       } as HumanizedSortable,
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1d91189 and 31e7132.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (43)
  • apps/assisted-disconnected-ui/package.json
  • apps/assisted-ui/package.json
  • apps/assisted-ui/src/components/App.tsx
  • libs/locales/lib/en/translation.json
  • libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx
  • libs/ui-lib/lib/cim/components/ClusterDeployment/components/ClusterDeploymentHostsSelectionAdvanced.tsx
  • libs/ui-lib/lib/cim/components/ClusterDeployment/customManifests/ConfigMapForm.tsx
  • libs/ui-lib/lib/cim/components/ClusterDeployment/hostDiscovery/ClusterDeploymentHostsDiscovery.tsx
  • libs/ui-lib/lib/cim/components/ClusterDeployment/hostSelection/ClusterDeploymentHostsSelectionAdvanced.tsx
  • libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvFormPage.tsx
  • libs/ui-lib/lib/cim/components/YamlPreview/YamlPreview.tsx
  • libs/ui-lib/lib/cim/components/modals/EditSSHKeyModal.tsx
  • libs/ui-lib/lib/cim/components/modals/MassApproveAgentModal.tsx
  • libs/ui-lib/lib/cim/components/modals/MassDeleteAgentModal.tsx
  • libs/ui-lib/lib/common/components/AddHosts/AddHostsContext.tsx
  • libs/ui-lib/lib/common/components/AlertsContextProvider.tsx
  • libs/ui-lib/lib/common/components/clusterWizard/ClusterWizardStepHeader.tsx
  • libs/ui-lib/lib/common/components/hosts/AITable.tsx
  • libs/ui-lib/lib/common/components/hosts/HostPropertyValidationPopover.tsx
  • libs/ui-lib/lib/common/components/hosts/HostStatus.tsx
  • libs/ui-lib/lib/common/components/hosts/HostsTableDetailContext.tsx
  • libs/ui-lib/lib/common/components/hosts/TableToolbar.tsx
  • libs/ui-lib/lib/common/components/hosts/tableUtils.tsx
  • libs/ui-lib/lib/common/components/storage/DisksTable.tsx
  • libs/ui-lib/lib/common/components/ui/CustomToolbarFilter.tsx
  • libs/ui-lib/lib/common/components/ui/GridGap.tsx
  • libs/ui-lib/lib/common/components/ui/StaticTextField.tsx
  • libs/ui-lib/lib/common/components/ui/Toolbar/ToolbarSecondaryGroup.tsx
  • libs/ui-lib/lib/common/components/ui/formik/CertificatesUploadField.tsx
  • libs/ui-lib/lib/common/components/ui/formik/InputField.tsx
  • libs/ui-lib/lib/common/components/ui/formik/LabelField.tsx
  • libs/ui-lib/lib/common/components/ui/formik/NumberInputField.tsx
  • libs/ui-lib/lib/common/components/ui/formik/SelectFieldWithSearch.tsx
  • libs/ui-lib/lib/common/components/ui/formik/TextAreaField.tsx
  • libs/ui-lib/lib/common/components/ui/formik/UploadField.tsx
  • libs/ui-lib/lib/common/features/featureGate.tsx
  • libs/ui-lib/lib/ocm/components/SentryErrorMonitorContextProvider.tsx
  • libs/ui-lib/lib/ocm/components/clusters/ClusterToolbar.tsx
  • libs/ui-lib/lib/ocm/components/hosts/ModalDialogsContext.tsx
  • libs/ui-lib/lib/ocm/components/ui/AssistedUILibVersion.tsx
  • libs/ui-lib/lib/ocm/store/slices/clusters/selectors.tsx
  • libs/ui-lib/package.json
  • package.json
💤 Files with no reviewable changes (3)
  • apps/assisted-ui/package.json
  • apps/assisted-disconnected-ui/package.json
  • package.json
🚧 Files skipped from review as they are similar to previous changes (20)
  • libs/ui-lib/lib/common/components/clusterWizard/ClusterWizardStepHeader.tsx
  • libs/ui-lib/lib/ocm/components/clusters/ClusterToolbar.tsx
  • libs/ui-lib/lib/cim/components/ClusterDeployment/customManifests/ConfigMapForm.tsx
  • libs/ui-lib/lib/cim/components/modals/EditSSHKeyModal.tsx
  • libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvFormPage.tsx
  • libs/ui-lib/lib/common/components/ui/formik/NumberInputField.tsx
  • libs/ui-lib/lib/common/components/hosts/TableToolbar.tsx
  • libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx
  • libs/ui-lib/lib/common/components/ui/formik/SelectFieldWithSearch.tsx
  • libs/ui-lib/package.json
  • libs/ui-lib/lib/ocm/components/hosts/ModalDialogsContext.tsx
  • libs/ui-lib/lib/common/components/ui/formik/UploadField.tsx
  • libs/ui-lib/lib/common/components/hosts/tableUtils.tsx
  • libs/ui-lib/lib/cim/components/ClusterDeployment/hostSelection/ClusterDeploymentHostsSelectionAdvanced.tsx
  • libs/ui-lib/lib/ocm/components/SentryErrorMonitorContextProvider.tsx
  • libs/ui-lib/lib/common/components/storage/DisksTable.tsx
  • libs/ui-lib/lib/common/components/AlertsContextProvider.tsx
  • libs/ui-lib/lib/common/features/featureGate.tsx
  • libs/ui-lib/lib/common/components/hosts/HostPropertyValidationPopover.tsx
  • libs/ui-lib/lib/common/components/hosts/HostStatus.tsx
🧰 Additional context used
🧠 Learnings (6)
📚 Learning: 2025-12-17T09:08:18.279Z
Learnt from: jgyselov
Repo: openshift-assisted/assisted-installer-ui PR: 3319
File: libs/ui-lib/lib/cim/components/helpers/toAssisted.ts:199-201
Timestamp: 2025-12-17T09:08:18.279Z
Learning: In libs/ui-lib/lib/cim/components/helpers/toAssisted.ts, the platformType field on agentClusterInstall.spec is guaranteed to always contain a valid PlatformType value (when lowercased), making the type assertion safe without additional runtime validation.

Applied to files:

  • libs/ui-lib/lib/ocm/components/ui/AssistedUILibVersion.tsx
  • libs/ui-lib/lib/ocm/store/slices/clusters/selectors.tsx
📚 Learning: 2026-01-07T15:19:02.310Z
Learnt from: rawagner
Repo: openshift-assisted/assisted-installer-ui PR: 3350
File: apps/assisted-ui/package.json:26-27
Timestamp: 2026-01-07T15:19:02.310Z
Learning: The react-router-dom-v5-compat package is designed to work alongside react-router-dom v4 or v5, not replace it. It declares peer dependencies on react-router-dom "4 || 5" and allows incremental migration by providing React Router v6 APIs while the application continues to run on v5. Having both react-router-dom5.x and react-router-dom-v5-compat installed together is the correct and intended configuration.

Applied to files:

  • apps/assisted-ui/src/components/App.tsx
📚 Learning: 2025-10-21T04:40:36.292Z
Learnt from: linoyaslan
Repo: openshift-assisted/assisted-installer-ui PR: 3190
File: libs/ui-lib/lib/ocm/components/clusterConfiguration/networkConfiguration/AdvancedNetworkFields.tsx:55-63
Timestamp: 2025-10-21T04:40:36.292Z
Learning: In libs/ui-lib/lib/ocm/components/clusterConfiguration/networkConfiguration/AdvancedNetworkFields.tsx, the network reordering logic in the useEffect (swapping clusterNetworks and serviceNetworks based on the primary machine network's IP family) is for UI consistency only. Validation of empty or invalid CIDRs is handled separately by validation schemas, not by the reordering logic.

Applied to files:

  • libs/ui-lib/lib/ocm/store/slices/clusters/selectors.tsx
  • libs/ui-lib/lib/cim/components/ClusterDeployment/components/ClusterDeploymentHostsSelectionAdvanced.tsx
  • libs/ui-lib/lib/cim/components/ClusterDeployment/hostDiscovery/ClusterDeploymentHostsDiscovery.tsx
📚 Learning: 2025-05-22T09:12:50.632Z
Learnt from: rawagner
Repo: openshift-assisted/assisted-installer-ui PR: 2942
File: libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentManifestsStep.tsx:93-97
Timestamp: 2025-05-22T09:12:50.632Z
Learning: When working with Formik's FieldArray, use the provided array helpers (like `remove()`, `push()`, etc.) instead of directly mutating the values array to ensure proper state tracking and re-rendering.

Applied to files:

  • libs/ui-lib/lib/common/components/ui/StaticTextField.tsx
  • libs/ui-lib/lib/common/components/ui/formik/LabelField.tsx
📚 Learning: 2025-12-17T09:16:41.439Z
Learnt from: jgyselov
Repo: openshift-assisted/assisted-installer-ui PR: 3319
File: libs/ui-lib/lib/common/components/hosts/utils.ts:208-210
Timestamp: 2025-12-17T09:16:41.439Z
Learning: In libs/ui-lib/lib/common/components/hosts/utils.ts, the nodeLabels field on Host objects is guaranteed to be valid JSON because it's always constructed using JSON.stringify in libs/ui-lib/lib/cim/components/helpers/toAssisted.ts, making direct JSON.parse safe without additional error handling.

Applied to files:

  • libs/ui-lib/lib/common/components/ui/formik/LabelField.tsx
📚 Learning: 2025-05-22T07:31:16.062Z
Learnt from: rawagner
Repo: openshift-assisted/assisted-installer-ui PR: 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.

Applied to files:

  • libs/ui-lib/lib/cim/components/YamlPreview/YamlPreview.tsx
🧬 Code graph analysis (7)
libs/ui-lib/lib/common/components/ui/formik/CertificatesUploadField.tsx (1)
libs/ui-lib/lib/common/components/ui/formik/types.ts (1)
  • UploadFieldProps (97-106)
libs/ui-lib/lib/common/components/ui/formik/InputField.tsx (1)
libs/ui-lib/lib/common/components/ui/formik/types.ts (1)
  • InputFieldProps (66-74)
apps/assisted-ui/src/components/App.tsx (1)
libs/ui-lib/lib/ocm/components/Routes.tsx (1)
  • UILibRoutes (25-61)
libs/ui-lib/lib/ocm/store/slices/clusters/selectors.tsx (1)
libs/ui-lib/lib/common/components/ui/table/utils.ts (1)
  • HumanizedSortable (7-11)
libs/ui-lib/lib/common/components/ui/formik/LabelField.tsx (3)
libs/types/accounts-management-service.d.ts (1)
  • Label (46-56)
libs/ui-lib/lib/common/components/ui/formik/utils.ts (1)
  • getFieldId (15-18)
libs/ui-lib/lib/common/hooks/index.ts (1)
  • useTranslation (3-3)
libs/ui-lib/lib/cim/components/modals/MassApproveAgentModal.tsx (3)
libs/ui-lib/lib/common/components/hosts/tableUtils.tsx (1)
  • hostnameColumn (59-92)
libs/ui-lib/lib/cim/types/k8s/agent.ts (1)
  • AgentK8sResource (32-74)
libs/ui-lib/lib/common/components/hosts/AITable.tsx (1)
  • TableRow (24-28)
libs/ui-lib/lib/common/components/ui/formik/TextAreaField.tsx (1)
libs/ui-lib/lib/common/components/ui/formik/types.ts (1)
  • TextAreaFieldProps (88-95)
🪛 Biome (2.1.2)
libs/ui-lib/lib/common/components/ui/formik/LabelField.tsx

[error] 17-17: Shouldn't redeclare 'Label'. Consider to delete it or rename it.

'Label' is defined here:

(lint/suspicious/noRedeclare)

🔇 Additional comments (29)
libs/ui-lib/lib/common/components/ui/Toolbar/ToolbarSecondaryGroup.tsx (1)

4-4: Correct React 18 typing fix.

This properly addresses the React 18 breaking change where React.FC no longer implicitly includes children in its props. Explicitly typing with React.PropsWithChildren is the standard fix.

libs/ui-lib/lib/common/components/ui/formik/TextAreaField.tsx (1)

14-14: LGTM! Correct React 18 type fix.

The PropsWithChildren wrapper is necessary since React 18's FC type no longer implicitly includes children. This component uses children (rendered at line 48), so the type update is appropriate. Based on the provided React documentation, this aligns with the recommended upgrade path.

libs/ui-lib/lib/common/components/hosts/AITable.tsx (1)

228-236: LGTM!

The change to type the unused _event parameter as unknown is a sensible improvement. Since the event is not used in the callback body, unknown is appropriate and safer than an implicit any. This aligns with the PR's goal of improving TypeScript types for React 18 compatibility.

libs/ui-lib/lib/common/components/ui/formik/CertificatesUploadField.tsx (1)

17-26: LGTM! Correct React 18 type fix.

In React 18, React.FC no longer implicitly includes children in its type definition. Since this component destructures and renders children (line 93), wrapping UploadFieldProps with React.PropsWithChildren is the appropriate fix to maintain type safety.

libs/ui-lib/lib/common/components/ui/formik/InputField.tsx (1)

17-21: LGTM!

The addition of React.PropsWithChildren<> is correct for React 18 compatibility. Since children is destructured and rendered (line 89), explicitly including it in the type is necessary now that React.FC no longer implicitly includes children.

libs/ui-lib/lib/cim/components/YamlPreview/YamlPreview.tsx (3)

2-4: LGTM!

The imports are correctly structured with proper TypeScript types for Monaco editor hooks and the ResizeObserver integration aligns with the PR's pattern of replacing react-measure with @react-hook/resize-observer.


17-26: LGTM!

The explicit editor.IStandaloneThemeData typing improves type safety and ensures the theme object conforms to Monaco's expected structure.


41-60: LGTM!

The component signature update to React.PropsWithChildren<YamlPreviewProps> aligns with React 18 type patterns. The typed callbacks (EditorDidMount, EditorWillMount) improve type safety, and the ResizeObserver integration correctly tracks container height changes.

apps/assisted-ui/src/components/App.tsx (1)

18-27: LGTM!

The BrowserRouter18 wrapper is correctly applied, preserving the existing basename configuration and maintaining the same component hierarchy with CompatRouter for the incremental migration.

libs/ui-lib/lib/common/components/ui/CustomToolbarFilter.tsx (1)

118-123: Cleaner with optional chaining; consider consistency with other portals.

The refactor to optional chaining and explicit ternary is cleaner. The as React.ReactElement cast addresses React 18's stricter typing for fragment children.

However, lines 133-137 use similar portal patterns but retain the old && style without type assertions. If the type fix is needed here, verify whether those paths might also trigger type errors in certain conditions.

libs/ui-lib/lib/cim/components/ClusterDeployment/components/ClusterDeploymentHostsSelectionAdvanced.tsx (3)

5-5: LGTM!

The import for useResizeObserver from @react-hook/resize-observer is correct and aligns with the PR's goal of replacing the deprecated react-measure library.


93-102: LGTM!

The wrapper div with the ref provides the measurement target for the resize observer, and the observed width is correctly passed to AgentsSelectionTable. This is the standard pattern for resize observer usage and cleanly replaces the previous Measure component approach.


61-65: No action needed—AgentsSelectionTable properly handles undefined width.

The width prop is correctly typed as optional (width?: number), and the component uses a defensive guard when consuming it (width && width > 700). When width is undefined, addAll evaluates to false, which simply omits certain columns from the table—no layout issues or errors.

libs/ui-lib/lib/cim/components/modals/MassDeleteAgentModal.tsx (3)

33-33: LGTM!

The explicit t<string> generic ensures the return type is narrowed to string, which aligns with the TableRow header title type requirements and matches the existing pattern in tableUtils.tsx.


66-66: LGTM!

Consistent application of the t<string> generic for the status column header title.


88-103: LGTM!

The t<string> generics are correctly applied to the Popover content strings (header, body, footer, and button text), ensuring proper type narrowing for React node children.

libs/ui-lib/lib/cim/components/modals/MassApproveAgentModal.tsx (3)

21-24: LGTM!

Correct React 18 fix. The React.PropsWithChildren wrapper is required because React 18 removed the implicit children prop from React.FC. The explicit destructuring of children and its usage in the component is properly implemented.


29-29: LGTM!

Consistent with the t<string> pattern applied across the codebase for header titles.


54-54: LGTM!

Status column header title correctly uses t<string> for type narrowing.

libs/ui-lib/lib/common/components/ui/GridGap.tsx (1)

7-9: LGTM!

The React.PropsWithChildren typing is the correct fix for React 18, where React.FC no longer implicitly includes children in its props type.

libs/ui-lib/lib/common/components/AddHosts/AddHostsContext.tsx (1)

13-23: LGTM!

Correct React 18 typing fix—explicitly wrapping AddHostsContextType with React.PropsWithChildren to account for children no longer being implicit in React.FC.

libs/ui-lib/lib/ocm/components/ui/AssistedUILibVersion.tsx (1)

4-11: LGTM!

Appropriate React 18 typing update. The component correctly renders children alongside the version metadata.

libs/ui-lib/lib/common/components/hosts/HostsTableDetailContext.tsx (1)

15-29: LGTM!

Correct React 18 typing fix for the context provider. The multi-line generic syntax is properly formatted.

libs/ui-lib/lib/common/components/ui/StaticTextField.tsx (3)

22-57: LGTM!

Correct React 18 typing for StaticField. The component properly renders children within the FormGroup.


66-77: LGTM!

The PropsWithChildren typing is correct. Children will be included in the ...props spread and passed through to StaticField.


83-96: LGTM!

Correct React 18 typing for StaticTextField. The component properly wraps children in the Content component.

libs/ui-lib/lib/cim/components/ClusterDeployment/hostDiscovery/ClusterDeploymentHostsDiscovery.tsx (2)

109-124: LGTM!

The wrapper div correctly anchors the resize observer, and the width prop is passed cleanly to the table component. This is a good refactor from the render-prop Measure pattern to a more idiomatic hook-based approach.


71-75: Resize observer implementation correctly handles initial undefined width.

The hook setup properly observes the container and updates width on resize. The child component ClusterDeploymentHostDiscoveryTable gracefully handles the initial undefined state via the width && width > 700 check (line 80), which safely falses when width is undefined, rendering fewer columns until the observer fires.

libs/ui-lib/lib/common/components/ui/formik/LabelField.tsx (1)

65-88: LGTM on the LabelGroup rendering logic.

The refactored label rendering using PatternFly's LabelGroup and editable Label components is clean. The edit handlers correctly integrate with the PatternFly edit callbacks, and the key generation using ${key}__${index} handles duplicate labels appropriately.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

@rawagner rawagner force-pushed the types_18 branch 2 times, most recently from 7dbaadd to 8c5540b Compare January 15, 2026 13:25
Replace/remove deprecated deps
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
libs/ui-lib/lib/common/components/ui/formik/SelectFieldWithSearch.tsx (1)

247-263: Missing key on outermost element in map.

When rendering lists in React, the key prop must be on the outermost element returned from the map callback. The shorthand <> fragment syntax doesn't support keys. This can cause reconciliation warnings and unexpected behavior.

Suggested fix
             selectOptions.map((option, index) => (
-              <>
+              <React.Fragment key={option.value as string}>
                 {option.showDivider && <Divider component="li" key={`divider-${index}`} />}
                 <SelectOption
                   hasCheckbox={isMultiSelect && !option.isAriaDisabled}
                   isSelected={
                     isMultiSelect && Array.isArray(value)
                       ? value.some((v) => isEqual(v, option.value))
                       : value === option.value
                   }
-                  key={`option-${index}`}
                   isFocused={focusedItemIndex === index}
                   ref={null}
                   {...option}
                 />
-              </>
+              </React.Fragment>
             ))
♻️ Duplicate comments (2)
libs/ui-lib/lib/common/components/ui/formik/LabelField.tsx (2)

26-27: Guard against undefined labels to prevent runtime errors.

If the form field isn't initialized with an array, labels.map() at line 63 will throw. Provide a fallback.

Suggested fix
-  const [{ value: labels }, { touched, error }, { setValue: setLabels, setTouched }] =
-    useField<string[]>(name);
+  const [{ value }, { touched, error }, { setValue: setLabels, setTouched }] =
+    useField<string[]>(name);
+  const labels = value ?? [];

133-141: Potential race condition: onBlur may fire before Escape key discard completes.

When the user presses Escape, onDiscardAdd() is called, but onBlur (line 133) fires as the input loses focus during the state update, potentially triggering onConfirmAdd() before the discard takes effect. Since React state updates are asynchronous, the label value in onConfirmAdd will still contain the typed text.

Suggested fix using a ref to suppress the blur handler
 const EditableLabelControl = ({ defaultLabel, onAddLabel }: EditableLabelControlProps) => {
   const [isEditing, setIsEditing] = React.useState<boolean>(false);
   const [label, setLabel] = React.useState<string>('');
+  const shouldDiscardRef = React.useRef(false);
   const { t } = useTranslation();

   const onConfirmAdd = () => {
+    if (shouldDiscardRef.current) {
+      shouldDiscardRef.current = false;
+      return;
+    }
     onAddLabel(label);
     setIsEditing(false);
     setLabel('');
   };

   const onDiscardAdd = () => {
+    shouldDiscardRef.current = true;
     setIsEditing(false);
     setLabel('');
   };
🧹 Nitpick comments (1)
libs/ui-lib/package.json (1)

47-47: Align @types/react-dom with @types/react to avoid type skew.
Consider bumping @types/react-dom to match @types/react (18.2.37) and confirm yarn check_types passes.

♻️ Proposed change
-    "@types/react-dom": "18.2.15",
+    "@types/react-dom": "18.2.37",
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7dbaadd and 65a4647.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (43)
  • apps/assisted-disconnected-ui/package.json
  • apps/assisted-ui/package.json
  • apps/assisted-ui/src/components/App.tsx
  • libs/locales/lib/en/translation.json
  • libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx
  • libs/ui-lib/lib/cim/components/ClusterDeployment/components/ClusterDeploymentHostsSelectionAdvanced.tsx
  • libs/ui-lib/lib/cim/components/ClusterDeployment/customManifests/ConfigMapForm.tsx
  • libs/ui-lib/lib/cim/components/ClusterDeployment/hostDiscovery/ClusterDeploymentHostsDiscovery.tsx
  • libs/ui-lib/lib/cim/components/ClusterDeployment/hostSelection/ClusterDeploymentHostsSelectionAdvanced.tsx
  • libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvFormPage.tsx
  • libs/ui-lib/lib/cim/components/YamlPreview/YamlPreview.tsx
  • libs/ui-lib/lib/cim/components/modals/EditSSHKeyModal.tsx
  • libs/ui-lib/lib/cim/components/modals/MassApproveAgentModal.tsx
  • libs/ui-lib/lib/cim/components/modals/MassDeleteAgentModal.tsx
  • libs/ui-lib/lib/common/components/AddHosts/AddHostsContext.tsx
  • libs/ui-lib/lib/common/components/AlertsContextProvider.tsx
  • libs/ui-lib/lib/common/components/clusterWizard/ClusterWizardStepHeader.tsx
  • libs/ui-lib/lib/common/components/hosts/AITable.tsx
  • libs/ui-lib/lib/common/components/hosts/HostPropertyValidationPopover.tsx
  • libs/ui-lib/lib/common/components/hosts/HostStatus.tsx
  • libs/ui-lib/lib/common/components/hosts/HostsTableDetailContext.tsx
  • libs/ui-lib/lib/common/components/hosts/TableToolbar.tsx
  • libs/ui-lib/lib/common/components/hosts/tableUtils.tsx
  • libs/ui-lib/lib/common/components/storage/DisksTable.tsx
  • libs/ui-lib/lib/common/components/ui/CustomToolbarFilter.tsx
  • libs/ui-lib/lib/common/components/ui/GridGap.tsx
  • libs/ui-lib/lib/common/components/ui/StaticTextField.tsx
  • libs/ui-lib/lib/common/components/ui/Toolbar/ToolbarSecondaryGroup.tsx
  • libs/ui-lib/lib/common/components/ui/formik/CertificatesUploadField.tsx
  • libs/ui-lib/lib/common/components/ui/formik/InputField.tsx
  • libs/ui-lib/lib/common/components/ui/formik/LabelField.tsx
  • libs/ui-lib/lib/common/components/ui/formik/NumberInputField.tsx
  • libs/ui-lib/lib/common/components/ui/formik/SelectFieldWithSearch.tsx
  • libs/ui-lib/lib/common/components/ui/formik/TextAreaField.tsx
  • libs/ui-lib/lib/common/components/ui/formik/UploadField.tsx
  • libs/ui-lib/lib/common/features/featureGate.tsx
  • libs/ui-lib/lib/ocm/components/SentryErrorMonitorContextProvider.tsx
  • libs/ui-lib/lib/ocm/components/clusters/ClusterToolbar.tsx
  • libs/ui-lib/lib/ocm/components/hosts/ModalDialogsContext.tsx
  • libs/ui-lib/lib/ocm/components/ui/AssistedUILibVersion.tsx
  • libs/ui-lib/lib/ocm/store/slices/clusters/selectors.tsx
  • libs/ui-lib/package.json
  • package.json
💤 Files with no reviewable changes (3)
  • package.json
  • apps/assisted-ui/package.json
  • apps/assisted-disconnected-ui/package.json
🚧 Files skipped from review as they are similar to previous changes (22)
  • libs/ui-lib/lib/common/components/ui/formik/UploadField.tsx
  • libs/ui-lib/lib/ocm/components/SentryErrorMonitorContextProvider.tsx
  • libs/ui-lib/lib/common/components/ui/formik/CertificatesUploadField.tsx
  • libs/ui-lib/lib/cim/components/modals/MassDeleteAgentModal.tsx
  • libs/ui-lib/lib/common/components/ui/formik/InputField.tsx
  • libs/ui-lib/lib/common/features/featureGate.tsx
  • apps/assisted-ui/src/components/App.tsx
  • libs/ui-lib/lib/cim/components/InfraEnv/InfraEnvFormPage.tsx
  • libs/ui-lib/lib/common/components/AlertsContextProvider.tsx
  • libs/ui-lib/lib/common/components/hosts/AITable.tsx
  • libs/ui-lib/lib/common/components/ui/StaticTextField.tsx
  • libs/ui-lib/lib/cim/components/ClusterDeployment/components/ClusterDeploymentHostsSelectionAdvanced.tsx
  • libs/ui-lib/lib/cim/components/modals/MassApproveAgentModal.tsx
  • libs/ui-lib/lib/cim/components/ClusterDeployment/hostSelection/ClusterDeploymentHostsSelectionAdvanced.tsx
  • libs/ui-lib/lib/ocm/store/slices/clusters/selectors.tsx
  • libs/ui-lib/lib/cim/components/ClusterDeployment/hostDiscovery/ClusterDeploymentHostsDiscovery.tsx
  • libs/ui-lib/lib/common/components/hosts/HostPropertyValidationPopover.tsx
  • libs/locales/lib/en/translation.json
  • libs/ui-lib/lib/cim/components/modals/EditSSHKeyModal.tsx
  • libs/ui-lib/lib/common/components/ui/formik/TextAreaField.tsx
  • libs/ui-lib/lib/common/components/ui/CustomToolbarFilter.tsx
  • libs/ui-lib/lib/ocm/components/ui/AssistedUILibVersion.tsx
🧰 Additional context used
🧠 Learnings (6)
📚 Learning: 2026-01-07T15:19:02.310Z
Learnt from: rawagner
Repo: openshift-assisted/assisted-installer-ui PR: 3350
File: apps/assisted-ui/package.json:26-27
Timestamp: 2026-01-07T15:19:02.310Z
Learning: The react-router-dom-v5-compat package is designed to work alongside react-router-dom v4 or v5, not replace it. It declares peer dependencies on react-router-dom "4 || 5" and allows incremental migration by providing React Router v6 APIs while the application continues to run on v5. Having both react-router-dom5.x and react-router-dom-v5-compat installed together is the correct and intended configuration.

Applied to files:

  • libs/ui-lib/package.json
📚 Learning: 2025-12-17T09:08:18.279Z
Learnt from: jgyselov
Repo: openshift-assisted/assisted-installer-ui PR: 3319
File: libs/ui-lib/lib/cim/components/helpers/toAssisted.ts:199-201
Timestamp: 2025-12-17T09:08:18.279Z
Learning: In libs/ui-lib/lib/cim/components/helpers/toAssisted.ts, the platformType field on agentClusterInstall.spec is guaranteed to always contain a valid PlatformType value (when lowercased), making the type assertion safe without additional runtime validation.

Applied to files:

  • libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx
  • libs/ui-lib/lib/cim/components/ClusterDeployment/customManifests/ConfigMapForm.tsx
📚 Learning: 2025-12-17T09:16:41.439Z
Learnt from: jgyselov
Repo: openshift-assisted/assisted-installer-ui PR: 3319
File: libs/ui-lib/lib/common/components/hosts/utils.ts:208-210
Timestamp: 2025-12-17T09:16:41.439Z
Learning: In libs/ui-lib/lib/common/components/hosts/utils.ts, the nodeLabels field on Host objects is guaranteed to be valid JSON because it's always constructed using JSON.stringify in libs/ui-lib/lib/cim/components/helpers/toAssisted.ts, making direct JSON.parse safe without additional error handling.

Applied to files:

  • libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx
  • libs/ui-lib/lib/common/components/ui/formik/LabelField.tsx
  • libs/ui-lib/lib/common/components/hosts/tableUtils.tsx
  • libs/ui-lib/lib/common/components/hosts/HostStatus.tsx
📚 Learning: 2025-05-22T09:12:50.632Z
Learnt from: rawagner
Repo: openshift-assisted/assisted-installer-ui PR: 2942
File: libs/ui-lib/lib/cim/components/ClusterDeployment/ClusterDeploymentManifestsStep.tsx:93-97
Timestamp: 2025-05-22T09:12:50.632Z
Learning: When working with Formik's FieldArray, use the provided array helpers (like `remove()`, `push()`, etc.) instead of directly mutating the values array to ensure proper state tracking and re-rendering.

Applied to files:

  • libs/ui-lib/lib/common/components/ui/formik/LabelField.tsx
📚 Learning: 2025-05-22T07:31:16.062Z
Learnt from: rawagner
Repo: openshift-assisted/assisted-installer-ui PR: 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.

Applied to files:

  • libs/ui-lib/lib/cim/components/YamlPreview/YamlPreview.tsx
📚 Learning: 2025-10-20T08:57:04.935Z
Learnt from: linoyaslan
Repo: openshift-assisted/assisted-installer-ui PR: 3190
File: libs/ui-lib/lib/ocm/components/clusterDetail/ClusterProperties.tsx:43-45
Timestamp: 2025-10-20T08:57:04.935Z
Learning: In the file `libs/ui-lib/lib/ocm/components/clusterDetail/ClusterProperties.tsx`, the `getStackTypeLabel` function returns 'Dual-stack' or 'IPv4' because the system currently only supports IPv4 single-stack clusters. IPv6-only single-stack clusters are not supported.

Applied to files:

  • libs/ui-lib/lib/common/components/hosts/tableUtils.tsx
🧬 Code graph analysis (3)
libs/ui-lib/lib/common/components/ui/formik/NumberInputField.tsx (1)
libs/ui-lib/lib/common/components/ui/formik/types.ts (1)
  • NumberInputFieldProps (76-86)
libs/ui-lib/lib/common/components/ui/formik/LabelField.tsx (3)
libs/ui-lib/lib/common/hooks/index.ts (1)
  • useTranslation (3-3)
libs/ui-lib/lib/common/components/ui/formik/utils.ts (1)
  • getFieldId (15-18)
libs/types/accounts-management-service.d.ts (1)
  • Label (46-56)
libs/ui-lib/lib/common/components/hosts/HostStatus.tsx (1)
libs/ui-lib/lib/common/components/hosts/types.ts (2)
  • HostStatus (81-83)
  • HostStatusProps (85-95)
🔇 Additional comments (29)
libs/ui-lib/lib/cim/components/ClusterDeployment/customManifests/ConfigMapForm.tsx (1)

220-220: Clearer truthiness check for error rendering.

!!isError makes the conditional explicit and avoids accidental rendering when isError is non-boolean.

libs/ui-lib/lib/common/components/hosts/tableUtils.tsx (1)

67-67: LGTM — explicit translation typing is consistent and safe.
No behavioral changes; this tightens types as intended.

Also applies to: 103-103, 135-135, 172-172, 191-191, 209-209, 236-236, 261-261, 286-286, 308-308, 387-387

libs/ui-lib/lib/common/components/storage/DisksTable.tsx (1)

42-44: LGTM!

The explicit generic type parameter t<string>(...) correctly ensures the translation function returns a string type, improving type safety for the bodyContent prop. This is consistent with the broader typing improvements in this PR.

libs/ui-lib/lib/common/components/ui/Toolbar/ToolbarSecondaryGroup.tsx (1)

4-5: LGTM for the typing update.
Please confirm this aligns with the repo’s React 18 type expectations (e.g., no TS/lint complaints about React.FC<React.PropsWithChildren> in this codebase).

libs/ui-lib/package.json (1)

13-13: Confirm ResizeObserver availability in supported environments.
@react-hook/resize-observer relies on the native ResizeObserver. If any supported browsers/environments lack it, add a polyfill or guard to prevent runtime failures.

libs/ui-lib/lib/common/components/ui/formik/SelectFieldWithSearch.tsx (1)

166-184: LGTM! Good type safety improvement.

Narrowing from any to unknown aligns with TypeScript best practices and the PR's goal of fixing React 18 types. The function body already handles the unknown type safely with appropriate checks before usage.

libs/ui-lib/lib/cim/components/Agent/tableUtils.tsx (5)

47-49: Explicit translation typing looks good.


94-96: Typed translation call is fine.


148-150: LGTM — typing is clearer here.


196-198: No concerns with the typed header title.


236-238: Looks good with the explicit generic.

libs/ui-lib/lib/ocm/components/hosts/ModalDialogsContext.tsx (1)

105-108: PropsWithChildren update is fine.

libs/ui-lib/lib/common/components/clusterWizard/ClusterWizardStepHeader.tsx (1)

4-4: LGTM — explicit children typing is good.

libs/ui-lib/lib/ocm/components/clusters/ClusterToolbar.tsx (1)

9-12: Typing update looks good.

libs/ui-lib/lib/common/components/ui/GridGap.tsx (1)

7-8: LGTM — typing/formatting update only.

libs/ui-lib/lib/common/components/hosts/TableToolbar.tsx (1)

38-47: LGTM!

The React.PropsWithChildren wrapper is the correct approach for React 18 compatibility, where React.FC no longer implicitly includes children. The component properly destructures and renders children.

libs/ui-lib/lib/common/components/ui/formik/NumberInputField.tsx (1)

18-35: LGTM!

The React.PropsWithChildren wrapper correctly types the children prop that is destructured and rendered in the SplitItem at line 84. The forwardRef usage remains compatible with this typing pattern.

libs/ui-lib/lib/common/components/hosts/HostsTableDetailContext.tsx (1)

15-29: LGTM!

The React.PropsWithChildren wrapper is correctly applied to the context provider, enabling proper typing for the children prop that gets rendered inside the HostsTableDetailContext.Provider.

libs/ui-lib/lib/common/components/AddHosts/AddHostsContext.tsx (1)

13-23: LGTM!

The React.PropsWithChildren wrapper correctly types the context provider's children prop, maintaining the standard pattern used across the codebase for React 18 compatibility.

libs/ui-lib/lib/common/components/hosts/HostStatus.tsx (2)

186-207: LGTM!

The React.PropsWithChildren wrapper correctly types WithHostStatusPopover, which renders children inside the Button component at line 204.


231-243: LGTM!

The React.PropsWithChildren wrapper is correctly applied to HostStatus. The component uses children for conditional rendering logic (lines 282, 287), and this typing aligns with the HostStatusProps interface which doesn't explicitly include children.

libs/ui-lib/lib/cim/components/YamlPreview/YamlPreview.tsx (4)

1-4: LGTM on import updates.

The imports are well-organized: EditorDidMount and EditorWillMount types from react-monaco-editor, editor namespace from monaco-editor for theme typing, and useResizeObserver from @react-hook/resize-observer to replace react-measure.


17-33: Good addition of explicit typing for the theme.

Typing the theme as editor.IStandaloneThemeData improves type safety and IDE support.


41-60: Clean migration to ResizeObserver-based sizing.

The implementation correctly:

  • Types the lifecycle callbacks with EditorDidMount and EditorWillMount
  • Uses a ref to the container div for observation
  • Updates state on resize to drive the editor height

One minor note: the initial render will have editorHeight as undefined until the resize observer fires. This is expected and preferable to rendering with incorrect dimensions.


87-100: Conditional rendering prevents zero-height editor issues.

The !!editorHeight guard ensures the Monaco editor only renders once valid dimensions are available, avoiding layout thrashing. The wrapper div with height: '100%' and ref correctly captures the available space.

libs/ui-lib/lib/common/components/ui/formik/LabelField.tsx (4)

1-16: LGTM!

Imports are well-organized and appropriate for the refactored component using PatternFly's LabelGroup.


32-55: LGTM!

The handlers correctly implement immutable array updates and properly trigger Formik's touched/validation states.


57-101: LGTM!

The LabelGroup rendering is well-structured with proper edit/delete callbacks. The error message display issue from the previous review has been addressed.


144-157: LGTM!

The Button implementation is clean with proper accessibility attributes and inline styling.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

@openshift-ci openshift-ci bot added the lgtm Indicates that a PR is ready to be merged. label Jan 16, 2026
@openshift-ci
Copy link

openshift-ci bot commented Jan 16, 2026

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: jgyselov, rawagner

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-merge-bot openshift-merge-bot bot merged commit a0b51ec into openshift-assisted:master Jan 16, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. lgtm Indicates that a PR is ready to be merged. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants