-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #146 from fhlavac/update
Pull new features from v5
- Loading branch information
Showing
43 changed files
with
3,574 additions
and
560 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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'); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
import React from 'react'; | ||
import { useDataViewFilters } from '@patternfly/react-data-view/dist/dynamic/Hooks'; | ||
import { DataViewFilters } from '@patternfly/react-data-view/dist/dynamic/DataViewFilters'; | ||
import { DataViewTextFilter } from '@patternfly/react-data-view/dist/dynamic/DataViewTextFilter'; | ||
import { DataViewToolbar } from '@patternfly/react-data-view/dist/esm/DataViewToolbar'; | ||
import { FilterIcon } from '@patternfly/react-icons'; | ||
|
||
const filtersProps = { | ||
ouiaId: 'DataViewFilters', | ||
toggleIcon: <FilterIcon />, | ||
values: { name: '', branch: '' } | ||
}; | ||
|
||
interface RepositoryFilters { | ||
name: string, | ||
branch: string | ||
}; | ||
|
||
const DataViewToolbarWithState = (props: any) => { // eslint-disable-line @typescript-eslint/no-explicit-any | ||
const { filters, onSetFilters, clearAllFilters } = useDataViewFilters<RepositoryFilters>({ initialFilters: { name: '', branch: '' } }); | ||
|
||
return ( | ||
<DataViewToolbar | ||
ouiaId='FiltersExampleHeader' | ||
clearAllFilters = {clearAllFilters} | ||
filters={ | ||
<DataViewFilters {...filtersProps} onChange={(_e, values) => onSetFilters(values)} values={filters} {...props}> | ||
<DataViewTextFilter filterId="name" title='Name' placeholder='Filter by name' /> | ||
<DataViewTextFilter filterId="branch" title='Branch' placeholder='Filter by branch' /> | ||
</DataViewFilters> | ||
} | ||
/> | ||
); | ||
}; | ||
|
||
describe('DataViewFilters', () => { | ||
it('renders DataViewFilters with menu and filter items', () => { | ||
cy.mount(<DataViewToolbarWithState />); | ||
cy.get('[data-ouia-component-id="DataViewFilters"]').should('exist'); | ||
cy.get('[data-ouia-component-id="DataViewFilters"] .pf-v6-c-menu-toggle').click(); | ||
|
||
cy.contains('Name').should('exist'); | ||
cy.contains('Branch').should('exist'); | ||
}); | ||
|
||
it('can select a filter option', () => { | ||
cy.mount(<DataViewToolbarWithState />); | ||
cy.get('[data-ouia-component-id="DataViewFilters"]').should('contain.text', 'Name'); | ||
cy.get('[data-ouia-component-id="DataViewFilters"] .pf-v6-c-menu-toggle').click(); | ||
cy.contains('Branch').click(); | ||
|
||
cy.get('[data-ouia-component-id="DataViewFilters"]').should('contain.text', 'Branch'); | ||
}); | ||
|
||
it('responds to input and clears the filters', () => { | ||
cy.mount(<DataViewToolbarWithState />); | ||
cy.get('[data-ouia-component-id="DataViewFilters"] .pf-v6-c-menu-toggle').click(); | ||
cy.contains('Name').click(); | ||
|
||
cy.get('input[placeholder="Filter by name"]').type('Repository one'); | ||
cy.get('.pf-v6-c-label__text').should('have.length', 1); | ||
cy.get('input[placeholder="Filter by name"]').clear(); | ||
cy.get('.pf-v6-c-label__text').should('have.length', 0); | ||
}); | ||
|
||
it('displays labels for selected filters', () => { | ||
cy.mount(<DataViewToolbarWithState />); | ||
cy.get('[data-ouia-component-id="DataViewFilters"] .pf-v6-c-menu-toggle').click(); | ||
cy.contains('Name').click(); | ||
cy.get('input[placeholder="Filter by name"]').type('Repository one'); | ||
|
||
cy.get('[data-ouia-component-id="DataViewFilters"] .pf-v6-c-menu-toggle').click(); | ||
cy.contains('Branch').click(); | ||
cy.get('input[placeholder="Filter by branch"]').type('Main branch'); | ||
|
||
cy.get('.pf-v6-c-label__text').should('have.length', 2); | ||
cy.get('.pf-v6-c-label__text').eq(0).should('contain.text', 'Repository one'); | ||
cy.get('.pf-v6-c-label__text').eq(1).should('contain.text', 'Main branch'); | ||
}); | ||
|
||
it('removes filters by clicking individual labels', () => { | ||
cy.mount(<DataViewToolbarWithState />); | ||
cy.get('[data-ouia-component-id="DataViewFilters"] .pf-v6-c-menu-toggle').click(); | ||
cy.contains('Name').click(); | ||
cy.get('input[placeholder="Filter by name"]').type('Repository one'); | ||
|
||
cy.get('[data-ouia-component-id="DataViewFilters"] .pf-v6-c-menu-toggle').click(); | ||
cy.contains('Branch').click(); | ||
cy.get('input[placeholder="Filter by branch"]').type('Main branch'); | ||
|
||
cy.get('[aria-label="Close Repository one"]').should('have.length', 1); | ||
cy.get('[aria-label="Close Main branch"]').should('have.length', 1); | ||
|
||
cy.get('[aria-label="Close Repository one"]').click(); | ||
cy.get('[aria-label="Close Repository one"]').should('have.length', 0); | ||
|
||
cy.get('[aria-label="Close Main branch"]').click(); | ||
cy.get('[aria-label="Close Main branch"]').should('have.length', 0); | ||
}); | ||
|
||
it('clears all filters using the clear-all button', () => { | ||
cy.mount(<DataViewToolbarWithState />); | ||
cy.get('[data-ouia-component-id="DataViewFilters"] .pf-v6-c-menu-toggle').click(); | ||
cy.contains('Name').click(); | ||
cy.get('input[placeholder="Filter by name"]').type('Repository one'); | ||
|
||
cy.get('[data-ouia-component-id="DataViewFilters"] .pf-v6-c-menu-toggle').click(); | ||
cy.contains('Branch').click(); | ||
cy.get('input[placeholder="Filter by branch"]').type('Main branch'); | ||
|
||
cy.get('[data-ouia-component-id="FiltersExampleHeader-clear-all-filters"]').should('exist').click(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
/* eslint-disable no-nested-ternary */ | ||
import React from 'react'; | ||
import { useDataViewSort } from '@patternfly/react-data-view/dist/dynamic/Hooks'; | ||
import { DataViewTable, DataViewTr, DataViewTh } from '@patternfly/react-data-view/dist/dynamic/DataViewTable'; | ||
import { BrowserRouter, useSearchParams } from 'react-router-dom'; | ||
import { ThProps } from '@patternfly/react-table'; | ||
|
||
interface Repository { | ||
name: string; | ||
branches: string; | ||
prs: string; | ||
workspaces: string; | ||
lastCommit: string; | ||
} | ||
|
||
const COLUMNS = [ | ||
{ label: 'Repository', key: 'name', index: 0 }, | ||
{ label: 'Branch', key: 'branches', index: 1 }, | ||
{ label: 'Pull request', key: 'prs', index: 2 }, | ||
{ label: 'Workspace', key: 'workspaces', index: 3 }, | ||
{ label: 'Last commit', key: 'lastCommit', index: 4 }, | ||
]; | ||
|
||
const repositories: Repository[] = [ | ||
{ name: 'Repository one', branches: 'Branch one', prs: 'Pull request one', workspaces: 'Workspace one', lastCommit: '2023-11-01' }, | ||
{ name: 'Repository six', branches: 'Branch six', prs: 'Pull request six', workspaces: 'Workspace six', lastCommit: '2023-11-06' }, | ||
{ name: 'Repository two', branches: 'Branch two', prs: 'Pull request two', workspaces: 'Workspace two', lastCommit: '2023-11-02' }, | ||
{ name: 'Repository five', branches: 'Branch five', prs: 'Pull request five', workspaces: 'Workspace five', lastCommit: '2023-11-05' }, | ||
{ name: 'Repository three', branches: 'Branch three', prs: 'Pull request three', workspaces: 'Workspace three', lastCommit: '2023-11-03' }, | ||
{ name: 'Repository four', branches: 'Branch four', prs: 'Pull request four', workspaces: 'Workspace four', lastCommit: '2023-11-04' }, | ||
]; | ||
|
||
const sortData = (data: Repository[], sortBy: keyof Repository | undefined, direction: 'asc' | 'desc' | undefined) => | ||
sortBy && direction | ||
? [ ...data ].sort((a, b) => | ||
direction === 'asc' | ||
? a[sortBy] < b[sortBy] ? -1 : a[sortBy] > b[sortBy] ? 1 : 0 | ||
: a[sortBy] > b[sortBy] ? -1 : a[sortBy] < b[sortBy] ? 1 : 0 | ||
) | ||
: data; | ||
|
||
const TestTable: React.FunctionComponent = () => { | ||
const [ searchParams, setSearchParams ] = useSearchParams(); | ||
const { sortBy, direction, onSort } = useDataViewSort({ searchParams, setSearchParams }); | ||
const sortByIndex = React.useMemo(() => COLUMNS.findIndex(item => item.key === sortBy), [ sortBy ]); | ||
|
||
const getSortParams = (columnIndex: number): ThProps['sort'] => ({ | ||
sortBy: { | ||
index: sortByIndex, | ||
direction, | ||
defaultDirection: 'asc', | ||
}, | ||
onSort: (_event, index, direction) => onSort(_event, COLUMNS[index].key, direction), | ||
columnIndex, | ||
}); | ||
|
||
const columns: DataViewTh[] = COLUMNS.map((column, index) => ({ | ||
cell: column.label, | ||
props: { sort: getSortParams(index) }, | ||
})); | ||
|
||
const rows: DataViewTr[] = React.useMemo( | ||
() => | ||
sortData(repositories, sortBy ? sortBy as keyof Repository : undefined, direction).map(({ name, branches, prs, workspaces, lastCommit }) => [ | ||
name, | ||
branches, | ||
prs, | ||
workspaces, | ||
lastCommit, | ||
]), | ||
[ sortBy, direction ] | ||
); | ||
|
||
return <DataViewTable aria-label="Repositories table" ouiaId="test-table" columns={columns} rows={rows} />; | ||
}; | ||
|
||
describe('DataViewTable Sorting with Hook', () => { | ||
it('sorts by repository name in ascending and descending order', () => { | ||
cy.mount( | ||
<BrowserRouter> | ||
<TestTable /> | ||
</BrowserRouter> | ||
); | ||
|
||
cy.get('[data-ouia-component-id="test-table-th-0"]') | ||
.find('button') | ||
.click(); | ||
cy.get('[data-ouia-component-id="test-table-td-0-0"]').should('contain', 'Repository five'); | ||
cy.get('[data-ouia-component-id="test-table-td-5-0"]').should('contain', 'Repository two'); | ||
|
||
cy.get('[data-ouia-component-id="test-table-th-0"]') | ||
.find('button') | ||
.click(); | ||
cy.get('[data-ouia-component-id="test-table-td-0-0"]').should('contain', 'Repository two'); | ||
cy.get('[data-ouia-component-id="test-table-td-5-0"]').should('contain', 'Repository five'); | ||
}); | ||
|
||
it('sorts by last commit date in ascending and descending order', () => { | ||
cy.mount( | ||
<BrowserRouter> | ||
<TestTable /> | ||
</BrowserRouter> | ||
); | ||
|
||
cy.get('[data-ouia-component-id="test-table-th-4"]') | ||
.find('button') | ||
.click(); | ||
cy.get('[data-ouia-component-id="test-table-td-0-4"]').should('contain', '2023-11-01'); | ||
cy.get('[data-ouia-component-id="test-table-td-5-4"]').should('contain', '2023-11-06'); | ||
|
||
cy.get('[data-ouia-component-id="test-table-th-4"]') | ||
.find('button') | ||
.click(); | ||
cy.get('[data-ouia-component-id="test-table-td-0-4"]').should('contain', '2023-11-06'); | ||
cy.get('[data-ouia-component-id="test-table-td-5-4"]').should('contain', '2023-11-01'); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import React, { useState } from 'react'; | ||
import { DataViewTextFilter } from '@patternfly/react-data-view/dist/dynamic/DataViewTextFilter'; | ||
import { DataViewToolbar } from '@patternfly/react-data-view/dist/dynamic/DataViewToolbar'; | ||
|
||
const defaultProps = { | ||
filterId: 'name', | ||
title: 'Name', | ||
value: '', | ||
ouiaId: 'DataViewTextFilter', | ||
placeholder: 'Filter by name' | ||
}; | ||
|
||
const DataViewToolbarWithState = (props: any) => { // eslint-disable-line @typescript-eslint/no-explicit-any | ||
const [ value, setValue ] = useState('Repository one'); | ||
|
||
return ( | ||
<DataViewToolbar clearAllFilters={() => setValue('')}> | ||
<DataViewTextFilter {...defaultProps} value={value} onChange={() => setValue('')} {...props} /> | ||
</DataViewToolbar> | ||
); | ||
}; | ||
|
||
describe('DataViewTextFilter', () => { | ||
|
||
it('renders DataViewTextFilter with correct initial values', () => { | ||
cy.mount(<DataViewToolbarWithState value="" />); | ||
cy.get('[data-ouia-component-id="DataViewTextFilter"]').should('exist'); | ||
cy.get('[data-ouia-component-id="DataViewTextFilter-input"] input') | ||
.should('have.attr', 'placeholder', 'Filter by name') | ||
.and('have.value', ''); | ||
}); | ||
|
||
it('accepts input when passed', () => { | ||
cy.mount(<DataViewToolbarWithState value="" />); | ||
cy.get('[data-ouia-component-id="DataViewTextFilter-input"] input') | ||
.type('Repository one') | ||
.should('have.value', 'Repository one'); | ||
}); | ||
|
||
it('displays a label when value is present and removes it on delete', () => { | ||
cy.mount(<DataViewToolbarWithState />); | ||
cy.get('[data-ouia-component-id="DataViewTextFilter-input"] input').should('have.value', 'Repository one'); | ||
|
||
cy.get('.pf-v6-c-label__text').contains('Repository one'); | ||
cy.get('.pf-m-label-group button.pf-v6-c-button.pf-m-plain').click(); | ||
|
||
cy.get('.pf-v6-c-label__text').should('not.exist'); | ||
cy.get('[data-ouia-component-id="DataViewTextFilter-input"] input').should('have.value', ''); | ||
}); | ||
|
||
it('clears input when the clear button is clicked', () => { | ||
cy.mount(<DataViewToolbarWithState />); | ||
cy.get('[data-ouia-component-id="DataViewTextFilter-input"] input').should('have.value', 'Repository one'); | ||
|
||
cy.get('[data-ouia-component-id="DataViewToolbar-clear-all-filters"]').click(); | ||
|
||
cy.get('[data-ouia-component-id="DataViewTextFilter-input"] input').should('have.value', ''); | ||
}); | ||
|
||
it('hides or shows the toolbar item based on showToolbarItem prop', () => { | ||
cy.mount( | ||
<DataViewToolbar> | ||
<DataViewTextFilter {...defaultProps} showToolbarItem={false} /> | ||
</DataViewToolbar> | ||
); | ||
cy.get('[data-ouia-component-id="DataViewTextFilter"]').should('not.exist'); | ||
|
||
cy.mount( | ||
<DataViewToolbar> | ||
<DataViewTextFilter {...defaultProps} showToolbarItem /> | ||
</DataViewToolbar> | ||
); | ||
cy.get('[data-ouia-component-id="DataViewTextFilter"]').should('exist'); | ||
}); | ||
}); |
Oops, something went wrong.