Skip to content

Comments

NETOBSERV-2486: Add Network Observability Operator support#3351

Open
jpinsonneau wants to merge 6 commits intoopenshift-assisted:masterfrom
jpinsonneau:netobserv
Open

NETOBSERV-2486: Add Network Observability Operator support#3351
jpinsonneau wants to merge 6 commits intoopenshift-assisted:masterfrom
jpinsonneau:netobserv

Conversation

@jpinsonneau
Copy link

@jpinsonneau jpinsonneau commented Jan 7, 2026

Add Network Observability Operator UI support

Summary

This PR adds comprehensive UI support for the Network Observability Operator in the Assisted Installer UI. This includes operator selection, configuration form with property management, integration into the operator selection workflow, and proper TypeScript type definitions. The implementation enables users to configure the Network Observability Operator with custom properties like FlowCollector creation and eBPF sampling rates.

image

Key Features

  • Operator Selection: Network Observability operator available in the operator selection UI
  • Property Configuration: Dynamic form for configuring operator properties (createFlowCollector, sampling)
  • Operator Properties Form: Reusable component for managing operator-specific configurations
  • Documentation Links: Integration with operator documentation

Changes

New Components

OperatorPropertiesForm.tsx:

  • Comprehensive form component for managing operator properties
  • Supports multiple property types: boolean, string, integer, float
  • Dynamic form generation based on operator property definitions
  • Form validation and sanitization
  • Expandable sections for better UX
  • Handles property serialization/deserialization to/from JSON
  • Integrates with Formik for form state management

Operator Integration

  1. Operator Specs (libs/ui-lib/lib/common/components/operators/operatorSpecs.tsx):

    • Added Network Observability operator to the operator catalog
    • Configured with proper description, documentation links, and support level
    • Categorized appropriately in the operator list
  2. Operator Selection (libs/ui-lib/lib/ocm/components/clusterWizard/Operators.tsx):

    • Enhanced to support operator properties in form state
    • Updated getOperatorsInitialValues to extract and preserve operator properties from cluster
    • Modified handleSubmit to include operator properties when updating cluster
    • Added operatorProperties field to OperatorsValues type
  3. Operator Checkbox (libs/ui-lib/lib/ocm/components/clusterConfiguration/operators/OperatorCheckbox.tsx):

    • Enhanced to display operator properties form when operator is selected
    • Integrated OperatorPropertiesForm component
    • Conditional rendering based on operator selection state
  4. Operators Service (libs/ui-lib/lib/ocm/services/OperatorsService.tsx):

    • Updated to handle operator properties in API calls

API Integration

libs/ui-lib/lib/common/api/assisted-service/OperatorsAPI.ts:

  • Updated to handle operator properties in operator-related API calls

Tests

libs/ui-lib/lib/ocm/components/clusterWizard/OperatorsSelect.test.ts:

  • Updated tests to account for operator properties in form values
  • Added test cases for operator properties handling

User Experience

Operator Selection Flow

  1. User navigates to Operators step in cluster wizard
  2. Network Observability operator appears in the operator list
  3. User can select/deselect the operator via checkbox
  4. When selected, an expandable properties section appears below the checkbox
  5. User can configure:
    • Create FlowCollector: Toggle to automatically create FlowCollector resource
    • Sampling: Number input for eBPF agent sampling rate (default: 50)

Property Form Features

  • Dynamic Form Generation: Form fields generated based on operator property definitions from API
  • Type-Specific Inputs:
    • Boolean → Switch component
    • Integer → NumberInput component
    • String → TextInput component
  • Validation: Client-side validation with helpful error messages
  • Default Values: Pre-populated with operator-defined defaults
  • Expandable UI: Properties section can be collapsed/expanded for better UX

Testing

  • ✅ All 79 unit tests passing in 6 test files
  • ✅ TypeScript definitions compile without errors
  • ✅ Operator properties form component tested
assisted-ui.mp4

Summary by CodeRabbit

  • New Features

    • Network Observability operator added with UI entry, docs link, and configurable operator properties that load when the operator is enabled.
  • Chores

    • Validation checks extended for network observability; host status labels expanded to include unbound and reclaiming variants.
  • Tests

    • Operator-related tests updated to include operatorProperties in test data.

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

@openshift-ci openshift-ci bot requested review from LiorSoffer and celdrake January 7, 2026 11:31
@openshift-ci
Copy link

openshift-ci bot commented Jan 7, 2026

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: jpinsonneau
Once this PR has been reviewed and has the lgtm label, please assign rawagner for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found 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-ci
Copy link

openshift-ci bot commented Jan 7, 2026

Welcome @jpinsonneau! It looks like this is your first PR to openshift-assisted/assisted-installer-ui 🎉

@openshift-ci
Copy link

openshift-ci bot commented Jan 7, 2026

Hi @jpinsonneau. Thanks for your PR.

I'm waiting for a openshift-assisted member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Details

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 kubernetes-sigs/prow repository.

@openshift-ci openshift-ci bot added needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. labels Jan 7, 2026
@coderabbitai
Copy link

coderabbitai bot commented Jan 7, 2026

Warning

Rate limit exceeded

@jpinsonneau has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 0 minutes and 4 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between c3d3f19 and f11151a.

📒 Files selected for processing (1)
  • libs/ui-lib/lib/ocm/components/clusterConfiguration/operators/OperatorPropertiesForm.tsx
📝 Walkthrough

Walkthrough

Adds Network Observability operator support (constants, docs link, spec/description, API/service), UI to fetch and configure operator properties (new form + checkbox behavior), extends OperatorsValues to carry operatorProperties, updates tests, and adds unbound host status variants plus new network-observability validation IDs/types.

Changes

Cohort / File(s) Summary
Type Definitions & Validation
libs/types/assisted-installer-service.d.ts
Added Host.status unbound variants (insufficient-unbound, disabled-unbound, discovering-unbound, reclaiming, reclaiming-rebooting); added network-observability-requirements-satisfied and network-observability-host-requirements-satisfied to ClusterValidationId and HostValidationId; added NETWORK_OBSERVABILITY to FeatureSupportLevelId.
Constants & Docs Links
libs/ui-lib/lib/common/config/constants.ts, libs/ui-lib/lib/common/config/docs_links.ts
New OPERATOR_NAME_NETWORK_OBSERVABILITY constant; added validation label keys and failure hints; new getNetworkObservabilityLink(ocpVersion?).
Operator Descriptions & Specs
libs/ui-lib/lib/common/components/operators/operatorDescriptions.tsx, libs/ui-lib/lib/common/components/operators/operatorSpecs.tsx
New DESCRIPTION_NETWORK_OBSERVABILITY; added Network Observability OperatorSpec (key, title, featureId: "NETWORK_OBSERVABILITY", description, learn-more link, support-level integration).
API & Service Layer
libs/ui-lib/lib/common/api/assisted-service/OperatorsAPI.ts, libs/ui-lib/lib/ocm/services/OperatorsService.tsx
OperatorsAPI.getProperties(operatorName) added; OperatorsService.getOperatorProperties(operatorName) wrapper added; introduces OperatorProperties typing.
Types & Form Values
libs/ui-lib/lib/common/types/clusters.ts, libs/ui-lib/lib/ocm/components/clusterWizard/Operators.tsx
OperatorsValues extended with operatorProperties: Record<string,string>; initial values memoized; submit payload can include optional properties per operator.
Operator Property UI Components
libs/ui-lib/lib/ocm/components/clusterConfiguration/operators/OperatorCheckbox.tsx, libs/ui-lib/lib/ocm/components/clusterConfiguration/operators/OperatorPropertiesForm.tsx
OperatorCheckbox fetches properties when checked (loading/error handling) and renders OperatorPropertiesForm; new OperatorPropertiesForm renders expandable, type-aware inputs, sanitizes/serializes properties, and writes stringified JSON into form state.
Tests
libs/ui-lib/lib/ocm/components/clusterWizard/OperatorsSelect.test.ts
Test fixtures updated to include operatorProperties: {} in OperatorsValues (shape change only).

Sequence Diagram

sequenceDiagram
    autonumber
    participant User
    participant OperatorCheckbox
    participant OperatorsService
    participant OperatorsAPI
    participant Server
    participant OperatorPropertiesForm
    participant Formik

    Note over OperatorCheckbox,OperatorsService: Operator selection + properties fetch (new flow)
    User->>OperatorCheckbox: checks operator
    OperatorCheckbox->>OperatorCheckbox: set isChecked=true, show loader
    OperatorCheckbox->>OperatorsService: getOperatorProperties(name)
    OperatorsService->>OperatorsAPI: getProperties(name)
    OperatorsAPI->>Server: GET /v2/supported-operators/{name}
    Server-->>OperatorsAPI: 200 OperatorProperties (metadata)
    OperatorsAPI-->>OperatorsService: OperatorProperties
    OperatorsService-->>OperatorCheckbox: OperatorProperties
    OperatorCheckbox->>OperatorPropertiesForm: render with properties
    OperatorPropertiesForm->>OperatorPropertiesForm: sanitize/init defaults
    User->>OperatorPropertiesForm: edit property
    OperatorPropertiesForm->>Formik: set operatorProperties[name] = JSON.stringify(...)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

lgtm, approved

Suggested reviewers

  • celdrake
  • LiorSoffer
  • ammont82

Poem

🐰 I fetched properties with a hop and a cheer,
eBPF flow maps hum networks far and near,
Expand, tweak, save — JSON snug and bright,
Operators sing observability at night,
Hooray — a carrot for telemetry delight! 🥕✨

🚥 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 clearly and specifically describes the main change: adding Network Observability Operator support to the Assisted Installer UI.
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.


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.

@jpinsonneau jpinsonneau changed the title Add Network Observability Operator support NETOBSERV-2486: Add Network Observability Operator support Jan 7, 2026
@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Jan 7, 2026
@openshift-ci-robot
Copy link

openshift-ci-robot commented Jan 7, 2026

@jpinsonneau: This pull request references NETOBSERV-2486 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 spike to target the "4.22.0" version, but no target version was set.

Details

In response to this:

Add Network Observability Operator UI support

Summary

This PR adds comprehensive UI support for the Network Observability Operator in the Assisted Installer UI. This includes operator selection, configuration form with property management, integration into the operator selection workflow, and proper TypeScript type definitions. The implementation enables users to configure the Network Observability Operator with custom properties like FlowCollector creation and eBPF sampling rates.

image

Key Features

  • Operator Selection: Network Observability operator available in the operator selection UI
  • Property Configuration: Dynamic form for configuring operator properties (createFlowCollector, sampling)
  • Operator Properties Form: Reusable component for managing operator-specific configurations
  • Documentation Links: Integration with operator documentation

Changes

New Components

OperatorPropertiesForm.tsx:

  • Comprehensive form component for managing operator properties
  • Supports multiple property types: boolean, string, integer, float
  • Dynamic form generation based on operator property definitions
  • Form validation and sanitization
  • Expandable sections for better UX
  • Handles property serialization/deserialization to/from JSON
  • Integrates with Formik for form state management

Operator Integration

  1. Operator Specs (libs/ui-lib/lib/common/components/operators/operatorSpecs.tsx):
  • Added Network Observability operator to the operator catalog
  • Configured with proper description, documentation links, and support level
  • Categorized appropriately in the operator list
  1. Operator Selection (libs/ui-lib/lib/ocm/components/clusterWizard/Operators.tsx):
  • Enhanced to support operator properties in form state
  • Updated getOperatorsInitialValues to extract and preserve operator properties from cluster
  • Modified handleSubmit to include operator properties when updating cluster
  • Added operatorProperties field to OperatorsValues type
  1. Operator Checkbox (libs/ui-lib/lib/ocm/components/clusterConfiguration/operators/OperatorCheckbox.tsx):
  • Enhanced to display operator properties form when operator is selected
  • Integrated OperatorPropertiesForm component
  • Conditional rendering based on operator selection state
  1. Operators Service (libs/ui-lib/lib/ocm/services/OperatorsService.tsx):
  • Updated to handle operator properties in API calls

API Integration

libs/ui-lib/lib/common/api/assisted-service/OperatorsAPI.ts:

  • Updated to handle operator properties in operator-related API calls

Tests

libs/ui-lib/lib/ocm/components/clusterWizard/OperatorsSelect.test.ts:

  • Updated tests to account for operator properties in form values
  • Added test cases for operator properties handling

User Experience

Operator Selection Flow

  1. User navigates to Operators step in cluster wizard
  2. Network Observability operator appears in the operator list
  3. User can select/deselect the operator via checkbox
  4. When selected, an expandable properties section appears below the checkbox
  5. User can configure:
  • Create FlowCollector: Toggle to automatically create FlowCollector resource
  • Sampling: Number input for eBPF agent sampling rate (default: 50)

Property Form Features

  • Dynamic Form Generation: Form fields generated based on operator property definitions from API
  • Type-Specific Inputs:
  • Boolean → Switch component
  • Integer → NumberInput component
  • String → TextInput component
  • Validation: Client-side validation with helpful error messages
  • Default Values: Pre-populated with operator-defined defaults
  • Expandable UI: Properties section can be collapsed/expanded for better UX

Testing

  • ✅ All 79 unit tests passing in 6 test files
  • ✅ TypeScript definitions compile without errors
  • ✅ Operator properties form component tested
assisted-ui.mp4

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.

@openshift-ci-robot
Copy link

openshift-ci-robot commented Jan 7, 2026

@jpinsonneau: This pull request references NETOBSERV-2486 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 spike to target the "4.22.0" version, but no target version was set.

Details

In response to this:

Add Network Observability Operator UI support

Summary

This PR adds comprehensive UI support for the Network Observability Operator in the Assisted Installer UI. This includes operator selection, configuration form with property management, integration into the operator selection workflow, and proper TypeScript type definitions. The implementation enables users to configure the Network Observability Operator with custom properties like FlowCollector creation and eBPF sampling rates.

image

Key Features

  • Operator Selection: Network Observability operator available in the operator selection UI
  • Property Configuration: Dynamic form for configuring operator properties (createFlowCollector, sampling)
  • Operator Properties Form: Reusable component for managing operator-specific configurations
  • Documentation Links: Integration with operator documentation

Changes

New Components

OperatorPropertiesForm.tsx:

  • Comprehensive form component for managing operator properties
  • Supports multiple property types: boolean, string, integer, float
  • Dynamic form generation based on operator property definitions
  • Form validation and sanitization
  • Expandable sections for better UX
  • Handles property serialization/deserialization to/from JSON
  • Integrates with Formik for form state management

Operator Integration

  1. Operator Specs (libs/ui-lib/lib/common/components/operators/operatorSpecs.tsx):
  • Added Network Observability operator to the operator catalog
  • Configured with proper description, documentation links, and support level
  • Categorized appropriately in the operator list
  1. Operator Selection (libs/ui-lib/lib/ocm/components/clusterWizard/Operators.tsx):
  • Enhanced to support operator properties in form state
  • Updated getOperatorsInitialValues to extract and preserve operator properties from cluster
  • Modified handleSubmit to include operator properties when updating cluster
  • Added operatorProperties field to OperatorsValues type
  1. Operator Checkbox (libs/ui-lib/lib/ocm/components/clusterConfiguration/operators/OperatorCheckbox.tsx):
  • Enhanced to display operator properties form when operator is selected
  • Integrated OperatorPropertiesForm component
  • Conditional rendering based on operator selection state
  1. Operators Service (libs/ui-lib/lib/ocm/services/OperatorsService.tsx):
  • Updated to handle operator properties in API calls

API Integration

libs/ui-lib/lib/common/api/assisted-service/OperatorsAPI.ts:

  • Updated to handle operator properties in operator-related API calls

Tests

libs/ui-lib/lib/ocm/components/clusterWizard/OperatorsSelect.test.ts:

  • Updated tests to account for operator properties in form values
  • Added test cases for operator properties handling

User Experience

Operator Selection Flow

  1. User navigates to Operators step in cluster wizard
  2. Network Observability operator appears in the operator list
  3. User can select/deselect the operator via checkbox
  4. When selected, an expandable properties section appears below the checkbox
  5. User can configure:
  • Create FlowCollector: Toggle to automatically create FlowCollector resource
  • Sampling: Number input for eBPF agent sampling rate (default: 50)

Property Form Features

  • Dynamic Form Generation: Form fields generated based on operator property definitions from API
  • Type-Specific Inputs:
  • Boolean → Switch component
  • Integer → NumberInput component
  • String → TextInput component
  • Validation: Client-side validation with helpful error messages
  • Default Values: Pre-populated with operator-defined defaults
  • Expandable UI: Properties section can be collapsed/expanded for better UX

Testing

  • ✅ All 79 unit tests passing in 6 test files
  • ✅ TypeScript definitions compile without errors
  • ✅ Operator properties form component tested
assisted-ui.mp4

Summary by CodeRabbit

Release Notes

  • New Features

  • Network Observability operator now available, providing network flow monitoring and observability capabilities

  • Added operator properties configuration interface for customizing operator-specific settings during cluster setup

  • Extended validation and host status tracking for improved cluster state management

  • Documentation

  • Network Observability documentation links added to the UI

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

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.

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

🧹 Nitpick comments (6)
libs/ui-lib/lib/ocm/components/clusterConfiguration/operators/OperatorCheckbox.tsx (1)

172-192: Properties are not refetched when operator is unchecked and re-checked.

When an operator is unchecked and then checked again, operatorProperties still contains the previously fetched data, so the fetch won't trigger. This may be intentional (caching), but if properties can change server-side, consider clearing operatorProperties when the operator is unchecked.

Additionally, consider adding a cleanup function to handle unmount during pending requests:

♻️ Optional: Add request cancellation
   React.useEffect(() => {
+    let cancelled = false;
     if (isChecked && operatorProperties.length === 0 && !propertiesLoading) {
       setPropertiesLoading(true);
       OperatorsService.getOperatorProperties(operatorId)
         .then((properties) => {
-          setOperatorProperties(properties);
+          if (!cancelled) {
+            setOperatorProperties(properties);
+          }
         })
         .catch((error) => {
-          handleApiError(error, () =>
-            addAlert({
-              title: 'Failed to fetch operator properties',
-              message: getApiErrorMessage(error),
-            }),
-          );
+          if (!cancelled) {
+            handleApiError(error, () =>
+              addAlert({
+                title: 'Failed to fetch operator properties',
+                message: getApiErrorMessage(error),
+              }),
+            );
+          }
         })
         .finally(() => {
-          setPropertiesLoading(false);
+          if (!cancelled) {
+            setPropertiesLoading(false);
+          }
         });
     }
+    return () => {
+      cancelled = true;
+    };
   }, [isChecked, operatorId, operatorProperties.length, propertiesLoading, addAlert]);
libs/ui-lib/lib/ocm/components/clusterConfiguration/operators/OperatorPropertiesForm.tsx (5)

141-167: Potential infinite loop risk in initialization useEffect.

The useEffect at line 141 calls setFieldValue('operatorProperties', ...) which updates values.operatorProperties. However, values.operatorProperties is also in the dependency array (line 167). This could potentially trigger re-renders, though the guard condition on line 142 should prevent an infinite loop.

Consider extracting the initialization check to a ref to make the intent clearer:

♻️ Suggested improvement
+  const initializedRef = React.useRef(false);
+
   React.useEffect(() => {
-    if (!values.operatorProperties || !values.operatorProperties[operatorName]) {
+    if (!initializedRef.current && (!values.operatorProperties || !values.operatorProperties[operatorName])) {
+      initializedRef.current = true;
       const defaults: Record<string, unknown> = {};
       // ... rest of initialization
     }
-  }, [operatorName, properties, setFieldValue, values.operatorProperties]);
+  }, [operatorName, properties, setFieldValue, values.operatorProperties]);

275-297: Consider extracting the NumberInput value computation.

The IIFE inside the value prop is complex and harder to read. Consider extracting it to a helper or computing it in the component body.

♻️ Suggested refactor
+  const getNumberValue = (
+    currentValue: unknown,
+    defaultValue: unknown
+  ): number => {
+    if (typeof currentValue === 'number') return currentValue;
+    if (typeof currentValue === 'string') {
+      const parsed = parseInt(currentValue, 10);
+      if (!isNaN(parsed)) return parsed;
+    }
+    if (typeof defaultValue === 'number') return defaultValue;
+    if (typeof defaultValue === 'string') {
+      const parsed = parseInt(defaultValue, 10);
+      if (!isNaN(parsed)) return parsed;
+    }
+    return 0;
+  };

   // In the JSX:
   <NumberInput
     id={fieldId}
-    value={(() => {
-      // ... IIFE logic
-    })()}
+    value={getNumberValue(currentValue, defaultValue)}
     // ...
   />

232-237: Minor: onToggle callback can be simplified.

♻️ Minor simplification
     <ExpandableSection
       toggleText={`Configure ${operatorName} properties`}
-      onToggle={() => setIsExpanded(!isExpanded)}
+      onToggle={(_event, expanded) => setIsExpanded(expanded)}
       isExpanded={isExpanded}
       data-testid={`operator-properties-${operatorId}`}
     >

This uses the expanded state from the callback rather than toggling based on current state, which is slightly more reliable.


146-148: Use the correct type definition or properly transform the API response to match the type definition.

The code imports OperatorProperty from the camelCase type definition but accesses both snake_case and camelCase properties via as any. This mismatch suggests the API response format differs from the imported type. Either import from the auto-generated SDK types that use snake_case properties (which match the OpenAPI spec), or ensure the type definition includes both formats. The current workaround at lines 146-147 and 248-249 bypasses TypeScript safety unnecessarily.


326-338: Simplify TextInput onChange handler to remove unnecessary type checking.

PatternFly 6.2.2's TextInput onChange callback signature is (event: React.FormEvent<HTMLInputElement>, value: string) => void. The second parameter is already the string value. The complex type checking for event objects is unnecessary and inconsistent with all other TextInput usages in the codebase (e.g., ClusterEventsToolbar.tsx, MultiSelectField.tsx, RichInputField.tsx), which directly use the value parameter.

Suggested simplification
                    onChange={(_, value) => {
                      // Extract value from event object if needed
                      // PatternFly TextInput onChange can pass either a string or an event object
                      let stringValue = '';
                      if (value && typeof value === 'object' && 'currentTarget' in value) {
                        const event = value as React.FormEvent<HTMLInputElement>;
                        stringValue = event.currentTarget.value;
                      } else if (typeof value === 'string') {
                        stringValue = value;
                      } else {
                        stringValue = String(value ?? '');
                      }
                      updateProperty(property.name || '', stringValue);
                    }}
+                    onChange={(_, value) => updateProperty(property.name || '', value)}
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d47ab5f and 486a1ae.

📒 Files selected for processing (12)
  • libs/types/assisted-installer-service.d.ts
  • libs/ui-lib/lib/common/api/assisted-service/OperatorsAPI.ts
  • libs/ui-lib/lib/common/components/operators/operatorDescriptions.tsx
  • libs/ui-lib/lib/common/components/operators/operatorSpecs.tsx
  • libs/ui-lib/lib/common/config/constants.ts
  • libs/ui-lib/lib/common/config/docs_links.ts
  • libs/ui-lib/lib/common/types/clusters.ts
  • libs/ui-lib/lib/ocm/components/clusterConfiguration/operators/OperatorCheckbox.tsx
  • libs/ui-lib/lib/ocm/components/clusterConfiguration/operators/OperatorPropertiesForm.tsx
  • libs/ui-lib/lib/ocm/components/clusterWizard/Operators.tsx
  • libs/ui-lib/lib/ocm/components/clusterWizard/OperatorsSelect.test.ts
  • libs/ui-lib/lib/ocm/services/OperatorsService.tsx
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2025-08-11T06:07:38.056Z
Learnt from: ammont82
Repo: openshift-assisted/assisted-installer-ui PR: 3101
File: libs/ui-lib/lib/common/config/docs_links.ts:203-221
Timestamp: 2025-08-11T06:07:38.056Z
Learning: The MetalLB, OADP, Cluster Observability, and NUMA Resources operators in the virtualization bundle don't require version fallback logic in their documentation link functions (getMetalLbLink, getOadpLink, getClusterObservabilityLink, getNumaResourcesLink) in libs/ui-lib/lib/common/config/docs_links.ts, unlike some other operators like LSO and NVIDIA GPU.

Applied to files:

  • libs/ui-lib/lib/common/config/docs_links.ts
  • libs/ui-lib/lib/common/components/operators/operatorDescriptions.tsx
  • libs/ui-lib/lib/common/components/operators/operatorSpecs.tsx
  • libs/ui-lib/lib/common/config/constants.ts
📚 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/components/clusterConfiguration/operators/OperatorCheckbox.tsx
  • libs/ui-lib/lib/common/components/operators/operatorSpecs.tsx
  • libs/ui-lib/lib/common/config/constants.ts
📚 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/clusterConfiguration/operators/OperatorCheckbox.tsx
  • libs/ui-lib/lib/ocm/components/clusterWizard/OperatorsSelect.test.ts
  • libs/types/assisted-installer-service.d.ts
🧬 Code graph analysis (5)
libs/ui-lib/lib/common/api/assisted-service/OperatorsAPI.ts (1)
libs/types/assisted-installer-service.d.ts (1)
  • OperatorProperties (2391-2391)
libs/ui-lib/lib/ocm/components/clusterWizard/Operators.tsx (1)
libs/ui-lib/lib/common/selectors/clusterSelectors.ts (1)
  • selectOlmOperators (40-44)
libs/ui-lib/lib/ocm/services/OperatorsService.tsx (1)
libs/types/assisted-installer-service.d.ts (1)
  • OperatorProperties (2391-2391)
libs/ui-lib/lib/common/components/operators/operatorSpecs.tsx (3)
libs/ui-lib/lib/common/config/constants.ts (1)
  • OPERATOR_NAME_NETWORK_OBSERVABILITY (353-353)
libs/ui-lib/lib/common/components/operators/operatorDescriptions.tsx (1)
  • DESCRIPTION_NETWORK_OBSERVABILITY (78-79)
libs/ui-lib/lib/common/config/docs_links.ts (1)
  • getNetworkObservabilityLink (241-244)
libs/ui-lib/lib/common/config/constants.ts (1)
libs/types/assisted-installer-service.d.ts (1)
  • ClusterValidationId (643-693)
🔇 Additional comments (19)
libs/types/assisted-installer-service.d.ts (3)

1108-1109: LGTM - Feature support level addition.

The NETWORK_OBSERVABILITY feature support level ID follows the established naming pattern and is correctly placed.


1174-1202: LGTM - Host status union expansion.

The new unbound host statuses (insufficient-unbound, disabled-unbound, discovering-unbound, reclaiming, reclaiming-rebooting) are correctly added and consistent with the HostRegistrationResponse.status definition at lines 1381-1409.


691-693: This duplication is intentional and follows the established pattern in the codebase. The results show that most -requirements-satisfied validations appear in both ClusterValidationId and HostValidationId, including similar validations like node-feature-discovery-requirements-satisfied, nvidia-gpu-requirements-satisfied, openshift-logging-requirements-satisfied, and others. The presence of network-observability-host-requirements-satisfied in both types aligns with this systematic design where cluster-level and host-level validations coexist for feature requirements.

Likely an incorrect or invalid review comment.

libs/ui-lib/lib/common/types/clusters.ts (1)

61-65: LGTM - OperatorsValues type extension.

The operatorProperties field with type Record<string, string> is appropriate for storing JSON-serialized operator configuration by operator name. The inline comment provides helpful context.

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

77-79: LGTM - Network Observability description.

The description accurately reflects the operator's functionality and follows the established pattern for other operator descriptions in this file.

libs/ui-lib/lib/ocm/services/OperatorsService.tsx (1)

10-13: LGTM - Service method addition.

The getOperatorProperties method follows the same pattern as the existing getSupportedOperators method. Error handling is delegated to the caller, which is consistent with the service layer design.

libs/ui-lib/lib/ocm/components/clusterWizard/OperatorsSelect.test.ts (1)

49-54: LGTM - Test data structure updated.

All test cases correctly include the new operatorProperties: {} field to match the updated OperatorsValues type. The empty object is appropriate since these tests focus on operator selection counting logic, not properties handling.

libs/ui-lib/lib/common/api/assisted-service/OperatorsAPI.ts (1)

13-17: LGTM - API method with proper URL encoding.

Good implementation with encodeURIComponent(operatorName) to safely handle operator names in the URL path. The method follows the established pattern and is properly typed.

libs/ui-lib/lib/common/config/docs_links.ts (1)

240-244: LGTM - Documentation link function follows established pattern.

The getNetworkObservabilityLink function correctly implements the documentation link pattern consistent with other operators that don't require version-specific fallback logic (MetalLB, OADP, Cluster Observability, NUMA Resources). The URL structure and version handling via getDocsOpenshiftVersion are correct.

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

354-366: LGTM! Network Observability operator spec follows established patterns.

The new operator entry is consistent with other operators in the Network category. It correctly uses the version-aware documentation link function and integrates with the feature support level system.

libs/ui-lib/lib/common/config/constants.ts (4)

353-353: LGTM! Operator constant follows naming conventions.

The constant follows the established OPERATOR_NAME_ prefix pattern with kebab-case value.


153-154: LGTM! Host validation labels and hints added correctly.

Both network-observability validation IDs are properly added to host validation mappings, consistent with the type definitions.

Also applies to: 228-229


266-267: LGTM! Cluster validation label added.

The cluster validation label is correctly added. The type assertion is appropriate for the partial mapping pattern used here.


355-366: Consider whether Network Observability should be added to singleClusterOperators.

The singleClusterOperators array (lines 355-366) lists operators with specific single-cluster behavior. Other observability operators like cluster-observability, loki, and openshift-logging are included. Verify if network-observability should also be added to this list based on its intended behavior.

libs/ui-lib/lib/ocm/components/clusterConfiguration/operators/OperatorCheckbox.tsx (1)

238-245: LGTM! Conditional rendering of properties form.

The form is correctly shown only when the operator is checked and has properties. The disabled state is properly derived from viewer mode or disabled reason.

libs/ui-lib/lib/ocm/components/clusterWizard/Operators.tsx (3)

32-45: LGTM! Operator properties extraction is well-implemented.

The function correctly extracts properties from OLM operators and handles undefined values safely.

Minor nit: Line 44 has a redundant || {} fallback since operatorProperties is already initialized as {} on line 33.


98-104: LGTM! Submit handler correctly includes operator properties.

The properties are properly included in the payload only when they exist for the operator.


124-130: Verify memoization behavior with cluster object.

The useMemo dependency on cluster may cause unnecessary recalculations if the cluster object reference changes even when relevant data (monitoredOperators) hasn't changed. Consider if this impacts performance in practice.

libs/ui-lib/lib/ocm/components/clusterConfiguration/operators/OperatorPropertiesForm.tsx (1)

25-101: Extensive sanitization suggests defensive coding against past issues.

The sanitizeValue and cleanProperties helpers contain extensive defensive checks against objects, functions, and event objects. While this is safe, the detailed comments about event object properties (isDefaultPrevented, nativeEvent, etc.) suggest this was added to fix a specific bug where event objects were accidentally stored.

If the root cause has been addressed elsewhere (e.g., in the onChange handlers), this sanitization layer may be more defensive than necessary. However, keeping it as a safety net is reasonable given the JSON serialization requirements.

@openshift-ci-robot
Copy link

openshift-ci-robot commented Jan 7, 2026

@jpinsonneau: This pull request references NETOBSERV-2486 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 spike to target the "4.22.0" version, but no target version was set.

Details

In response to this:

Add Network Observability Operator UI support

Summary

This PR adds comprehensive UI support for the Network Observability Operator in the Assisted Installer UI. This includes operator selection, configuration form with property management, integration into the operator selection workflow, and proper TypeScript type definitions. The implementation enables users to configure the Network Observability Operator with custom properties like FlowCollector creation and eBPF sampling rates.

image

Key Features

  • Operator Selection: Network Observability operator available in the operator selection UI
  • Property Configuration: Dynamic form for configuring operator properties (createFlowCollector, sampling)
  • Operator Properties Form: Reusable component for managing operator-specific configurations
  • Documentation Links: Integration with operator documentation

Changes

New Components

OperatorPropertiesForm.tsx:

  • Comprehensive form component for managing operator properties
  • Supports multiple property types: boolean, string, integer, float
  • Dynamic form generation based on operator property definitions
  • Form validation and sanitization
  • Expandable sections for better UX
  • Handles property serialization/deserialization to/from JSON
  • Integrates with Formik for form state management

Operator Integration

  1. Operator Specs (libs/ui-lib/lib/common/components/operators/operatorSpecs.tsx):
  • Added Network Observability operator to the operator catalog
  • Configured with proper description, documentation links, and support level
  • Categorized appropriately in the operator list
  1. Operator Selection (libs/ui-lib/lib/ocm/components/clusterWizard/Operators.tsx):
  • Enhanced to support operator properties in form state
  • Updated getOperatorsInitialValues to extract and preserve operator properties from cluster
  • Modified handleSubmit to include operator properties when updating cluster
  • Added operatorProperties field to OperatorsValues type
  1. Operator Checkbox (libs/ui-lib/lib/ocm/components/clusterConfiguration/operators/OperatorCheckbox.tsx):
  • Enhanced to display operator properties form when operator is selected
  • Integrated OperatorPropertiesForm component
  • Conditional rendering based on operator selection state
  1. Operators Service (libs/ui-lib/lib/ocm/services/OperatorsService.tsx):
  • Updated to handle operator properties in API calls

API Integration

libs/ui-lib/lib/common/api/assisted-service/OperatorsAPI.ts:

  • Updated to handle operator properties in operator-related API calls

Tests

libs/ui-lib/lib/ocm/components/clusterWizard/OperatorsSelect.test.ts:

  • Updated tests to account for operator properties in form values
  • Added test cases for operator properties handling

User Experience

Operator Selection Flow

  1. User navigates to Operators step in cluster wizard
  2. Network Observability operator appears in the operator list
  3. User can select/deselect the operator via checkbox
  4. When selected, an expandable properties section appears below the checkbox
  5. User can configure:
  • Create FlowCollector: Toggle to automatically create FlowCollector resource
  • Sampling: Number input for eBPF agent sampling rate (default: 50)

Property Form Features

  • Dynamic Form Generation: Form fields generated based on operator property definitions from API
  • Type-Specific Inputs:
  • Boolean → Switch component
  • Integer → NumberInput component
  • String → TextInput component
  • Validation: Client-side validation with helpful error messages
  • Default Values: Pre-populated with operator-defined defaults
  • Expandable UI: Properties section can be collapsed/expanded for better UX

Testing

  • ✅ All 79 unit tests passing in 6 test files
  • ✅ TypeScript definitions compile without errors
  • ✅ Operator properties form component tested
assisted-ui.mp4

Summary by CodeRabbit

  • New Features

  • Network Observability operator added with UI, docs link, and operator properties configuration during cluster setup.

  • Chores

  • Added operator properties to operator payloads and form state; extended validation IDs and host status variants to support observability flows.

  • Tests

  • Updated operator-related tests to include operatorProperties field.

  • Documentation

  • Added Network Observability documentation links in the UI.

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

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.

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: 1

🤖 Fix all issues with AI agents
In
@libs/ui-lib/lib/ocm/components/clusterConfiguration/operators/OperatorPropertiesForm.tsx:
- Around line 103-115: The normalizeOperatorProperty function currently uses an
unsafe cast (prop as any) to access snake_case API fields; reconcile the
conflicting OperatorProperty definitions (the hand-written type in
libs/types/assisted-installer-service.d.ts vs the SDK model in
libs/sdks/.../operator-property.ts) so the code can rely on a single correct
shape, then remove the as any cast in normalizeOperatorProperty and update its
parameter type to accept the actual API shape (or create a distinct
ApiOperatorProperty type), and finally implement/route through a small
deserialization layer that maps api fields (data_type, default_value) to
internal camelCase fields (dataType, defaultValue) in normalizeOperatorProperty
without bypassing TypeScript checks.
🧹 Nitpick comments (3)
libs/ui-lib/lib/ocm/components/clusterConfiguration/operators/OperatorCheckbox.tsx (2)

172-205: Consider using a more robust condition than operatorProperties.length === 0.

The useEffect depends on operatorProperties.length, which means if the array identity changes but the length remains 0, the effect won't re-run. This could cause issues if a fetch fails silently or returns an empty array.

Consider tracking the fetch status with a dedicated flag (e.g., propertiesFetched) instead of relying on array length.

♻️ Proposed refactor
- const [operatorProperties, setOperatorProperties] = React.useState<OperatorProperties>([]);
- const [propertiesLoading, setPropertiesLoading] = React.useState(false);
+ const [operatorProperties, setOperatorProperties] = React.useState<OperatorProperties>([]);
+ const [propertiesLoading, setPropertiesLoading] = React.useState(false);
+ const [propertiesFetched, setPropertiesFetched] = React.useState(false);

  // Fetch operator properties when operator is selected
  React.useEffect(() => {
-   if (isChecked && operatorProperties.length === 0 && !propertiesLoading) {
+   if (isChecked && !propertiesFetched && !propertiesLoading) {
      setPropertiesLoading(true);
      let cancelled = false;
      OperatorsService.getOperatorProperties(operatorId)
        .then((properties) => {
          if (!cancelled) {
            setOperatorProperties(properties);
+           setPropertiesFetched(true);
          }
        })
        .catch((error) => {
          if (!cancelled) {
            handleApiError(error, () =>
              addAlert({
                title: 'Failed to fetch operator properties',
                message: getApiErrorMessage(error),
              }),
            );
          }
        })
        .finally(() => {
          if (!cancelled) {
            setPropertiesLoading(false);
          }
        });
      return () => {
        cancelled = true;
      };
    } else if (!isChecked) {
      // Clear properties when operator is unchecked to allow refetch on re-check
      setOperatorProperties([]);
+     setPropertiesFetched(false);
    }
- }, [isChecked, operatorId, operatorProperties.length, propertiesLoading, addAlert]);
+ }, [isChecked, operatorId, propertiesFetched, propertiesLoading, addAlert]);

251-258: Minor: operatorName prop receives the same value as operatorId.

Line 254 passes operatorName={operatorId}, which duplicates the value from operatorId. If the component doesn't need a separate name, consider using operatorId internally or deriving the display name from operator specs.

libs/ui-lib/lib/ocm/components/clusterConfiguration/operators/OperatorPropertiesForm.tsx (1)

25-62: Observation: Extensive defensive programming suggests potential architectural concern.

The sanitizeValue function includes detailed guards against event objects, DOM elements, and functions. While this implementation is correct, the need for such extensive sanitization may indicate that callers are passing unsanitized values (e.g., raw events instead of event.target.value).

Consider whether the root cause can be addressed by ensuring values are properly extracted at the call site (e.g., in updateProperty callers).

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 486a1ae and a4661cf.

📒 Files selected for processing (2)
  • libs/ui-lib/lib/ocm/components/clusterConfiguration/operators/OperatorCheckbox.tsx
  • libs/ui-lib/lib/ocm/components/clusterConfiguration/operators/OperatorPropertiesForm.tsx
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: ammont82
Repo: openshift-assisted/assisted-installer-ui PR: 3101
File: libs/ui-lib/lib/common/config/docs_links.ts:203-221
Timestamp: 2025-08-11T06:07:38.056Z
Learning: The MetalLB, OADP, Cluster Observability, and NUMA Resources operators in the virtualization bundle don't require version fallback logic in their documentation link functions (getMetalLbLink, getOadpLink, getClusterObservabilityLink, getNumaResourcesLink) in libs/ui-lib/lib/common/config/docs_links.ts, unlike some other operators like LSO and NVIDIA GPU.
📚 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/clusterConfiguration/operators/OperatorCheckbox.tsx
🧬 Code graph analysis (1)
libs/ui-lib/lib/ocm/components/clusterConfiguration/operators/OperatorPropertiesForm.tsx (3)
libs/types/assisted-installer-service.d.ts (1)
  • OperatorProperty (2392-2417)
libs/ui-lib/lib/common/types/clusters.ts (1)
  • OperatorsValues (61-65)
libs/ui-lib/lib/common/components/ui/formik/utils.ts (1)
  • getFieldId (15-18)
🔇 Additional comments (3)
libs/ui-lib/lib/ocm/components/clusterConfiguration/operators/OperatorCheckbox.tsx (1)

19-19: LGTM!

The new imports and state setup correctly support the operator properties fetching workflow.

Also applies to: 26-26, 34-36, 136-136, 143-144

libs/ui-lib/lib/ocm/components/clusterConfiguration/operators/OperatorPropertiesForm.tsx (2)

277-361: LGTM!

The form rendering logic correctly handles different property types (boolean, integer, string) with appropriate PatternFly components and includes proper disabled state handling and test IDs.


336-341: Review comment is incorrect. PatternFly React v6's NumberInput.onChange receives only (event: React.FormEvent<HTMLInputElement>) => void, not a second value parameter. The current implementation at lines 336–341 correctly accesses event.target.value and is consistent with the project's own NumberInputField wrapper component, which uses the same pattern.

No changes needed.

Likely an incorrect or invalid review comment.

@openshift-ci-robot
Copy link

openshift-ci-robot commented Jan 7, 2026

@jpinsonneau: This pull request references NETOBSERV-2486 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 spike to target the "4.22.0" version, but no target version was set.

Details

In response to this:

Add Network Observability Operator UI support

Summary

This PR adds comprehensive UI support for the Network Observability Operator in the Assisted Installer UI. This includes operator selection, configuration form with property management, integration into the operator selection workflow, and proper TypeScript type definitions. The implementation enables users to configure the Network Observability Operator with custom properties like FlowCollector creation and eBPF sampling rates.

image

Key Features

  • Operator Selection: Network Observability operator available in the operator selection UI
  • Property Configuration: Dynamic form for configuring operator properties (createFlowCollector, sampling)
  • Operator Properties Form: Reusable component for managing operator-specific configurations
  • Documentation Links: Integration with operator documentation

Changes

New Components

OperatorPropertiesForm.tsx:

  • Comprehensive form component for managing operator properties
  • Supports multiple property types: boolean, string, integer, float
  • Dynamic form generation based on operator property definitions
  • Form validation and sanitization
  • Expandable sections for better UX
  • Handles property serialization/deserialization to/from JSON
  • Integrates with Formik for form state management

Operator Integration

  1. Operator Specs (libs/ui-lib/lib/common/components/operators/operatorSpecs.tsx):
  • Added Network Observability operator to the operator catalog
  • Configured with proper description, documentation links, and support level
  • Categorized appropriately in the operator list
  1. Operator Selection (libs/ui-lib/lib/ocm/components/clusterWizard/Operators.tsx):
  • Enhanced to support operator properties in form state
  • Updated getOperatorsInitialValues to extract and preserve operator properties from cluster
  • Modified handleSubmit to include operator properties when updating cluster
  • Added operatorProperties field to OperatorsValues type
  1. Operator Checkbox (libs/ui-lib/lib/ocm/components/clusterConfiguration/operators/OperatorCheckbox.tsx):
  • Enhanced to display operator properties form when operator is selected
  • Integrated OperatorPropertiesForm component
  • Conditional rendering based on operator selection state
  1. Operators Service (libs/ui-lib/lib/ocm/services/OperatorsService.tsx):
  • Updated to handle operator properties in API calls

API Integration

libs/ui-lib/lib/common/api/assisted-service/OperatorsAPI.ts:

  • Updated to handle operator properties in operator-related API calls

Tests

libs/ui-lib/lib/ocm/components/clusterWizard/OperatorsSelect.test.ts:

  • Updated tests to account for operator properties in form values
  • Added test cases for operator properties handling

User Experience

Operator Selection Flow

  1. User navigates to Operators step in cluster wizard
  2. Network Observability operator appears in the operator list
  3. User can select/deselect the operator via checkbox
  4. When selected, an expandable properties section appears below the checkbox
  5. User can configure:
  • Create FlowCollector: Toggle to automatically create FlowCollector resource
  • Sampling: Number input for eBPF agent sampling rate (default: 50)

Property Form Features

  • Dynamic Form Generation: Form fields generated based on operator property definitions from API
  • Type-Specific Inputs:
  • Boolean → Switch component
  • Integer → NumberInput component
  • String → TextInput component
  • Validation: Client-side validation with helpful error messages
  • Default Values: Pre-populated with operator-defined defaults
  • Expandable UI: Properties section can be collapsed/expanded for better UX

Testing

  • ✅ All 79 unit tests passing in 6 test files
  • ✅ TypeScript definitions compile without errors
  • ✅ Operator properties form component tested
assisted-ui.mp4

Summary by CodeRabbit

  • New Features

  • Network Observability operator added with UI, docs link, and configurable operator properties during cluster setup.

  • Chores

  • Validation checks extended for network observability; host status variants expanded to represent unbound/reclaiming states.

  • Tests

  • Operator-related tests updated to include operatorProperties in test data.

  • Documentation

  • Added Network Observability documentation link in the UI.

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

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.

@openshift-ci-robot
Copy link

openshift-ci-robot commented Jan 7, 2026

@jpinsonneau: This pull request references NETOBSERV-2486 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 spike to target the "4.22.0" version, but no target version was set.

Details

In response to this:

Add Network Observability Operator UI support

Summary

This PR adds comprehensive UI support for the Network Observability Operator in the Assisted Installer UI. This includes operator selection, configuration form with property management, integration into the operator selection workflow, and proper TypeScript type definitions. The implementation enables users to configure the Network Observability Operator with custom properties like FlowCollector creation and eBPF sampling rates.

image

Key Features

  • Operator Selection: Network Observability operator available in the operator selection UI
  • Property Configuration: Dynamic form for configuring operator properties (createFlowCollector, sampling)
  • Operator Properties Form: Reusable component for managing operator-specific configurations
  • Documentation Links: Integration with operator documentation

Changes

New Components

OperatorPropertiesForm.tsx:

  • Comprehensive form component for managing operator properties
  • Supports multiple property types: boolean, string, integer, float
  • Dynamic form generation based on operator property definitions
  • Form validation and sanitization
  • Expandable sections for better UX
  • Handles property serialization/deserialization to/from JSON
  • Integrates with Formik for form state management

Operator Integration

  1. Operator Specs (libs/ui-lib/lib/common/components/operators/operatorSpecs.tsx):
  • Added Network Observability operator to the operator catalog
  • Configured with proper description, documentation links, and support level
  • Categorized appropriately in the operator list
  1. Operator Selection (libs/ui-lib/lib/ocm/components/clusterWizard/Operators.tsx):
  • Enhanced to support operator properties in form state
  • Updated getOperatorsInitialValues to extract and preserve operator properties from cluster
  • Modified handleSubmit to include operator properties when updating cluster
  • Added operatorProperties field to OperatorsValues type
  1. Operator Checkbox (libs/ui-lib/lib/ocm/components/clusterConfiguration/operators/OperatorCheckbox.tsx):
  • Enhanced to display operator properties form when operator is selected
  • Integrated OperatorPropertiesForm component
  • Conditional rendering based on operator selection state
  1. Operators Service (libs/ui-lib/lib/ocm/services/OperatorsService.tsx):
  • Updated to handle operator properties in API calls

API Integration

libs/ui-lib/lib/common/api/assisted-service/OperatorsAPI.ts:

  • Updated to handle operator properties in operator-related API calls

Tests

libs/ui-lib/lib/ocm/components/clusterWizard/OperatorsSelect.test.ts:

  • Updated tests to account for operator properties in form values
  • Added test cases for operator properties handling

User Experience

Operator Selection Flow

  1. User navigates to Operators step in cluster wizard
  2. Network Observability operator appears in the operator list
  3. User can select/deselect the operator via checkbox
  4. When selected, an expandable properties section appears below the checkbox
  5. User can configure:
  • Create FlowCollector: Toggle to automatically create FlowCollector resource
  • Sampling: Number input for eBPF agent sampling rate (default: 50)

Property Form Features

  • Dynamic Form Generation: Form fields generated based on operator property definitions from API
  • Type-Specific Inputs:
  • Boolean → Switch component
  • Integer → NumberInput component
  • String → TextInput component
  • Validation: Client-side validation with helpful error messages
  • Default Values: Pre-populated with operator-defined defaults
  • Expandable UI: Properties section can be collapsed/expanded for better UX

Testing

  • ✅ All 79 unit tests passing in 6 test files
  • ✅ TypeScript definitions compile without errors
  • ✅ Operator properties form component tested
assisted-ui.mp4

Summary by CodeRabbit

  • New Features

  • Network Observability operator added with UI entry, docs link, and in-setup configurable operator properties that load when the operator is enabled.

  • Chores

  • Validation checks extended for network observability; host status options expanded to cover unbound and reclaiming variants.

  • Tests

  • Operator-related tests updated to include operatorProperties in test data.

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

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.

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

🧹 Nitpick comments (3)
libs/ui-lib/lib/ocm/components/clusterConfiguration/operators/OperatorPropertiesForm.tsx (3)

92-129: Consider reducing duplication between cleanProperties and updateProperty.

Both functions iterate through properties and filter out non-primitives with similar logic (lines 97-120 vs. 259-281). Since currentProperties is already cleaned in the memo (line 204), the defensive re-checks in updateProperty may be redundant—or intentionally guarding against race conditions.

If the defensive re-sanitization is necessary, consider extracting the shared filtering logic into a reusable helper to reduce maintenance overhead.

♻️ Example refactor to share filtering logic
+// Shared helper to filter and sanitize a properties object
+const filterToSerializableProperties = (
+  props: Record<string, unknown>
+): Record<string, string | number | boolean> => {
+  const filtered: Record<string, string | number | boolean> = {};
+  for (const key in props) {
+    if (Object.prototype.hasOwnProperty.call(props, key) && typeof key === 'string') {
+      const value = props[key];
+      if (typeof value === 'function') continue;
+      if (typeof value === 'object' && value !== null) continue;
+      filtered[key] = sanitizeValue(value);
+    }
+  }
+  return filtered;
+};
+
 const cleanProperties = (props: Record<string, unknown>): Record<string, string | number | boolean> => {
-  const cleaned: Record<string, string | number | boolean> = {};
   try {
-    for (const [key, value] of Object.entries(props)) {
-      if (typeof key !== 'string') continue;
-      if (typeof value === 'function') continue;
-      if (typeof value === 'object' && value !== null) continue;
-      const sanitized = sanitizeValue(value);
-      cleaned[key] = sanitized;
-    }
+    const cleaned = filterToSerializableProperties(props);
     JSON.stringify(cleaned);
+    return cleaned;
   } catch (error) {
     console.warn('Failed to clean properties:', error);
     return {};
   }
-  return cleaned;
 };

 // In updateProperty:
-  const newProperties: Record<string, string | number | boolean> = {};
-  for (const key in currentProperties) {
-    if (Object.prototype.hasOwnProperty.call(currentProperties, key) && typeof key === 'string') {
-      const existingValue = currentProperties[key];
-      if (typeof existingValue === 'function') continue;
-      if (typeof existingValue === 'object' && existingValue !== null) continue;
-      newProperties[key] = sanitizeValue(existingValue);
-    }
-  }
+  const newProperties = filterToSerializableProperties(currentProperties);
   newProperties[propertyName] = sanitizedValue;

Also applies to: 249-306


218-247: Initialization logic works correctly for typical use, minor edge case to note.

The initializationRef prevents re-initialization after the first render, which is appropriate for the main use case (operator checked → component mounts → defaults initialized → operator unchecked → component unmounts → operator checked again → component remounts with fresh ref).

However, there's an edge case: if values.operatorProperties[operatorId] is cleared by an external action while the component remains mounted, re-initialization won't occur because initializationRef.current stays true (line 220). This seems unlikely in practice but worth noting for future maintenance.


353-379: Consider bounds for NumberInput based on property metadata.

The onMinus handler prevents negative values with Math.max(0, numValue - 1) (line 362), but onPlus has no upper limit (line 369). While this asymmetry might be intentional (e.g., sampling rates can be any positive integer), consider whether the API could provide optional min/max values in the property metadata to enforce consistent bounds on both ends.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 98e26de and 2daf49f.

📒 Files selected for processing (2)
  • libs/ui-lib/lib/ocm/components/clusterConfiguration/operators/OperatorCheckbox.tsx
  • libs/ui-lib/lib/ocm/components/clusterConfiguration/operators/OperatorPropertiesForm.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • libs/ui-lib/lib/ocm/components/clusterConfiguration/operators/OperatorCheckbox.tsx
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: ammont82
Repo: openshift-assisted/assisted-installer-ui PR: 3101
File: libs/ui-lib/lib/common/config/docs_links.ts:203-221
Timestamp: 2025-08-11T06:07:38.056Z
Learning: The MetalLB, OADP, Cluster Observability, and NUMA Resources operators in the virtualization bundle don't require version fallback logic in their documentation link functions (getMetalLbLink, getOadpLink, getClusterObservabilityLink, getNumaResourcesLink) in libs/ui-lib/lib/common/config/docs_links.ts, unlike some other operators like LSO and NVIDIA GPU.
📚 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/clusterConfiguration/operators/OperatorPropertiesForm.tsx
📚 Learning: 2025-09-02T08:03:57.204Z
Learnt from: jgyselov
Repo: openshift-assisted/assisted-installer-ui PR: 3151
File: libs/ui-lib/lib/cim/components/ClusterDeployment/constants.ts:25-25
Timestamp: 2025-09-02T08:03:57.204Z
Learning: In the openshift-assisted/assisted-installer-ui repository, non-English translations are handled separately from the main development process. When adding new translation keys to English locale files, it's expected that non-English locale files (es, fr, ja, ko, zh) may not immediately contain the corresponding translations, as these are managed through a different workflow.

Applied to files:

  • libs/ui-lib/lib/ocm/components/clusterConfiguration/operators/OperatorPropertiesForm.tsx
📚 Learning: 2025-10-19T17:22:52.502Z
Learnt from: linoyaslan
Repo: openshift-assisted/assisted-installer-ui PR: 3190
File: libs/ui-lib/lib/ocm/components/clusterConfiguration/networkConfiguration/networkConfigurationValidation.ts:69-69
Timestamp: 2025-10-19T17:22:52.502Z
Learning: CIM UI changes in the repository openshift-assisted/assisted-installer-ui (e.g., files under libs/ui-lib/lib/cim/) are handled separately by the CIM team and should be tracked via separate issues rather than being included in PRs for other UI components.

Applied to files:

  • libs/ui-lib/lib/ocm/components/clusterConfiguration/operators/OperatorPropertiesForm.tsx
🧬 Code graph analysis (1)
libs/ui-lib/lib/ocm/components/clusterConfiguration/operators/OperatorPropertiesForm.tsx (4)
libs/types/assisted-installer-service.d.ts (1)
  • OperatorProperty (2392-2417)
libs/ui-lib/lib/ocm/services/InfraEnvIdsCacheService.ts (1)
  • key (32-35)
libs/ui-lib/lib/common/types/clusters.ts (1)
  • OperatorsValues (61-65)
libs/ui-lib/lib/common/components/ui/formik/utils.ts (1)
  • getFieldId (15-18)
🔇 Additional comments (3)
libs/ui-lib/lib/ocm/components/clusterConfiguration/operators/OperatorPropertiesForm.tsx (3)

18-151: Type safety improvements look excellent.

The distinct type definitions (ApiOperatorProperty for snake_case API responses, NormalizedOperatorProperty for internal camelCase) and the normalizeOperatorProperty deserialization layer effectively address the previous review's type safety concerns. The targeted type assertions (as ApiOperatorProperty, as OperatorProperty) are a significant improvement over the previous as any cast, and the fallback logic handles both API contract and axios-case-converter scenarios cleanly.


47-129: Defensive sanitization approach is appropriate and well-documented.

The extensive primitive-only checks in sanitizeValue and cleanProperties are justified by the JSON serialization requirements explained in the comments. The explicit rejection of functions, event objects, and DOM elements (with detailed comments referencing specific properties like isDefaultPrevented, nativeEvent, etc.) suggests this guards against real-world edge cases.


344-352: Input handlers correctly match PatternFly 6 API signatures.

The Switch and TextInput onChange handlers properly destructure the PatternFly callback parameters (event and value/checked) and pass only primitives to updateProperty. This aligns with the defensive sanitization strategy and prevents event objects from polluting the state.

Also applies to: 380-388

@openshift-ci-robot
Copy link

openshift-ci-robot commented Jan 7, 2026

@jpinsonneau: This pull request references NETOBSERV-2486 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 spike to target the "4.22.0" version, but no target version was set.

Details

In response to this:

Add Network Observability Operator UI support

Summary

This PR adds comprehensive UI support for the Network Observability Operator in the Assisted Installer UI. This includes operator selection, configuration form with property management, integration into the operator selection workflow, and proper TypeScript type definitions. The implementation enables users to configure the Network Observability Operator with custom properties like FlowCollector creation and eBPF sampling rates.

image

Key Features

  • Operator Selection: Network Observability operator available in the operator selection UI
  • Property Configuration: Dynamic form for configuring operator properties (createFlowCollector, sampling)
  • Operator Properties Form: Reusable component for managing operator-specific configurations
  • Documentation Links: Integration with operator documentation

Changes

New Components

OperatorPropertiesForm.tsx:

  • Comprehensive form component for managing operator properties
  • Supports multiple property types: boolean, string, integer, float
  • Dynamic form generation based on operator property definitions
  • Form validation and sanitization
  • Expandable sections for better UX
  • Handles property serialization/deserialization to/from JSON
  • Integrates with Formik for form state management

Operator Integration

  1. Operator Specs (libs/ui-lib/lib/common/components/operators/operatorSpecs.tsx):
  • Added Network Observability operator to the operator catalog
  • Configured with proper description, documentation links, and support level
  • Categorized appropriately in the operator list
  1. Operator Selection (libs/ui-lib/lib/ocm/components/clusterWizard/Operators.tsx):
  • Enhanced to support operator properties in form state
  • Updated getOperatorsInitialValues to extract and preserve operator properties from cluster
  • Modified handleSubmit to include operator properties when updating cluster
  • Added operatorProperties field to OperatorsValues type
  1. Operator Checkbox (libs/ui-lib/lib/ocm/components/clusterConfiguration/operators/OperatorCheckbox.tsx):
  • Enhanced to display operator properties form when operator is selected
  • Integrated OperatorPropertiesForm component
  • Conditional rendering based on operator selection state
  1. Operators Service (libs/ui-lib/lib/ocm/services/OperatorsService.tsx):
  • Updated to handle operator properties in API calls

API Integration

libs/ui-lib/lib/common/api/assisted-service/OperatorsAPI.ts:

  • Updated to handle operator properties in operator-related API calls

Tests

libs/ui-lib/lib/ocm/components/clusterWizard/OperatorsSelect.test.ts:

  • Updated tests to account for operator properties in form values
  • Added test cases for operator properties handling

User Experience

Operator Selection Flow

  1. User navigates to Operators step in cluster wizard
  2. Network Observability operator appears in the operator list
  3. User can select/deselect the operator via checkbox
  4. When selected, an expandable properties section appears below the checkbox
  5. User can configure:
  • Create FlowCollector: Toggle to automatically create FlowCollector resource
  • Sampling: Number input for eBPF agent sampling rate (default: 50)

Property Form Features

  • Dynamic Form Generation: Form fields generated based on operator property definitions from API
  • Type-Specific Inputs:
  • Boolean → Switch component
  • Integer → NumberInput component
  • String → TextInput component
  • Validation: Client-side validation with helpful error messages
  • Default Values: Pre-populated with operator-defined defaults
  • Expandable UI: Properties section can be collapsed/expanded for better UX

Testing

  • ✅ All 79 unit tests passing in 6 test files
  • ✅ TypeScript definitions compile without errors
  • ✅ Operator properties form component tested
assisted-ui.mp4

Summary by CodeRabbit

  • New Features

  • Network Observability operator added with UI entry, docs link, and configurable operator properties that load when the operator is enabled.

  • Chores

  • Validation checks extended for network observability; host status labels expanded to include unbound and reclaiming variants.

  • Tests

  • Operator-related tests updated to include operatorProperties in test data.

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

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.

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

🧹 Nitpick comments (1)
libs/ui-lib/lib/ocm/components/clusterConfiguration/operators/OperatorPropertiesForm.tsx (1)

344-376: Consider consolidating NumberInput value computation logic.

The value prop uses computeNumberInputValue (line 347), but the onMinus and onPlus handlers duplicate similar parsing logic inline (lines 349-352, 359-362). For consistency and DRY, consider extracting the inline logic to reuse computeNumberInputValue or creating a shared helper.

The hardcoded minimum of 0 and lack of maximum (lines 353-365) are appropriately documented with comments suggesting future enhancement when API adds min/max metadata.

♻️ Potential refactor to consolidate logic
 <NumberInput
   id={fieldId}
   value={computeNumberInputValue(currentValue, defaultValue)}
   onMinus={() => {
-    const numValue =
-      typeof currentValue === 'number'
-        ? currentValue
-        : parseInt(String(currentValue ?? defaultValue ?? 0), 10);
+    const numValue = computeNumberInputValue(currentValue, defaultValue);
     updateProperty(property.name || '', Math.max(0, numValue - 1));
   }}
   onPlus={() => {
-    const numValue =
-      typeof currentValue === 'number'
-        ? currentValue
-        : parseInt(String(currentValue ?? defaultValue ?? 0), 10);
+    const numValue = computeNumberInputValue(currentValue, defaultValue);
     updateProperty(property.name || '', numValue + 1);
   }}
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2daf49f and c3d3f19.

📒 Files selected for processing (1)
  • libs/ui-lib/lib/ocm/components/clusterConfiguration/operators/OperatorPropertiesForm.tsx
🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
Learnt from: ammont82
Repo: openshift-assisted/assisted-installer-ui PR: 3101
File: libs/ui-lib/lib/common/config/docs_links.ts:203-221
Timestamp: 2025-08-11T06:07:38.056Z
Learning: The MetalLB, OADP, Cluster Observability, and NUMA Resources operators in the virtualization bundle don't require version fallback logic in their documentation link functions (getMetalLbLink, getOadpLink, getClusterObservabilityLink, getNumaResourcesLink) in libs/ui-lib/lib/common/config/docs_links.ts, unlike some other operators like LSO and NVIDIA GPU.
📚 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/components/clusterConfiguration/operators/OperatorPropertiesForm.tsx
📚 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/clusterConfiguration/operators/OperatorPropertiesForm.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/ocm/components/clusterConfiguration/operators/OperatorPropertiesForm.tsx
📚 Learning: 2025-09-02T08:03:57.204Z
Learnt from: jgyselov
Repo: openshift-assisted/assisted-installer-ui PR: 3151
File: libs/ui-lib/lib/cim/components/ClusterDeployment/constants.ts:25-25
Timestamp: 2025-09-02T08:03:57.204Z
Learning: In the openshift-assisted/assisted-installer-ui repository, non-English translations are handled separately from the main development process. When adding new translation keys to English locale files, it's expected that non-English locale files (es, fr, ja, ko, zh) may not immediately contain the corresponding translations, as these are managed through a different workflow.

Applied to files:

  • libs/ui-lib/lib/ocm/components/clusterConfiguration/operators/OperatorPropertiesForm.tsx
📚 Learning: 2025-10-19T17:22:52.502Z
Learnt from: linoyaslan
Repo: openshift-assisted/assisted-installer-ui PR: 3190
File: libs/ui-lib/lib/ocm/components/clusterConfiguration/networkConfiguration/networkConfigurationValidation.ts:69-69
Timestamp: 2025-10-19T17:22:52.502Z
Learning: CIM UI changes in the repository openshift-assisted/assisted-installer-ui (e.g., files under libs/ui-lib/lib/cim/) are handled separately by the CIM team and should be tracked via separate issues rather than being included in PRs for other UI components.

Applied to files:

  • libs/ui-lib/lib/ocm/components/clusterConfiguration/operators/OperatorPropertiesForm.tsx
🔇 Additional comments (7)
libs/ui-lib/lib/ocm/components/clusterConfiguration/operators/OperatorPropertiesForm.tsx (7)

18-45: LGTM: Well-designed type architecture.

The separation between ApiOperatorProperty (API contract with snake_case) and NormalizedOperatorProperty (internal camelCase) provides clear type boundaries. The component props accepting a union of both types offers flexibility for different transformation scenarios (raw API vs. axios-case-converter), and the documentation clearly explains the intent.


47-137: LGTM: Robust sanitization layer.

The defensive sanitization functions (sanitizeValue, filterToSerializableProperties, cleanProperties) provide strong guarantees for JSON serialization. The extensive type checks and error handling are well-justified by the comments and prevent runtime failures from corrupted state or unexpected input types.


139-187: LGTM: Clean deserialization layer.

The normalizeOperatorProperty function properly handles both API contract (snake_case) and axios-transformed (camelCase) formats with clear preference for the API format. The computeNumberInputValue helper provides consistent number parsing with sensible fallbacks.


226-261: Initialization logic is sound with documented tradeoff.

The initializationRef prevents re-initialization on re-renders, which is the correct behavior for the typical mount/unmount cycle. The edge case comment (lines 227-232) transparently documents the limitation where external clearing of operatorProperties[operatorId] while the component remains mounted won't trigger re-initialization. This tradeoff is acceptable given the unlikely scenario and the complexity that full dependency tracking would introduce.


263-297: LGTM: Robust update handler with excellent error recovery.

The updateProperty function implements defense-in-depth: sanitizes input, re-filters the base state, verifies serializability, and provides a minimal fallback if stringify fails. The outer try-catch prevents state corruption. This defensive approach is appropriate for maintaining JSON-serializable form state.


303-343: LGTM: Clean, accessible rendering logic.

The expandable section with proper FormGroup structure, helper text, and data-testid attributes provides good accessibility and testability. The Switch component for boolean properties correctly passes the checked state to updateProperty.


377-393: LGTM: TextInput and overall structure are well-implemented.

The TextInput for string properties and the overall StackItem mapping provide a clean, extensible structure. The data-testid attributes enable reliable testing, and the early return (lines 299-301) for empty properties is appropriate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. 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