Skip to content

CONSOLE-5103: Add networking extensions to Node views#235

Open
jeff-phillips-18 wants to merge 1 commit into
openshift:mainfrom
jeff-phillips-18:node-configuration-network-tab
Open

CONSOLE-5103: Add networking extensions to Node views#235
jeff-phillips-18 wants to merge 1 commit into
openshift:mainfrom
jeff-phillips-18:node-configuration-network-tab

Conversation

@jeff-phillips-18

@jeff-phillips-18 jeff-phillips-18 commented Jul 7, 2026

Copy link
Copy Markdown
Member

Closes CONSOLE-5103
Closes CONSOLE-4947

Summary

Adds a new Network tab to Node detail views that displays network topology and associated policies.

Changes:

  • New Network Tab - Adds "Network" sub-nav tab under Node → Configuration showing network topology visualization for individual nodes
  • NodeNetworkingPoliciesPanel - New side panel component displaying NodeNetworkConfigurationPolicies that apply to the selected node with formatted "Affects" column showing impacted interfaces
  • Node Topology View - Reuses existing topology visualization components with node-specific context, includes zoom controls and legend
  • Shared TopologyControlBar - Extracts control bar logic from cluster topology into reusable component
  • TopologySidebar - New sidebar for node topology showing interface and state details

Screen Shots:

image

Technical Details:

  • Filters policies by isPolicyAppliedInNode() to show only relevant policies for the node
  • Formats policy affects display showing bond/bridge port names (e.g., "bond0 (eth0, eth1)")
  • Stores topology node positions in localStorage for persistence

Testing:

  • Added unit tests for NodeNetworkingPoliciesPanel, NodeTopologyToolbar, and formatPolicyAffectsDisplay utility
  • Added utils.test.ts covering getCorrelatedEnactment function
  • Test coverage for empty states, sorting, and policy filtering

🤖 Generated with https://claude.com/claude-code

Summary by CodeRabbit

  • New Features

    • Added a new Network view for nodes, showing topology alongside networking policies.
    • Added a toolbar and sidebar experience for navigating node networking details.
    • Displayed node networking policies with readable interface impact summaries and links to full policy lists.
  • Bug Fixes

    • Improved handling of access-denied cases when node networking data can’t be viewed.
    • Updated search and navigation labels across supported languages for the new network screens.

@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Jul 7, 2026
@openshift-ci-robot

openshift-ci-robot commented Jul 7, 2026

Copy link
Copy Markdown

@jeff-phillips-18: This pull request references CONSOLE-5103 which is a valid jira issue.

Details

In response to this:

Closes CONSOLE-5103

Summary

Adds a new Network tab to Node detail views that displays network topology and associated policies.

Changes:

  • New Network Tab - Adds "Network" sub-nav tab under Node → Configuration showing network topology visualization for individual nodes
  • NodeNetworkingPoliciesPanel - New side panel component displaying NodeNetworkConfigurationPolicies that apply to the selected node with formatted "Affects" column showing impacted interfaces
  • Node Topology View - Reuses existing topology visualization components with node-specific context, includes zoom controls and legend
  • Shared TopologyControlBar - Extracts control bar logic from cluster topology into reusable component
  • TopologySidebar - New sidebar for node topology showing interface and state details

Screen Shots:

image

Technical Details:

  • Filters policies by isPolicyAppliedInNode() to show only relevant policies for the node
  • Formats policy affects display showing bond/bridge port names (e.g., "bond0 (eth0, eth1)")
  • Stores topology node positions in localStorage for persistence

Testing:

  • Added unit tests for NodeNetworkingPoliciesPanel, NodeTopologyToolbar, and formatPolicyAffectsDisplay utility
  • Added utils.test.ts covering getCorrelatedEnactment function
  • Test coverage for empty states, sorting, and policy filtering

🤖 Generated with https://claude.com/claude-code

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

openshift-ci Bot commented Jul 7, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: jeff-phillips-18
Once this PR has been reviewed and has the lgtm label, please assign sjd78 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

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown

Caution

Review failed

An error occurred during the review process. Please try again later.

Walkthrough

Adds a node network topology sub-navigation feature with a policies panel, extracts a reusable ControlBar component, exports an enactment correlation utility, adds a formatting helper for policy interface affects, normalizes import paths across topology components, and updates locale files, a forbidden-status constant, and jest config.

Changes

Node Topology Sub-Nav Feature

Layer / File(s) Summary
Shared constants and config
src/utils/constants.ts, jest.config.ts
Adds FORBIDDEN_STATUS = 403 constant and updates jest's transformIgnorePatterns to allow transforming @kubevirt-ui/* packages.
ControlBar extraction and import cleanup
src/utils/topology/components/TopologyControlBar/TopologyControlBar.tsx, src/views/nodenetworkconfiguration/Topology.tsx, src/utils/topology/utils/position.ts, src/utils/topology/components/CustomNode/CustomNode.tsx, src/utils/topology/components/TopologySidebar/*, src/utils/components/MultiSelect/MultiSelect.tsx, src/views/nodenetworkconfiguration/components/TopologyToolbar/TopologyToolbar.tsx
New ControlBar component wraps TopologyControlBar with zoom/fit/reset handlers; Topology.tsx now uses ControlBar and FORBIDDEN_STATUS; position.ts functions accept Controller; several files switch between relative and alias import paths.
Enactment/formatting utilities
src/utils/topology/utils/utils.ts, src/utils/topology/components/NodeNetworkingPoliciesPanel/utils/formatPolicyAffectsDisplay.ts, *.test.ts
getCorrelatedEnactment is now exported; new formatPolicyAffectsDisplay formats bond/bridge/ethernet interface summaries, both covered by new unit tests.
Node networking policies panel
src/utils/topology/components/NodeNetworkingPoliciesPanel/NodeNetworkingPoliciesPanel.tsx, *.test.tsx
Watches V1NodeNetworkConfigurationPolicy resources, filters/sorts those applying to a node, and renders loading/error/empty states plus a summary table with a "see all" link; tests cover these states.
Node topology view, toolbar, sidebar, page
src/views/nodeConfigurationNetworkPanel/**
NodeTopology watches node state/enactments and renders topology or access-denied UI; NodeTopologySidebar shows a drawer; NodeTopologyToolbar renders a "Network" title with navigation; NodeTopologyPage assembles the visualization controller, topology, and policies panel; includes SCSS and toolbar tests.
Manifest registration
src/views/nodeConfigurationNetworkPanel/manifest.ts, plugin-manifest.ts
Registers a console.node/sub-nav-tab extension for the new Network tab and wires it into the top-level plugin manifest.
Locale updates
locales/en/*.json, locales/es/*.json, locales/fr/*.json, locales/ja/*.json, locales/ko/*.json, locales/zh/*.json
Adds "Affects", "Network", policy panel messaging, node label search, and see-all navigation keys; removes obsolete "NodeNetworkState" key.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant NodeTopologyPage
  participant NodeTopology
  participant K8sAPI as useK8sWatchResource
  participant NodeNetworkingPoliciesPanel

  User->>NodeTopologyPage: Open Network sub-nav tab
  NodeTopologyPage->>NodeTopology: Render with visualization controller
  NodeTopology->>K8sAPI: Watch node network state and enactments
  K8sAPI-->>NodeTopology: Return state/enactments or forbidden error
  alt Forbidden
    NodeTopology-->>User: Render AccessDenied view
  else Loaded
    NodeTopology->>NodeTopology: transformDataToTopologyModel + controller.fromModel
    NodeTopology-->>User: Render TopologyView with sidebar/toolbar/ControlBar
  end
  NodeTopologyPage->>NodeNetworkingPoliciesPanel: Render with node
  NodeNetworkingPoliciesPanel->>K8sAPI: Watch NodeNetworkConfigurationPolicy list
  K8sAPI-->>NodeNetworkingPoliciesPanel: Return policies
  NodeNetworkingPoliciesPanel->>NodeNetworkingPoliciesPanel: Filter/sort policies applied to node
  NodeNetworkingPoliciesPanel-->>User: Render policy table or empty state
Loading
🚥 Pre-merge checks | ✅ 15
✅ Passed checks (15 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding networking-related extensions to node views.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Stable And Deterministic Test Names ✅ Passed All changed test titles are static strings; none include generated names, timestamps, UUIDs, node/namespace names, or other dynamic values.
Test Structure And Quality ✅ Passed The PR adds focused Jest/RTL unit tests, with afterEach cleanup and no cluster interactions or indefinite waits; the Ginkgo-only checklist isn’t applicable here.
Microshift Test Compatibility ✅ Passed PASS: The added tests are Jest/RTL unit tests, not Ginkgo e2e tests, and no MicroShift-unsupported APIs or guards are present.
Single Node Openshift (Sno) Test Compatibility ✅ Passed No Ginkgo e2e tests were added; the commit changes only TS/TSX/JSON/CSS files and zero .go files, so SNO-specific multi-node checks don’t apply.
Topology-Aware Scheduling Compatibility ✅ Passed PR only adds console UI/topology pages and locale strings; changed files contain no pod scheduling/manifests, nodeSelectors, affinity, tolerations, or replica logic.
Ote Binary Stdout Contract ✅ Passed No changed process-level code writes to stdout; scans found no fmt/console/klog/process.stdout usage or suite hooks in the touched files.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed No new Ginkgo e2e tests were added; the PR only adds TS unit tests and UI code, with no IPv4-only or external-connectivity assumptions found.
No-Weak-Crypto ✅ Passed No MD5/SHA1/DES/RC4/3DES/Blowfish/ECB, custom crypto, or secret/token comparisons were added in the touched node-topology code.
Container-Privileges ✅ Passed Changed files are frontend/locales only, and repo search found no privileged/hostPID/hostNetwork/hostIPC/allowPrivilegeEscalation/SYS_ADMIN/root settings.
No-Sensitive-Data-In-Logs ✅ Passed No console/logger calls or sensitive-data logging patterns were added in the changed node-networking files.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

Tools execution failed with the following error:

Failed to run tools: 13 INTERNAL: Received RST_STREAM with code 2 (Internal server error)


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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 5

Caution

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

⚠️ Outside diff range comments (1)
src/views/nodenetworkconfiguration/manifest.ts (1)

1-2: 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

Import the sub-nav-tab type before casting. EncodedExtension<NodeSubNavTab> uses an undeclared type here, which will fail TypeScript compilation. Import the matching SDK type or drop the generic if it isn’t needed.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/views/nodenetworkconfiguration/manifest.ts` around lines 1 - 2, The
manifest typing uses NodeSubNavTab in the EncodedExtension cast without
declaring that type, so TypeScript will fail. Update the imports in manifest.ts
to bring in the matching SDK type used by the sub-nav tab, or remove the generic
from EncodedExtension if it is unnecessary. Use the existing HrefNavItem,
RoutePage, and EncodedExtension imports as the reference point when fixing the
cast.
🧹 Nitpick comments (5)
src/views/nodenetworkconfiguration/utils/utils.ts (1)

220-227: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Return type doesn't account for undefined.

Array.prototype.find can return undefined, and the tests confirm this happens (toBeUndefined()), but the declared return type is V1beta1NodeNetworkConfigurationEnactment only. Now that this is exported as a public helper, consumers relying on the type signature could be misled into skipping undefined checks.

As per coding guidelines, "Type safety — strict is false in tsconfig, but new code should use explicit types."

♻️ Proposed fix
 export const getCorrelatedEnactment = (
   availableEnhancments: V1beta1NodeNetworkConfigurationEnactment[],
   nnsName: string,
-): V1beta1NodeNetworkConfigurationEnactment => {
+): V1beta1NodeNetworkConfigurationEnactment | undefined => {
   return availableEnhancments?.find((nnce) =>
     nnce.metadata?.ownerReferences?.some((ref) => ref.name === nnsName),
   );
 };
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/views/nodenetworkconfiguration/utils/utils.ts` around lines 220 - 227,
The exported helper getCorrelatedEnactment currently returns the result of
Array.prototype.find, which can be undefined, but its signature only declares
V1beta1NodeNetworkConfigurationEnactment. Update the return type to explicitly
include undefined so consumers of getCorrelatedEnactment handle the
missing-match case correctly, and keep the implementation as-is since the find
call already reflects that behavior.

Source: Coding guidelines

src/views/nodenetworkconfiguration/NodeTopologyPage.tsx (1)

40-43: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Selection navigation pushes a new history entry on every click.

navigate({ pathname, search }) defaults to push navigation, so every node selection in the topology adds a browser history entry. For a page centered on clicking through many nodes, this will make the back button step through selections instead of leaving the page, degrading UX.

♻️ Suggested fix
     visualization.addEventListener(SELECTION_EVENT, (id) => {
       const newParams = new URLSearchParams({ [SELECTED_ID_QUERY_PARAM]: id });
-      navigate({ pathname: pathnameRef.current, search: newParams.toString() });
+      navigate({ pathname: pathnameRef.current, search: newParams.toString() }, { replace: true });
     });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/views/nodenetworkconfiguration/NodeTopologyPage.tsx` around lines 40 -
43, The selection handler in NodeTopologyPage’s visualization.addEventListener
callback is using navigate with the default push behavior, which adds a history
entry for every node click. Update the navigate call to use replace behavior
when syncing the SELECTED_ID_QUERY_PARAM so node selections don’t pollute
browser history; keep the same pathnameRef.current and URLSearchParams flow, but
ensure repeated selections overwrite the current entry instead of pushing a new
one.
src/views/nodenetworkconfiguration/components/TopologyControlBar/TopologyControlBar.tsx (2)

15-41: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Memoize controlButtons to avoid rebuilding callbacks on every render.

createTopologyControlButtons(...) runs on every render of ControlBar, recreating all four callbacks even when controller hasn't changed. Consider wrapping in useMemo keyed on controller.

♻️ Proposed refactor
-const ControlBar: FC<ControlBarProps> = ({ controller }) => {
+const ControlBar: FC<ControlBarProps> = ({ controller }) => {
+  const controlButtons = useMemo(() => {
+    if (!controller) return null;
+    return createTopologyControlButtons({
+      ...defaultControlButtonsOptions,
+      zoomInCallback: action(() => {
+        const scale = controller.getGraph().getScale();
+        controller.getGraph().setScale(scale * 1.1);
+      }),
+      zoomOutCallback: action(() => {
+        const scale = controller.getGraph().getScale();
+        controller.getGraph().setScale(scale * 0.9);
+      }),
+      fitToScreenCallback: action(() => {
+        controller.getGraph().fit(40);
+      }),
+      resetViewCallback: action(() => {
+        controller.getGraph().reset();
+        controller.getGraph().layout();
+      }),
+    });
+  }, [controller]);
+
   if (!controller) {
     return null;
   }
-  return (
-    <TopologyControlBar
-      controlButtons={createTopologyControlButtons({
-        ...defaultControlButtonsOptions,
-        zoomInCallback: action(() => {
-          const scale = controller.getGraph().getScale();
-          controller.getGraph().setScale(scale * 1.1);
-        }),
-        zoomOutCallback: action(() => {
-          const scale = controller.getGraph().getScale();
-          controller.getGraph().setScale(scale * 0.9);
-        }),
-        fitToScreenCallback: action(() => {
-          controller.getGraph().fit(40);
-        }),
-        resetViewCallback: action(() => {
-          controller.getGraph().reset();
-          controller.getGraph().layout();
-        }),
-      })}
-    />
-  );
+  return <TopologyControlBar controlButtons={controlButtons} />;
 };
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/views/nodenetworkconfiguration/components/TopologyControlBar/TopologyControlBar.tsx`
around lines 15 - 41, The ControlBar component recreates controlButtons and its
action-wrapped callbacks on every render even when controller is unchanged.
Update ControlBar in TopologyControlBar.tsx to memoize the
createTopologyControlButtons call with useMemo, using controller as the
dependency, so the zoomInCallback, zoomOutCallback, fitToScreenCallback, and
resetViewCallback are not rebuilt unnecessarily.

1-44: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

File name doesn't match exported component.

File is TopologyControlBar.tsx but the default export is ControlBar. Consider renaming the file to ControlBar.tsx (or the component to TopologyControlBar) to match the convention. As per coding guidelines, File & directory naming specifies React components: PascalCase.tsx, implying filename should match the component name.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/views/nodenetworkconfiguration/components/TopologyControlBar/TopologyControlBar.tsx`
around lines 1 - 44, The exported React component name and filename are
inconsistent: this module default-exports ControlBar, but the file is named
TopologyControlBar.tsx. Rename either the file to match ControlBar or the
component to TopologyControlBar so the default export, component identifier, and
filename are aligned with the naming convention used in the
TopologyControlBar/ControlBar component.

Source: Coding guidelines

src/views/nodenetworkconfiguration/NodeTopology.tsx (1)

42-127: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Consider adding a post-mount re-fit effect like Topology.tsx.

Topology.tsx has a secondary effect using requestAnimationFrame to re-run fit(40) after mount, to correct scale once the container size stabilizes (e.g., navigating from another flow). NodeTopology.tsx omits this, so the initial fit may look off in the same scenario. Self-recoverable via the zoom controls, but worth aligning for consistency.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/views/nodenetworkconfiguration/NodeTopology.tsx` around lines 42 - 127,
Add the missing post-mount re-fit behavior to NodeTopology so the graph can
correct its scale after the container stabilizes, matching the pattern used in
Topology.tsx. In NodeTopology, introduce a secondary effect that runs after the
initial render/initialization, uses requestAnimationFrame to call
controller.getGraph().fit(40), and cleans up the frame handle on unmount. Keep
the existing modelInitialized logic in NodeTopology and make sure the new effect
is gated on controller and the topology being ready.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@src/views/nodenetworkconfiguration/components/NodeNetworkingPoliciesPanel/utils/formatPolicyAffectsDisplay.ts`:
- Around line 20-39: The bridge formatting logic in formatBridgeInterfaceAffects
only returns the first nested bond’s ports and drops any other bridge ports, so
update it to aggregate all bridge ports instead of using ports.find(...). Keep
the existing name resolution in resolveBondPortName, but combine plain port
names and nested LINK_AGGREGATION port names into one list for iface.name, then
return the full joined set; also update the related
formatPolicyAffectsDisplay.test.ts expectation to include eth0 alongside the
bonded ports.

In `@src/views/nodenetworkconfiguration/components/TopologySidebar/Drawer.tsx`:
- Around line 20-33: The conditional rendering in the Drawer component is
ordered incorrectly, causing a selected policy to fall through to
StateDetailsPage when its interface is not yet present. Update the logic in
Drawer (using selectedPolicy, selectedInterface, and selectedState from
useSelectedResources) so the selectedPolicy branch is checked before the
selectedState branch, ensuring PolicyDrawer renders for pending policies.

In `@src/views/nodenetworkconfiguration/NodeTopology.tsx`:
- Around line 76-96: The initial-fit logic in NodeTopology currently uses
modelInitialized as a one-time gate, so switching to a different
obj.metadata.name in the same tab skips restoreNodePositions and
controller.getGraph().fit(40) for the new node. Update the effect around
transformDataToTopologyModel and controller.fromModel to track the last rendered
node name instead of only a boolean ref, and reset the fit/restore gate whenever
obj.metadata.name changes so each node gets its own initial framing.
- Around line 91-95: The mismatch is in the restoreNodePositions helper
signature: useVisualizationController() returns Controller, but
restoreNodePositions currently expects Visualization even though it only calls
getGraph(). Update restoreNodePositions in NodeTopology.tsx to accept Controller
instead of Visualization, and keep the call site in the modelInitialized.current
block unchanged so the types align.

In `@src/views/nodenetworkconfiguration/NodeTopologyPage.tsx`:
- Around line 40-43: The SELECTION_EVENT handler in NodeTopologyPage is writing
the raw selected value into the query string, but `@patternfly/react-topology`
provides a string array. Update the
visualization.addEventListener(SELECTION_EVENT, ...) callback to extract the
active ID from the array, and when the selection is empty remove
SELECTED_ID_QUERY_PARAM instead of serializing the array directly. Keep the
change localized around navigate, pathnameRef, and SELECTED_ID_QUERY_PARAM.

---

Outside diff comments:
In `@src/views/nodenetworkconfiguration/manifest.ts`:
- Around line 1-2: The manifest typing uses NodeSubNavTab in the
EncodedExtension cast without declaring that type, so TypeScript will fail.
Update the imports in manifest.ts to bring in the matching SDK type used by the
sub-nav tab, or remove the generic from EncodedExtension if it is unnecessary.
Use the existing HrefNavItem, RoutePage, and EncodedExtension imports as the
reference point when fixing the cast.

---

Nitpick comments:
In
`@src/views/nodenetworkconfiguration/components/TopologyControlBar/TopologyControlBar.tsx`:
- Around line 15-41: The ControlBar component recreates controlButtons and its
action-wrapped callbacks on every render even when controller is unchanged.
Update ControlBar in TopologyControlBar.tsx to memoize the
createTopologyControlButtons call with useMemo, using controller as the
dependency, so the zoomInCallback, zoomOutCallback, fitToScreenCallback, and
resetViewCallback are not rebuilt unnecessarily.
- Around line 1-44: The exported React component name and filename are
inconsistent: this module default-exports ControlBar, but the file is named
TopologyControlBar.tsx. Rename either the file to match ControlBar or the
component to TopologyControlBar so the default export, component identifier, and
filename are aligned with the naming convention used in the
TopologyControlBar/ControlBar component.

In `@src/views/nodenetworkconfiguration/NodeTopology.tsx`:
- Around line 42-127: Add the missing post-mount re-fit behavior to NodeTopology
so the graph can correct its scale after the container stabilizes, matching the
pattern used in Topology.tsx. In NodeTopology, introduce a secondary effect that
runs after the initial render/initialization, uses requestAnimationFrame to call
controller.getGraph().fit(40), and cleans up the frame handle on unmount. Keep
the existing modelInitialized logic in NodeTopology and make sure the new effect
is gated on controller and the topology being ready.

In `@src/views/nodenetworkconfiguration/NodeTopologyPage.tsx`:
- Around line 40-43: The selection handler in NodeTopologyPage’s
visualization.addEventListener callback is using navigate with the default push
behavior, which adds a history entry for every node click. Update the navigate
call to use replace behavior when syncing the SELECTED_ID_QUERY_PARAM so node
selections don’t pollute browser history; keep the same pathnameRef.current and
URLSearchParams flow, but ensure repeated selections overwrite the current entry
instead of pushing a new one.

In `@src/views/nodenetworkconfiguration/utils/utils.ts`:
- Around line 220-227: The exported helper getCorrelatedEnactment currently
returns the result of Array.prototype.find, which can be undefined, but its
signature only declares V1beta1NodeNetworkConfigurationEnactment. Update the
return type to explicitly include undefined so consumers of
getCorrelatedEnactment handle the missing-match case correctly, and keep the
implementation as-is since the find call already reflects that behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: deeeb9d8-8852-4a85-a013-101ce5d1b5c9

📥 Commits

Reviewing files that changed from the base of the PR and between 19c58a7 and af3f3be.

📒 Files selected for processing (25)
  • jest.config.ts
  • locales/en/plugin__nmstate-console-plugin.json
  • locales/es/plugin__nmstate-console-plugin.json
  • locales/fr/plugin__nmstate-console-plugin.json
  • locales/ja/plugin__nmstate-console-plugin.json
  • locales/ko/plugin__nmstate-console-plugin.json
  • locales/zh/plugin__nmstate-console-plugin.json
  • src/views/nodenetworkconfiguration/NodeTopology.scss
  • src/views/nodenetworkconfiguration/NodeTopology.tsx
  • src/views/nodenetworkconfiguration/NodeTopologyPage.tsx
  • src/views/nodenetworkconfiguration/Topology.tsx
  • src/views/nodenetworkconfiguration/components/NodeNetworkingPoliciesPanel/NodeNetworkingPoliciesPanel.test.tsx
  • src/views/nodenetworkconfiguration/components/NodeNetworkingPoliciesPanel/NodeNetworkingPoliciesPanel.tsx
  • src/views/nodenetworkconfiguration/components/NodeNetworkingPoliciesPanel/utils/formatPolicyAffectsDisplay.test.ts
  • src/views/nodenetworkconfiguration/components/NodeNetworkingPoliciesPanel/utils/formatPolicyAffectsDisplay.ts
  • src/views/nodenetworkconfiguration/components/NodeTopologyToolbar/NodeTopologyToolbar.scss
  • src/views/nodenetworkconfiguration/components/NodeTopologyToolbar/NodeTopologyToolbar.test.tsx
  • src/views/nodenetworkconfiguration/components/NodeTopologyToolbar/NodeTopologyToolbar.tsx
  • src/views/nodenetworkconfiguration/components/TopologyControlBar/TopologyControlBar.tsx
  • src/views/nodenetworkconfiguration/components/TopologySidebar/Drawer.tsx
  • src/views/nodenetworkconfiguration/components/TopologySidebar/TopologySidebar.scss
  • src/views/nodenetworkconfiguration/components/TopologySidebar/TopologySidebar.tsx
  • src/views/nodenetworkconfiguration/manifest.ts
  • src/views/nodenetworkconfiguration/utils/utils.test.ts
  • src/views/nodenetworkconfiguration/utils/utils.ts

Comment thread src/views/nodenetworkconfiguration/components/TopologySidebar/Drawer.tsx Outdated
Comment thread src/views/nodenetworkconfiguration/NodeTopology.tsx Outdated
Comment thread src/views/nodenetworkconfiguration/NodeTopology.tsx Outdated
Comment thread src/views/nodeConfigurationNetworkPanel/NodeTopologyPage.tsx
@jeff-phillips-18

Copy link
Copy Markdown
Member Author

/test e2e-tests

@avivtur

avivtur commented Jul 8, 2026

Copy link
Copy Markdown

@pcbailey please review

@jeff-phillips-18 jeff-phillips-18 force-pushed the node-configuration-network-tab branch from af3f3be to 5262d28 Compare July 8, 2026 13:40

@pcbailey pcbailey left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hi, Jeff! I just had a few comments.

},
} as EncodedExtension<RoutePage>,
{
type: 'console.node/sub-nav-tab',

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Please move this code to a separate view directory named "node-topology-panel". This view is for the "Node network configuration" tab in the Networking section. Also, please use kebab-case for the view directory name. I plan to eventually go through and correct the others.

Could you also please create a "topology" directory in the "src/utils" directory and place any shared code there?

if (!enactmentsLoaded || enactmentsError || isEmpty(enactments)) {
return [];
}
const nodeEnactments = getCorrelatedEnactment(enactments, obj.metadata.name);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Please extract this to a variable and use the getName selector.

}
}, [controller, state, stateLoaded, stateError, availableEnactments, obj.metadata.name]);

if (stateError?.response?.status === 403)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Please extract 403 to a constant with a descriptive name. I can update any other references to point to it in a future PR.

@jeff-phillips-18 jeff-phillips-18 force-pushed the node-configuration-network-tab branch from 5262d28 to e008d09 Compare July 8, 2026 16:04
@jeff-phillips-18

Copy link
Copy Markdown
Member Author

/test e2e-tests

@openshift-ci

openshift-ci Bot commented Jul 8, 2026

Copy link
Copy Markdown

@jeff-phillips-18: all tests passed!

Full PR test history. Your PR dashboard.

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. I understand the commands that are listed here.

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.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants