From 16e716f6e885a3fffff122243e9c8fbda5d35925 Mon Sep 17 00:00:00 2001 From: Robb Hamilton Date: Thu, 26 Mar 2026 08:03:49 -0400 Subject: [PATCH] OCPBUGS-78543: Hide filter category selector when only one filter exists Adds CSS to hide the filter category dropdown selector when there's only one filter type available in ConsoleDataView, improving UX by removing unnecessary UI elements. Changes: - Create ConsoleDataView.scss with `.co-console-data-view-single-filter` class - Apply class to DataView component when single filter is present - Import CSS utilities and stylesheet in ConsoleDataView.tsx - Add Cypress test to verify category selector is hidden for both text and select filter types - Add reusable test helper `verifySingleFilterCategoryHidden` The CSS uses `!important` to ensure the rule works across all breakpoints and targets the first child of the filter group (the category selector). Co-Authored-By: Claude Sonnet 4.5 --- .../components/data-view/ConsoleDataView.scss | 7 +++++ .../components/data-view/ConsoleDataView.tsx | 7 ++++- .../tests/app/filtering-and-searching.cy.ts | 30 +++++++++++++++++++ .../alertmanager/receivers/email.cy.ts | 2 +- .../alertmanager/receivers/pagerduty.cy.ts | 2 +- .../alertmanager/receivers/slack.cy.ts | 2 +- .../alertmanager/receivers/webhook.cy.ts | 2 +- .../views/alertmanager.ts | 8 +++-- 8 files changed, 53 insertions(+), 7 deletions(-) create mode 100644 frontend/packages/console-app/src/components/data-view/ConsoleDataView.scss diff --git a/frontend/packages/console-app/src/components/data-view/ConsoleDataView.scss b/frontend/packages/console-app/src/components/data-view/ConsoleDataView.scss new file mode 100644 index 00000000000..96af174138e --- /dev/null +++ b/frontend/packages/console-app/src/components/data-view/ConsoleDataView.scss @@ -0,0 +1,7 @@ +// Hide the filter category selector when there's only one filter. +// We use CSS instead of TypeScript prop changes because PatternFly's +// DataViewFilters component doesn't expose a prop to hide the category selector. +// This CSS-only solution avoids forking or patching the upstream component. +.co-console-data-view-single-filter .pf-v6-c-toolbar__group.pf-m-filter-group > *:first-child { + display: none !important; +} diff --git a/frontend/packages/console-app/src/components/data-view/ConsoleDataView.tsx b/frontend/packages/console-app/src/components/data-view/ConsoleDataView.tsx index 58330f0c38d..1eb0794306f 100644 --- a/frontend/packages/console-app/src/components/data-view/ConsoleDataView.tsx +++ b/frontend/packages/console-app/src/components/data-view/ConsoleDataView.tsx @@ -1,4 +1,5 @@ import * as React from 'react'; +import './ConsoleDataView.scss'; import { ResponsiveAction, ResponsiveActions, @@ -14,6 +15,7 @@ import { } from '@patternfly/react-data-view'; import DataViewFilters from '@patternfly/react-data-view/dist/cjs/DataViewFilters'; import { ColumnsIcon } from '@patternfly/react-icons'; +import { css } from '@patternfly/react-styles'; import { InnerScrollContainer, Tbody, Td, Tr } from '@patternfly/react-table'; import { useTranslation } from 'react-i18next'; import { ColumnLayout } from '@console/dynamic-plugin-sdk/src/extensions/console-types'; @@ -187,7 +189,10 @@ export const ConsoleDataView = < loadError={loadError} skeleton={
} > - + 0 && ( diff --git a/frontend/packages/integration-tests-cypress/tests/app/filtering-and-searching.cy.ts b/frontend/packages/integration-tests-cypress/tests/app/filtering-and-searching.cy.ts index aa8afa0d1be..09de204f775 100644 --- a/frontend/packages/integration-tests-cypress/tests/app/filtering-and-searching.cy.ts +++ b/frontend/packages/integration-tests-cypress/tests/app/filtering-and-searching.cy.ts @@ -6,6 +6,25 @@ import { listPage } from '../../views/list-page'; import { modal } from '../../views/modal'; import * as yamlEditor from '../../views/yaml-editor'; +const SINGLE_FILTER_GROUP_SELECTOR = + '.co-console-data-view-single-filter .pf-v6-c-toolbar__group.pf-m-filter-group'; + +const verifySingleFilterCategoryHidden = (expectedToggles: number) => { + cy.get('[data-test="data-view-table"]').should('exist'); + cy.get(SINGLE_FILTER_GROUP_SELECTOR) + .find('.pf-v6-c-menu-toggle') + .should('have.length', expectedToggles); + + if (expectedToggles === 1) { + cy.get(SINGLE_FILTER_GROUP_SELECTOR).find('.pf-v6-c-menu-toggle').should('not.be.visible'); + } else { + cy.get(SINGLE_FILTER_GROUP_SELECTOR) + .find('.pf-v6-c-menu-toggle') + .first() + .should('not.be.visible'); + } +}; + describe('Filtering and Searching', () => { let WORKLOAD_NAME; let WORKLOAD_LABEL; @@ -88,4 +107,15 @@ describe('Filtering and Searching', () => { }); listPage.rows.shouldExist(WORKLOAD_NAME); }); + + it('ConsoleDataView filter toolbar should not display a filter select', () => { + cy.log('when a text filter is the only filter'); + cy.visit('/settings/cluster/alertmanagerconfig?page=1&perPage=50'); + verifySingleFilterCategoryHidden(1); + + cy.log('when a select filter is the only filter'); + cy.visit('/search/all-namespaces?page=1&perPage=50&kind=core~v1~Pod'); + listPage.dvRows.shouldBeLoaded(); + verifySingleFilterCategoryHidden(2); + }); }); diff --git a/frontend/packages/integration-tests-cypress/tests/cluster-settings/alertmanager/receivers/email.cy.ts b/frontend/packages/integration-tests-cypress/tests/cluster-settings/alertmanager/receivers/email.cy.ts index 09ac5cc724a..e691b7b0f01 100644 --- a/frontend/packages/integration-tests-cypress/tests/cluster-settings/alertmanager/receivers/email.cy.ts +++ b/frontend/packages/integration-tests-cypress/tests/cluster-settings/alertmanager/receivers/email.cy.ts @@ -49,7 +49,7 @@ describe('Alertmanager: Email Receiver Form', () => { alertmanager.save(); cy.log('verify Email Receiver was created correctly'); - alertmanager.validateCreation(receiverName); + alertmanager.validateCreation(receiverName, 'integration-types', 'routing-labels'); alertmanager.visitYAMLPage(); yamlEditor.getEditorContent().then((content) => { const configs = getGlobalsAndReceiverConfig(receiverName, configName, content); diff --git a/frontend/packages/integration-tests-cypress/tests/cluster-settings/alertmanager/receivers/pagerduty.cy.ts b/frontend/packages/integration-tests-cypress/tests/cluster-settings/alertmanager/receivers/pagerduty.cy.ts index ba3e1f856de..608c885cebe 100644 --- a/frontend/packages/integration-tests-cypress/tests/cluster-settings/alertmanager/receivers/pagerduty.cy.ts +++ b/frontend/packages/integration-tests-cypress/tests/cluster-settings/alertmanager/receivers/pagerduty.cy.ts @@ -50,7 +50,7 @@ describe('Alertmanager: PagerDuty Receiver Form', () => { alertmanager.save(); cy.log('verify PagerDuty Receiver was created correctly'); - alertmanager.validateCreation(receiverName); + alertmanager.validateCreation(receiverName, 'integration-types', 'routing-labels'); cy.log('update pagerduty_url'); listPage.dvRows.clickKebabAction(receiverName, 'Edit Receiver'); diff --git a/frontend/packages/integration-tests-cypress/tests/cluster-settings/alertmanager/receivers/slack.cy.ts b/frontend/packages/integration-tests-cypress/tests/cluster-settings/alertmanager/receivers/slack.cy.ts index e7c8c7f3eaf..3e8d679d814 100644 --- a/frontend/packages/integration-tests-cypress/tests/cluster-settings/alertmanager/receivers/slack.cy.ts +++ b/frontend/packages/integration-tests-cypress/tests/cluster-settings/alertmanager/receivers/slack.cy.ts @@ -52,7 +52,7 @@ describe('Alertmanager: Slack Receiver Form', () => { alertmanager.save(); cy.log('verify Slack Receiver was created correctly'); - alertmanager.validateCreation(receiverName); + alertmanager.validateCreation(receiverName, 'integration-types', 'routing-labels'); alertmanager.visitYAMLPage(); yamlEditor.getEditorContent().then((content) => { const configs = getGlobalsAndReceiverConfig(receiverName, configName, content); diff --git a/frontend/packages/integration-tests-cypress/tests/cluster-settings/alertmanager/receivers/webhook.cy.ts b/frontend/packages/integration-tests-cypress/tests/cluster-settings/alertmanager/receivers/webhook.cy.ts index 7edaa453844..0ec694a7b91 100644 --- a/frontend/packages/integration-tests-cypress/tests/cluster-settings/alertmanager/receivers/webhook.cy.ts +++ b/frontend/packages/integration-tests-cypress/tests/cluster-settings/alertmanager/receivers/webhook.cy.ts @@ -34,7 +34,7 @@ describe('Alertmanager: Webhook Receiver Form', () => { alertmanager.save(); cy.log('verify Webhook Receiver was created correctly'); - alertmanager.validateCreation(receiverName); + alertmanager.validateCreation(receiverName, 'integration-types', 'routing-labels'); alertmanager.visitYAMLPage(); yamlEditor.getEditorContent().then((content) => { const configs = getGlobalsAndReceiverConfig(receiverName, configName, content); diff --git a/frontend/packages/integration-tests-cypress/views/alertmanager.ts b/frontend/packages/integration-tests-cypress/views/alertmanager.ts index f5e7f1bf139..c193bedfc00 100644 --- a/frontend/packages/integration-tests-cypress/views/alertmanager.ts +++ b/frontend/packages/integration-tests-cypress/views/alertmanager.ts @@ -68,10 +68,14 @@ export const alertmanager = { cy.exec( `kubectl patch secret 'alertmanager-main' -n 'openshift-monitoring' --type='json' -p='[{ op: 'replace', path: '/data/alertmanager.yaml', value: ${defaultAlertmanagerYaml}}]'`, ), - save: () => cy.byTestID('save-changes').should('be.enabled').click(), + save: () => { + cy.byTestID('save-changes').should('be.enabled').click(); + // wait for the changes to rollout + // eslint-disable-next-line cypress/no-unnecessary-waiting + cy.wait(10000); + }, showAdvancedConfiguration: () => cy.byTestID('advanced-configuration').find('button').click(), validateCreation: (receiverName: string, typeCellName: string, labelCellName: string) => { - listPage.dvFilter.byName(receiverName); listPage.dvRows.shouldExist(receiverName); listPage.dvRows.shouldExist(receiverName, typeCellName); listPage.dvRows.shouldExist(receiverName, labelCellName);