Skip to content

Commit 7ccf0de

Browse files
committed
fix(renderer): Introduce DataViewTableRenderer
1 parent bf8be34 commit 7ccf0de

File tree

17 files changed

+631
-160
lines changed

17 files changed

+631
-160
lines changed

cypress/component/DataView.cy.tsx

Lines changed: 6 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import React from 'react';
22
import { Pagination } from '@patternfly/react-core';
3-
import { Table, Tbody, Th, Thead, Tr, Td } from '@patternfly/react-table';
43
import { BulkSelect } from '@patternfly/react-component-groups/dist/dynamic/BulkSelect';
5-
import DataView from '../../packages/module/dist/dynamic/DataView';
6-
import DataViewToolbar from '../../packages/module/dist/dynamic/DataViewToolbar';
4+
import { DataView } from '@patternfly/react-data-view/dist/dynamic/DataView';
5+
import { DataViewToolbar } from '@patternfly/react-data-view/dist/dynamic/DataViewToolbar';
6+
import { DataViewTable } from '@patternfly/react-data-view/dist/dynamic/DataViewTable';
77

88
interface Repository {
99
name: string;
@@ -26,14 +26,9 @@ const repositories: Repository[] = [
2626
{ name: 'one - 5', branches: 'two - 5', prs: 'three - 5', workspaces: 'four - 5', lastCommit: 'five - 5' },
2727
{ name: 'one - 6', branches: 'two - 6', prs: 'three - 6', workspaces: 'four - 6', lastCommit: 'five - 6' }
2828
];
29+
const rows = repositories.map(item => Object.values(item));
2930

30-
const cols: Record<keyof Repository, string> = {
31-
name: 'Repositories',
32-
branches: 'Branches',
33-
prs: 'Pull requests',
34-
workspaces: 'Workspaces',
35-
lastCommit: 'Last commit'
36-
};
31+
const columns = [ 'Repositories', 'Branches', 'Pull requests', 'Workspaces', 'Last commit' ];
3732

3833
describe('DataView', () => {
3934
it('renders the data view layout', () => {
@@ -61,24 +56,7 @@ describe('DataView', () => {
6156
/>
6257
}
6358
/>
64-
<Table aria-label="Repositories table" ouiaId={ouiaId}>
65-
<Thead data-ouia-component-id={`${ouiaId}-thead`}>
66-
<Tr ouiaId={`${ouiaId}-tr-head`}>
67-
{Object.values(cols).map((column, index) => <Th key={index} data-ouia-component-id={`${ouiaId}-th-${index}`}>{column}</Th>)}
68-
</Tr>
69-
</Thead>
70-
<Tbody>
71-
{repositories.map((repo, rowIndex) => (
72-
<Tr key={repo.name}>
73-
<Td data-ouia-component-id={`${ouiaId}-td-${rowIndex}-name`} dataLabel={cols.name}>{repo.name}</Td>
74-
<Td data-ouia-component-id={`${ouiaId}-td-${rowIndex}-branches`} dataLabel={cols.branches}>{repo.branches}</Td>
75-
<Td data-ouia-component-id={`${ouiaId}-td-${rowIndex}-prs`} dataLabel={cols.prs}>{repo.prs}</Td>
76-
<Td data-ouia-component-id={`${ouiaId}-td-${rowIndex}-workspaces`} dataLabel={cols.workspaces}>{repo.workspaces}</Td>
77-
<Td data-ouia-component-id={`${ouiaId}-td-${rowIndex}-last-commit`} dataLabel={cols.lastCommit}>{repo.lastCommit}</Td>
78-
</Tr>
79-
))}
80-
</Tbody>
81-
</Table>
59+
<DataViewTable aria-label='Repositories table' ouiaId={ouiaId} columns={columns} rows={rows} />
8260
<DataViewToolbar ouiaId="DataViewFooter" pagination={<Pagination isCompact {...PAGINATION} />} />
8361
</DataView>
8462
);
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import React from 'react';
2+
import { DataViewTable } from '@patternfly/react-data-view/dist/dynamic/DataViewTable';
3+
4+
interface Repository {
5+
name: string;
6+
branches: string | null;
7+
prs: string | null;
8+
workspaces: string;
9+
lastCommit: string;
10+
}
11+
12+
const repositories: Repository[] = [
13+
{ name: 'one', branches: 'two', prs: 'three', workspaces: 'four', lastCommit: 'five' },
14+
{ name: 'one - 2', branches: null, prs: null, workspaces: 'four - 2', lastCommit: 'five - 2' },
15+
{ name: 'one - 3', branches: 'two - 3', prs: 'three - 3', workspaces: 'four - 3', lastCommit: 'five - 3' },
16+
{ name: 'one - 4', branches: 'two - 4', prs: 'null', workspaces: 'four - 4', lastCommit: 'five - 4' },
17+
{ name: 'one - 5', branches: 'two - 5', prs: 'three - 5', workspaces: 'four - 5', lastCommit: 'five - 5' },
18+
{ name: 'one - 6', branches: 'two - 6', prs: 'three - 6', workspaces: 'four - 6', lastCommit: 'five - 6' }
19+
];
20+
const rows = repositories.map(item => Object.values(item));
21+
22+
const columns = [ 'Repositories', 'Branches', 'Pull requests', 'Workspaces', 'Last commit' ];
23+
24+
describe('DataViewTable', () => {
25+
26+
it('renders the data view table', () => {
27+
const ouiaId = 'data';
28+
29+
cy.mount(
30+
<DataViewTable aria-label='Repositories table' ouiaId={ouiaId} columns={columns} rows={rows} />
31+
);
32+
33+
cy.get('[data-ouia-component-id="data-th-0"]').contains('Repositories');
34+
cy.get('[data-ouia-component-id="data-th-1"]').contains('Branches');
35+
cy.get('[data-ouia-component-id="data-th-2"]').contains('Pull requests');
36+
cy.get('[data-ouia-component-id="data-th-3"]').contains('Workspaces');
37+
cy.get('[data-ouia-component-id="data-th-4"]').contains('Last commit');
38+
39+
cy.get('[data-ouia-component-id="data-td-0-name"]').contains('one');
40+
cy.get('[data-ouia-component-id="data-td-2-branches"]').contains('two - 3');
41+
cy.get('[data-ouia-component-id="data-td-3-prs"]').contains('null');
42+
cy.get('[data-ouia-component-id="data-td-4-workspaces"]').contains('four - 5');
43+
cy.get('[data-ouia-component-id="data-td-5-last-commit"]').contains('five - 6');
44+
});
45+
});

packages/module/patternfly-docs/content/extensions/data-view/examples/Components/Components.md

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@ source: react
1111
# If you use typescript, the name of the interface to display props for
1212
# These are found through the sourceProps function provided in patternfly-docs.source.js
1313
sortValue: 4
14-
propComponents: ['DataViewToolbar']
14+
propComponents: ['DataViewToolbar', 'DataViewTable']
1515
sourceLink: https://github.com/patternfly/react-data-view/blob/main/packages/module/patternfly-docs/content/extensions/data-view/examples/Components/Components.md
1616
---
1717
import { BulkSelect } from '@patternfly/react-component-groups';
18-
import DataViewToolbar from '@patternfly/react-data-view/dist/dynamic/DataViewToolbar';
18+
import { DataViewToolbar } from '@patternfly/react-data-view/dist/dynamic/DataViewToolbar';
19+
import { DataViewTable } from '@patternfly/react-data-view/dist/dynamic/DataViewTable';
1920

2021
## Data view toolbar
2122

@@ -29,3 +30,29 @@ Data view toolbar can contain a `pagination`, `bulkSelect` or any other children
2930

3031
```
3132

33+
## Data view table
34+
35+
The **data view table** component renders your columns and rows definition into a [table](/components/table) component.
36+
37+
### Basic example
38+
39+
```js file="./DataViewTableExample.tsx"
40+
41+
```
42+
43+
The `DataViewTable` component accepts the following props:
44+
45+
- `columns` defining the column headers of the table. Each item in the array can be a `ReactNode` (for simple headers) or an object with the following properties:
46+
- `cell` (`ReactNode`) content to display in the column header.
47+
- optional `props` (`ThProps`) to pass to the `<Th>` component, such as `width`, `sort`, and other table header cell properties.
48+
49+
- `rows` defining the rows to be displayed in the table. Each item in the array can be either an array of `DataViewTd` (for simple rows) or an object with the following properties:
50+
- `row` (`DataViewTd[]`) defining the content for each cell in the row.
51+
- optional `id` (`string`) for the row.
52+
- optional `props` (`TrProps`) to pass to the `<Tr>` component, such as `isHoverable`, `isRowSelected`, and other table row properties.
53+
54+
- optional `ouiaId`
55+
56+
- optional `props` (`TableProps`) that are passed down to the `<Table>` component, except for `onSelect`, which is managed internally.
57+
58+
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import React from 'react';
2+
import { DataViewTable } from '@patternfly/react-data-view/dist/dynamic/DataViewTable';
3+
4+
interface Repository {
5+
name: string;
6+
branches: string | null;
7+
prs: string | null;
8+
workspaces: string;
9+
lastCommit: string;
10+
}
11+
12+
const repositories: Repository[] = [
13+
{ name: 'one', branches: 'two', prs: 'three', workspaces: 'four', lastCommit: 'five' },
14+
{ name: 'one - 2', branches: null, prs: null, workspaces: 'four - 2', lastCommit: 'five - 2' },
15+
{ name: 'one - 3', branches: 'two - 3', prs: 'three - 3', workspaces: 'four - 3', lastCommit: 'five - 3' },
16+
{ name: 'one - 4', branches: 'two - 4', prs: 'null', workspaces: 'four - 4', lastCommit: 'five - 4' },
17+
{ name: 'one - 5', branches: 'two - 5', prs: 'three - 5', workspaces: 'four - 5', lastCommit: 'five - 5' },
18+
{ name: 'one - 6', branches: 'two - 6', prs: 'three - 6', workspaces: 'four - 6', lastCommit: 'five - 6' }
19+
];
20+
21+
const rows = repositories.map(item => Object.values(item));
22+
23+
const columns = [ 'Repositories', 'Branches', 'Pull requests', 'Workspaces', 'Last commit' ];
24+
25+
const ouiaId = 'TableExample';
26+
27+
export const BasicExample: React.FunctionComponent = () => (
28+
<DataViewTable aria-label='Repositories table' ouiaId={ouiaId} columns={columns} rows={rows} />
29+
);

packages/module/patternfly-docs/content/extensions/data-view/examples/Functionality/Functionality.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { useDataViewPagination, useDataViewSelection } from '@patternfly/react-d
1818
import { DataView } from '@patternfly/react-data-view/dist/dynamic/DataView';
1919
import { BulkSelect, BulkSelectValue } from '@patternfly/react-component-groups/dist/dynamic/BulkSelect';
2020
import { DataViewToolbar } from '@patternfly/react-data-view/dist/dynamic/DataViewToolbar';
21+
import { DataViewTable } from '@patternfly/react-data-view/dist/dynamic/DataViewTable';
2122
import { BrowserRouter, useSearchParams } from 'react-router-dom';
2223

2324
This is a list of functionality you can use to manage data displayed in the **data view**.
@@ -34,9 +35,9 @@ The `useDataViewPagination` hook manages the pagination state of the data view.
3435

3536
**Initial values:**
3637
- `perPage` initial value
37-
- (optional) `page` initial value
38-
- (optional) `searchParams` object
39-
- (optional) `seSearchParams` function
38+
- optional `page` initial value
39+
- optional `searchParams` object
40+
- optional `setSearchParams` function
4041

4142
While the hook works seamlessly with React Router library, you do not need to use it to take advantage of URL persistence. The `searchParams` and `setSearchParams` props can be managed using native browser APIs (`URLSearchParams` and `window.history.pushState`) or any other routing library of your choice. If you don't pass these two props, the pagination state will be stored internally without the URL usage.
4243

@@ -68,8 +69,8 @@ Data view toolbar can display a bulk selection component using the `bulkSelect`
6869
The `useDataViewSelection` hook manages the selection state of the data view.
6970

7071
**Initial values:**
71-
- (optional) `initialSelected` array of record's identifiers selected by default
72-
- (optional) `matchOption` function to check if given record is selected
72+
- optional `initialSelected` array of record's identifiers selected by default
73+
- `matchOption` function to check if given record is selected
7374

7475
*When no `matchOption` is passed, the `Array.prototype.includes()` operation is performed on the `selected` array.*
7576

packages/module/patternfly-docs/content/extensions/data-view/examples/Functionality/PaginationExample.tsx

Lines changed: 9 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import React, { useMemo } from 'react';
22
import { Pagination } from '@patternfly/react-core';
3-
import { Table, Tbody, Th, Thead, Tr, Td } from '@patternfly/react-table';
4-
import { useDataViewPagination } from '@patternfly/react-data-view/dist/dynamic/Hooks';
5-
import DataView from '@patternfly/react-data-view/dist/dynamic/DataView';
6-
import DataViewToolbar from '@patternfly/react-data-view/dist/dynamic/DataViewToolbar';
73
import { BrowserRouter, useSearchParams } from 'react-router-dom';
4+
import { useDataViewPagination } from '@patternfly/react-data-view/dist/dynamic/Hooks';
5+
import { DataView } from '@patternfly/react-data-view/dist/dynamic/DataView';
6+
import { DataViewToolbar } from '@patternfly/react-data-view/dist/dynamic/DataViewToolbar';
7+
import { DataViewTable } from '@patternfly/react-data-view/dist/dynamic/DataViewTable';
88

99
const perPageOptions = [
1010
{ title: '5', value: 5 },
@@ -28,13 +28,9 @@ const repositories: Repository[] = [
2828
{ name: 'one - 6', branches: 'two - 6', prs: 'three - 6', workspaces: 'four - 6', lastCommit: 'five - 6' }
2929
];
3030

31-
const cols = {
32-
name: 'Repositories',
33-
branches: 'Branches',
34-
prs: 'Pull requests',
35-
workspaces: 'Workspaces',
36-
lastCommit: 'Last commit'
37-
};
31+
const rows = repositories.map(item => Object.values(item));
32+
33+
const columns = [ 'Repositories', 'Branches', 'Pull requests', 'Workspaces', 'Last commit' ];
3834

3935
const ouiaId = 'LayoutExample';
4036

@@ -43,24 +39,11 @@ const MyTable: React.FunctionComponent = () => {
4339
const pagination = useDataViewPagination({ perPage: 5, searchParams, setSearchParams });
4440
const { page, perPage } = pagination;
4541

46-
const data = useMemo(() => repositories.slice((page - 1) * perPage, ((page - 1) * perPage) + perPage), [ page, perPage ]);
42+
const pageRows = useMemo(() => rows.slice((page - 1) * perPage, ((page - 1) * perPage) + perPage), [ page, perPage ]);
4743
return (
4844
<DataView>
4945
<DataViewToolbar ouiaId='DataViewHeader' pagination={<Pagination perPageOptions={perPageOptions} itemCount={repositories.length} {...pagination} />} />
50-
<Table aria-label="Repositories table" ouiaId={ouiaId}>
51-
<Thead data-ouia-component-id={`${ouiaId}-thead`}>
52-
<Tr ouiaId={`${ouiaId}-tr-head`}>
53-
{Object.values(cols).map((column, index) => <Th key={index} data-ouia-component-id={`${ouiaId}-th-${index}`}>{column}</Th>)}
54-
</Tr>
55-
</Thead>
56-
<Tbody>
57-
{data.map((repo, rowIndex) => (
58-
<Tr key={repo.name} ouiaId={`${ouiaId}-tr-${rowIndex}`}>
59-
{Object.keys(cols).map((column, colIndex) => <Td key={colIndex} data-ouia-component-id={`${ouiaId}-td-${rowIndex}-${colIndex}`}>{repo[column]}</Td>)}
60-
</Tr>
61-
))}
62-
</Tbody>
63-
</Table>
46+
<DataViewTable aria-label='Repositories table' ouiaId={ouiaId} columns={columns} rows={pageRows} />
6447
<DataViewToolbar ouiaId='DataViewFooter' pagination={<Pagination isCompact perPageOptions={perPageOptions} itemCount={repositories.length} {...pagination} />} />
6548
</DataView>
6649
)
Lines changed: 9 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import React from 'react';
2-
import { Table, Tbody, Th, Thead, Tr, Td } from '@patternfly/react-table';
32
import { useDataViewSelection } from '@patternfly/react-data-view/dist/dynamic/Hooks';
43
import { BulkSelect, BulkSelectValue } from '@patternfly/react-component-groups/dist/dynamic/BulkSelect';
54
import { DataView } from '@patternfly/react-data-view/dist/dynamic/DataView';
65
import { DataViewToolbar } from '@patternfly/react-data-view/dist/dynamic/DataViewToolbar';
6+
import { DataViewTable } from '@patternfly/react-data-view/dist/dynamic/DataViewTable';
77

88
interface Repository {
99
name: string;
@@ -22,27 +22,23 @@ const repositories: Repository[] = [
2222
{ name: 'one - 6', branches: 'two - 6', prs: 'three - 6', workspaces: 'four - 6', lastCommit: 'five - 6' }
2323
];
2424

25-
const cols = {
26-
name: 'Repositories',
27-
branches: 'Branches',
28-
prs: 'Pull requests',
29-
workspaces: 'Workspaces',
30-
lastCommit: 'Last commit'
31-
};
25+
const rows = repositories.map(item => Object.values(item));
26+
27+
const columns = [ 'Repositories', 'Branches', 'Pull requests', 'Workspaces', 'Last commit' ];
3228

3329
const ouiaId = 'LayoutExample';
3430

3531
export const BasicExample: React.FunctionComponent = () => {
36-
const selection = useDataViewSelection({});
37-
const { selected, onSelect, isSelected } = selection;
32+
const selection = useDataViewSelection({ matchOption: (a, b) => a[0] === b[0] });
33+
const { selected, onSelect } = selection;
3834

3935
const handleBulkSelect = (value: BulkSelectValue) => {
4036
value === BulkSelectValue.none && onSelect(false);
41-
value === BulkSelectValue.all && onSelect(true, repositories);
37+
value === BulkSelectValue.all && onSelect(true, rows);
4238
};
4339

4440
return (
45-
<DataView>
41+
<DataView selection={selection}>
4642
<DataViewToolbar
4743
ouiaId='DataViewHeader'
4844
bulkSelect={
@@ -55,34 +51,7 @@ export const BasicExample: React.FunctionComponent = () => {
5551
/>
5652
}
5753
/>
58-
<Table aria-label="Repositories table" ouiaId={ouiaId}>
59-
<Thead data-ouia-component-id={`${ouiaId}-thead`}>
60-
<Tr ouiaId={`${ouiaId}-tr-head`}>
61-
<Th key="row-select"/>
62-
{Object.values(cols).map((column, index) => (
63-
<Th key={index} data-ouia-component-id={`${ouiaId}-th-${index}`}>{column}</Th>
64-
))}
65-
</Tr>
66-
</Thead>
67-
<Tbody>
68-
{repositories.map((repo, rowIndex) => (
69-
<Tr key={repo.name} ouiaId={`${ouiaId}-tr-${rowIndex}`}>
70-
<Td
71-
key={`select-${rowIndex}`}
72-
select={{
73-
rowIndex,
74-
onSelect: (_event, isSelecting) => onSelect(isSelecting, repo),
75-
isSelected: isSelected(repo),
76-
isDisabled: false
77-
}}
78-
/>
79-
{Object.keys(cols).map((column, colIndex) => (
80-
<Td key={colIndex} data-ouia-component-id={`${ouiaId}-td-${rowIndex}-${colIndex}`}>{repo[column]}</Td>
81-
))}
82-
</Tr>
83-
))}
84-
</Tbody>
85-
</Table>
54+
<DataViewTable aria-label='Repositories table' ouiaId={ouiaId} columns={columns} rows={rows} />
8655
</DataView>
8756
);
8857
}

packages/module/patternfly-docs/content/extensions/data-view/examples/Layout/Layout.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { useDataViewPagination, useDataViewSelection } from '@patternfly/react-d
1919
import { BulkSelect, BulkSelectValue } from '@patternfly/react-component-groups/dist/dynamic/BulkSelect';
2020
import DataView from '@patternfly/react-data-view/dist/dynamic/DataView';
2121
import DataViewToolbar from '@patternfly/react-data-view/dist/dynamic/DataViewToolbar';
22+
import DataViewTable from '@patternfly/react-data-view/dist/dynamic/DataViewTable';
2223

2324
The **data view** component renders record data in a configured layout.
2425

0 commit comments

Comments
 (0)