Skip to content

CONSOLE-5012: Migrate remaining modals to useOverlay pattern#15990

Merged
openshift-merge-bot[bot] merged 2 commits intoopenshift:mainfrom
rhamilto:CONSOLE-5012-6
Feb 12, 2026
Merged

CONSOLE-5012: Migrate remaining modals to useOverlay pattern#15990
openshift-merge-bot[bot] merged 2 commits intoopenshift:mainfrom
rhamilto:CONSOLE-5012-6

Conversation

@rhamilto
Copy link
Member

@rhamilto rhamilto commented Feb 4, 2026

Summary

Migrates several modals from the deprecated createModalLauncher pattern to the modern useOverlay/OverlayComponent pattern for better accessibility and consistency. Also consolidates delete modal implementations.

Migrated modals:

  • Labels and Pod Selector modals
  • Annotations modal
  • PubSub modal (with accessibility-safe pattern for non-React contexts)
  • Alert Routing modal
  • Column Management modal
  • Delete modal consolidation (removed DeleteOverlay, unified on DeleteModalOverlay)

Key changes:

  • Created OverlayComponent wrappers for all migrated modals
  • Exported lazy-loaded overlay components from modals/index.ts
  • Updated all usages to call launchModal() with useOverlay() hook
  • Added SyncPubSubModalLauncher for topology connector accessibility
  • Maintained user settings HOC compatibility in Column Management modal
  • Removed deprecated DeleteOverlay component
  • Updated OLM and Metal3 plugins to use DeleteModalOverlay
  • Standardized variable naming: const launchModal = useOverlay() throughout

The PubSub modal uses a module-level reference synced via React Context to support non-React topology connectors while maintaining proper accessibility through the OverlayProvider.

All modals follow consistent naming: *ModalOverlay and Lazy*ModalOverlay

Files modified:

Core modal migrations:

  • public/components/modals/labels-modal.tsx - Labels and Pod Selector modals
  • public/components/modals/tags.tsx - Annotations modal
  • public/components/modals/alert-routing-modal.tsx - Alert Routing modal
  • public/components/modals/column-management-modal.tsx - Column Management modal
  • public/components/modals/index.ts - Lazy-loaded exports
  • packages/knative-plugin/src/components/pub-sub/PubSubController.tsx - PubSub modal
  • packages/knative-plugin/src/components/pub-sub/PubSubModalLauncher.ts - PubSub launcher

Delete modal consolidation:

  • public/components/modals/delete-modal.tsx - Removed DeleteOverlay, kept DeleteModalOverlay
  • packages/operator-lifecycle-manager/src/actions/useDefaultOperandActions.ts - OLM operand delete
  • packages/operator-lifecycle-manager/src/actions/useOperatorActions.ts - OLM CSV delete
  • packages/metal3-plugin/src/components/baremetal-hosts/host-actions-provider.ts - Metal3 host delete

Usage updates:

  • packages/console-app/src/actions/hooks/useCommonActions.ts - Common actions for labels/annotations
  • packages/console-app/src/components/data-view/ConsoleDataView.tsx - Column management
  • public/components/filter-toolbar.tsx - Column management
  • public/components/monitoring/alertmanager/alertmanager-config.tsx - Alert routing
  • packages/topology/src/components/graph-view/Topology.tsx - PubSub launcher sync

Related PRs:

Test plan

  • Verify Labels modal opens correctly from resource actions
  • Verify Annotations modal opens correctly from resource actions
  • Verify PubSub modal opens correctly from topology connectors
  • Verify Alert Routing modal opens correctly from Alertmanager config
  • Verify Column Management modal opens correctly from table headers and filter toolbar
  • Verify Delete modal works correctly for:
    • OLM operands
    • OLM ClusterServiceVersions
    • Metal3 bare metal hosts
    • Other resources using common delete action
  • Verify all modals close properly
  • Verify accessibility (keyboard navigation, screen readers)

🤖 Generated with Claude Code

@rhamilto rhamilto changed the title Migrate modals to useOverlay pattern CONSOLE-5012: Migrate remaining modals to useOverlay pattern Feb 4, 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 Feb 4, 2026
@openshift-ci-robot
Copy link
Contributor

openshift-ci-robot commented Feb 4, 2026

@rhamilto: This pull request references CONSOLE-5012 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set.

Details

In response to this:

Summary

Migrates several modals from the deprecated createModalLauncher pattern to the modern useOverlay/OverlayComponent pattern for better accessibility and consistency.

Migrated modals:

  • Labels and Pod Selector modals
  • Annotations modal
  • PubSub modal (with accessibility-safe pattern for non-React contexts)
  • Alert Routing modal
  • Column Management modal

Key changes:

  • Created OverlayComponent wrappers for all migrated modals
  • Exported lazy-loaded overlay components from modals/index.ts
  • Updated all usages to call launchModal() with useOverlay() hook
  • Added SyncPubSubModalLauncher for topology connector accessibility
  • Maintained user settings HOC compatibility in Column Management modal

The PubSub modal uses a module-level reference synced via React Context to support non-React topology connectors while maintaining proper accessibility through the OverlayProvider.

All modals follow consistent naming: *ModalOverlay and Lazy*ModalOverlay

Files modified:

  • packages/console-app/src/actions/hooks/useCommonActions.ts
  • packages/console-app/src/components/data-view/ConsoleDataView.tsx
  • packages/knative-plugin/src/components/pub-sub/PubSubController.tsx
  • packages/knative-plugin/src/components/pub-sub/PubSubModalLauncher.ts
  • packages/topology/src/components/graph-view/Topology.tsx
  • public/components/filter-toolbar.tsx
  • public/components/modals/alert-routing-modal.tsx
  • public/components/modals/column-management-modal.tsx
  • public/components/modals/index.ts
  • public/components/modals/labels-modal.tsx
  • public/components/modals/tags.tsx
  • public/components/monitoring/alertmanager/alertmanager-config.tsx

Related PRs:

Test plan

  • Verify Labels modal opens correctly from resource actions
  • Verify Annotations modal opens correctly from resource actions
  • Verify PubSub modal opens correctly from topology connectors
  • Verify Alert Routing modal opens correctly from Alertmanager config
  • Verify Column Management modal opens correctly from table headers and filter toolbar
  • Verify all modals close properly
  • Verify accessibility (keyboard navigation, screen readers)

🤖 Generated with 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-robot
Copy link
Contributor

openshift-ci-robot commented Feb 4, 2026

@rhamilto: This pull request references CONSOLE-5012 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set.

Details

In response to this:

Summary

Migrates several modals from the deprecated createModalLauncher pattern to the modern useOverlay/OverlayComponent pattern for better accessibility and consistency.

Note: this PR builds on #15946, so it should merge first.

Migrated modals:

  • Labels and Pod Selector modals
  • Annotations modal
  • PubSub modal (with accessibility-safe pattern for non-React contexts)
  • Alert Routing modal
  • Column Management modal

Key changes:

  • Created OverlayComponent wrappers for all migrated modals
  • Exported lazy-loaded overlay components from modals/index.ts
  • Updated all usages to call launchModal() with useOverlay() hook
  • Added SyncPubSubModalLauncher for topology connector accessibility
  • Maintained user settings HOC compatibility in Column Management modal

The PubSub modal uses a module-level reference synced via React Context to support non-React topology connectors while maintaining proper accessibility through the OverlayProvider.

All modals follow consistent naming: *ModalOverlay and Lazy*ModalOverlay

Files modified:

  • packages/console-app/src/actions/hooks/useCommonActions.ts
  • packages/console-app/src/components/data-view/ConsoleDataView.tsx
  • packages/knative-plugin/src/components/pub-sub/PubSubController.tsx
  • packages/knative-plugin/src/components/pub-sub/PubSubModalLauncher.ts
  • packages/topology/src/components/graph-view/Topology.tsx
  • public/components/filter-toolbar.tsx
  • public/components/modals/alert-routing-modal.tsx
  • public/components/modals/column-management-modal.tsx
  • public/components/modals/index.ts
  • public/components/modals/labels-modal.tsx
  • public/components/modals/tags.tsx
  • public/components/monitoring/alertmanager/alertmanager-config.tsx

Related PRs:

Test plan

  • Verify Labels modal opens correctly from resource actions
  • Verify Annotations modal opens correctly from resource actions
  • Verify PubSub modal opens correctly from topology connectors
  • Verify Alert Routing modal opens correctly from Alertmanager config
  • Verify Column Management modal opens correctly from table headers and filter toolbar
  • Verify all modals close properly
  • Verify accessibility (keyboard navigation, screen readers)

🤖 Generated with 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.

@rhamilto rhamilto changed the title CONSOLE-5012: Migrate remaining modals to useOverlay pattern [WIP] CONSOLE-5012: Migrate remaining modals to useOverlay pattern Feb 4, 2026
@openshift-ci openshift-ci bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Feb 4, 2026
);
export const labelsModalLauncher = createModalLauncher<LabelsModalProps>(LabelsModal);

export const podSelectorModal = createModalLauncher<PodSelectorModalProps>((props) => {
Copy link
Member Author

Choose a reason for hiding this comment

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

This is orphaned.

@openshift-ci-robot
Copy link
Contributor

openshift-ci-robot commented Feb 4, 2026

@rhamilto: This pull request references CONSOLE-5012 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set.

Details

In response to this:

Summary

Migrates several modals from the deprecated createModalLauncher pattern to the modern useOverlay/OverlayComponent pattern for better accessibility and consistency.

Note: this PR builds on #15946, so it should merge first.

Migrated modals:

  • Labels and Pod Selector modals
  • Annotations modal
  • PubSub modal (with accessibility-safe pattern for non-React contexts)
  • Alert Routing modal
  • Column Management modal

Key changes:

  • Created OverlayComponent wrappers for all migrated modals
  • Exported lazy-loaded overlay components from modals/index.ts
  • Updated all usages to call launchModal() with useOverlay() hook
  • Added SyncPubSubModalLauncher for topology connector accessibility
  • Maintained user settings HOC compatibility in Column Management modal

The PubSub modal uses a module-level reference synced via React Context to support non-React topology connectors while maintaining proper accessibility through the OverlayProvider.

All modals follow consistent naming: *ModalOverlay and Lazy*ModalOverlay

Files modified:

  • packages/console-app/src/actions/hooks/useCommonActions.ts
  • packages/console-app/src/components/data-view/ConsoleDataView.tsx
  • packages/knative-plugin/src/components/pub-sub/PubSubController.tsx
  • packages/knative-plugin/src/components/pub-sub/PubSubModalLauncher.ts
  • packages/topology/src/components/graph-view/Topology.tsx
  • public/components/filter-toolbar.tsx
  • public/components/modals/alert-routing-modal.tsx
  • public/components/modals/column-management-modal.tsx
  • public/components/modals/index.ts
  • public/components/modals/labels-modal.tsx
  • public/components/modals/tags.tsx
  • public/components/monitoring/alertmanager/alertmanager-config.tsx

Related PRs:

Test plan

  • Verify Labels modal opens correctly from resource actions
  • Verify Annotations modal opens correctly from resource actions
  • Verify PubSub modal opens correctly from topology connectors
  • Verify Alert Routing modal opens correctly from Alertmanager config
  • Verify Column Management modal opens correctly from table headers and filter toolbar
  • Verify all modals close properly
  • Verify accessibility (keyboard navigation, screen readers)

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features

  • Improved error modal handling with enhanced confirmation workflows for complex operations like node movement in topology views.

  • Bug Fixes

  • Better error handling and display across modal operations with consistent error messaging.

  • Deprecated Features

  • Removed confirm modal functionality; operations now use improved warning modals.

  • Pod selector modal no longer available.

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
Contributor

openshift-ci-robot commented Feb 4, 2026

@rhamilto: This pull request references CONSOLE-5012 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set.

Details

In response to this:

Summary

Migrates several modals from the deprecated createModalLauncher pattern to the modern useOverlay/OverlayComponent pattern for better accessibility and consistency.

Note: this PR builds on #15946, so it should merge first.

Migrated modals:

  • Labels and Pod Selector modals
  • Annotations modal
  • PubSub modal (with accessibility-safe pattern for non-React contexts)
  • Alert Routing modal
  • Column Management modal

Key changes:

  • Created OverlayComponent wrappers for all migrated modals
  • Exported lazy-loaded overlay components from modals/index.ts
  • Updated all usages to call launchModal() with useOverlay() hook
  • Added SyncPubSubModalLauncher for topology connector accessibility
  • Maintained user settings HOC compatibility in Column Management modal
  • Removed orphaned podSelectorModal and related code.

The PubSub modal uses a module-level reference synced via React Context to support non-React topology connectors while maintaining proper accessibility through the OverlayProvider.

All modals follow consistent naming: *ModalOverlay and Lazy*ModalOverlay

Files modified:

  • packages/console-app/src/actions/hooks/useCommonActions.ts
  • packages/console-app/src/components/data-view/ConsoleDataView.tsx
  • packages/knative-plugin/src/components/pub-sub/PubSubController.tsx
  • packages/knative-plugin/src/components/pub-sub/PubSubModalLauncher.ts
  • packages/topology/src/components/graph-view/Topology.tsx
  • public/components/filter-toolbar.tsx
  • public/components/modals/alert-routing-modal.tsx
  • public/components/modals/column-management-modal.tsx
  • public/components/modals/index.ts
  • public/components/modals/labels-modal.tsx
  • public/components/modals/tags.tsx
  • public/components/monitoring/alertmanager/alertmanager-config.tsx

Related PRs:

Test plan

  • Verify Labels modal opens correctly from resource actions
  • Verify Annotations modal opens correctly from resource actions
  • Verify PubSub modal opens correctly from topology connectors
  • Verify Alert Routing modal opens correctly from Alertmanager config
  • Verify Column Management modal opens correctly from table headers and filter toolbar
  • Verify all modals close properly
  • Verify accessibility (keyboard navigation, screen readers)

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features

  • Improved error modal handling with enhanced confirmation workflows for complex operations like node movement in topology views.

  • Bug Fixes

  • Better error handling and display across modal operations with consistent error messaging.

  • Deprecated Features

  • Removed confirm modal functionality; operations now use improved warning modals.

  • Pod selector modal no longer available.

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 requested review from Leo6Leo and rawagner February 4, 2026 16:24
@openshift-ci openshift-ci bot added the component/core Related to console core functionality label Feb 4, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 4, 2026

📝 Walkthrough

Walkthrough

This change refactors the modal system from direct launcher functions to an overlay-based architecture. Modal components are converted to OverlayComponents and accessed via lazy-loaded Lazy*Overlay wrappers through a generic launchModal function. A new error-modal-handler utility enables error modal launches from both React (useErrorModalLauncher hook) and non-React contexts (launchErrorModal function) via a SyncErrorModalLauncher component. PubSub, move-node, and node-maintenance modals are updated to follow the overlay pattern. Multiple components replace direct modal invocations with useOverlay-based launchers. Legacy modal launchers (confirmModal, createModalLauncher exports) are removed across the codebase.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely describes the main change: migrating remaining modals from createModalLauncher to useOverlay pattern, which is the primary refactoring objective.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

Copy link
Contributor

@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: 6

🤖 Fix all issues with AI agents
In
`@frontend/packages/dev-console/src/components/pipeline-section/pipeline/__tests__/pipeline-template-utils.spec.ts`:
- Around line 19-23: Remove the unused referenceForModel mock from the jest.mock
block in the test file: delete the referenceForModel property so the mock only
exports k8sCreate and k8sUpdate (to match the actual imported symbols like
k8sCreate and k8sUpdate); this keeps the mocked API surface consistent with the
imports and avoids dead code in the jest.mock declaration.

In
`@frontend/packages/dev-console/src/components/pipeline-section/pipeline/pipeline-template-utils.ts`:
- Around line 931-934: The modal title and fallback message are hardcoded;
update the call to launchErrorModal in pipeline-template-utils.ts to use
i18next.t(...) for the title (e.g., i18next.t('pipelines~Error Exposing Route'))
and for the fallback error string instead of 'Unknown error exposing the Webhook
route'; ensure i18next is imported where launchErrorModal is called and pass the
translated strings, keeping the existing use of e.message when present.

In
`@frontend/packages/knative-plugin/src/components/pub-sub/PubSubModalLauncher.ts`:
- Around line 31-37: The Promise returned by addPubSubConnectionModal (created
in launchPubSubModalRef) can remain unresolved when the overlay is dismissed via
ModalWrapper.onClose (Escape/outside click); update the modal overlay logic so
the Promise is always settled: in the object passed to launchPubSubModalRef for
PubSubModalOverlay, add a settled-tracking wrapper around the provided
close/cancel handlers and expose a cleanup handler (e.g., onUnmount or wrap
props.closeOverlay) that checks the settled flag and calls reject(new
Error('User cancelled via overlay')) if not already settled; implement the
tracking in PubSubModalOverlay (or the wrapper you pass in) so
unmount/ModalWrapper.onClose triggers that cleanup to reject the Promise when
dismissed outside of explicit close() or cancel().

In
`@frontend/packages/knative-plugin/src/topology/components/knativeComponentUtils.ts`:
- Around line 261-264: The error modal title is grammatically incorrect in the
launchErrorModal call using i18next.t('knative-plugin~Error while sink'); update
the message to a clear, grammatical string (e.g., "Error while creating sink" or
"Error configuring sink") and adjust the i18n key/value accordingly so
launchErrorModal({ title: i18next.t('knative-plugin~...'), error: error.message
}) shows the corrected title; ensure you update the corresponding translation
entry for the chosen key.

In `@frontend/packages/metal3-plugin/src/components/maintenance/actions.tsx`:
- Around line 47-48: The memoized actions array uses the
startNodeMaintenanceModal launcher but it's missing from the useMemo dependency
list; update the useMemo dependencies to include the startNodeMaintenanceModal
reference returned by useStartNodeMaintenanceModalLauncher so the memoized
callback re-computes when the launcher changes. Locate the useMemo call that
currently depends on [maintenances, resource.metadata.name, t,
stopNodeMaintenanceModalLauncher] and add startNodeMaintenanceModal (the value
from useStartNodeMaintenanceModalLauncher) to that array to avoid stale
closures.

In
`@frontend/packages/topology/src/components/graph-view/components/componentUtils.ts`:
- Around line 139-155: The catch currently swallows all errors from
moveNodeToGroup; change it to distinguish user cancellation from real failures
by inspecting the thrown error (e.g., error.name === 'AbortError' or a
project-specific CancelledError/flag) and only ignore those; for other errors
surface them via the app's notification/logger and rethrow or return a failure
so the UI can show feedback. Update the catch block surrounding moveNodeToGroup
(and the subsequent optimistic action involving controller.getNodeById and
dropResult.appendChild) to log/notify on non-cancellation errors and avoid
silently swallowing them.
🧹 Nitpick comments (7)
frontend/public/components/modals/error-modal.tsx (1)

18-37: Remove ModalErrorContent — unused legacy pattern.

ModalErrorContent implements the older modal factory pattern and is not referenced elsewhere in the codebase. ErrorModal provides the modern overlay-based approach. Removing the legacy component reduces maintenance burden and clarifies the single source of truth for error modal behavior.

frontend/packages/knative-plugin/src/components/pub-sub/PubSubModalLauncher.ts (2)

21-21: Add TypeScript typing for props parameter.

The props parameter lacks type annotation, making it any. This reduces type safety and IDE support. Consider typing it properly based on PubSubModalOverlay's expected props.

-export const addPubSubConnectionModal = (props) => {
+export const addPubSubConnectionModal = (props: Omit<Parameters<typeof import('./PubSubController').PubSubModalOverlay>[0], 'close' | 'cancel'>) => {

Alternatively, define a dedicated type and export it for consumers.


22-39: Potential race condition between launcher check and invocation.

There's a window between checking launchPubSubModalRef on line 23 and using it on line 32 where the ref could be nullified (e.g., if SyncPubSubModalLauncher unmounts). While unlikely in practice, consider capturing the ref in a local variable for safety.

 export const addPubSubConnectionModal = (props) => {
   return import('./PubSubController' /* webpackChunkName: "pub-sub-connectors" */).then((m) => {
-    if (!launchPubSubModalRef) {
+    const launcher = launchPubSubModalRef;
+    if (!launcher) {
       // eslint-disable-next-line no-console
       console.error(
         'PubSub modal launcher not initialized. Make sure SyncPubSubModalLauncher is rendered in the topology component tree.',
       );
       return Promise.reject(new Error('Modal launcher not available'));
     }

     return new Promise<void>((resolve, reject) => {
-      launchPubSubModalRef(m.PubSubModalOverlay, {
+      launcher(m.PubSubModalOverlay, {
         ...props,
frontend/packages/topology/src/actions/edgeActions.ts (1)

104-111: Redundant if (err) check in catch block.

The if (err) conditional is unnecessary since the .catch() handler already implies an error occurred. While technically safe, it's misleading—Promise rejections can legitimately pass undefined as the rejection reason, and this check would silently skip showing the error modal in that edge case.

Consider removing the conditional or handling the undefined case explicitly:

       return removeTopologyResourceConnection(element, resource).catch((err) => {
-        if (err) {
-          launchErrorModal({
-            title: t('topology~Error deleting connector'),
-            error: err.message,
-          });
-        }
+        launchErrorModal({
+          title: t('topology~Error deleting connector'),
+          error: err?.message || t('topology~An unknown error occurred'),
+        });
       });
frontend/packages/knative-plugin/src/topology/components/knativeComponentUtils.ts (1)

190-195: Inconsistent optional chaining for error.message access.

Line 226 uses error?.message (defensive) while lines 193 and 263 use error.message directly. If error could ever be undefined or lack a message property, the latter would throw. Standardize the approach:

       createSinkConnection(edge.getSource(), dropResult).catch((error) => {
         launchErrorModal({
           title: i18next.t('knative-plugin~Error moving event source sink'),
-          error: error.message,
+          error: error?.message,
         });
       });

Apply the same pattern to line 263.

Also applies to: 223-228, 260-265

frontend/packages/topology/src/utils/__tests__/moveNodeToGroup.spec.tsx (1)

88-99: Incomplete test coverage for handler cleanup verification.

The test acknowledges cleanup "is tested indirectly through the error case" but doesn't actually verify the cleanup occurred. After unmount, a subsequent call to moveNodeToGroup should throw "Move node handlers not initialized" - that would be a concrete verification.

💡 Suggested enhancement for explicit cleanup verification
     it('should cleanup handlers on unmount', () => {
       const { unmount } = render(
         <MoveNodeHandlersProvider>
           <SyncMoveNodeHandlers />
         </MoveNodeHandlersProvider>,
       );
 
       unmount();
 
-      // After unmount, handlers should be cleaned up
-      // This is tested indirectly through the error case
+      // After unmount, moveNodeToGroup should throw "not initialized"
+      const mockNode = {
+        getId: () => 'test',
+        getLabel: () => 'Test',
+        getParent: () => ({ getId: () => 'graph' }),
+        getGraph: () => ({ getId: () => 'graph' }),
+      };
+      await expect(moveNodeToGroup(mockNode as Node, null)).rejects.toThrow(
+        'Move node handlers not initialized',
+      );
     });
frontend/packages/topology/src/utils/moveNodeToGroup.tsx (1)

118-203: Defer handler initialization until confirmation is required.
Right now the function throws even when the node has no source group (no confirmation needed). This makes non‑group moves unnecessarily dependent on handler initialization.

♻️ Suggested change
-  const handlers = moduleHandlers;
-  if (!handlers) {
-    throw new Error(
-      'Move node handlers not initialized. Ensure MoveNodeHandlersProvider is mounted.',
-    );
-  }
-
-  // If moving from a group, show confirmation
-  if (sourceGroup) {
+  // If moving from a group, show confirmation
+  if (sourceGroup) {
+    const handlers = moduleHandlers;
+    if (!handlers) {
+      throw new Error(
+        'Move node handlers not initialized. Ensure MoveNodeHandlersProvider is mounted.',
+      );
+    }

Comment on lines 47 to 48
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [maintenances, resource.metadata.name, t]);
}, [maintenances, resource.metadata.name, t, stopNodeMaintenanceModalLauncher]);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Missing startNodeMaintenanceModal in useMemo dependencies.

The startNodeMaintenanceModal launcher is used in the memoized callback (line 34) but isn't included in the dependency array. If the launcher reference changes (e.g., when resource.metadata.name changes and useStartNodeMaintenanceModalLauncher returns a new function), the memoized action will hold a stale reference. Since you've already added stopNodeMaintenanceModalLauncher, adding the start launcher keeps behavior symmetric and correct.

🔧 Proposed fix
     return [action];
-    // eslint-disable-next-line react-hooks/exhaustive-deps
-  }, [maintenances, resource.metadata.name, t, stopNodeMaintenanceModalLauncher]);
+  }, [maintenances, resource.metadata.name, t, stopNodeMaintenanceModalLauncher, startNodeMaintenanceModal]);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [maintenances, resource.metadata.name, t]);
}, [maintenances, resource.metadata.name, t, stopNodeMaintenanceModalLauncher]);
}, [maintenances, resource.metadata.name, t, stopNodeMaintenanceModalLauncher, startNodeMaintenanceModal]);
🤖 Prompt for AI Agents
In `@frontend/packages/metal3-plugin/src/components/maintenance/actions.tsx`
around lines 47 - 48, The memoized actions array uses the
startNodeMaintenanceModal launcher but it's missing from the useMemo dependency
list; update the useMemo dependencies to include the startNodeMaintenanceModal
reference returned by useStartNodeMaintenanceModalLauncher so the memoized
callback re-computes when the launcher changes. Locate the useMemo call that
currently depends on [maintenances, resource.metadata.name, t,
stopNodeMaintenanceModalLauncher] and add startNodeMaintenanceModal (the value
from useStartNodeMaintenanceModalLauncher) to that array to avoid stale
closures.

@openshift-ci openshift-ci bot added component/dev-console Related to dev-console approved Indicates a PR has been approved by an approver from all required OWNERS files. component/knative Related to knative-plugin component/metal3 Related to metal3-plugin component/monitoring Related to monitoring component/shared Related to console-shared component/topology Related to topology kind/i18n Indicates issue or PR relates to internationalization or has content that needs to be translated component/olm Related to OLM labels Feb 4, 2026
@openshift-ci-robot
Copy link
Contributor

openshift-ci-robot commented Feb 4, 2026

@rhamilto: This pull request references CONSOLE-5012 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set.

Details

In response to this:

Summary

Migrates several modals from the deprecated createModalLauncher pattern to the modern useOverlay/OverlayComponent pattern for better accessibility and consistency. Also consolidates delete modal implementations.

Migrated modals:

  • Labels and Pod Selector modals
  • Annotations modal
  • PubSub modal (with accessibility-safe pattern for non-React contexts)
  • Alert Routing modal
  • Column Management modal
  • Delete modal consolidation (removed DeleteOverlay, unified on DeleteModalOverlay)

Key changes:

  • Created OverlayComponent wrappers for all migrated modals
  • Exported lazy-loaded overlay components from modals/index.ts
  • Updated all usages to call launchModal() with useOverlay() hook
  • Added SyncPubSubModalLauncher for topology connector accessibility
  • Maintained user settings HOC compatibility in Column Management modal
  • Removed deprecated DeleteOverlay component
  • Updated OLM and Metal3 plugins to use DeleteModalOverlay
  • Standardized variable naming: const launchModal = useOverlay() throughout

The PubSub modal uses a module-level reference synced via React Context to support non-React topology connectors while maintaining proper accessibility through the OverlayProvider.

All modals follow consistent naming: *ModalOverlay and Lazy*ModalOverlay

Files modified:

Core modal migrations:

  • public/components/modals/labels-modal.tsx - Labels and Pod Selector modals
  • public/components/modals/tags.tsx - Annotations modal
  • public/components/modals/alert-routing-modal.tsx - Alert Routing modal
  • public/components/modals/column-management-modal.tsx - Column Management modal
  • public/components/modals/index.ts - Lazy-loaded exports
  • packages/knative-plugin/src/components/pub-sub/PubSubController.tsx - PubSub modal
  • packages/knative-plugin/src/components/pub-sub/PubSubModalLauncher.ts - PubSub launcher

Delete modal consolidation:

  • public/components/modals/delete-modal.tsx - Removed DeleteOverlay, kept DeleteModalOverlay
  • packages/operator-lifecycle-manager/src/actions/useDefaultOperandActions.ts - OLM operand delete
  • packages/operator-lifecycle-manager/src/actions/useOperatorActions.ts - OLM CSV delete
  • packages/metal3-plugin/src/components/baremetal-hosts/host-actions-provider.ts - Metal3 host delete

Usage updates:

  • packages/console-app/src/actions/hooks/useCommonActions.ts - Common actions for labels/annotations
  • packages/console-app/src/components/data-view/ConsoleDataView.tsx - Column management
  • public/components/filter-toolbar.tsx - Column management
  • public/components/monitoring/alertmanager/alertmanager-config.tsx - Alert routing
  • packages/topology/src/components/graph-view/Topology.tsx - PubSub launcher sync

Related PRs:

Test plan

  • Verify Labels modal opens correctly from resource actions
  • Verify Annotations modal opens correctly from resource actions
  • Verify PubSub modal opens correctly from topology connectors
  • Verify Alert Routing modal opens correctly from Alertmanager config
  • Verify Column Management modal opens correctly from table headers and filter toolbar
  • Verify Delete modal works correctly for:
  • OLM operands
  • OLM ClusterServiceVersions
  • Metal3 bare metal hosts
  • Other resources using common delete action
  • Verify all modals close properly
  • Verify accessibility (keyboard navigation, screen readers)

🤖 Generated with 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.

@rhamilto rhamilto force-pushed the CONSOLE-5012-6 branch 3 times, most recently from d8a4c5a to ae6ccb5 Compare February 4, 2026 20:13
@rhamilto
Copy link
Member Author

rhamilto commented Feb 5, 2026

/retest

1 similar comment
@rhamilto
Copy link
Member Author

rhamilto commented Feb 5, 2026

/retest

@rhamilto rhamilto changed the title [WIP] CONSOLE-5012: Migrate remaining modals to useOverlay pattern CONSOLE-5012: Migrate remaining modals to useOverlay pattern Feb 5, 2026
This change migrates several modals from the deprecated createModalLauncher
pattern to the modern useOverlay/OverlayComponent pattern for better
accessibility and consistency.

Migrated modals:
- Labels and Pod Selector modals
- Annotations modal
- PubSub modal (with accessibility-safe pattern for non-React contexts)
- Alert Routing modal
- Column Management modal

Key changes:
- Created OverlayComponent wrappers for all migrated modals
- Exported lazy-loaded overlay components from modals/index.ts
- Updated all usages to call launchModal() with useOverlay() hook
- Added SyncPubSubModalLauncher for topology connector accessibility
- Maintained user settings HOC compatibility in Column Management modal

The PubSub modal uses a module-level reference synced via React Context
to support non-React topology connectors while maintaining proper
accessibility through the OverlayProvider.

All modals follow consistent naming: *ModalOverlay and Lazy*ModalOverlay

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
@openshift-ci openshift-ci bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Feb 5, 2026
Replace all usages of DeleteOverlay with DeleteModalOverlay for
consistency. Remove the deprecated DeleteOverlay component which used
the older Backdrop/Modal pattern.

Updated files:
- useDefaultOperandActions.ts - OLM operand delete action
- useOperatorActions.ts - OLM CSV delete action
- host-actions-provider.ts - Metal3 bare metal host delete action
- delete-modal.tsx - removed DeleteOverlay component

All delete actions now use the modern OverlayComponent pattern through
DeleteModalOverlay. Also updated variable naming from launcher to
launchModal for consistency.

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
);
};

export const DeleteOverlay: FC<DeleteModalProps> = (props) => {
Copy link
Member Author

Choose a reason for hiding this comment

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

This is a better pattern using newer components, but the goal is to get to a single delete modal knowing we will refactor the old one in future work.

@rhamilto
Copy link
Member Author

rhamilto commented Feb 5, 2026

This PR is not dependent on useQueryParamsMutator or the revised confirm or error modals.

/assign @jhadvig
/assign @vojtechszocs

Tech debt, so assigning labels
/label px-approved
/label docs-approved

@openshift-ci openshift-ci bot added px-approved Signifies that Product Support has signed off on this PR docs-approved Signifies that Docs has signed off on this PR labels Feb 5, 2026
@rhamilto
Copy link
Member Author

rhamilto commented Feb 5, 2026

/unassign @vojtechszocs
/assign @yanpzhan

@openshift-ci openshift-ci bot assigned yanpzhan and unassigned vojtechszocs Feb 5, 2026
@rhamilto
Copy link
Member Author

rhamilto commented Feb 6, 2026

/retest

1 similar comment
@rhamilto
Copy link
Member Author

rhamilto commented Feb 6, 2026

/retest

Copy link
Member

@jhadvig jhadvig left a comment

Choose a reason for hiding this comment

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

/lgtm

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

openshift-ci bot commented Feb 9, 2026

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: jhadvig, rhamilto

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

The pull request process is described here

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

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

@jhadvig jhadvig added the plugin-api-approved Indicates a PR with plugin API changes has been approved by an API reviewer label Feb 9, 2026
@yanpzhan
Copy link
Contributor

Regression tests about modals on cluster launched against the pr passed.
/verified by yanpzhan

@openshift-ci-robot openshift-ci-robot added the verified Signifies that the PR passed pre-merge verification criteria label Feb 10, 2026
@openshift-ci-robot
Copy link
Contributor

@yanpzhan: This PR has been marked as verified by yanpzhan.

Details

In response to this:

Regression tests about modals on cluster launched against the pr passed.
/verified by yanpzhan

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.

@rhamilto
Copy link
Member Author

/retest

2 similar comments
@rhamilto
Copy link
Member Author

/retest

@rhamilto
Copy link
Member Author

/retest

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Feb 12, 2026

@rhamilto: 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.

@openshift-merge-bot openshift-merge-bot bot merged commit d4a5df2 into openshift:main Feb 12, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. component/core Related to console core functionality component/dev-console Related to dev-console component/knative Related to knative-plugin component/metal3 Related to metal3-plugin component/monitoring Related to monitoring component/olm Related to OLM component/shared Related to console-shared component/topology Related to topology docs-approved Signifies that Docs has signed off on this PR jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. kind/i18n Indicates issue or PR relates to internationalization or has content that needs to be translated lgtm Indicates that a PR is ready to be merged. plugin-api-approved Indicates a PR with plugin API changes has been approved by an API reviewer px-approved Signifies that Product Support has signed off on this PR verified Signifies that the PR passed pre-merge verification criteria

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants