Skip to content

OU-1237: 4.22 breaking changes#368

Merged
openshift-merge-bot[bot] merged 5 commits intoopenshift:mainfrom
PeterYurkovich:4.22-breaking-changes
May 6, 2026
Merged

OU-1237: 4.22 breaking changes#368
openshift-merge-bot[bot] merged 5 commits intoopenshift:mainfrom
PeterYurkovich:4.22-breaking-changes

Conversation

@PeterYurkovich
Copy link
Copy Markdown
Contributor

@PeterYurkovich PeterYurkovich commented May 5, 2026

Summary by CodeRabbit

  • New Features

    • Added CSS/SCSS TypeScript declarations for module imports
    • Improved virtualized logs table layout and responsive sizing
  • Bug Fixes

    • Enhanced dev-server error reporting with more detailed output
    • Fixed logs table resize detection for dynamic content
  • Refactor

    • Modernized React usage to named hook imports and typings across the frontend
    • Migrated ESLint to flat config and updated routing to React Router v7
    • Updated TypeScript configuration for improved module/JSX handling
  • Chores

    • Upgraded frontend toolchain (ESLint v9, Prettier v3, TypeScript 5.9)
    • Removed legacy/unused configuration and build artifacts
    • Improved E2E test stability with consistent keystroke timing

@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label May 5, 2026
@openshift-ci-robot
Copy link
Copy Markdown

openshift-ci-robot commented May 5, 2026

@PeterYurkovich: This pull request references OU-1237 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 task to target the "5.0.0" version, but no target version was set.

Details

In response to this:

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 jgbernalp and zhuje May 5, 2026 16:04
@openshift-ci openshift-ci Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label May 5, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 5, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Replaces legacy React namespace usage with named React imports and FC typings across frontend code, upgrades toolchain/config (TypeScript, webpack, ESLint, packages), removes a multi-stage Dockerfile, updates dev Docker/Make/devspace settings, and applies broad Cypress test/support formatting and small test wiring edits.

Changes

React & Tooling Modernization

Layer / File(s) Summary
TS & Build Config
web/tsconfig.json, web/webpack.config.ts, web/package.json
TypeScript settings updated (moduleResolution→bundler, target→es2021, jsx→react-jsx, strict:false); webpack devServer hot:false, liveReload:true, stats.errorDetails:true; package/tooling versions and devDependencies upgraded.
ESLint Flat Config
web/.eslintrc.yml, web/eslint.config.ts
Removed legacy web/.eslintrc.yml; added new flat-config web/eslint.config.ts wiring Prettier/React/TypeScript rules and plugins.
React API Migration
web/src/components/**, web/src/hooks/**, web/src/pages/**
Replaced default import React with named imports (FC, hooks, types); converted components from React.FC to FC; switched React.use* to direct hooks; adjusted event/type annotations and some effect dependencies.
Router & URL State
web/src/e2e-tests-app.tsx, web/src/pages/*, web/src/hooks/useURLState.ts
Replaced react-router-dom-v5-compat with react-router; migrated URL state to useSearchParams; refactored setters to build new URLSearchParams instances (no in-place mutation).
Component Logic Refinements
web/src/components/filters/*, web/src/components/logs-toolbar.tsx, web/src/components/filters/search-select.tsx, web/src/components/logs-metrics.tsx
Introduced useCallback for handlers, moved derived state to useMemo, replaced in-place mutations with immutable updates in places, adjusted PatternFly Select wiring to controlled selected/onOpenChange pattern.

Cypress Tests & Support

Layer / File(s) Summary
Cypress TS & Fixtures
web/cypress/tsconfig.json, web/cypress/fixtures/data-test.ts, web/src/index.d.ts
Added Cypress/NODE types to cypress tsconfig; added panelGroupHeader/panelHeader fixtures; added ambient *.css/*.scss module declarations.
Support Commands & Utilities
web/cypress/support/commands/*.ts, web/cypress/support/e2e.ts, web/cypress/support/scripts/*.sh
Wide formatting/typing normalization across auth, env, log, selector, utility commands; behavior preserved except a few typing return adjustments; findLogsInLokistack.sh lightly reformatted.
Test Specs & Helpers
web/cypress/e2e/logging/*, web/cypress/e2e/logging/testUtils.cy.ts
Normalized imports/formatting in many specs; added typed IndexField[] assertions and minor invocation reorder in one dev suite; core assertions and flows unchanged.
Removed View Utilities
web/cypress/views/utils.ts
Removed helper functions: clickIfExist, getValFromElement, getTextFromElement, getPFVersion.
Cypress Runtime Tweaks
web/cypress/e2e/integration/*.cy.ts
Added Cypress.Keyboard.defaults({ keystrokeDelay: 15 }) to several integration specs; one test added a short .wait(500) after cy.visit.

Build / Docker / Devspace

Layer / File(s) Summary
Dev Docker base
Dockerfile.devspace
Switched build-stage base image to registry.access.redhat.com/ubi9/go-toolset:1.25.
Removed Multi-stage Dockerfile
Dockerfile.konflux
Deleted entire multi-stage Dockerfile.konflux (frontend builder, Go builder, final runtime stage removed).
Makefile wiring
Makefile
Updated start-devspace-backend ./plugin-backend flags to use /etc/plugin/config/config.yaml for both -plugin-config-path and -config-path; minor .PHONY whitespace cleanup.
Devspace image tag
devspace.yaml
Updated dev.app.devImage tag from :devspace:devspace-pf6.
Repo config
.coderabbit.yaml
Enabled inheritance: true and set reviews.review_status: false.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

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

coderabbitai[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

Copy link
Copy Markdown

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

🧹 Nitpick comments (3)
web/cypress/e2e/integration/logs-page.cy.ts (1)

103-103: ⚡ Quick win

Replace fixed sleep with a deterministic wait

Line 103 uses a hard cy.wait(500), which can still flake under slower CI and adds avoidable latency. Since this test already aliases the initial request, wait on that alias instead.

Proposed change
-    cy.visit(LOGS_PAGE_URL).wait(500);
+    cy.visit(LOGS_PAGE_URL);
+    cy.wait('@queryRangeStreams');
🤖 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 `@web/cypress/e2e/integration/logs-page.cy.ts` at line 103, Replace the fixed
sleep after cy.visit(LOGS_PAGE_URL).wait(500) with a deterministic wait on the
previously created network alias—remove the .wait(500) and call
cy.wait('@<theAliasName>') (use the actual alias used in this test) immediately
after cy.visit(LOGS_PAGE_URL) so the test waits for the real request to complete
instead of sleeping.
web/src/hooks/useURLState.ts (2)

208-234: 💤 Low value

Potential stale closure in URL normalization effect.

setQueryInURL captures queryParams and location from the closure at render time. Since these are not in the dependency array (and the eslint rule is disabled), the effect may use stale values if the URL changes between renders.

Consider wrapping setQueryInURL in useCallback with proper dependencies, or include queryParams in this effect's dependency array to ensure freshness.

🤖 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 `@web/src/hooks/useURLState.ts` around lines 208 - 234, The URL-normalization
useEffect is susceptible to a stale closure because setQueryInURL (which
references queryParams and location) can capture outdated values; update the
code so setQueryInURL is stable or the effect sees fresh values—either memoize
setQueryInURL with useCallback including queryParams and location in its
dependency list, or add queryParams (and location if used) to the effect
dependencies that currently include initialSchema, schema, and configLoaded;
ensure you keep getDefaultQuery/defaultQueryFromTenant and the logic comparing
defaultOtelQuery/defaultViaqQuery unchanged while removing the eslint-disable so
React's lint enforces correct deps.

69-69: ⚡ Quick win

Consider using setSearchParams for cleaner URL updates.

The code retrieves queryParams from useSearchParams but ignores the setter function, instead manually constructing URL strings with navigate(). Using setSearchParams would simplify the URL update logic throughout this file.

Example for setQueryInURL:

const [queryParams, setSearchParams] = useSearchParams();
// ...
const setQueryInURL = (newQuery: string, replace?: boolean) => {
  const trimmedQuery = newQuery.trim();
  setSearchParams((prev) => {
    prev.set(QUERY_PARAM_KEY, trimmedQuery);
    return prev;
  }, { replace });
};
🤖 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 `@web/src/hooks/useURLState.ts` at line 69, The hook currently calls
useSearchParams only to read queryParams and manually builds URLs with navigate,
which is more error-prone; update the hook to destructure both values from
useSearchParams (const [queryParams, setSearchParams] = useSearchParams()) and
refactor functions that modify the URL—notably setQueryInURL and any
navigate-based setters that change QUERY_PARAM_KEY—to call setSearchParams with
an updater callback (mutating/setting QUERY_PARAM_KEY on the passed
URLSearchParams) and pass the replace option when needed, removing manual URL
string construction and navigate usage for query-only changes.
🤖 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.

Nitpick comments:
In `@web/cypress/e2e/integration/logs-page.cy.ts`:
- Line 103: Replace the fixed sleep after cy.visit(LOGS_PAGE_URL).wait(500) with
a deterministic wait on the previously created network alias—remove the
.wait(500) and call cy.wait('@<theAliasName>') (use the actual alias used in
this test) immediately after cy.visit(LOGS_PAGE_URL) so the test waits for the
real request to complete instead of sleeping.

In `@web/src/hooks/useURLState.ts`:
- Around line 208-234: The URL-normalization useEffect is susceptible to a stale
closure because setQueryInURL (which references queryParams and location) can
capture outdated values; update the code so setQueryInURL is stable or the
effect sees fresh values—either memoize setQueryInURL with useCallback including
queryParams and location in its dependency list, or add queryParams (and
location if used) to the effect dependencies that currently include
initialSchema, schema, and configLoaded; ensure you keep
getDefaultQuery/defaultQueryFromTenant and the logic comparing
defaultOtelQuery/defaultViaqQuery unchanged while removing the eslint-disable so
React's lint enforces correct deps.
- Line 69: The hook currently calls useSearchParams only to read queryParams and
manually builds URLs with navigate, which is more error-prone; update the hook
to destructure both values from useSearchParams (const [queryParams,
setSearchParams] = useSearchParams()) and refactor functions that modify the
URL—notably setQueryInURL and any navigate-based setters that change
QUERY_PARAM_KEY—to call setSearchParams with an updater callback
(mutating/setting QUERY_PARAM_KEY on the passed URLSearchParams) and pass the
replace option when needed, removing manual URL string construction and navigate
usage for query-only changes.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: b1a3c509-2a07-40a3-9925-5ea3bb45732c

📥 Commits

Reviewing files that changed from the base of the PR and between 2dd2c47 and bea31b9.

📒 Files selected for processing (5)
  • web/cypress/e2e/integration/logs-alerts.cy.ts
  • web/cypress/e2e/integration/logs-detail-page.cy.ts
  • web/cypress/e2e/integration/logs-dev-page.cy.ts
  • web/cypress/e2e/integration/logs-page.cy.ts
  • web/src/hooks/useURLState.ts
✅ Files skipped from review due to trivial changes (1)
  • web/cypress/e2e/integration/logs-alerts.cy.ts

Copy link
Copy Markdown

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

🧹 Nitpick comments (2)
web/src/components/tenant-dropdown.tsx (2)

40-47: ⚡ Quick win

Guard the missing-value case before normalizing the selection.

PatternFly types Select.onSelect with an optional value. If that ever comes through as undefined, String(value) becomes the literal "undefined" and this code will forward it as if it were a real tenant. An early value == null return makes the handler robust. (pf-react-staging.patternfly.org)

Suggested change
   const onSelect = (
     _: ReactMouseEvent<Element, MouseEvent> | undefined,
     value: string | number | undefined,
   ) => {
+    if (value == null) {
+      setIsOpen(false);
+      return;
+    }
     const selectedValue = isOption(value) ? value.value : String(value);
     setIsOpen(false);
     if (selectedValue && selectedValue !== selectedTenant) {
       onTenantSelected?.(selectedValue);
     }
🤖 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 `@web/src/components/tenant-dropdown.tsx` around lines 40 - 47, The onSelect
handler currently normalizes an optional value with String(value) which can
produce the literal "undefined" and be forwarded as a tenant; update the
onSelect function to early-return when value == null (or value === undefined)
before calling isOption/String, so you only proceed to setIsOpen, compare
against selectedTenant, and call onTenantSelected with a real selection;
reference the onSelect function and use the existing helpers isOption,
setIsOpen, selectedTenant, and onTenantSelected when implementing the guard.

12-19: ⚡ Quick win

Let onOpenChange own outside-close behavior.

PatternFly already calls onOpenChange when the menu should close because of outside clicks or configured close keys. Keeping a second window-level click listener here duplicates that logic and gives this component two separate close paths to maintain. (pf-react-staging.patternfly.org)

Suggested change
 import {
   FC,
   MouseEvent as ReactMouseEvent,
   Ref,
-  useCallback,
-  useEffect,
-  useRef,
   useState,
 } from 'react';
@@
-  const selectRef = useRef<HTMLDivElement>(null);
-
   const onToggle = () => setIsOpen(!isOpen);
@@
-  const handleClickOutside = useCallback(
-    (event: MouseEvent) => {
-      if (isOpen && !selectRef.current?.contains(event.target as Node)) {
-        setIsOpen(false);
-      }
-    },
-    [isOpen, setIsOpen],
-  );
-
-  useEffect(() => {
-    if (isOpen) {
-      window.addEventListener('click', handleClickOutside);
-    }
-    return () => {
-      window.removeEventListener('click', handleClickOutside);
-    };
-  }, [isOpen, handleClickOutside]);
@@
-    <div ref={selectRef}>
+    <div>

Also applies to: 37-38, 51-67, 82-82

🤖 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 `@web/src/components/tenant-dropdown.tsx` around lines 12 - 19, Remove the
manual window-level click listener and associated outside-click handling so
PatternFly's onOpenChange controls outside-close behavior; specifically, delete
the useEffect that adds/removes window.addEventListener('click', ...) and any
helper like handleClickOutside or logic that calls setIsOpen(false) from that
listener, and instead rely on the component's onOpenChange/onToggle handlers
(e.g., the isOpen state setter and the onOpenChange prop passed into
TenantDropdown) so there is a single close path managed by PatternFly.
🤖 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.

Nitpick comments:
In `@web/src/components/tenant-dropdown.tsx`:
- Around line 40-47: The onSelect handler currently normalizes an optional value
with String(value) which can produce the literal "undefined" and be forwarded as
a tenant; update the onSelect function to early-return when value == null (or
value === undefined) before calling isOption/String, so you only proceed to
setIsOpen, compare against selectedTenant, and call onTenantSelected with a real
selection; reference the onSelect function and use the existing helpers
isOption, setIsOpen, selectedTenant, and onTenantSelected when implementing the
guard.
- Around line 12-19: Remove the manual window-level click listener and
associated outside-click handling so PatternFly's onOpenChange controls
outside-close behavior; specifically, delete the useEffect that adds/removes
window.addEventListener('click', ...) and any helper like handleClickOutside or
logic that calls setIsOpen(false) from that listener, and instead rely on the
component's onOpenChange/onToggle handlers (e.g., the isOpen state setter and
the onOpenChange prop passed into TenantDropdown) so there is a single close
path managed by PatternFly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 0fb1406e-b834-4f42-af8f-2ebc31a35c99

📥 Commits

Reviewing files that changed from the base of the PR and between bea31b9 and 18a5908.

📒 Files selected for processing (1)
  • web/src/components/tenant-dropdown.tsx

@etmurasaki
Copy link
Copy Markdown
Contributor

/label qe-approved

@openshift-ci openshift-ci Bot added the qe-approved Signifies that QE has signed off on this PR label May 6, 2026
@PeterYurkovich
Copy link
Copy Markdown
Contributor Author

/test ci/prow/test-e2e

@PeterYurkovich
Copy link
Copy Markdown
Contributor Author

/retest

@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented May 6, 2026

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

@zhuje
Copy link
Copy Markdown
Contributor

zhuje commented May 6, 2026

/lgtm

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label May 6, 2026
@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented May 6, 2026

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: PeterYurkovich, zhuje

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:
  • OWNERS [PeterYurkovich,zhuje]

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

@openshift-merge-bot openshift-merge-bot Bot merged commit 81c3a0f into openshift:main May 6, 2026
7 checks passed
@PeterYurkovich
Copy link
Copy Markdown
Contributor Author

/cherry-pick release-coo-ocp-4.22

@openshift-cherrypick-robot
Copy link
Copy Markdown

@PeterYurkovich: #368 failed to apply on top of branch "release-coo-ocp-4.22":

Applying: feat: 4.22 breaking changes
Using index info to reconstruct a base tree...
M	web/src/attribute-filters.tsx
M	web/src/components/alerts/logs-alerts-metrics.tsx
M	web/src/components/filters/attribute-filter.tsx
M	web/src/components/filters/attribute-value-data.tsx
M	web/src/components/filters/search-select.tsx
M	web/src/components/logs-table.tsx
M	web/src/components/refresh-interval-dropdown.tsx
M	web/src/components/virtualized-logs-table.tsx
M	web/src/hooks/LogsConfigProvider.tsx
M	web/src/hooks/useLogs.ts
M	web/src/hooks/useURLState.ts
M	web/src/pages/logs-detail-page.tsx
M	web/src/pages/logs-dev-page.tsx
M	web/src/pages/logs-page.tsx
Falling back to patching base and 3-way merge...
Auto-merging web/src/pages/logs-page.tsx
CONFLICT (content): Merge conflict in web/src/pages/logs-page.tsx
Auto-merging web/src/pages/logs-dev-page.tsx
CONFLICT (content): Merge conflict in web/src/pages/logs-dev-page.tsx
Auto-merging web/src/pages/logs-detail-page.tsx
CONFLICT (content): Merge conflict in web/src/pages/logs-detail-page.tsx
Auto-merging web/src/hooks/useURLState.ts
CONFLICT (content): Merge conflict in web/src/hooks/useURLState.ts
Removing web/src/hooks/useQueryParams.ts
Auto-merging web/src/hooks/useLogs.ts
CONFLICT (content): Merge conflict in web/src/hooks/useLogs.ts
Auto-merging web/src/hooks/LogsConfigProvider.tsx
CONFLICT (content): Merge conflict in web/src/hooks/LogsConfigProvider.tsx
Auto-merging web/src/components/virtualized-logs-table.tsx
CONFLICT (content): Merge conflict in web/src/components/virtualized-logs-table.tsx
Auto-merging web/src/components/refresh-interval-dropdown.tsx
CONFLICT (content): Merge conflict in web/src/components/refresh-interval-dropdown.tsx
Auto-merging web/src/components/logs-table.tsx
CONFLICT (content): Merge conflict in web/src/components/logs-table.tsx
Auto-merging web/src/components/filters/search-select.tsx
CONFLICT (content): Merge conflict in web/src/components/filters/search-select.tsx
Auto-merging web/src/components/filters/attribute-value-data.tsx
CONFLICT (content): Merge conflict in web/src/components/filters/attribute-value-data.tsx
Auto-merging web/src/components/filters/attribute-filter.tsx
Auto-merging web/src/components/alerts/logs-alerts-metrics.tsx
CONFLICT (content): Merge conflict in web/src/components/alerts/logs-alerts-metrics.tsx
Auto-merging web/src/attribute-filters.tsx
CONFLICT (content): Merge conflict in web/src/attribute-filters.tsx
Removing web/cypress/views/utils.ts
Removing web/.eslintrc.yml
Removing Dockerfile.konflux
error: Failed to merge in the changes.
hint: Use 'git am --show-current-patch=diff' to see the failed patch
hint: When you have resolved this problem, run "git am --continue".
hint: If you prefer to skip this patch, run "git am --skip" instead.
hint: To restore the original branch and stop patching, run "git am --abort".
hint: Disable this message with "git config set advice.mergeConflict false"
Patch failed at 0001 feat: 4.22 breaking changes

Details

In response to this:

/cherry-pick release-coo-ocp-4.22

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.

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. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. lgtm Indicates that a PR is ready to be merged. qe-approved Signifies that QE has signed off on this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants