Skip to content

OCPBUGS-81519: Fix Search page state mutation and unnecessary component remounts#16266

Open
stefanonardo wants to merge 1 commit intoopenshift:mainfrom
stefanonardo:OCPBUGS-81519
Open

OCPBUGS-81519: Fix Search page state mutation and unnecessary component remounts#16266
stefanonardo wants to merge 1 commit intoopenshift:mainfrom
stefanonardo:OCPBUGS-81519

Conversation

@stefanonardo
Copy link
Copy Markdown
Contributor

@stefanonardo stefanonardo commented Apr 9, 2026

Summary

  • Fix state mutation bug in updateSelectedItems and updateNewItems — creates a new Set instead of copying the reference, ensuring React detects state changes
  • Replace filter-value-based component keys with stable key={resource} to prevent ResourceList from remounting on every filter change (which tore down WebSocket watches and caused duplicate LIST requests)
  • Wrap ResourceList in React.memo and debounce the nameFilter prop + URL update to prevent expensive re-renders during typing
  • Memoize selector prop with useMemo for referential stability with React.memo
  • Add URL-to-filter sync in useConsoleDataViewFilters to keep filters in sync without remounting (compensates for PatternFly's useDataViewFilters only reading searchParams on mount)

Note on PatternFly upstream

PatternFly's useDataViewFilters hook only reads searchParams on mount (empty deps useEffect), which means it assumes the component remounts when URL filters change. This forced us to add a workaround useEffect in useConsoleDataViewFilters to sync URL changes to internal filter state. Ideally, useDataViewFilters should be reactive to searchParams changes natively — an upstream fix in @patternfly/react-data-view would allow us to remove this workaround.

Test plan

  • Navigate to Home > Search, select multiple resource types, rapidly toggle selections — state should stay consistent
  • With several resource types selected, open Network tab, type in the Name filter — no duplicate LIST requests should appear
  • Verify input is responsive during typing (filter applies after 300ms debounce)
  • Clear name filter (X button) — should clear both input and results immediately
  • Verify label filter still works correctly (applies on Enter key)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Bi-directional URL and filter synchronization: Filters now automatically update when URL query parameters change.
  • Improvements

    • Optimized search name filtering with debounced updates for better performance.
    • Enhanced selection state management for improved stability.
    • Refined filter clearing behavior for consistency across operations.

@openshift-ci-robot openshift-ci-robot added jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. jira/valid-bug Indicates that a referenced Jira bug is valid for the branch this PR is targeting. labels Apr 9, 2026
@openshift-ci-robot
Copy link
Copy Markdown
Contributor

@stefanonardo: This pull request references Jira Issue OCPBUGS-81519, which is valid. The bug has been moved to the POST state.

3 validation(s) were run on this bug
  • bug is open, matching expected state (open)
  • bug target version (4.22.0) matches configured target version for branch (4.22.0)
  • bug is in the state ASSIGNED, which is one of the valid states (NEW, ASSIGNED, POST)

The bug has been updated to refer to the pull request using the external bug tracker.

Details

In response to this:

Summary

  • Fix state mutation bug in updateSelectedItems and updateNewItems — creates a new Set instead of copying the reference, ensuring React detects state changes
  • Replace filter-value-based component keys with stable key={resource} to prevent ResourceList from remounting on every filter change (which tore down WebSocket watches and caused duplicate LIST requests)
  • Wrap ResourceList in React.memo and debounce the nameFilter prop + URL update to prevent expensive re-renders during typing
  • Memoize selector prop with useMemo for referential stability with React.memo
  • Add URL-to-filter sync in useConsoleDataViewFilters to keep filters in sync without remounting (compensates for PatternFly's useDataViewFilters only reading searchParams on mount)

Note on PatternFly upstream

PatternFly's useDataViewFilters hook only reads searchParams on mount (empty deps useEffect), which means it assumes the component remounts when URL filters change. This forced us to add a workaround useEffect in useConsoleDataViewFilters to sync URL changes to internal filter state. Ideally, useDataViewFilters should be reactive to searchParams changes natively — an upstream fix in @patternfly/react-data-view would allow us to remove this workaround.

Test plan

  • Navigate to Home > Search, select multiple resource types, rapidly toggle selections — state should stay consistent
  • With several resource types selected, open Network tab, type in the Name filter — no duplicate LIST requests should appear
  • Verify input is responsive during typing (filter applies after 300ms debounce)
  • Clear name filter (X button) — should clear both input and results immediately
  • Verify label filter still works correctly (applies on Enter key)

🤖 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 openshift-ci bot requested review from cajieh and sg00dwin April 9, 2026 12:25
@openshift-ci openshift-ci bot added the component/core Related to console core functionality label Apr 9, 2026
@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci bot commented Apr 9, 2026

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: stefanonardo
Once this PR has been reviewed and has the lgtm label, please assign spadgett 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-robot
Copy link
Copy Markdown
Contributor

@stefanonardo: This pull request references Jira Issue OCPBUGS-81519, which is valid.

3 validation(s) were run on this bug
  • bug is open, matching expected state (open)
  • bug target version (4.22.0) matches configured target version for branch (4.22.0)
  • bug is in the state POST, which is one of the valid states (NEW, ASSIGNED, POST)
Details

In response to this:

Summary

  • Fix state mutation bug in updateSelectedItems and updateNewItems — creates a new Set instead of copying the reference, ensuring React detects state changes
  • Replace filter-value-based component keys with stable key={resource} to prevent ResourceList from remounting on every filter change (which tore down WebSocket watches and caused duplicate LIST requests)
  • Wrap ResourceList in React.memo and debounce the nameFilter prop + URL update to prevent expensive re-renders during typing
  • Memoize selector prop with useMemo for referential stability with React.memo
  • Add URL-to-filter sync in useConsoleDataViewFilters to keep filters in sync without remounting (compensates for PatternFly's useDataViewFilters only reading searchParams on mount)

Note on PatternFly upstream

PatternFly's useDataViewFilters hook only reads searchParams on mount (empty deps useEffect), which means it assumes the component remounts when URL filters change. This forced us to add a workaround useEffect in useConsoleDataViewFilters to sync URL changes to internal filter state. Ideally, useDataViewFilters should be reactive to searchParams changes natively — an upstream fix in @patternfly/react-data-view would allow us to remove this workaround.

Test plan

  • Navigate to Home > Search, select multiple resource types, rapidly toggle selections — state should stay consistent
  • With several resource types selected, open Network tab, type in the Name filter — no duplicate LIST requests should appear
  • Verify input is responsive during typing (filter applies after 300ms debounce)
  • Clear name filter (X button) — should clear both input and results immediately
  • Verify label filter still works correctly (applies on Enter key)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

  • Bi-directional URL and filter synchronization: Filters now automatically update when URL query parameters change.

  • Improvements

  • Optimized search name filtering with debounced updates for better performance.

  • Enhanced selection state management for improved stability.

  • Refined filter clearing behavior for consistency across operations.

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.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 9, 2026

📝 Walkthrough

Walkthrough

This pull request introduces URL↔filter state synchronization in the data view filter hook and refactors the search component's filtering logic. The hook now uses a ref-based side effect to detect and reconcile mismatches between internal filter state and URL query parameters, applying partial updates when divergence is detected. The search component consolidates filtering behavior around debounced name filters, memoizes selector computation, mutes ResourceList with explicit props to prevent unnecessary reconciliation, and ensures immutability of selection state by cloning the Set before mutations.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

Copy link
Copy Markdown
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.

Caution

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

⚠️ Outside diff range comments (1)
frontend/public/components/search.tsx (1)

136-146: ⚠️ Potential issue | 🟡 Minor

Hydrate the debounced name state directly from the URL.

Line 136 only updates typeaheadNameFilter. On back/forward navigation or any external location.search change, debouncedNameFilter stays stale until the 300ms callback fires, so the input/URL and rendered results can disagree for one debounce window.

Suggested fix
-    setTypeaheadNameFilter(name || '');
+    const nextName = name || '';
+    setTypeaheadNameFilter(nextName);
+    setDebouncedNameFilter(nextName);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/public/components/search.tsx` around lines 136 - 146, When hydrating
from location.search you only update typeaheadNameFilter, leaving
debouncedNameFilter stale until the debounce fires; update debouncedNameFilter
immediately as well to keep UI/results in sync. In the effect that reads the
name from location.search (where setTypeaheadNameFilter(name || '') is called),
also call setDebouncedNameFilter(name || '') so the debounced state mirrors the
URL instantly without invoking debouncedNameFilterCallback (which would
re-trigger setQueryArgument).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@frontend/public/components/search.tsx`:
- Around line 136-146: When hydrating from location.search you only update
typeaheadNameFilter, leaving debouncedNameFilter stale until the debounce fires;
update debouncedNameFilter immediately as well to keep UI/results in sync. In
the effect that reads the name from location.search (where
setTypeaheadNameFilter(name || '') is called), also call
setDebouncedNameFilter(name || '') so the debounced state mirrors the URL
instantly without invoking debouncedNameFilterCallback (which would re-trigger
setQueryArgument).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: c5d56cc9-28dc-474d-81a4-8b0c6d7d3aa7

📥 Commits

Reviewing files that changed from the base of the PR and between f9ad621 and b5bd9af.

📒 Files selected for processing (2)
  • frontend/packages/console-app/src/components/data-view/useConsoleDataViewFilters.ts
  • frontend/public/components/search.tsx
📜 Review details
🧰 Additional context used
📓 Path-based instructions (1)
**

⚙️ CodeRabbit configuration file

-Focus on major issues impacting performance, readability, maintainability and security. Avoid nitpicks and avoid verbosity.

Files:

  • frontend/packages/console-app/src/components/data-view/useConsoleDataViewFilters.ts
  • frontend/public/components/search.tsx
🔇 Additional comments (1)
frontend/public/components/search.tsx (1)

148-163: [Rewritten comment]
[Exactly ONE classification tag]

@stefanonardo
Copy link
Copy Markdown
Contributor Author

/retest-required

…nt remounts

Fix Set reference copy bug in resource selection handlers, replace
filter-embedded component keys with stable keys to prevent WebSocket
watch teardown, and add memo/debounce to ResourceList to avoid expensive
re-renders during typing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@stefanonardo
Copy link
Copy Markdown
Contributor Author

/retest-required

@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci bot commented Apr 9, 2026

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

component/core Related to console core functionality jira/valid-bug Indicates that a referenced Jira bug is valid for the branch this PR is targeting. 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.

2 participants