Skip to content

CONSOLE-5158: Add filter by group for nodes#16253

Open
jeff-phillips-18 wants to merge 1 commit into
openshift:mainfrom
jeff-phillips-18:node-group-filter
Open

CONSOLE-5158: Add filter by group for nodes#16253
jeff-phillips-18 wants to merge 1 commit into
openshift:mainfrom
jeff-phillips-18:node-group-filter

Conversation

@jeff-phillips-18

@jeff-phillips-18 jeff-phillips-18 commented Apr 3, 2026

Copy link
Copy Markdown
Member

Summary

Adds a "Filter by groups" checkbox filter to the Nodes page, enabling users to filter nodes by their assigned group annotations. Also improves the UX of the "Edit groups" button by showing it in a disabled state with an informative tooltip when users lack permission, rather than hiding it completely.

Changes

  • Nodes page filter: Added new "Filter by groups" checkbox filter that dynamically populates with all existing group names from the node list
  • Edit groups button UX: Changed the "Edit groups" button (both on Nodes page and Node Details Card) to remain visible but disabled when users lack permission, with a tooltip explaining why
  • i18n: Added localization strings for "Filter by groups" and permission tooltip

Implementation details

  • Leverages the existing getExistingGroups() utility to extract unique group names from nodes
  • Filter logic follows the same pattern as roles and architecture filters
  • Tooltip only displays when user lacks permission (not during loading state)

Test plan

  • Verify "Filter by groups" appears in the filter toolbar on the Nodes page
  • Verify filter options dynamically populate based on groups assigned to nodes
  • Verify filtering works correctly when selecting one or multiple groups
  • Verify "Edit groups" button shows disabled state with tooltip when user lacks nodes/patch permission
  • Verify "Edit" button in Node Details Card shows disabled state with tooltip when user lacks permission
  • Verify buttons are enabled and tooltips don't show when user has permission

Manual Test Steps

Prerequisites

  • Access to an OpenShift cluster with console running in tech-preview
  • Multiple nodes with different groups assigned (to test filtering)
  • Two test users:
    • User A: Has nodes/patch permission
    • User B: Does NOT have nodes/patch permission

Test Case 1: Filter by Groups - Basic Functionality

Steps:

  1. Navigate to Compute → Nodes page
  2. Locate the filter toolbar above the nodes table
  3. Verify "Filter by groups" option appears in the filter toolbar

Expected Result:

  • "Filter by groups" filter is visible in the toolbar alongside other filters (status, roles, architecture, etc.)

Test Case 2: Filter Options Populate Dynamically

Steps:

  1. On the Nodes page, click the "Filter by groups" dropdown
  2. Observe the available group options

Expected Result:

  • Dropdown displays all unique groups that are currently assigned to nodes in the cluster
  • Options dynamically reflect the actual groups present (no hardcoded values)
  • If no nodes have groups, the dropdown should be empty or show no options

Test Case 3: Single Group Filtering

Steps:

  1. Click "Filter by groups" dropdown
  2. Select a single group (e.g., "production")
  3. Observe the nodes table

Expected Result:

  • Table shows only nodes that belong to the selected group
  • Nodes without the selected group are hidden
  • Filter chip appears showing the active filter

Test Case 4: Multiple Group Filtering

Steps:

  1. Click "Filter by groups" dropdown
  2. Select multiple groups (e.g., "production" and "staging")
  3. Observe the nodes table

Expected Result:

  • Table shows nodes that belong to ANY of the selected groups (OR logic)
  • Multiple filter chips appear for each selected group
  • Correct count of filtered nodes is displayed

Test Case 5: Edit Groups Button - Disabled State (No Permission)

Steps:

  1. Log in as User B (without nodes/patch permission)
  2. Navigate to Compute → Nodes page
  3. Locate the "Edit groups" button in the page header

Expected Result:

  • "Edit groups" button is visible but in a disabled state
  • Hovering over the button displays tooltip: "You do not have permission to edit groups."
  • Clicking the button does nothing

Test Case 6: Edit Groups Button - Enabled State (With Permission)

Steps:

  1. Log in as User A (with nodes/patch permission)
  2. Navigate to Compute → Nodes page
  3. Locate the "Edit groups" button in the page header

Expected Result:

  • "Edit groups" button is enabled
  • No tooltip appears when hovering
  • Clicking the button opens the Groups Editor modal

Test Case 7: Node Details Card - Edit Button Disabled (No Permission)

Steps:

  1. Log in as User B (without nodes/patch permission)
  2. Navigate to Compute → Nodes page
  3. Click on any node name to view node details
  4. Locate the "Groups" section in the Details Card
  5. Locate the "Edit" button next to "Groups"

Expected Result:

  • "Edit" button is visible but disabled
  • Hovering over the button displays tooltip: "You do not have permission to edit groups."
  • Clicking the button does nothing

Test Case 8: Node Details Card - Edit Button Enabled (With Permission)

Steps:

  1. Log in as User A (with nodes/patch permission)
  2. Navigate to Compute → Nodes page
  3. Click on any node name to view node details
  4. Locate the "Groups" section in the Details Card
  5. Locate the "Edit" button next to "Groups"

Expected Result:

  • "Edit" button is enabled
  • No tooltip appears when hovering
  • Clicking the button opens the Node Groups Editor modal

Test Case 9: Combined Filter Testing

Steps:

  1. On the Nodes page, apply multiple filters simultaneously:
    - Filter by status (e.g., "Ready")
    - Filter by roles (e.g., "worker")
    - Filter by groups (e.g., "production")
  2. Observe the nodes table

Expected Result:

  • Table shows only nodes matching ALL applied filters (AND logic across different filter types)
  • All filter chips are displayed
  • Removing individual filter chips correctly updates the results

Notes:

  • The "Filter by groups" feature only appears when Node Management v1 is enabled
  • Test with various group configurations (nodes with 0, 1, or multiple groups)
  • Verify i18n strings are properly loaded (no missing translation keys)

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

Summary by CodeRabbit

  • New Features

    • Added a group-based checkbox filter to the nodes view (when the feature is enabled) to filter nodes by selected group membership.
    • Improved the “Edit groups” control: it’s now consistently shown when enabled, disabled while editing is in progress, and provides guidance when permission is missing.
  • Localization

    • Added English strings for the “You do not have permission to edit groups.” message and the “Filter by groups” label.

@openshift-ci-robot

openshift-ci-robot commented Apr 3, 2026

Copy link
Copy Markdown
Contributor

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

Details

In response to this:

Summary

Adds a "Filter by groups" checkbox filter to the Nodes page, enabling users to filter nodes by their assigned group annotations. Also improves the UX of the "Edit groups" button by showing it in a disabled state with an informative tooltip when users lack permission, rather than hiding it completely.

Changes

  • Nodes page filter: Added new "Filter by groups" checkbox filter that dynamically populates with all existing group names from the node list
  • Edit groups button UX: Changed the "Edit groups" button (both on Nodes page and Node Details Card) to remain visible but disabled when users lack permission, with a tooltip explaining why
  • i18n: Added localization strings for "Filter by groups" and permission tooltip

Implementation details

  • Leverages the existing getExistingGroups() utility to extract unique group names from nodes
  • Filter logic follows the same pattern as roles and architecture filters
  • Tooltip only displays when user lacks permission (not during loading state)

Test plan

  • Verify "Filter by groups" appears in the filter toolbar on the Nodes page
  • Verify filter options dynamically populate based on groups assigned to nodes
  • Verify filtering works correctly when selecting one or multiple groups
  • Verify "Edit groups" button shows disabled state with tooltip when user lacks nodes/patch permission
  • Verify "Edit" button in Node Details Card shows disabled state with tooltip when user lacks permission
  • Verify buttons are enabled and tooltips don't show when user has permission

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

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Apr 3, 2026
@openshift-ci openshift-ci Bot requested review from Leo6Leo and spadgett April 3, 2026 13:24
@openshift-ci openshift-ci Bot added component/core Related to console core functionality kind/i18n Indicates issue or PR relates to internationalization or has content that needs to be translated labels Apr 3, 2026
@openshift-ci-robot

openshift-ci-robot commented Apr 3, 2026

Copy link
Copy Markdown
Contributor

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

Details

In response to this:

Summary

Adds a "Filter by groups" checkbox filter to the Nodes page, enabling users to filter nodes by their assigned group annotations. Also improves the UX of the "Edit groups" button by showing it in a disabled state with an informative tooltip when users lack permission, rather than hiding it completely.

Changes

  • Nodes page filter: Added new "Filter by groups" checkbox filter that dynamically populates with all existing group names from the node list
  • Edit groups button UX: Changed the "Edit groups" button (both on Nodes page and Node Details Card) to remain visible but disabled when users lack permission, with a tooltip explaining why
  • i18n: Added localization strings for "Filter by groups" and permission tooltip

Implementation details

  • Leverages the existing getExistingGroups() utility to extract unique group names from nodes
  • Filter logic follows the same pattern as roles and architecture filters
  • Tooltip only displays when user lacks permission (not during loading state)

Test plan

  • Verify "Filter by groups" appears in the filter toolbar on the Nodes page
  • Verify filter options dynamically populate based on groups assigned to nodes
  • Verify filtering works correctly when selecting one or multiple groups
  • Verify "Edit groups" button shows disabled state with tooltip when user lacks nodes/patch permission
  • Verify "Edit" button in Node Details Card shows disabled state with tooltip when user lacks permission
  • Verify buttons are enabled and tooltips don't show when user has permission

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

Summary by CodeRabbit

Release Notes

  • New Features
  • Added a "Groups" filter to the nodes data view for filtering and viewing nodes by group membership
  • Improved the "Edit groups" button with enhanced visual feedback, including disabled state and informative tooltips that clarify permission restrictions when users cannot edit groups

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

coderabbitai Bot commented Apr 3, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Enterprise

Run ID: 4eeccad3-7ba0-4deb-950d-61859f12e55e

📥 Commits

Reviewing files that changed from the base of the PR and between ec9dff3 and d7ff01d.

📒 Files selected for processing (3)
  • frontend/packages/console-app/locales/en/console-app.json
  • frontend/packages/console-app/src/components/nodes/NodesPage.tsx
  • frontend/packages/console-app/src/components/nodes/node-dashboard/DetailsCard.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • frontend/packages/console-app/src/components/nodes/node-dashboard/DetailsCard.tsx
  • frontend/packages/console-app/locales/en/console-app.json

Walkthrough

Adds group-based checkbox filtering to the Nodes page, two English locale strings, and changes the group Edit button to always render (disabled when unauthorized) with a tooltip; DetailsCard gets the same edit-button behavior.

Changes

Node group filtering and edit UX

Layer / File(s) Summary
Locale keys
frontend/packages/console-app/locales/en/console-app.json
Adds "You do not have permission to edit groups." and "Filter by groups", and reorders the existing Edit key.
NodesPage: group filter integration
frontend/packages/console-app/src/components/nodes/NodesPage.tsx
Imports getExistingGroups, computes nodeGroupFilterOptions, adds a groups checkbox filter and initialFilters.groups, extends NodeFilters with groups: string[], and updates matchesAdditionalFilters to apply group membership (excluding CSR resources when groups are selected).
NodesPage: renderGroupEditButton header
frontend/packages/console-app/src/components/nodes/NodesPage.tsx
Refactors header "Edit groups" into renderGroupEditButton that disables the button when `isEditLoading
DetailsCard: unified edit-button render
frontend/packages/console-app/src/components/nodes/node-dashboard/DetailsCard.tsx
Adds Tooltip import, introduces renderGroupEditButton helper with identical disablement and tooltip-wrapping logic, and changes layout to always render the Edit button adjacent to the "Groups" display when nodeMgmtV1Enabled.

🎯 3 (Moderate) | ⏱️ ~25 minutes


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error)

Check name Status Explanation Resolution
No-Sensitive-Data-In-Logs ❌ Error The PR adds console.error logging that logs unfiltered exception objects which may contain sensitive data like Prometheus URLs, HTTP responses, and internal endpoint details from fetch errors. Remove or sanitize the console.error statement, or only log safe error properties (e.g., error message) without exposing the full error object containing URLs and response data.
✅ Passed checks (14 passed)
Check name Status Explanation
Title check ✅ Passed The PR title clearly and specifically identifies the main change: adding a filter-by-groups feature to the Nodes page, directly matching the primary functionality in the changeset.
Description check ✅ Passed The PR description comprehensively covers all required template sections including analysis, solution details, test plan with nine detailed test cases, and manual testing steps, exceeding the template requirements.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Stable And Deterministic Test Names ✅ Passed This PR contains no Ginkgo test files. The changes are frontend-only (React/TypeScript components and locale files) with no Go test code added or modified. The check for stable test names does not...
Test Structure And Quality ✅ Passed PR is a frontend TypeScript/React change (UI filter feature) with no Ginkgo test code to review; custom check applies only to Go test files.
Microshift Test Compatibility ✅ Passed No Ginkgo e2e tests were added in this PR. Changes are limited to frontend React components and JSON localization files.
Single Node Openshift (Sno) Test Compatibility ✅ Passed PR does not add any Ginkgo e2e tests. The modified test files are backend unit tests using Go's standard testing package, not Ginkgo-based e2e tests.
Topology-Aware Scheduling Compatibility ✅ Passed PR contains only frontend console UI changes (React components and i18n strings). No deployment manifests, operator code, controllers, or scheduling constraints are introduced, making the topology-...
Ote Binary Stdout Contract ✅ Passed PR modifies only frontend React components and locale files; no Go test binaries or process-level entry points (main, TestMain, BeforeSuite, etc.) present. OTE Binary Stdout Contract check is inapp...
Ipv6 And Disconnected Network Test Compatibility ✅ Passed No Ginkgo e2e tests added to the PR. Changes are frontend TypeScript/React components and JSON localization files only, not e2e test code.
No-Weak-Crypto ✅ Passed No weak cryptography usage detected. PR contains only UI/localization changes for node filtering and permission display, with no crypto operations.
Container-Privileges ✅ Passed This PR contains only UI component code and locale files; no container/K8s manifests present. The check for privileged container configurations is not applicable.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
frontend/packages/console-app/src/components/nodes/NodesPage.tsx (1)

705-711: Use isCSRResource() to filter before extracting group options.

The data array mixes NodeKind and CertificateSigningRequestKind objects, but getExistingGroups expects NodeKind[]. While the current code works safely—getNodeGroups defensively handles CSRs via optional chaining—the type cast obscures this. Since isCSRResource() is already available, filter explicitly:

Suggested improvement
 const nodeGroupFilterOptions = useMemo<DataViewFilterOption[]>(() => {
-  const groupNames = getExistingGroups(data as NodeKind[]);
+  const actualNodes = data.filter((item) => !isCSRResource(item)) as NodeKind[];
+  const groupNames = getExistingGroups(actualNodes);
   return groupNames.map((groupName) => ({
     value: groupName,
     label: groupName,
   }));
 }, [data]);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/packages/console-app/src/components/nodes/NodesPage.tsx` around
lines 705 - 711, nodeGroupFilterOptions currently casts mixed data to NodeKind[]
before calling getExistingGroups, hiding that data may include
CertificateSigningRequestKind; update the useMemo to first filter data using
isCSRResource(item) to exclude CSRs (e.g. data.filter(item =>
!isCSRResource(item))) and then pass that filtered array to getExistingGroups
without a type cast so getExistingGroups receives a proper NodeKind[] and the
types are accurate.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@frontend/packages/console-app/src/components/nodes/NodesPage.tsx`:
- Around line 769-775: The Groups checkbox filter (DataViewCheckboxFilter with
filterId="groups" using nodeGroupFilterOptions) must only be rendered when the
feature flag nodeMgmtV1Enabled is true; update the JSX to conditionally include
that DataViewCheckboxFilter based on nodeMgmtV1Enabled and ensure the same flag
is used when computing additionalFilterNodes for the NodeList (or move
generation of filter nodes into a memo that depends on nodeMgmtV1Enabled) so the
filter visibility matches the presence of the Groups column.

---

Nitpick comments:
In `@frontend/packages/console-app/src/components/nodes/NodesPage.tsx`:
- Around line 705-711: nodeGroupFilterOptions currently casts mixed data to
NodeKind[] before calling getExistingGroups, hiding that data may include
CertificateSigningRequestKind; update the useMemo to first filter data using
isCSRResource(item) to exclude CSRs (e.g. data.filter(item =>
!isCSRResource(item))) and then pass that filtered array to getExistingGroups
without a type cast so getExistingGroups receives a proper NodeKind[] and the
types are accurate.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Pro

Run ID: 3a0f7827-0bdf-44d3-bd97-a24d9c17b5e5

📥 Commits

Reviewing files that changed from the base of the PR and between 89b5685 and cb1d6a3.

📒 Files selected for processing (3)
  • frontend/packages/console-app/locales/en/console-app.json
  • frontend/packages/console-app/src/components/nodes/NodesPage.tsx
  • frontend/packages/console-app/src/components/nodes/node-dashboard/DetailsCard.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/locales/en/console-app.json
  • frontend/packages/console-app/src/components/nodes/node-dashboard/DetailsCard.tsx
  • frontend/packages/console-app/src/components/nodes/NodesPage.tsx
🔇 Additional comments (4)
frontend/packages/console-app/locales/en/console-app.json (1)

392-392: LGTM!

New i18n strings are correctly added and follow the existing key/value conventions. The permission tooltip message is clear and consistent with other permission-related strings in the codebase.

Also applies to: 453-453

frontend/packages/console-app/src/components/nodes/node-dashboard/DetailsCard.tsx (1)

104-119: LGTM!

The tooltip pattern is correctly implemented. The wrapper <div> is the right approach for attaching tooltips to disabled buttons (disabled elements don't receive focus/hover events). The conditional ref assignment ensures the tooltip only appears when permission is definitively denied (not during loading).

frontend/packages/console-app/src/components/nodes/NodesPage.tsx (2)

831-840: LGTM!

The groups filter logic correctly handles CSR resources by returning false early, and the membership check using some() with includes() follows the established pattern from the roles filter. Good consistency.


1080-1095: LGTM!

Same tooltip pattern as DetailsCard.tsx - wrapper span for the disabled button trigger, conditional ref assignment, and tooltip content for permission denial. Consistent implementation across both locations.

Comment thread frontend/packages/console-app/src/components/nodes/NodesPage.tsx Outdated
@jeff-phillips-18

Copy link
Copy Markdown
Member Author

/test e2e-gcp-console

@jeff-phillips-18

Copy link
Copy Markdown
Member Author

/retest

@jhadvig jhadvig left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for this change! The filter implementation cleanly follows the existing roles/architecture patterns, the feature flag gating is properly applied, and the disabled-button-with-tooltip UX is a nice improvement over hiding the button entirely. The DetailsCard refactoring to OverviewDetailItem is also a welcome cleanup.

A few things to address — the always-mounted Tooltip, a ref type mismatch, and missing test coverage — but overall this is solid work. See inline comments for details.

Comment on lines +1096 to +1099
<Tooltip
triggerRef={editGroupButtonRef}
content={t('console-app~You do not have permission to edit groups.')}
/>

@jhadvig jhadvig May 19, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The <Tooltip> is always mounted in the DOM, even when the user has permission and the tooltip will never display. When canEdit is true, editGroupButtonRef.current is null — PF handles it gracefully, but it's an unnecessary component mount with internal effects/subscriptions.

Conditionally render it only when the button is actually disabled:

{!isEditLoading && !canEdit && (
  <Tooltip
    triggerRef={editGroupButtonRef}
    content={t('console-app~You do not have permission to edit groups.')}
  />
)}

Same issue in DetailsCard.tsx.

const { t } = useTranslation();
const launchOverlay = useOverlay();
const nodeMgmtV1Enabled = useFlag(FLAG_NODE_MGMT_V1);
const editGroupButtonRef = useRef<HTMLDivElement>(null);

@jhadvig jhadvig May 19, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ref type mismatch — useRef<HTMLDivElement> but it's attached to a <span> wrapper below (line 1087). Should be useRef<HTMLSpanElement>.

Note: in DetailsCard.tsx the wrapper is a <div>, so it's correct there — just inconsistent here.

Comment on lines +705 to +711
const nodeGroupFilterOptions = useMemo<DataViewFilterOption[]>(() => {
const groupNames = getExistingGroups(data as NodeKind[]);
return groupNames.map((groupName) => ({
value: groupName,
label: groupName,
}));
}, [data]);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

[NIT] [data] dependency means this recomputes whenever any node changes (not just group annotations), which then cascades through additionalFilterNodes. This mirrors how machineSetFilterOptions works so it's consistent, just noting for awareness — on large clusters with frequent metrics refreshes, getExistingGroups iterates all nodes on every update.

</DescriptionListGroup>
<Flex justifyContent={{ default: 'justifyContentSpaceBetween' }}>
<FlexItem>
<OverviewDetailItem isLoading={!obj} title={t('console-app~Groups')}>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

👍 Nice improvement — the previous code used raw <dt> elements with manual PF class names, which was fragile. Switching to OverviewDetailItem delegates the proper semantic structure while keeping the edit button positioned via Flex. Cleaner and more consistent.

Comment on lines 833 to +843
}
}

// Groups filter
if (filters.groups.length > 0) {
if (isCSR) {
return false;
}
const nodeGroups = getNodeGroups(resource as NodeKind);
if (!filters.groups.some((r) => nodeGroups.includes(r))) {
return false;

@jhadvig jhadvig May 19, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

No tests added for the new filter behavior. The filter follows established patterns, but the matchesAdditionalFilters logic and the disabled-button-with-tooltip UX should have coverage — at minimum:

  • Groups filter options are correctly derived from node data
  • Filter correctly includes/excludes nodes by selected groups
  • CSR resources are excluded from group filtering
  • Filter only renders when nodeMgmtV1Enabled is true

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

While I agree there should be tests for these additions to the NodesPage, there are currently no tests for the NodesPage. I have attempted to create tests but as claude says:

  I attempted extensively to render the full NodesPage component, but after persistent effort, encountered insurmountable issues:
  - 20+ nested dependencies requiring mocking
  - Circular dependency chains through PatternFly topology components
  - Undefined component errors despite extensive mocking attempts
  - Complex Redux/plugin system integrations that fail in Jest environment

Claude keeps creating mimic code and testing the mimic'd code rather than the actual code being used. I don't feel adding those tests serve any purpose.

@jhadvig jhadvig left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for the update! The renderGroupEditButton() rework in NodesPage.tsx is a nice improvement — the Tooltip now only renders when the button is actually disabled, which addresses the original concern cleanly.

Two items still open:

  1. DetailsCard.tsx still uses the always-mounted Tooltip pattern — the useRef<HTMLDivElement> + <Tooltip triggerRef={editGroupButtonRef}> is still rendered unconditionally. Consider applying the same conditional pattern used in NodesPage.tsx.
  2. No tests added — the filter logic, disabled button behavior, and feature flag gating still have no test coverage.

Comment on lines +114 to +117
<Tooltip
triggerRef={editGroupButtonRef}
content={t('console-app~You do not have permission to edit groups.')}
/>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The Tooltip is still always mounted here, even when the user has permission. NodesPage.tsx was updated to conditionally render the Tooltip — consider applying the same pattern here:

{!isEditLoading && !canEdit && (
  <Tooltip content={t('console-app~You do not have permission to edit groups.')}>
    <span>{editButton}</span>
  </Tooltip>
)}

@jhadvig

jhadvig commented May 20, 2026

Copy link
Copy Markdown
Member

@jeff-phillips-18 it looks like we need to re-run the yarn i18n

@jhadvig

jhadvig commented May 27, 2026

Copy link
Copy Markdown
Member

@jeff-phillips-18 thank you the PR looks good. One more thing, could you please add tests based on the Test Plan. Thank you

@openshift-ci-robot

openshift-ci-robot commented May 27, 2026

Copy link
Copy Markdown
Contributor

@jeff-phillips-18: This pull request references CONSOLE-5158 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 bug to target either version "5.0." or "openshift-5.0.", but it targets "openshift-4.22" instead.

Details

In response to this:

Summary

Adds a "Filter by groups" checkbox filter to the Nodes page, enabling users to filter nodes by their assigned group annotations. Also improves the UX of the "Edit groups" button by showing it in a disabled state with an informative tooltip when users lack permission, rather than hiding it completely.

Changes

  • Nodes page filter: Added new "Filter by groups" checkbox filter that dynamically populates with all existing group names from the node list
  • Edit groups button UX: Changed the "Edit groups" button (both on Nodes page and Node Details Card) to remain visible but disabled when users lack permission, with a tooltip explaining why
  • i18n: Added localization strings for "Filter by groups" and permission tooltip

Implementation details

  • Leverages the existing getExistingGroups() utility to extract unique group names from nodes
  • Filter logic follows the same pattern as roles and architecture filters
  • Tooltip only displays when user lacks permission (not during loading state)

Test plan

  • Verify "Filter by groups" appears in the filter toolbar on the Nodes page
  • Verify filter options dynamically populate based on groups assigned to nodes
  • Verify filtering works correctly when selecting one or multiple groups
  • Verify "Edit groups" button shows disabled state with tooltip when user lacks nodes/patch permission
  • Verify "Edit" button in Node Details Card shows disabled state with tooltip when user lacks permission
  • Verify buttons are enabled and tooltips don't show when user has permission

Manual Test Steps

Prerequisites

  • Access to an OpenShift cluster with console running in tech-preview
  • Multiple nodes with different groups assigned (to test filtering)
  • Two test users:
    • User A: Has nodes/patch permission
    • User B: Does NOT have nodes/patch permission

Test Case 1: Filter by Groups - Basic Functionality

Steps:

  1. Navigate to Compute → Nodes page
  2. Locate the filter toolbar above the nodes table
  3. Verify "Filter by groups" option appears in the filter toolbar

Expected Result:

  • "Filter by groups" filter is visible in the toolbar alongside other filters (status, roles, architecture, etc.)

Test Case 2: Filter Options Populate Dynamically

Steps:

  1. On the Nodes page, click the "Filter by groups" dropdown
  2. Observe the available group options

Expected Result:

  • Dropdown displays all unique groups that are currently assigned to nodes in the cluster
  • Options dynamically reflect the actual groups present (no hardcoded values)
  • If no nodes have groups, the dropdown should be empty or show no options

Test Case 3: Single Group Filtering

Steps:

  1. Click "Filter by groups" dropdown
  2. Select a single group (e.g., "production")
  3. Observe the nodes table

Expected Result:

  • Table shows only nodes that belong to the selected group
  • Nodes without the selected group are hidden
  • Filter chip appears showing the active filter

Test Case 4: Multiple Group Filtering

Steps:

  1. Click "Filter by groups" dropdown
  2. Select multiple groups (e.g., "production" and "staging")
  3. Observe the nodes table

Expected Result:

  • Table shows nodes that belong to ANY of the selected groups (OR logic)
  • Multiple filter chips appear for each selected group
  • Correct count of filtered nodes is displayed

Test Case 5: Edit Groups Button - Disabled State (No Permission)

Steps:

  1. Log in as User B (without nodes/patch permission)
  2. Navigate to Compute → Nodes page
  3. Locate the "Edit groups" button in the page header

Expected Result:

  • "Edit groups" button is visible but in a disabled state
  • Hovering over the button displays tooltip: "You do not have permission to edit groups."
  • Clicking the button does nothing

Test Case 6: Edit Groups Button - Enabled State (With Permission)

Steps:

  1. Log in as User A (with nodes/patch permission)
  2. Navigate to Compute → Nodes page
  3. Locate the "Edit groups" button in the page header

Expected Result:

  • "Edit groups" button is enabled
  • No tooltip appears when hovering
  • Clicking the button opens the Groups Editor modal

Test Case 7: Node Details Card - Edit Button Disabled (No Permission)

Steps:

  1. Log in as User B (without nodes/patch permission)
  2. Navigate to Compute → Nodes page
  3. Click on any node name to view node details
  4. Locate the "Groups" section in the Details Card
  5. Locate the "Edit" button next to "Groups"

Expected Result:

  • "Edit" button is visible but disabled
  • Hovering over the button displays tooltip: "You do not have permission to edit groups."
  • Clicking the button does nothing

Test Case 8: Node Details Card - Edit Button Enabled (With Permission)

Steps:

  1. Log in as User A (with nodes/patch permission)
  2. Navigate to Compute → Nodes page
  3. Click on any node name to view node details
  4. Locate the "Groups" section in the Details Card
  5. Locate the "Edit" button next to "Groups"

Expected Result:

  • "Edit" button is enabled
  • No tooltip appears when hovering
  • Clicking the button opens the Node Groups Editor modal

Test Case 9: Combined Filter Testing

Steps:

  1. On the Nodes page, apply multiple filters simultaneously:
  • Filter by status (e.g., "Ready")
  • Filter by roles (e.g., "worker")
  • Filter by groups (e.g., "production")
  1. Observe the nodes table

Expected Result:

  • Table shows only nodes matching ALL applied filters (AND logic across different filter types)
  • All filter chips are displayed
  • Removing individual filter chips correctly updates the results

Notes:

  • The "Filter by groups" feature only appears when Node Management v1 is enabled
  • Test with various group configurations (nodes with 0, 1, or multiple groups)
  • Verify i18n strings are properly loaded (no missing translation keys)

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

Summary by CodeRabbit

Release Notes

  • New Features
  • Added a "Groups" filter to the nodes data view for filtering and viewing nodes by group membership
  • Improved the "Edit groups" button with enhanced visual feedback, including disabled state and informative tooltips that clarify permission restrictions when users cannot edit groups

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.

@jeff-phillips-18

Copy link
Copy Markdown
Member Author

@jeff-phillips-18 thank you the PR looks good. One more thing, could you please add tests based on the Test Plan. Thank you

@jhadvig I have added the manual test steps to the PR description.

@jeff-phillips-18

Copy link
Copy Markdown
Member Author

/retest

@openshift-ci

openshift-ci Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

@jeff-phillips-18: all tests passed!

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

@TheRealJon TheRealJon left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

/lgtm

Should we add a Jira issue to track adding tests to the nodes dashboard?

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Jun 16, 2026
@openshift-ci

openshift-ci Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: jeff-phillips-18, TheRealJon

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

@openshift-ci openshift-ci Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jun 16, 2026
@jeff-phillips-18

Copy link
Copy Markdown
Member Author

Should we add a Jira issue to track adding tests to the nodes dashboard?

Added https://redhat.atlassian.net/browse/CONSOLE-5362

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants