Skip to content

Commit ab5fc67

Browse files
authored
Merge pull request #27 from fhlavac/error
Add error state to the DataView table
2 parents 8784729 + ee663f8 commit ab5fc67

File tree

16 files changed

+578
-222
lines changed

16 files changed

+578
-222
lines changed

cypress/component/DataViewTableBasic.cy.tsx

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React from 'react';
2-
import DataViewTableBasic from '@patternfly/react-data-view/dist/esm/DataViewTableBasic';
2+
import DataViewTableBasic from '@patternfly/react-data-view/dist/dynamic/DataViewTableBasic';
3+
import DataView from '@patternfly/react-data-view/dist/dynamic/DataView';
34

45
interface Repository {
56
name: string;
@@ -48,7 +49,9 @@ describe('DataViewTableBasic', () => {
4849
const ouiaId = 'data';
4950

5051
cy.mount(
51-
<DataViewTableBasic aria-label='Repositories table' ouiaId={ouiaId} columns={columns} rows={[]} emptyState="No data found" />
52+
<DataView activeState="empty">
53+
<DataViewTableBasic aria-label='Repositories table' ouiaId={ouiaId} columns={columns} rows={[]} states={{ empty: "No data found" }} />
54+
</DataView>
5255
);
5356

5457
cy.get('[data-ouia-component-id="data-th-0"]').contains('Repositories');
@@ -60,4 +63,23 @@ describe('DataViewTableBasic', () => {
6063
cy.get('[data-ouia-component-id="data-tr-empty"]').should('be.visible');
6164
cy.get('[data-ouia-component-id="data-tr-empty"]').contains('No data found');
6265
});
66+
67+
it('renders a basic data view table with an error state', () => {
68+
const ouiaId = 'data';
69+
70+
cy.mount(
71+
<DataView activeState="error">
72+
<DataViewTableBasic aria-label='Repositories table' ouiaId={ouiaId} columns={columns} rows={[]} states={{ error: "Some error" }} />
73+
</DataView>
74+
);
75+
76+
cy.get('[data-ouia-component-id="data-th-0"]').contains('Repositories');
77+
cy.get('[data-ouia-component-id="data-th-1"]').contains('Branches');
78+
cy.get('[data-ouia-component-id="data-th-2"]').contains('Pull requests');
79+
cy.get('[data-ouia-component-id="data-th-3"]').contains('Workspaces');
80+
cy.get('[data-ouia-component-id="data-th-4"]').contains('Last commit');
81+
82+
cy.get('[data-ouia-component-id="data-tr-error"]').should('be.visible');
83+
cy.get('[data-ouia-component-id="data-tr-error"]').contains('Some error');
84+
});
6385
});

cypress/component/DataViewTableTree.cy.tsx

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React from 'react';
22
import { DataViewTable, DataViewTrTree } from '@patternfly/react-data-view/dist/dynamic/DataViewTable';
3+
import DataView from '@patternfly/react-data-view/dist/dynamic/DataView';
34

45
interface Repository {
56
name: string;
@@ -130,7 +131,9 @@ describe('DataViewTableTree', () => {
130131
const ouiaId = 'tree';
131132

132133
cy.mount(
133-
<DataViewTable isTreeTable aria-label='Repositories table' ouiaId={ouiaId} columns={columns} rows={[]} emptyState="No data found" />
134+
<DataView activeState="empty">
135+
<DataViewTable isTreeTable aria-label='Repositories table' ouiaId={ouiaId} columns={columns} rows={[]} states={{ empty: "No data found" }} />
136+
</DataView>
134137
);
135138

136139
cy.get('[data-ouia-component-id="tree-th-0"]').contains('Repositories');
@@ -142,4 +145,23 @@ describe('DataViewTableTree', () => {
142145
cy.get('[data-ouia-component-id="tree-tr-empty"]').should('be.visible');
143146
cy.get('[data-ouia-component-id="tree-tr-empty"]').contains('No data found');
144147
});
148+
149+
it('renders a tree data view table with an error state', () => {
150+
const ouiaId = 'data';
151+
152+
cy.mount(
153+
<DataView activeState="error">
154+
<DataViewTable isTreeTable aria-label='Repositories table' ouiaId={ouiaId} columns={columns} rows={[]} states={{ error:"Some error" }} />
155+
</DataView>
156+
);
157+
158+
cy.get('[data-ouia-component-id="data-th-0"]').contains('Repositories');
159+
cy.get('[data-ouia-component-id="data-th-1"]').contains('Branches');
160+
cy.get('[data-ouia-component-id="data-th-2"]').contains('Pull requests');
161+
cy.get('[data-ouia-component-id="data-th-3"]').contains('Workspaces');
162+
cy.get('[data-ouia-component-id="data-th-4"]').contains('Last commit');
163+
164+
cy.get('[data-ouia-component-id="data-tr-error"]').should('be.visible');
165+
cy.get('[data-ouia-component-id="data-tr-error"]').contains('Some error');
166+
});
145167
});

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

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ sourceLink: https://github.com/patternfly/react-data-view/blob/main/packages/mod
1616
---
1717
import { Button, EmptyState, EmptyStateActions, EmptyStateBody, EmptyStateFooter, EmptyStateHeader, EmptyStateIcon } from '@patternfly/react-core';
1818
import { CubesIcon, FolderIcon, FolderOpenIcon, LeafIcon, ExclamationCircleIcon } from '@patternfly/react-icons';
19-
import { BulkSelect } from '@patternfly/react-component-groups';
19+
import { BulkSelect, ErrorState } from '@patternfly/react-component-groups';
2020
import { DataViewToolbar } from '@patternfly/react-data-view/dist/dynamic/DataViewToolbar';
2121
import { DataViewTable } from '@patternfly/react-data-view/dist/dynamic/DataViewTable';
2222
import { useDataViewSelection } from '@patternfly/react-data-view/dist/dynamic/Hooks';
23-
import { DataView } from '@patternfly/react-data-view/dist/dynamic/DataView';
23+
import { DataView, DataViewState } from '@patternfly/react-data-view/dist/dynamic/DataView';
2424

2525
## Data view toolbar
2626

@@ -74,8 +74,15 @@ It is also possible to disable row selection using the `isSelectDisabled` functi
7474
```
7575

7676
### Empty state example
77-
The data view table also supports displaying a custom empty state. You can pass it using the `emptyState` property and it will be displayed in case there are no rows to be rendered.
77+
The data view table supports displaying a custom empty state. You can pass it using the `states` property and `empty` key. It will be automatically displayed in case there are no rows to be rendered.
7878

7979
```js file="./DataViewTableEmptyExample.tsx"
8080

8181
```
82+
83+
### Error state example
84+
The data view table also supports displaying an error state. You can pass it using the `states` property and `error` key. It will be displayed in case the data view recieves its `state` property set to `error`.
85+
86+
```js file="./DataViewTableErrorExample.tsx"
87+
88+
```

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

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import React from 'react';
2+
import { DataView, DataViewState } from '@patternfly/react-data-view/dist/dynamic/DataView';
23
import { DataViewTable, DataViewTr, DataViewTh } from '@patternfly/react-data-view/dist/dynamic/DataViewTable';
34
import { CubesIcon } from '@patternfly/react-icons';
45
import { Button, EmptyState, EmptyStateActions, EmptyStateBody, EmptyStateFooter, EmptyStateHeader, EmptyStateIcon } from '@patternfly/react-core';
@@ -21,7 +22,7 @@ const columns: DataViewTh[] = [ 'Repositories', 'Branches', 'Pull requests', 'Wo
2122

2223
const ouiaId = 'TableExample';
2324

24-
const emptyState = (
25+
const empty = (
2526
<EmptyState>
2627
<EmptyStateHeader titleText="No data found" headingLevel="h4" icon={<EmptyStateIcon icon={CubesIcon} />} />
2728
<EmptyStateBody>There are no matching data to be displayed.</EmptyStateBody>
@@ -38,11 +39,13 @@ const emptyState = (
3839
);
3940

4041
export const BasicExample: React.FunctionComponent = () => (
41-
<DataViewTable
42-
aria-label='Repositories table'
43-
ouiaId={ouiaId}
44-
columns={columns}
45-
rows={rows}
46-
emptyState={emptyState}
47-
/>
42+
<DataView activeState={DataViewState.empty}>
43+
<DataViewTable
44+
aria-label='Repositories table'
45+
ouiaId={ouiaId}
46+
columns={columns}
47+
rows={rows}
48+
states={{ empty }}
49+
/>
50+
</DataView>
4851
);
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import React from 'react';
2+
import { DataView, DataViewState } from '@patternfly/react-data-view/dist/dynamic/DataView';
3+
import { DataViewTable, DataViewTr, DataViewTh } from '@patternfly/react-data-view/dist/dynamic/DataViewTable';
4+
import { ErrorState } from '@patternfly/react-component-groups';
5+
6+
interface Repository {
7+
id: number;
8+
name: string;
9+
branches: string | null;
10+
prs: string | null;
11+
workspaces: string;
12+
lastCommit: string;
13+
}
14+
15+
const repositories: Repository[] = [];
16+
17+
// you can also pass props to Tr by returning { row: DataViewTd[], props: TrProps } }
18+
const rows: DataViewTr[] = repositories.map((repository) => Object.values(repository));
19+
20+
const columns: DataViewTh[] = [ 'Repositories', 'Branches', 'Pull requests', 'Workspaces', 'Last commit' ];
21+
22+
const ouiaId = 'TableErrorExample';
23+
24+
const error = (
25+
<ErrorState errorTitle='Unable to load data' errorDescription='There was an error retrieving data. Check your connection and reload the page.' />
26+
);
27+
28+
export const BasicExample: React.FunctionComponent = () => (
29+
<DataView activeState={DataViewState.error}>
30+
<DataViewTable
31+
aria-label='Repositories table'
32+
ouiaId={ouiaId}
33+
columns={columns}
34+
rows={rows}
35+
states={{ error }}
36+
/>
37+
</DataView>
38+
);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ 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: 2
14-
propComponents: ['DataView']
14+
propComponents: ['DataView', 'DataViewState']
1515
sourceLink: https://github.com/patternfly/react-data-view/blob/main/packages/module/patternfly-docs/content/extensions/data-view/examples/Layout/Layout.md
1616
---
1717
import { useMemo } from 'react';

packages/module/src/DataView/DataView.tsx

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,31 @@ import React from 'react';
22
import { Stack, StackItem } from '@patternfly/react-core';
33
import { DataViewSelection, InternalContextProvider } from '../InternalContext';
44

5+
export const DataViewState = {
6+
empty: 'empty',
7+
loading: 'loading',
8+
error: 'error'
9+
} as const;
10+
11+
export type DataViewState = typeof DataViewState[keyof typeof DataViewState];
12+
513
export interface DataViewProps {
614
/** Content rendered inside the data view */
715
children: React.ReactNode;
816
/** Custom OUIA ID */
917
ouiaId?: string;
1018
/** Selection context configuration */
11-
selection?: DataViewSelection
19+
selection?: DataViewSelection;
20+
/** Currently active state */
21+
activeState?: DataViewState;
1222
}
1323

1424
export type DataViewImpementationProps = Omit<DataViewProps, 'onSelect' | 'isItemSelected' | 'isItemSelectDisabled'>;
1525

1626
const DataViewImplementation: React.FC<DataViewImpementationProps> = ({
1727
children, ouiaId = 'DataView', ...props
1828
}: DataViewImpementationProps) => (
19-
<Stack data-ouia-component-id={`${ouiaId}-stack}`} {...props}>
29+
<Stack data-ouia-component-id={`${ouiaId}-stack`} {...props}>
2030
{React.Children.map(children, (child, index) => (
2131
<StackItem data-ouia-component-id={`${ouiaId}-stack-item-${index}`}>
2232
{child}
@@ -25,8 +35,8 @@ const DataViewImplementation: React.FC<DataViewImpementationProps> = ({
2535
</Stack>
2636
)
2737

28-
export const DataView: React.FC<DataViewProps> = ({ children, selection, ...props }: DataViewProps) => (
29-
<InternalContextProvider selection={selection}>
38+
export const DataView: React.FC<DataViewProps> = ({ children, selection, activeState, ...props }: DataViewProps) => (
39+
<InternalContextProvider selection={selection} activeState={activeState} >
3040
<DataViewImplementation {...props}>{children}</DataViewImplementation>
3141
</InternalContextProvider>
3242
);

packages/module/src/DataView/__snapshots__/DataView.test.tsx.snap

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ exports[`DataView component should render correctly 1`] = `
77
<div>
88
<div
99
class="pf-v5-l-stack"
10-
data-ouia-component-id="DataView-stack}"
10+
data-ouia-component-id="DataView-stack"
1111
>
1212
<div
1313
class="pf-v5-l-stack__item"
@@ -45,7 +45,7 @@ exports[`DataView component should render correctly 1`] = `
4545
"container": <div>
4646
<div
4747
class="pf-v5-l-stack"
48-
data-ouia-component-id="DataView-stack}"
48+
data-ouia-component-id="DataView-stack"
4949
>
5050
<div
5151
class="pf-v5-l-stack__item"

packages/module/src/DataViewTableBasic/DataViewTableBasic.test.tsx

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React from 'react';
22
import { render } from '@testing-library/react';
33
import { DataViewTableBasic } from './DataViewTableBasic';
4+
import DataView from '../DataView/DataView';
45

56
interface Repository {
67
name: string;
@@ -37,7 +38,18 @@ describe('DataViewTable component', () => {
3738

3839
test('should render with an empty state', () => {
3940
const { container } = render(
40-
<DataViewTableBasic aria-label='Repositories table' ouiaId={ouiaId} columns={columns} emptyState="No data found" rows={[]} />
41+
<DataView activeState="empty">
42+
<DataViewTableBasic aria-label='Repositories table' ouiaId={ouiaId} columns={columns} states={{ empty:"No data found" }} rows={[]} />
43+
</DataView>
44+
);
45+
expect(container).toMatchSnapshot();
46+
});
47+
48+
test('should render with an error state', () => {
49+
const { container } = render(
50+
<DataView activeState="error">
51+
<DataViewTableBasic aria-label='Repositories table' ouiaId={ouiaId} columns={columns} states={{ error:"Some error" }} rows={[]} />
52+
</DataView>
4153
);
4254
expect(container).toMatchSnapshot();
4355
});

0 commit comments

Comments
 (0)