Skip to content

Commit

Permalink
Merge pull request #14 from fhlavac/table-renderer
Browse files Browse the repository at this point in the history
  • Loading branch information
fhlavac authored Aug 29, 2024
2 parents 37e31c1 + 50f46b1 commit d8900b3
Show file tree
Hide file tree
Showing 29 changed files with 926 additions and 328 deletions.
44 changes: 11 additions & 33 deletions cypress/component/DataView.cy.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React from 'react';
import { Pagination } from '@patternfly/react-core';
import { Table, Tbody, Th, Thead, Tr, Td } from '@patternfly/react-table';
import { BulkSelect } from '@patternfly/react-component-groups/dist/dynamic/BulkSelect';
import DataView from '../../packages/module/dist/dynamic/DataView';
import DataViewToolbar from '../../packages/module/dist/dynamic/DataViewToolbar';
import { DataView } from '@patternfly/react-data-view/dist/dynamic/DataView';
import { DataViewToolbar } from '@patternfly/react-data-view/dist/dynamic/DataViewToolbar';
import { DataViewTable } from '@patternfly/react-data-view/dist/dynamic/DataViewTable';

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

const cols: Record<keyof Repository, string> = {
name: 'Repositories',
branches: 'Branches',
prs: 'Pull requests',
workspaces: 'Workspaces',
lastCommit: 'Last commit'
};
const columns = [ 'Repositories', 'Branches', 'Pull requests', 'Workspaces', 'Last commit' ];

describe('DataView', () => {
it('renders the data view layout', () => {
Expand Down Expand Up @@ -61,24 +56,7 @@ describe('DataView', () => {
/>
}
/>
<Table aria-label="Repositories table" ouiaId={ouiaId}>
<Thead data-ouia-component-id={`${ouiaId}-thead`}>
<Tr ouiaId={`${ouiaId}-tr-head`}>
{Object.values(cols).map((column, index) => <Th key={index} data-ouia-component-id={`${ouiaId}-th-${index}`}>{column}</Th>)}
</Tr>
</Thead>
<Tbody>
{repositories.map((repo, rowIndex) => (
<Tr key={repo.name}>
<Td data-ouia-component-id={`${ouiaId}-td-${rowIndex}-name`} dataLabel={cols.name}>{repo.name}</Td>
<Td data-ouia-component-id={`${ouiaId}-td-${rowIndex}-branches`} dataLabel={cols.branches}>{repo.branches}</Td>
<Td data-ouia-component-id={`${ouiaId}-td-${rowIndex}-prs`} dataLabel={cols.prs}>{repo.prs}</Td>
<Td data-ouia-component-id={`${ouiaId}-td-${rowIndex}-workspaces`} dataLabel={cols.workspaces}>{repo.workspaces}</Td>
<Td data-ouia-component-id={`${ouiaId}-td-${rowIndex}-last-commit`} dataLabel={cols.lastCommit}>{repo.lastCommit}</Td>
</Tr>
))}
</Tbody>
</Table>
<DataViewTable aria-label='Repositories table' ouiaId={ouiaId} columns={columns} rows={rows} />
<DataViewToolbar ouiaId="DataViewFooter" pagination={<Pagination isCompact {...PAGINATION} />} />
</DataView>
);
Expand All @@ -91,11 +69,11 @@ describe('DataView', () => {
cy.get('[data-ouia-component-id="data-th-3"]').contains('Workspaces');
cy.get('[data-ouia-component-id="data-th-4"]').contains('Last commit');

cy.get('[data-ouia-component-id="data-td-0-name"]').contains('one');
cy.get('[data-ouia-component-id="data-td-2-branches"]').contains('two - 3');
cy.get('[data-ouia-component-id="data-td-3-prs"]').contains('null');
cy.get('[data-ouia-component-id="data-td-4-workspaces"]').contains('four - 5');
cy.get('[data-ouia-component-id="data-td-5-last-commit"]').contains('five - 6');
cy.get('[data-ouia-component-id="data-td-0-0"]').contains('one');
cy.get('[data-ouia-component-id="data-td-2-1"]').contains('two - 3');
cy.get('[data-ouia-component-id="data-td-3-2"]').contains('null');
cy.get('[data-ouia-component-id="data-td-4-3"]').contains('four - 5');
cy.get('[data-ouia-component-id="data-td-5-4"]').contains('five - 6');

cy.get('[data-ouia-component-id="DataViewFooter-pagination"]').should('exist');
});
Expand Down
45 changes: 45 additions & 0 deletions cypress/component/DataViewTable.cy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import React from 'react';
import { DataViewTable } from '@patternfly/react-data-view/dist/dynamic/DataViewTable';

interface Repository {
name: string;
branches: string | null;
prs: string | null;
workspaces: string;
lastCommit: string;
}

const repositories: Repository[] = [
{ name: 'one', branches: 'two', prs: 'three', workspaces: 'four', lastCommit: 'five' },
{ name: 'one - 2', branches: null, prs: null, workspaces: 'four - 2', lastCommit: 'five - 2' },
{ name: 'one - 3', branches: 'two - 3', prs: 'three - 3', workspaces: 'four - 3', lastCommit: 'five - 3' },
{ name: 'one - 4', branches: 'two - 4', prs: 'null', workspaces: 'four - 4', lastCommit: 'five - 4' },
{ name: 'one - 5', branches: 'two - 5', prs: 'three - 5', workspaces: 'four - 5', lastCommit: 'five - 5' },
{ name: 'one - 6', branches: 'two - 6', prs: 'three - 6', workspaces: 'four - 6', lastCommit: 'five - 6' }
];
const rows = repositories.map(item => Object.values(item));

const columns = [ 'Repositories', 'Branches', 'Pull requests', 'Workspaces', 'Last commit' ];

describe('DataViewTable', () => {

it('renders the data view table', () => {
const ouiaId = 'data';

cy.mount(
<DataViewTable aria-label='Repositories table' ouiaId={ouiaId} columns={columns} rows={rows} />
);

cy.get('[data-ouia-component-id="data-th-0"]').contains('Repositories');
cy.get('[data-ouia-component-id="data-th-1"]').contains('Branches');
cy.get('[data-ouia-component-id="data-th-2"]').contains('Pull requests');
cy.get('[data-ouia-component-id="data-th-3"]').contains('Workspaces');
cy.get('[data-ouia-component-id="data-th-4"]').contains('Last commit');

cy.get('[data-ouia-component-id="data-td-0-0"]').contains('one');
cy.get('[data-ouia-component-id="data-td-2-1"]').contains('two - 3');
cy.get('[data-ouia-component-id="data-td-3-2"]').contains('null');
cy.get('[data-ouia-component-id="data-td-4-3"]').contains('four - 5');
cy.get('[data-ouia-component-id="data-td-5-4"]').contains('five - 6');
});
});
2 changes: 1 addition & 1 deletion cypress/e2e/DataViewEvents.spec.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ describe('Test the Data view docs page', () => {
it('displays a table and opens detail', () => {
const ouiaId = 'ContextExample';

cy.visit('http://localhost:8006/extensions/data-view/context');
cy.visit('http://localhost:8006/extensions/data-view/events-context');

cy.get(`[data-ouia-component-id="${ouiaId}-th-0"]`).contains('Repositories');
cy.get(`[data-ouia-component-id="${ouiaId}-th-4"]`).contains('Last commit');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,51 @@ 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: 4
propComponents: ['DataViewToolbar']
propComponents: ['DataViewToolbar', 'DataViewTable']
sourceLink: https://github.com/patternfly/react-data-view/blob/main/packages/module/patternfly-docs/content/extensions/data-view/examples/Components/Components.md
---
import { BulkSelect } from '@patternfly/react-component-groups';
import DataViewToolbar from '@patternfly/react-data-view/dist/dynamic/DataViewToolbar';
import { ExclamationCircleIcon } from '@patternfly/react-icons';
import { DataViewToolbar } from '@patternfly/react-data-view/dist/dynamic/DataViewToolbar';
import { DataViewTable } from '@patternfly/react-data-view/dist/dynamic/DataViewTable';

## Data view toolbar

The **data view toolbar** component renders a default opinionated data view toolbar above or below the data section.

Data view toolbar can contain a `pagination`, `bulkSelect` or any other children content passed. The preffered way of passing children toolbar items is using the [toolbar item](/components/toolbar#toolbar-items) component.

### Basic example
### Basic toolbar example

```js file="./DataViewToolbarExample.tsx"

```

## Data view table

The **data view table** component renders your columns and rows definition into a [table](/components/table) component.

### Rows and columns customization

This example shows possible formats of `rows` and `columns` passed to the `DataViewTable` which allow you various customizations of the table header and body.

```js file="./DataViewTableExample.tsx"

```

The `DataViewTable` component accepts the following props:

- `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:
- `cell` (`ReactNode`) content to display in the column header.
- optional `props` (`ThProps`) to pass to the `<Th>` component, such as `width`, `sort`, and other table header cell properties.

- `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:
- `row` (`DataViewTd[]`) defining the content for each cell in the row.
- optional `id` (`string`) for the row (can be used to match items in selection).
- optional `props` (`TrProps`) to pass to the `<Tr>` component, such as `isHoverable`, `isRowSelected`, and other table row properties.

- optional `ouiaId`

- optional `props` (`TableProps`) that are passed down to the `<Table>` component, except for `onSelect`, which is managed internally.


Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React from 'react';
import { DataViewTable, DataViewTh, DataViewTr } from '@patternfly/react-data-view/dist/dynamic/DataViewTable';
import { ExclamationCircleIcon } from '@patternfly/react-icons';
import { Button } from '@patternfly/react-core';

interface Repository {
id: number;
name: string;
branches: string | null;
prs: string | null;
workspaces: string;
lastCommit: string;
}

const repositories: Repository[] = [
{ id: 1, name: 'one', branches: 'two', prs: 'three', workspaces: 'four', lastCommit: 'five' },
{ id: 2, name: 'one - 2', branches: null, prs: null, workspaces: 'four - 2', lastCommit: 'five - 2' },
{ id: 3, name: 'one - 3', branches: 'two - 3', prs: 'three - 3', workspaces: 'four - 3', lastCommit: 'five - 3' },
{ id: 4, name: 'one - 4', branches: 'two - 4', prs: 'null', workspaces: 'four - 4', lastCommit: 'five - 4' },
{ id: 5, name: 'one - 5', branches: 'two - 5', prs: 'three - 5', workspaces: 'four - 5', lastCommit: 'five - 5' },
{ id: 6, name: 'one - 6', branches: 'two - 6', prs: 'three - 6', workspaces: 'four - 6', lastCommit: 'five - 6' }
];

// you can also pass props to Tr by returning { row: DataViewTd[], props: TrProps } }
const rows: DataViewTr[] = repositories.map(({ id, name, branches, prs, workspaces, lastCommit }) => [
{ id, cell: workspaces, props: { favorites: { isFavorited: true } } },
{ cell: <Button href='#' variant='link' isInline>{name}</Button> },
branches,
prs,
workspaces,
lastCommit
]);

const columns: DataViewTh[] = [
null,
'Repositories',
{ cell: <>Branches<ExclamationCircleIcon className='pf-v5-u-ml-sm' color='var(--pf-v5-global--danger-color--100)'/></> },
'Pull requests',
{ cell: 'Workspaces', props: { info: { tooltip: 'More information' } } },
{ cell: 'Last commit', props: { sort: { sortBy: {}, columnIndex: 4 } } }
];

const ouiaId = 'TableExample';

export const BasicExample: React.FunctionComponent = () => (
<DataViewTable aria-label='Repositories table' ouiaId={ouiaId} columns={columns} rows={rows} />
);

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
# Sidenav top-level section
# should be the same for all markdown files
section: extensions
subsection: Data view
# Sidenav secondary level section
# should be the same for all markdown files
id: Events context
# Tab (react | react-demos | html | html-demos | design-guidelines | accessibility)
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
sourceLink: https://github.com/patternfly/react-data-view/blob/main/packages/module/patternfly-docs/content/extensions/data-view/examples/EventsContext/EventsContext.md
---
import { useState, useEffect, useRef, useMemo } from 'react';
import { Table, Tbody, Th, Thead, Tr, Td } from '@patternfly/react-table';
import { DataView } from '@patternfly/react-data-view/dist/dynamic/DataView';
import { DataViewTable } from '@patternfly/react-data-view/dist/dynamic/DataViewTable';
import { useDataViewEventsContext, DataViewEventsContext, DataViewEventsProvider, EventTypes } from '@patternfly/react-data-view/dist/dynamic/DataViewEventsContext';
import { Drawer, DrawerContent, DrawerContentBody } from '@patternfly/react-core';

The **data view events context** provides a way of listening to the data view events from the outside of the component.

### Row click subscription example
The following example demonstrates how to use the `DataViewEventsContext` to manage shared state and handle events. The `DataViewEventsProvider` is used to wrap components that need access to the shared context. This example illustrates how to set up a layout that listens for data view row click events and displays detailed information about the selected row in a [drawer component](/components/drawer).


```js file="./EventsExample.tsx"

```

Loading

0 comments on commit d8900b3

Please sign in to comment.