diff --git a/cypress/component/DataViewFilters.cy.tsx b/cypress/component/DataViewFilters.cy.tsx index b0cdea1e..1e41657e 100644 --- a/cypress/component/DataViewFilters.cy.tsx +++ b/cypress/component/DataViewFilters.cy.tsx @@ -98,7 +98,7 @@ describe('DataViewFilters', () => { cy.get('[aria-label="Close Main branch"]').should('have.length', 0); }); - it('clears all filters using the clear-all button', () => { + it('clears all filters using the clear-all button and resets attribute to first', () => { cy.mount(); cy.get('[data-ouia-component-id="DataViewFilters"] .pf-v6-c-menu-toggle').click(); cy.contains('Name').click(); @@ -108,6 +108,8 @@ describe('DataViewFilters', () => { cy.contains('Branch').click(); cy.get('input[placeholder="Filter by branch"]').type('Main branch'); + cy.get('[data-ouia-component-id="DataViewFilters"]').should('contain.text', 'Branch'); cy.get('[data-ouia-component-id="FiltersExampleHeader-clear-all-filters"]').should('exist').click(); + cy.get('[data-ouia-component-id="DataViewFilters"]').should('contain.text', 'Name'); }); }); diff --git a/packages/module/src/DataViewFilters/DataViewFilters.test.tsx b/packages/module/src/DataViewFilters/DataViewFilters.test.tsx index 172ab6f6..d0fe60ef 100644 --- a/packages/module/src/DataViewFilters/DataViewFilters.test.tsx +++ b/packages/module/src/DataViewFilters/DataViewFilters.test.tsx @@ -37,4 +37,78 @@ describe('DataViewFilters component', () => { fireEvent.input(input, { target: { value: 'abc' } }); expect(mockOnChange).toHaveBeenCalledWith('one', { one: 'abc' }); }); + + it('should use defaultActiveFilter as initial active filter', () => { + const { container } = render( + + + + + } + /> + ); + + const toggle = container.querySelector('[data-ouia-component-id="DataViewFilters"] .pf-v6-c-menu-toggle') as HTMLButtonElement; + expect(toggle.textContent).toContain('Two'); + }); + + it('should reset active filter to defaultActiveFilter when all values are cleared', () => { + const { container, rerender } = render( + + + + + } + /> + ); + + const toggle = container.querySelector('[data-ouia-component-id="DataViewFilters"] .pf-v6-c-menu-toggle') as HTMLButtonElement; + expect(toggle.textContent).toContain('Two'); + + rerender( + + + + + } + /> + ); + + expect(toggle.textContent).toContain('Two'); + }); + + it('should reset active filter to first item when all values are cleared without defaultActiveFilter', () => { + const { container, rerender } = render( + + + + + } + /> + ); + + const toggle = container.querySelector('[data-ouia-component-id="DataViewFilters"] .pf-v6-c-menu-toggle') as HTMLButtonElement; + expect(toggle.textContent).toContain('One'); + + rerender( + + + + + } + /> + ); + + expect(toggle.textContent).toContain('One'); + }); }); diff --git a/packages/module/src/DataViewFilters/DataViewFilters.tsx b/packages/module/src/DataViewFilters/DataViewFilters.tsx index dc0dc218..b9b39622 100644 --- a/packages/module/src/DataViewFilters/DataViewFilters.tsx +++ b/packages/module/src/DataViewFilters/DataViewFilters.tsx @@ -1,4 +1,4 @@ -import { Children, isValidElement, cloneElement, useMemo, useState, useRef, useEffect, ReactElement, ReactNode } from 'react'; +import { Children, isValidElement, cloneElement, useMemo, useCallback, useState, useRef, useEffect, ReactElement, ReactNode } from 'react'; import { Menu, MenuContent, MenuItem, MenuList, MenuToggle, Popper, ToolbarGroup, ToolbarToggleGroup, ToolbarToggleGroupProps, } from '@patternfly/react-core'; @@ -31,6 +31,8 @@ export interface DataViewFiltersProps extends Omit({ breakpoint = 'xl', onChange, values, + defaultActiveFilter, ...props }: DataViewFiltersProps) => { const [ activeAttributeMenu, setActiveAttributeMenu ] = useState(''); @@ -60,9 +63,25 @@ export const DataViewFilters = ({ isValidElement(child) ? { filterId: String((child.props as any).filterId), title: String((child.props as any).title) } : undefined ).filter((item): item is DataViewFilterIdentifiers => !!item), [ childrenHash ]); // eslint-disable-line react-hooks/exhaustive-deps + const getDefaultTitle = useCallback(() => { + if (defaultActiveFilter) { + const match = filterItems.find(item => item.filterId === defaultActiveFilter); + if (match) { + return match.title; + } + } + return filterItems.length > 0 ? filterItems[0].title : ''; + }, [ defaultActiveFilter, filterItems ]); + + useEffect(() => { + setActiveAttributeMenu(getDefaultTitle()); + }, [ filterItems, getDefaultTitle ]); + useEffect(() => { - filterItems.length > 0 && setActiveAttributeMenu(filterItems[0].title); - }, [ filterItems ]); + if (values && Object.values(values).every(v => v === '' || v === undefined || (Array.isArray(v) && v.length === 0))) { + setActiveAttributeMenu(getDefaultTitle()); + } + }, [ values, getDefaultTitle ]); const handleClickOutside = (event: MouseEvent) => isAttributeMenuOpen &&