Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions cypress/component/DataViewCheckboxFilter.cy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import React from 'react';
import { DataViewCheckboxFilter, DataViewCheckboxFilterProps } from '@patternfly/react-data-view/dist/dynamic/DataViewCheckboxFilter';
import { DataViewToolbar } from '@patternfly/react-data-view/dist/dynamic/DataViewToolbar';

describe('DataViewCheckboxFilter component', () => {
const defaultProps: DataViewCheckboxFilterProps = {
filterId: 'test-checkbox-filter',
title: 'Test checkbox filter',
value: [ 'workspace-one' ],
options: [
{ label: 'Workspace one', value: 'workspace-one' },
{ label: 'Workspace two', value: 'workspace-two' },
{ label: 'Workspace three', value: 'workspace-three' },
],
};

it('renders a checkbox filter with options', () => {
const onChange = cy.stub().as('onChange');

cy.mount(
<DataViewToolbar filters={<DataViewCheckboxFilter {...defaultProps} onChange={onChange} />} />
);

cy.get('[data-ouia-component-id="DataViewCheckboxFilter-toggle"]')
.contains('Test checkbox filter')
.should('be.visible');

cy.get('[data-ouia-component-id="DataViewCheckboxFilter-badge"]')
.should('exist')
.contains('1');

cy.get('[data-ouia-component-id="DataViewCheckboxFilter-toggle"]').click();
cy.get('[data-ouia-component-id="DataViewCheckboxFilter-menu"]').should('be.visible');

cy.get('[data-ouia-component-id="DataViewCheckboxFilter-menu"]')
.find('li')
.should('have.length', 3)
.first()
.contains('Workspace one');

cy.get('[data-ouia-component-id="DataViewCheckboxFilter-menu"]')
.find('li')
.first()
.find('input[type="checkbox"]')
.should('be.checked');

cy.get('[data-ouia-component-id="DataViewCheckboxFilter-menu"]')
.find('li')
.eq(1)
.find('input[type="checkbox"]')
.click();

cy.get('@onChange').should('have.been.calledWith', Cypress.sinon.match.object, [ 'workspace-two', 'workspace-one' ]);
});

it('renders a checkbox filter with no options selected', () => {
const emptyProps = { ...defaultProps, value: [] };

cy.mount(
<DataViewToolbar filters={<DataViewCheckboxFilter {...emptyProps} />} />
);

cy.get('[data-ouia-component-id="DataViewCheckboxFilter-toggle"]').contains('Test checkbox filter');
cy.get('[data-ouia-component-id="DataViewCheckboxFilter-badge"]').should('not.exist');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ import { useDataViewFilters, useDataViewPagination } from '@patternfly/react-dat
import { DataView } from '@patternfly/react-data-view/dist/dynamic/DataView';
import { DataViewTable } from '@patternfly/react-data-view/dist/dynamic/DataViewTable';
import { DataViewToolbar } from '@patternfly/react-data-view/dist/dynamic/DataViewToolbar';
import { DataViewFilters } from '@patternfly/react-data-view/dist/dynamic/DataViewFilters';
import { DataViewFilterOption, DataViewFilters } from '@patternfly/react-data-view/dist/dynamic/DataViewFilters';
import { DataViewTextFilter } from '@patternfly/react-data-view/dist/dynamic/DataViewTextFilter';
import { DataViewCheckboxFilter } from '@patternfly/react-data-view/dist/dynamic/DataViewCheckboxFilter';

const perPageOptions = [
{ title: '5', value: 5 },
Expand All @@ -17,38 +18,51 @@ interface Repository {
name: string;
branch: string | null;
prs: string | null;
workspaces: string;
workspace: string;
lastCommit: string;
}

interface RepositoryFilters {
name: string,
branch: string
branch: string,
workspace: string[]
}

const repositories: Repository[] = [
{ name: 'Repository one', branch: 'Branch one', prs: 'Pull request one', workspaces: 'Workspace one', lastCommit: 'Timestamp one' },
{ name: 'Repository two', branch: 'Branch two', prs: 'Pull request two', workspaces: 'Workspace two', lastCommit: 'Timestamp two' },
{ name: 'Repository three', branch: 'Branch three', prs: 'Pull request three', workspaces: 'Workspace three', lastCommit: 'Timestamp three' },
{ name: 'Repository four', branch: 'Branch four', prs: 'Pull request four', workspaces: 'Workspace four', lastCommit: 'Timestamp four' },
{ name: 'Repository five', branch: 'Branch five', prs: 'Pull request five', workspaces: 'Workspace five', lastCommit: 'Timestamp five' },
{ name: 'Repository six', branch: 'Branch six', prs: 'Pull request six', workspaces: 'Workspace six', lastCommit: 'Timestamp six' }
{ name: 'Repository one', branch: 'Branch one', prs: 'Pull request one', workspace: 'Workspace one', lastCommit: 'Timestamp one' },
{ name: 'Repository two', branch: 'Branch two', prs: 'Pull request two', workspace: 'Workspace two', lastCommit: 'Timestamp two' },
{ name: 'Repository three', branch: 'Branch three', prs: 'Pull request three', workspace: 'Workspace one', lastCommit: 'Timestamp three' },
{ name: 'Repository four', branch: 'Branch four', prs: 'Pull request four', workspace: 'Workspace one', lastCommit: 'Timestamp four' },
{ name: 'Repository five', branch: 'Branch five', prs: 'Pull request five', workspace: 'Workspace two', lastCommit: 'Timestamp five' },
{ name: 'Repository six', branch: 'Branch six', prs: 'Pull request six', workspace: 'Workspace three', lastCommit: 'Timestamp six' }
];

const columns = [ 'Name', 'Branch', 'Pull requests', 'Workspaces', 'Last commit' ];
const filterOptions: DataViewFilterOption[] = [
{ label: 'Workspace one', value: 'workspace-one' },
{ label: 'Workspace two', value: 'workspace-two' },
{ label: 'Workspace three', value: 'workspace-three' }
];

const columns = [ 'Name', 'Branch', 'Pull requests', 'Workspace', 'Last commit' ];

const ouiaId = 'LayoutExample';

const MyTable: React.FunctionComponent = () => {
const [ searchParams, setSearchParams ] = useSearchParams();
const { filters, onSetFilters, clearAllFilters } = useDataViewFilters<RepositoryFilters>({ initialFilters: { name: '', branch: '', workspace: [] }, searchParams, setSearchParams });
const pagination = useDataViewPagination({ perPage: 5 });
const { page, perPage } = pagination;
const { filters, onSetFilters, clearAllFilters } = useDataViewFilters<RepositoryFilters>({ initialFilters: { name: '', branch: '' }, searchParams, setSearchParams });

const pageRows = useMemo(() => repositories
.filter(item => (!filters.name || item.name?.toLocaleLowerCase().includes(filters.name?.toLocaleLowerCase())) && (!filters.branch || item.branch?.toLocaleLowerCase().includes(filters.branch?.toLocaleLowerCase())))
const filteredData = useMemo(() => repositories.filter(item =>
(!filters.name || item.name?.toLocaleLowerCase().includes(filters.name?.toLocaleLowerCase())) &&
(!filters.branch || item.branch?.toLocaleLowerCase().includes(filters.branch?.toLocaleLowerCase())) &&
(!filters.workspace || filters.workspace.length === 0 || filters.workspace.includes(String(filterOptions.find(option => option.label === item.workspace)?.value)))
), [ filters ]);

const pageRows = useMemo(() => filteredData
.slice((page - 1) * perPage, ((page - 1) * perPage) + perPage)
.map(item => Object.values(item)), [ page, perPage, filters ]);
.map(item => Object.values(item)),
[ page, perPage, filteredData ]);

return (
<DataView>
Expand All @@ -58,14 +72,15 @@ const MyTable: React.FunctionComponent = () => {
pagination={
<Pagination
perPageOptions={perPageOptions}
itemCount={repositories.length}
itemCount={filteredData.length}
{...pagination}
/>
}
filters={
<DataViewFilters onChange={(_e, values) => onSetFilters(values)} values={filters}>
<DataViewTextFilter filterId="name" title='Name' placeholder='Filter by name' />
<DataViewTextFilter filterId="branch" title='Branch' placeholder='Filter by branch' />
<DataViewCheckboxFilter filterId="workspace" title='Workspace' placeholder='Filter by workspace' options={filterOptions} />
</DataViewFilters>
}
/>
Expand All @@ -76,7 +91,7 @@ const MyTable: React.FunctionComponent = () => {
<Pagination
isCompact
perPageOptions={perPageOptions}
itemCount={repositories.length}
itemCount={filteredData.length}
{...pagination}
/>
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ source: react
# If you use typescript, the name of the interface to display props for
# These are found through the sourceProps function provided in patternfly-docs.source.js
sortValue: 3
propComponents: ['DataViewFilters', 'DataViewTextFilter']
propComponents: ['DataViewFilters', 'DataViewTextFilter', 'DataViewCheckboxFilter']
sourceLink: https://github.com/patternfly/react-data-view/blob/main/packages/module/patternfly-docs/content/extensions/data-view/examples/Functionality/Functionality.md
---
import { useMemo } from 'react';
Expand All @@ -23,6 +23,7 @@ import { DataViewToolbar } from '@patternfly/react-data-view/dist/dynamic/DataVi
import { DataViewTable } from '@patternfly/react-data-view/dist/dynamic/DataViewTable';
import { DataViewFilters } from '@patternfly/react-data-view/dist/dynamic/DataViewFilters';
import { DataViewTextFilter } from '@patternfly/react-data-view/dist/dynamic/DataViewTextFilter';
import { DataViewCheckboxFilter } from '@patternfly/react-data-view/dist/dynamic/DataViewCheckboxFilter';

This is a list of functionality you can use to manage data displayed in the **data view**.

Expand Down Expand Up @@ -92,7 +93,7 @@ The `useDataViewSelection` hook manages the selection state of the data view.
Enables filtering of data records in the data view and displays the applied filter chips.

### Toolbar usage
The data view toolbar can include a set of filters by passing a React node to the `filters` property. You can use predefined components `DataViewFilters` and `DataViewTextFilter` to customize and handle filtering directly in the toolbar. The `DataViewFilters` is a wrapper allowing conditional filtering using multiple attributes. If you need just a single filter, you can use `DataViewTextFilter` or a different filter component alone. Props of these filter components are listed at the bottom of this page.
The data view toolbar can include a set of filters by passing a React node to the `filters` property. You can use predefined components `DataViewFilters`, `DataViewTextFilter` and `DataViewCheckboxFilter` to customize and handle filtering directly in the toolbar. The `DataViewFilters` is a wrapper allowing conditional filtering using multiple attributes. If you need just a single filter, you can use `DataViewTextFilter`, `DataViewCheckboxFilter` or a different filter component alone. Props of these filter components are listed at the bottom of this page.

You can decide between passing `value` and `onChange` event to every filter separately or pass `values` and `onChange` to the `DataViewFilters` wrapper which make them available to its children. Props directly passed to child filters have a higher priority than the "inherited" ones.

Expand All @@ -101,7 +102,7 @@ You can decide between passing `value` and `onChange` event to every filter sepa
The `useDataViewFilters` hook manages the filter state of the data view. It allows you to define default filter values, synchronize filter state with URL parameters, and handle filter changes efficiently.

**Initial values:**
- `initialFilters` object with default filter values
- `initialFilters` object with default filter values (if the filter param allows multiple values, pass an array)
- optional `searchParams` object for managing URL-based filter state
- optional `setSearchParams` function to update the URL when filters are modified

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React from 'react';
import { render } from '@testing-library/react';
import DataViewCheckboxFilter, { DataViewCheckboxFilterProps } from './DataViewCheckboxFilter';
import DataViewToolbar from '../DataViewToolbar';

describe('DataViewCheckboxFilter component', () => {
const defaultProps: DataViewCheckboxFilterProps = {
filterId: 'test-checkbox-filter',
title: 'Test Checkbox Filter',
value: [ 'workspace-one' ],
options: [
{ label: 'Workspace one', value: 'workspace-one' },
{ label: 'Workspace two', value: 'workspace-two' },
{ label: 'Workspace three', value: 'workspace-three' },
],
};

it('should render correctly', () => {
const { container } = render(
<DataViewToolbar filters={<DataViewCheckboxFilter {...defaultProps} />} />
);
expect(container).toMatchSnapshot();
});
});
Loading