Skip to content

NETOBSERV-1829 Expose status + NETOBSERV-2376 Report more info#1388

Open
jpinsonneau wants to merge 5 commits intonetobserv:mainfrom
jpinsonneau:1829
Open

NETOBSERV-1829 Expose status + NETOBSERV-2376 Report more info#1388
jpinsonneau wants to merge 5 commits intonetobserv:mainfrom
jpinsonneau:1829

Conversation

@jpinsonneau
Copy link
Copy Markdown
Member

@jpinsonneau jpinsonneau commented Mar 30, 2026

Description

  • show status indicator next to pages titles

    • flow collector status
    • netflow traffic
    • health
  • bring user to FlowCollector/status page when clicking on the indicator

  • add a link in the alerts to bring the user in the status page too

  • components status from operator PR below

  • Normal scenario:

image image image
  • Kafka issue:
image
  • Lokistack issue:
image

Assisted-by: claude-4.6-opus-high

Dependencies

netobserv/netobserv-operator#2610

Checklist

If you are not familiar with our processes or don't know what to answer in the list below, let us know in a comment: the maintainers will take care of that.

  • Is this PR backed with a JIRA ticket? If so, make sure it is written as a title prefix (in general, PRs affecting the NetObserv/Network Observability product should be backed with a JIRA ticket - especially if they bring user facing changes).
  • Does this PR require product documentation?
    • If so, make sure the JIRA epic is labelled with "documentation" and provides a description relevant for doc writers, such as use cases or scenarios. Any required step to activate or configure the feature should be documented there, such as new CRD knobs.
  • Does this PR require a product release notes entry?
    • If so, fill in "Release Note Text" in the JIRA.
  • Is there anything else the QE team should know before testing? E.g: configuration changes, environment setup, etc.
    • If so, make sure it is described in the JIRA ticket.
  • QE requirements (check 1 from the list):
    • Standard QE validation, with pre-merge tests unless stated otherwise.
    • Regression tests only (e.g. refactoring with no user-facing change).
    • No QE (e.g. trivial change with high reviewer's confidence, or per agreement with the QE team).

Summary by CodeRabbit

  • New Features

    • Added FlowCollector status indicator displayed across the application, showing readiness states (ready, degraded, pending, error, on hold) with visual indicators
    • Integrated status visibility on Network Health and Network Traffic pages
    • Added "View FlowCollector status" action link in alert notifications for quick access
  • Tests

    • Added comprehensive test coverage for FlowCollector status logic and UI components

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 30, 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

Walkthrough

Adds FlowCollector status support: new locale keys, a status-derivation utility, status icon and indicator components that watch the FlowCollector CR, UI integrations (banner, headers, flow traffic form), pipeline/resource-status UI changes, dummy CR updates, and unit tests plus a Jest mock.

Changes

Cohort / File(s) Summary
Localization & Test Setup
web/locales/en/plugin__netobserv-plugin.json, web/setup-tests.tsx
Added English locale keys for FlowCollector status UI and a Jest mock for useK8sWatchResource returning [null, false, null].
Status Utility
web/src/components/forms/utils.ts
Added FlowCollectorOverallStatus type and getFlowCollectorOverallStatus(cr, loadError) implementing status rules for loading, onHold, error, pending, ready, and degraded.
Status Icon & Indicator
web/src/components/status/flowcollector-status-icon.tsx, web/src/components/status/flowcollector-status-indicator.tsx
New FlowCollectorStatusIcon (icon + tooltip per status) and FlowCollectorStatusIndicator (watches FlowCollector CR via useK8sWatchResource, computes status, renders plain header button that navigates to status page).
Banner & Header Integrations
web/src/components/alerts/banner.tsx, web/src/components/health/network-health.tsx, web/src/components/netflow-traffic.tsx
Inserted status indicator into page headers and added "View FlowCollector status" action link in the alert banner.
Flow Traffic Form
web/src/components/forms/flowCollector-status.tsx
Refactored to use getFlowCollectorOverallStatus; show on-hold alert only for onHold; added header-side status button; always render traffic button but disable/gate navigation and adjust tooltip trigger based on computed status.
Pipeline & Resource Status UI
web/src/components/forms/pipeline.tsx, web/src/components/forms/resource-status.tsx
Replaced condition-driven step/status logic with component/integration-based statuses (ComponentStatus, ExporterStatus), updated step wiring/status mapping, added ComponentStatusTable UI and replica details, and added error handling around StepNode data access.
Dummy CR Simulator
web/moduleMapper/dummy.tsx
Overhauled mocked FlowCollector CR: new conditions, status.components, status.integrations, and new randomized update logic targeting components/integrations instead of prior condition toggles.
Tests
web/src/components/status/__tests__/flowcollector-status.spec.tsx
New unit tests covering getFlowCollectorOverallStatus behavior, FlowCollectorStatusIcon mappings, and FlowCollectorStatusIndicator rendering/variants.

Sequence Diagram

sequenceDiagram
    participant UI as User/UI
    participant Indicator as FlowCollectorStatusIndicator
    participant Watch as useK8sWatchResource
    participant K8s as Kubernetes API
    participant Utils as getFlowCollectorOverallStatus

    UI->>Indicator: render header button
    Indicator->>Watch: subscribe to FlowCollector CR (flows.netobserv.io/v1beta2, name:"cluster")
    Watch->>K8s: watch FlowCollector resource
    K8s-->>Watch: return (fc, loaded, loadError)
    Watch-->>Indicator: provide (fc, loaded, loadError)
    Indicator->>Utils: compute overall status (fc, loadError)
    Utils-->>Indicator: return status (ready/degraded/pending/error/onHold/loading)
    Indicator->>UI: render FlowCollectorStatusIcon + tooltip (status)
    UI-->>Indicator: user clicks button
    Indicator->>UI: navigate to flowCollectorStatusPath
Loading

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title references NETOBSERV-1829 and NETOBSERV-2376 tickets but lacks specificity about the actual changes (status indicators, page navigation, component status). Clarify the title to describe the main user-facing change, such as 'Add FlowCollector status indicators to page headers' or similar.
✅ Passed checks (1 passed)
Check name Status Explanation
Description check ✅ Passed The PR description includes the required sections: a clear Description with visual context, Dependencies, and a Checklist with QE requirements selected.

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

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

Warning

Review ran into problems

🔥 Problems

Timed out fetching pipeline failures after 30000ms


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
web/src/components/forms/flowCollector-status.tsx (1)

41-42: Don’t infer loaded from loadError.

getFlowCollectorOverallStatus expects the real watch completion flag, but ResourceWatcherContext only exposes loadError. Passing !ctx.loadError collapses “still loading” into “loaded with no error”. Please thread loaded through the context or derive the status before the context boundary.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/src/components/forms/flowCollector-status.tsx` around lines 41 - 42, The
code incorrectly infers loaded as !ctx.loadError when calling
getFlowCollectorOverallStatus; instead expose or derive a real loaded flag from
ResourceWatcherContext and use that. Update ResourceWatcherContext to include a
boolean loaded set when the watch completes (or compute loaded before crossing
the context boundary where you have the real watch completion), then replace
calls using !ctx.loadError with ctx.loaded when invoking
getFlowCollectorOverallStatus and any other places relying on load state
(reference: getFlowCollectorOverallStatus, ResourceWatcherContext,
ctx.loadError, ctx.loaded).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@web/setup-tests.tsx`:
- Around line 31-33: The global test mock for useK8sWatchResource currently
returns [null, false, null], forcing loaded=false for all consumers; change the
export in web/setup-tests.tsx to a configurable jest.fn() named
useK8sWatchResource that by default returns [null, true, null] (loaded=true) and
allow individual tests to override behavior via mockImplementation or
mockImplementationOnce to simulate loading/error states for components like
resource-watcher.tsx; update any tests that rely on the former global loading
behavior to explicitly set the mock to [null, false, null] or an error tuple
when needed.

---

Nitpick comments:
In `@web/src/components/forms/flowCollector-status.tsx`:
- Around line 41-42: The code incorrectly infers loaded as !ctx.loadError when
calling getFlowCollectorOverallStatus; instead expose or derive a real loaded
flag from ResourceWatcherContext and use that. Update ResourceWatcherContext to
include a boolean loaded set when the watch completes (or compute loaded before
crossing the context boundary where you have the real watch completion), then
replace calls using !ctx.loadError with ctx.loaded when invoking
getFlowCollectorOverallStatus and any other places relying on load state
(reference: getFlowCollectorOverallStatus, ResourceWatcherContext,
ctx.loadError, ctx.loaded).
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 86cd83fc-c74f-4a74-baf5-043d88609d7c

📥 Commits

Reviewing files that changed from the base of the PR and between 15f11bc and d510460.

📒 Files selected for processing (8)
  • web/locales/en/plugin__netobserv-plugin.json
  • web/setup-tests.tsx
  • web/src/components/alerts/banner.tsx
  • web/src/components/forms/flowCollector-status.tsx
  • web/src/components/forms/utils.ts
  • web/src/components/health/network-health.tsx
  • web/src/components/netflow-traffic.tsx
  • web/src/components/status/flowcollector-status-indicator.tsx

Comment on lines +31 to +33
useK8sWatchResource: () => {
return [null, false, null];
},
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Don’t leave every useK8sWatchResource mock in the loading state.

Returning [null, false, null] here forces loaded=false for every consumer. web/src/components/forms/resource-watcher.tsx will stay on its spinner path, and the new indicator can only render loading in tests. Please make this a configurable jest.fn() with a loaded default, then opt into loading/error states per test.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/setup-tests.tsx` around lines 31 - 33, The global test mock for
useK8sWatchResource currently returns [null, false, null], forcing loaded=false
for all consumers; change the export in web/setup-tests.tsx to a configurable
jest.fn() named useK8sWatchResource that by default returns [null, true, null]
(loaded=true) and allow individual tests to override behavior via
mockImplementation or mockImplementationOnce to simulate loading/error states
for components like resource-watcher.tsx; update any tests that rely on the
former global loading behavior to explicitly set the mock to [null, false, null]
or an error tuple when needed.

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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
web/src/components/forms/utils.ts (1)

27-38: Make the Ready check authoritative before hasError.

Right now any non-ComponentUnused false condition short-circuits to pending, so a CR with Ready=True plus another false condition will never surface as ready here. Downstream, that keeps showTrafficButton false in web/src/components/forms/flowCollector-status.tsx Line 42.

Proposed refactor
-  const hasError = conditions.some(c => c.status === 'False' && c.reason !== 'ComponentUnused');
-  if (hasError) {
-    const readyCondition = conditions.find(c => c.type === 'Ready');
-    if (readyCondition?.status === 'False') {
-      return 'error';
-    }
-    return 'pending';
-  }
   const readyCondition = conditions.find(c => c.type === 'Ready');
   if (readyCondition?.status === 'True') {
     return 'ready';
   }
+  const hasError = conditions.some(c => c.status === 'False' && c.reason !== 'ComponentUnused');
+  if (readyCondition?.status === 'False' && hasError) {
+    return 'error';
+  }
   return 'pending';
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/src/components/forms/utils.ts` around lines 27 - 38, The Ready condition
must be evaluated first so a Ready=True wins even if other conditions are False;
update the logic around the conditions array (the hasError boolean and
readyCondition lookup) to first find readyCondition (conditions.find(c => c.type
=== 'Ready')) and if its status === 'True' immediately return 'ready', otherwise
proceed to evaluate hasError (conditions.some(c => c.status === 'False' &&
c.reason !== 'ComponentUnused')) and if readyCondition?.status === 'False'
return 'error', else return 'pending' as appropriate; adjust the code in
utils.ts where hasError and readyCondition are computed so Ready is
authoritative.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@web/src/components/forms/flowCollector-status.tsx`:
- Around line 41-42: The status computation is using a synthetic loaded flag
(!ctx.loadError) which diverges from the real watch loaded state; update the
code so the real loaded flag from the watch is used: either add a loaded
property to ResourceWatcherContext and propagate the watch's loaded value
through the context, then call getFlowCollectorOverallStatus(ctx.data,
ctx.loaded, ctx.loadError) from flowCollector-status.tsx, or change
getFlowCollectorOverallStatus to drop the loaded parameter and compute readiness
from data/loadError consistently (also update flowcollector-status-indicator.tsx
to match). Ensure the fix references getFlowCollectorOverallStatus,
ResourceWatcherContext, flowCollector-status.tsx,
flowcollector-status-indicator.tsx, and useK8sWatchResource so both components
use the same real loaded boolean.

---

Nitpick comments:
In `@web/src/components/forms/utils.ts`:
- Around line 27-38: The Ready condition must be evaluated first so a Ready=True
wins even if other conditions are False; update the logic around the conditions
array (the hasError boolean and readyCondition lookup) to first find
readyCondition (conditions.find(c => c.type === 'Ready')) and if its status ===
'True' immediately return 'ready', otherwise proceed to evaluate hasError
(conditions.some(c => c.status === 'False' && c.reason !== 'ComponentUnused'))
and if readyCondition?.status === 'False' return 'error', else return 'pending'
as appropriate; adjust the code in utils.ts where hasError and readyCondition
are computed so Ready is authoritative.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2148dc3a-cc3f-4376-b9cd-8bdcd576a81f

📥 Commits

Reviewing files that changed from the base of the PR and between d510460 and 5065f07.

📒 Files selected for processing (8)
  • web/locales/en/plugin__netobserv-plugin.json
  • web/setup-tests.tsx
  • web/src/components/alerts/banner.tsx
  • web/src/components/forms/flowCollector-status.tsx
  • web/src/components/forms/utils.ts
  • web/src/components/health/network-health.tsx
  • web/src/components/netflow-traffic.tsx
  • web/src/components/status/flowcollector-status-indicator.tsx
✅ Files skipped from review due to trivial changes (2)
  • web/locales/en/plugin__netobserv-plugin.json
  • web/src/components/status/flowcollector-status-indicator.tsx
🚧 Files skipped from review as they are similar to previous changes (4)
  • web/src/components/alerts/banner.tsx
  • web/src/components/netflow-traffic.tsx
  • web/setup-tests.tsx
  • web/src/components/health/network-health.tsx

@jpinsonneau jpinsonneau changed the title Expose status / FlowCollector link NETOBSERV-1829 Expose status / FlowCollector link Mar 31, 2026
@jpinsonneau jpinsonneau added the ok-to-test To set manually when a PR is safe to test. Triggers image build on PR. label Mar 31, 2026
@github-actions
Copy link
Copy Markdown

New image:

quay.io/netobserv/network-observability-console-plugin:71c0c00

It will expire in two weeks.

To deploy this build, run from the operator repo, assuming the operator is running:

USER=netobserv VERSION=71c0c00 make set-plugin-image

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.

🧹 Nitpick comments (1)
web/src/components/status/__tests__/flowcollector-status.spec.tsx (1)

71-81: Test doesn't fully exercise the ComponentUnused exclusion.

The condition has status: 'Unknown', which wouldn't trigger hasError anyway (only 'False' does). To validate the exclusion logic at utils.ts:26, use status: 'False':

Suggested fix
   it('should ignore ComponentUnused conditions', () => {
     const cr = {
       status: {
         conditions: [
           { type: 'Ready', status: 'True', reason: 'Ready' },
-          { type: 'WaitingFLPTransformer', status: 'Unknown', reason: 'ComponentUnused' }
+          { type: 'WaitingFLPTransformer', status: 'False', reason: 'ComponentUnused' }
         ]
       }
     };
     expect(getFlowCollectorOverallStatus(cr, null)).toBe('ready');
   });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/src/components/status/__tests__/flowcollector-status.spec.tsx` around
lines 71 - 81, The test for getFlowCollectorOverallStatus does not exercise the
ComponentUnused exclusion because the condition uses status: 'Unknown' instead
of a failing status; change the WaitingFLPTransformer condition's status from
'Unknown' to 'False' so hasError (referenced in utils.ts at the exclusion logic
around line with ComponentUnused) would normally mark it as an error but is
excluded by the ComponentUnused reason, validating the exclusion behavior in
getFlowCollectorOverallStatus.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@web/src/components/status/__tests__/flowcollector-status.spec.tsx`:
- Around line 71-81: The test for getFlowCollectorOverallStatus does not
exercise the ComponentUnused exclusion because the condition uses status:
'Unknown' instead of a failing status; change the WaitingFLPTransformer
condition's status from 'Unknown' to 'False' so hasError (referenced in utils.ts
at the exclusion logic around line with ComponentUnused) would normally mark it
as an error but is excluded by the ComponentUnused reason, validating the
exclusion behavior in getFlowCollectorOverallStatus.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8512c42a-201d-4810-9a6c-8f2f7849964a

📥 Commits

Reviewing files that changed from the base of the PR and between 5065f07 and 7ace1e5.

📒 Files selected for processing (5)
  • web/setup-tests.tsx
  • web/src/components/forms/flowCollector-status.tsx
  • web/src/components/forms/utils.ts
  • web/src/components/status/__tests__/flowcollector-status.spec.tsx
  • web/src/components/status/flowcollector-status-indicator.tsx
✅ Files skipped from review due to trivial changes (1)
  • web/setup-tests.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • web/src/components/status/flowcollector-status-indicator.tsx

@jpinsonneau jpinsonneau marked this pull request as draft March 31, 2026 09:07
@github-actions github-actions bot removed the ok-to-test To set manually when a PR is safe to test. Triggers image build on PR. label Mar 31, 2026
@jpinsonneau jpinsonneau marked this pull request as ready for review March 31, 2026 09:53
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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@web/src/components/forms/flowCollector-status.tsx`:
- Around line 54-57: The Button wrapping the FlowCollectorStatusIcon (Button
component rendering at the FlowCollector status page) is non-functional and
should be replaced with a non-interactive element: remove the Button and render
the FlowCollectorStatusIcon inside a semantic, non-interactive wrapper (e.g., a
span or div) instead of Button, drop the aria-label and variant props, preserve
existing styling (cursor: 'default' or className) and keep the surrounding
FlexItem; update any imports/usages that assumed Button here and ensure no
onClick or role="button" remains.

In `@web/src/components/status/flowcollector-status-icon.tsx`:
- Around line 49-52: The icon-only Status component currently places the
translated status text only inside Tooltip (tooltipContent) making it
inaccessible to non-mouse users; update the wrapper span that currently renders
{icon} to include role="img" and aria-label set to the localized tooltipContent
(or the same translated status string) so screen readers always announce the
status—modify the span around {icon} in flowcollector-status-icon.tsx (the
element inside Tooltip) to add role="img" and aria-label={tooltipContent} while
preserving the existing Tooltip and icon usage.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 29ce06b0-c0c4-4200-bf64-17fc17d4453a

📥 Commits

Reviewing files that changed from the base of the PR and between 7ace1e5 and b439be5.

📒 Files selected for processing (10)
  • web/locales/en/plugin__netobserv-plugin.json
  • web/setup-tests.tsx
  • web/src/components/alerts/banner.tsx
  • web/src/components/forms/flowCollector-status.tsx
  • web/src/components/forms/utils.ts
  • web/src/components/health/network-health.tsx
  • web/src/components/netflow-traffic.tsx
  • web/src/components/status/__tests__/flowcollector-status.spec.tsx
  • web/src/components/status/flowcollector-status-icon.tsx
  • web/src/components/status/flowcollector-status-indicator.tsx
✅ Files skipped from review due to trivial changes (4)
  • web/setup-tests.tsx
  • web/src/components/alerts/banner.tsx
  • web/locales/en/plugin__netobserv-plugin.json
  • web/src/components/status/flowcollector-status-indicator.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • web/src/components/netflow-traffic.tsx
  • web/src/components/status/tests/flowcollector-status.spec.tsx

Comment on lines +54 to +57
<FlexItem>
<Button variant="plain" aria-label={t('FlowCollector status')} style={{ cursor: 'default' }}>
<FlowCollectorStatusIcon status={status} />
</Button>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Make the title indicator non-interactive on this page.

This Button has no action, so it adds a dead interactive control to the tab order. Since the user is already on the FlowCollector status page, render the icon in a non-button wrapper here instead.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/src/components/forms/flowCollector-status.tsx` around lines 54 - 57, The
Button wrapping the FlowCollectorStatusIcon (Button component rendering at the
FlowCollector status page) is non-functional and should be replaced with a
non-interactive element: remove the Button and render the
FlowCollectorStatusIcon inside a semantic, non-interactive wrapper (e.g., a span
or div) instead of Button, drop the aria-label and variant props, preserve
existing styling (cursor: 'default' or className) and keep the surrounding
FlexItem; update any imports/usages that assumed Button here and ensure no
onClick or role="button" remains.

Comment on lines +49 to +52
return (
<Tooltip content={tooltipContent} position="bottom">
<span style={{ display: 'inline-flex', verticalAlign: 'middle' }}>{icon}</span>
</Tooltip>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Expose the localized status outside the tooltip.

Right now this component renders only a visual icon plus a tooltip. That makes the new status indicator effectively mouse-first unless each caller remembers to add its own accessible name. Put the translated status on the wrapper (role="img" + aria-label) so the state is announced everywhere this icon is used.

♿ Proposed fix
   return (
     <Tooltip content={tooltipContent} position="bottom">
-      <span style={{ display: 'inline-flex', verticalAlign: 'middle' }}>{icon}</span>
+      <span
+        role="img"
+        aria-label={tooltipContent}
+        style={{ display: 'inline-flex', verticalAlign: 'middle' }}
+      >
+        {icon}
+      </span>
     </Tooltip>
   );
📝 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
return (
<Tooltip content={tooltipContent} position="bottom">
<span style={{ display: 'inline-flex', verticalAlign: 'middle' }}>{icon}</span>
</Tooltip>
return (
<Tooltip content={tooltipContent} position="bottom">
<span
role="img"
aria-label={tooltipContent}
style={{ display: 'inline-flex', verticalAlign: 'middle' }}
>
{icon}
</span>
</Tooltip>
);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/src/components/status/flowcollector-status-icon.tsx` around lines 49 -
52, The icon-only Status component currently places the translated status text
only inside Tooltip (tooltipContent) making it inaccessible to non-mouse users;
update the wrapper span that currently renders {icon} to include role="img" and
aria-label set to the localized tooltipContent (or the same translated status
string) so screen readers always announce the status—modify the span around
{icon} in flowcollector-status-icon.tsx (the element inside Tooltip) to add
role="img" and aria-label={tooltipContent} while preserving the existing Tooltip
and icon usage.

@jpinsonneau
Copy link
Copy Markdown
Member Author

@jotak would it be good to remove the overall step in the pipeline view since we have it next to the title now ?

image

@jpinsonneau jpinsonneau changed the title NETOBSERV-1829 Expose status / FlowCollector link NETOBSERV-1829 Expose status + NETOBSERV-2376 Report more info Apr 1, 2026
@jpinsonneau jpinsonneau added the ok-to-test To set manually when a PR is safe to test. Triggers image build on PR. label Apr 1, 2026
@github-actions github-actions bot removed the ok-to-test To set manually when a PR is safe to test. Triggers image build on PR. label Apr 1, 2026
@openshift-ci
Copy link
Copy Markdown

openshift-ci bot commented Apr 1, 2026

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please ask for approval from jotak. 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

@jpinsonneau jpinsonneau added the ok-to-test To set manually when a PR is safe to test. Triggers image build on PR. label Apr 1, 2026
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 1, 2026

New image:

quay.io/netobserv/network-observability-console-plugin:1de08d8

It will expire in two weeks.

To deploy this build, run from the operator repo, assuming the operator is running:

USER=netobserv VERSION=1de08d8 make set-plugin-image

@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 1, 2026

New image:

quay.io/netobserv/network-observability-console-plugin:b118697

It will expire in two weeks.

To deploy this build, run from the operator repo, assuming the operator is running:

USER=netobserv VERSION=b118697 make set-plugin-image

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.

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (1)
web/src/components/forms/flowCollector-status.tsx (1)

125-125: ⚠️ Potential issue | 🟡 Minor

Typo: "retreiving" → "retrieving".

✏️ Fix
-                        {t('An error occured while retreiving FlowCollector: {{error}}', { error: ctx.loadError })}
+                        {t('An error occurred while retrieving FlowCollector: {{error}}', { error: ctx.loadError })}

Note: Also "occured" → "occurred".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/src/components/forms/flowCollector-status.tsx` at line 125, The
translation string passed to t(...) in FlowCollector-status.tsx has typos;
update the message inside the t call from "An error occured while retreiving
FlowCollector: {{error}}" to "An error occurred while retrieving FlowCollector:
{{error}}" (keep the interpolation { error: ctx.loadError } unchanged) so the UI
displays correct spelling.
🧹 Nitpick comments (8)
web/src/components/forms/pipeline.tsx (3)

314-316: Magic number 100 for setTimeout delay.

Consider extracting as a named constant for clarity.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/src/components/forms/pipeline.tsx` around lines 314 - 316, The anonymous
setTimeout delay of 100 in the pipeline component is a magic number—replace it
with a named constant (e.g., FIT_DELAY_MS or RESIZE_DEBOUNCE_MS) declared near
the top of the module or component so its meaning is clear; update the call that
currently invokes setTimeout(() => fit(), 100) to use that constant and add a
brief comment about the constant's purpose to aid readability and future tuning
(reference the fit invocation inside the pipeline component).

66-84: stateToRunStatus and exporterStateToRunStatus are nearly identical.

Consider unifying them. The only difference is Ready + unhealthyPodCount handling, which could be a parameter or handled upstream.

Also applies to: 86-99

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/src/components/forms/pipeline.tsx` around lines 66 - 84, The two
functions stateToRunStatus and exporterStateToRunStatus are almost identical;
unify them by extracting a single helper (e.g., normalizeStateToRunStatus) that
accepts the ComponentStatus-like object plus an optional flag or predicate for
the Ready+unhealthyPodCount check (or accept unhealthyPodCount as a parameter),
then replace both stateToRunStatus and exporterStateToRunStatus to call that
helper; reference the existing symbols stateToRunStatus,
exporterStateToRunStatus and unhealthyPodCount when updating callers so the
Ready branch logic is preserved via the extra parameter instead of duplicating
switch logic.

123-125: Empty catch block silently swallows errors.

At minimum, log or report the error to aid debugging.

♻️ Add minimal logging
-  } catch {
+  } catch (e) {
+    console.warn('StepNode render failed', e);
     return null;
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/src/components/forms/pipeline.tsx` around lines 123 - 125, The current
catch block in web/src/components/forms/pipeline.tsx swallows errors (catch {
return null; })—change it to capture the thrown error (e.g., catch (err)) and
log or report it before returning null; use the app's logger if available (or
console.error) and include contextual info (function/component name and relevant
variables) so errors in the pipeline form logic are visible during debugging.
web/moduleMapper/dummy.tsx (1)

313-326: Random state updates don't include 'Unused'.

The states array omits 'Unused', so that UI path won't be exercised during dev testing. Add it if you want coverage.

♻️ Include Unused state
-          const states = ['Ready', 'InProgress', 'Degraded', 'Failure'];
+          const states = ['Ready', 'InProgress', 'Degraded', 'Failure', 'Unused'];
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/moduleMapper/dummy.tsx` around lines 313 - 326, The simulated status
updater omits the 'Unused' state so the UI path isn't exercised; update the
local states array (the one defined as const states = ['Ready', 'InProgress',
'Degraded', 'Failure'];) inside the random update block that mutates
fc.status.components[...] and fc.status.integrations.monitoring to include
'Unused' (e.g., add 'Unused' to the states array) so randomized assignments to
component or integration state can produce that value during dev testing.
web/src/components/forms/resource-status.tsx (3)

119-135: Using array index as React key for exporters.

exporter-${i} works here since exporters likely don't reorder, but if the list can change order, consider using a stable identifier like exp.name or exp.type combined.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/src/components/forms/resource-status.tsx` around lines 119 - 135, The
list mapping uses array index as the React key and selector id
(`key={`exporter-${i}`}` and selectedTypes entries), which can break stability
if exporters reorder; change the key and the values stored in selectedTypes to a
stable identifier such as `${exp.name || exp.type}` (or another unique property
on each exporter) and update the row selection logic in the map and the
onRowClick handler (and any consumers of selectedTypes, e.g., setSelectedTypes)
to use that stable id instead of `exporter-${i}` so keys and selection remain
consistent when the array changes.

29-61: Consider consolidating stateColor and StateIcon into a single mapping.

Both functions map the same state values. A single lookup object would reduce duplication and ensure consistency.

♻️ Example consolidation
const STATE_CONFIG: Record<string, { color: LabelColor; icon: React.ReactNode }> = {
  Ready: { color: 'green', icon: <CheckCircleIcon color="var(--pf-v5-global--success-color--100)" /> },
  Degraded: { color: 'orange', icon: <ExclamationTriangleIcon color="var(--pf-v5-global--warning-color--100)" /> },
  // ... etc
};

const stateColor = (state: string | undefined): LabelColor => STATE_CONFIG[state ?? '']?.color ?? 'grey';
const StateIcon: FC<{ state: string | undefined }> = ({ state }) => STATE_CONFIG[state ?? '']?.icon ?? <UnknownIcon ... />;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/src/components/forms/resource-status.tsx` around lines 29 - 61,
stateColor and StateIcon duplicate the same state-to-presentation mapping;
consolidate them by creating a single lookup (e.g., STATE_CONFIG) that maps each
state string to an object with color and icon properties, then rewrite
stateColor to return STATE_CONFIG[state ?? '']?.color ?? 'grey' and change
StateIcon to return STATE_CONFIG[state ?? '']?.icon ?? <UnknownIcon ...>,
updating imports/types as needed (refer to the stateColor and StateIcon symbols
to locate the code and ensure LabelColor typing and default fallbacks are
preserved).

114-116: Nested ternaries are hard to scan.

This chain determines the Details cell content. Consider extracting to a helper for readability.

♻️ Cleaner approach
+const getStatusDetail = (status: ComponentStatus): string =>
+  status.podIssues || status.message || status.reason || '-';
+
 <Td>
-  {c.status.podIssues ? c.status.podIssues : c.status.message ? c.status.message : c.status.reason || '-'}
+  {getStatusDetail(c.status)}
 </Td>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/src/components/forms/resource-status.tsx` around lines 114 - 116, The
Details cell uses nested ternaries (c.status.podIssues ? ... ) which is hard to
read; extract this logic into a small helper like getStatusDetail(status) (or
statusMessage(status)) that returns status.podIssues || status.message ||
status.reason || '-' using optional chaining/nullish coalescing, then replace
the inline expression in the <Td> with a call to that helper; implement the
helper in the same resource-status.tsx (or a nearby util) to improve readability
and testability and reference c.status when invoking it.
web/src/components/forms/utils.ts (1)

27-31: Magic string 'Ready,Degraded' couples to operator's exact output.

If the operator changes this reason format, the degraded state won't be detected. Consider extracting as a constant or matching with a pattern (e.g., includes 'Degraded').

♻️ More resilient check
   if (readyCondition?.status === 'True') {
-    if (readyCondition.reason === 'Ready,Degraded') {
+    if (readyCondition.reason?.includes('Degraded')) {
       return 'degraded';
     }
     return 'ready';
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/src/components/forms/utils.ts` around lines 27 - 31, The check for
readyCondition.reason === 'Ready,Degraded' is brittle; update the code around
readyCondition (the block that currently returns 'degraded' when reason equals
'Ready,Degraded') to use a resilient check: either extract the literal into a
constant (e.g., READY_DEGRADED_REASON) and compare to that constant, or match
the reason with a pattern such as readyCondition.reason?.includes('Degraded') or
a regex (/Degraded/). Ensure the new check still falls back to returning 'ready'
when not degraded and keep references to readyCondition.reason and the branch
that returns 'degraded' intact so behavior is clear.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@web/src/components/forms/pipeline.tsx`:
- Around line 218-228: The processor step uses _.last(steps)!.id which can throw
if steps is empty; change the runAfterTasks creation in the block that builds
the processor step (where existing?.spec is checked and the object with id:
'processor' is pushed) to safely compute the previous id—e.g., check
steps.length or _.last(steps) before accessing .id and either set runAfterTasks
to an empty array or omit it when there is no previous step; update any
references to runAfterTasks consumers to accept an empty/missing array if
needed.

---

Outside diff comments:
In `@web/src/components/forms/flowCollector-status.tsx`:
- Line 125: The translation string passed to t(...) in FlowCollector-status.tsx
has typos; update the message inside the t call from "An error occured while
retreiving FlowCollector: {{error}}" to "An error occurred while retrieving
FlowCollector: {{error}}" (keep the interpolation { error: ctx.loadError }
unchanged) so the UI displays correct spelling.

---

Nitpick comments:
In `@web/moduleMapper/dummy.tsx`:
- Around line 313-326: The simulated status updater omits the 'Unused' state so
the UI path isn't exercised; update the local states array (the one defined as
const states = ['Ready', 'InProgress', 'Degraded', 'Failure'];) inside the
random update block that mutates fc.status.components[...] and
fc.status.integrations.monitoring to include 'Unused' (e.g., add 'Unused' to the
states array) so randomized assignments to component or integration state can
produce that value during dev testing.

In `@web/src/components/forms/pipeline.tsx`:
- Around line 314-316: The anonymous setTimeout delay of 100 in the pipeline
component is a magic number—replace it with a named constant (e.g., FIT_DELAY_MS
or RESIZE_DEBOUNCE_MS) declared near the top of the module or component so its
meaning is clear; update the call that currently invokes setTimeout(() => fit(),
100) to use that constant and add a brief comment about the constant's purpose
to aid readability and future tuning (reference the fit invocation inside the
pipeline component).
- Around line 66-84: The two functions stateToRunStatus and
exporterStateToRunStatus are almost identical; unify them by extracting a single
helper (e.g., normalizeStateToRunStatus) that accepts the ComponentStatus-like
object plus an optional flag or predicate for the Ready+unhealthyPodCount check
(or accept unhealthyPodCount as a parameter), then replace both stateToRunStatus
and exporterStateToRunStatus to call that helper; reference the existing symbols
stateToRunStatus, exporterStateToRunStatus and unhealthyPodCount when updating
callers so the Ready branch logic is preserved via the extra parameter instead
of duplicating switch logic.
- Around line 123-125: The current catch block in
web/src/components/forms/pipeline.tsx swallows errors (catch { return null;
})—change it to capture the thrown error (e.g., catch (err)) and log or report
it before returning null; use the app's logger if available (or console.error)
and include contextual info (function/component name and relevant variables) so
errors in the pipeline form logic are visible during debugging.

In `@web/src/components/forms/resource-status.tsx`:
- Around line 119-135: The list mapping uses array index as the React key and
selector id (`key={`exporter-${i}`}` and selectedTypes entries), which can break
stability if exporters reorder; change the key and the values stored in
selectedTypes to a stable identifier such as `${exp.name || exp.type}` (or
another unique property on each exporter) and update the row selection logic in
the map and the onRowClick handler (and any consumers of selectedTypes, e.g.,
setSelectedTypes) to use that stable id instead of `exporter-${i}` so keys and
selection remain consistent when the array changes.
- Around line 29-61: stateColor and StateIcon duplicate the same
state-to-presentation mapping; consolidate them by creating a single lookup
(e.g., STATE_CONFIG) that maps each state string to an object with color and
icon properties, then rewrite stateColor to return STATE_CONFIG[state ??
'']?.color ?? 'grey' and change StateIcon to return STATE_CONFIG[state ??
'']?.icon ?? <UnknownIcon ...>, updating imports/types as needed (refer to the
stateColor and StateIcon symbols to locate the code and ensure LabelColor typing
and default fallbacks are preserved).
- Around line 114-116: The Details cell uses nested ternaries
(c.status.podIssues ? ... ) which is hard to read; extract this logic into a
small helper like getStatusDetail(status) (or statusMessage(status)) that
returns status.podIssues || status.message || status.reason || '-' using
optional chaining/nullish coalescing, then replace the inline expression in the
<Td> with a call to that helper; implement the helper in the same
resource-status.tsx (or a nearby util) to improve readability and testability
and reference c.status when invoking it.

In `@web/src/components/forms/utils.ts`:
- Around line 27-31: The check for readyCondition.reason === 'Ready,Degraded' is
brittle; update the code around readyCondition (the block that currently returns
'degraded' when reason equals 'Ready,Degraded') to use a resilient check: either
extract the literal into a constant (e.g., READY_DEGRADED_REASON) and compare to
that constant, or match the reason with a pattern such as
readyCondition.reason?.includes('Degraded') or a regex (/Degraded/). Ensure the
new check still falls back to returning 'ready' when not degraded and keep
references to readyCondition.reason and the branch that returns 'degraded'
intact so behavior is clear.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: dff4c8f3-16b7-4f3d-9222-59cbcbce6212

📥 Commits

Reviewing files that changed from the base of the PR and between b439be5 and 74f8861.

📒 Files selected for processing (7)
  • web/moduleMapper/dummy.tsx
  • web/src/components/forms/flowCollector-status.tsx
  • web/src/components/forms/pipeline.tsx
  • web/src/components/forms/resource-status.tsx
  • web/src/components/forms/utils.ts
  • web/src/components/status/__tests__/flowcollector-status.spec.tsx
  • web/src/components/status/flowcollector-status-icon.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • web/src/components/status/tests/flowcollector-status.spec.tsx
  • web/src/components/status/flowcollector-status-icon.tsx

@github-actions github-actions bot removed the ok-to-test To set manually when a PR is safe to test. Triggers image build on PR. label Apr 1, 2026
@jpinsonneau jpinsonneau added the ok-to-test To set manually when a PR is safe to test. Triggers image build on PR. label Apr 3, 2026
@kapjain-rh kapjain-rh removed the ok-to-test To set manually when a PR is safe to test. Triggers image build on PR. label Apr 6, 2026
@kapjain-rh
Copy link
Copy Markdown
Member

/ok-to-test

@openshift-ci openshift-ci bot added the ok-to-test To set manually when a PR is safe to test. Triggers image build on PR. label Apr 6, 2026
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 6, 2026

New image:

quay.io/netobserv/network-observability-console-plugin:61f40a0

It will expire in two weeks.

To deploy this build, run from the operator repo, assuming the operator is running:

USER=netobserv VERSION=61f40a0 make set-plugin-image

1 similar comment
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 6, 2026

New image:

quay.io/netobserv/network-observability-console-plugin:61f40a0

It will expire in two weeks.

To deploy this build, run from the operator repo, assuming the operator is running:

USER=netobserv VERSION=61f40a0 make set-plugin-image

@jpinsonneau
Copy link
Copy Markdown
Member Author

Rebased without changes

@github-actions github-actions bot removed the ok-to-test To set manually when a PR is safe to test. Triggers image build on PR. label Apr 8, 2026
@jpinsonneau
Copy link
Copy Markdown
Member Author

Rebased without changes

@codecov
Copy link
Copy Markdown

codecov bot commented Apr 10, 2026

Codecov Report

❌ Patch coverage is 81.69014% with 13 lines in your changes missing coverage. Please review.
✅ Project coverage is 52.53%. Comparing base (c83176f) to head (82c9d7d).

Files with missing lines Patch % Lines
web/moduleMapper/dummy.tsx 0.00% 11 Missing ⚠️
web/src/components/alerts/banner.tsx 50.00% 1 Missing ⚠️
...mponents/status/flowcollector-status-indicator.tsx 93.33% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1388      +/-   ##
==========================================
+ Coverage   52.48%   52.53%   +0.05%     
==========================================
  Files         229      232       +3     
  Lines       12246    12355     +109     
  Branches     1531     1551      +20     
==========================================
+ Hits         6427     6491      +64     
- Misses       5224     5269      +45     
  Partials      595      595              
Flag Coverage Δ
uitests 56.74% <81.69%> (+0.02%) ⬆️
unittests 40.96% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
web/src/components/forms/utils.ts 39.68% <100.00%> (ø)
web/src/components/netflow-traffic.tsx 71.00% <100.00%> (+0.17%) ⬆️
...rc/components/status/flowcollector-status-icon.tsx 100.00% <100.00%> (ø)
web/src/components/alerts/banner.tsx 38.88% <50.00%> (-2.29%) ⬇️
...mponents/status/flowcollector-status-indicator.tsx 93.33% <93.33%> (ø)
web/moduleMapper/dummy.tsx 26.98% <0.00%> (-1.12%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@kapjain-rh
Copy link
Copy Markdown
Member

/ok-to-test

@openshift-ci openshift-ci bot added the ok-to-test To set manually when a PR is safe to test. Triggers image build on PR. label Apr 13, 2026
@github-actions
Copy link
Copy Markdown

New image:

quay.io/netobserv/network-observability-console-plugin:6fe6277

It will expire in two weeks.

To deploy this build, run from the operator repo, assuming the operator is running:

USER=netobserv VERSION=6fe6277 make set-plugin-image

Copy link
Copy Markdown
Contributor

@leandroberetta leandroberetta left a comment

Choose a reason for hiding this comment

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

lgtm, thanks @jpinsonneau !

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

Labels

lgtm ok-to-test To set manually when a PR is safe to test. Triggers image build on PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants