@patternfly/react-data-view 5.2.0 → 5.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/DataView/DataView.d.ts +1 -1
- package/dist/cjs/DataViewTableBasic/DataViewTableBasic.d.ts +4 -2
- package/dist/cjs/DataViewTableBasic/DataViewTableBasic.js +24 -23
- package/dist/cjs/DataViewTableBasic/DataViewTableBasic.test.js +10 -5
- package/dist/cjs/{DataViewTableHeader/DataViewTableHeader.d.ts → DataViewTableHead/DataViewTableHead.d.ts} +3 -3
- package/dist/cjs/{DataViewTableHeader/DataViewTableHeader.js → DataViewTableHead/DataViewTableHead.js} +6 -6
- package/dist/cjs/{DataViewTableHeader/DataViewTableHeader.test.js → DataViewTableHead/DataViewTableHead.test.js} +5 -5
- package/dist/cjs/DataViewTableHead/index.d.ts +2 -0
- package/dist/cjs/{DataViewTableHeader → DataViewTableHead}/index.js +3 -3
- package/dist/cjs/DataViewTableTree/DataViewTableTree.d.ts +4 -2
- package/dist/cjs/DataViewTableTree/DataViewTableTree.js +6 -5
- package/dist/cjs/DataViewTableTree/DataViewTableTree.test.js +7 -2
- package/dist/cjs/DataViewToolbar/DataViewToolbar.js +2 -2
- package/dist/cjs/InternalContext/InternalContext.d.ts +9 -3
- package/dist/cjs/InternalContext/InternalContext.js +6 -2
- package/dist/cjs/index.d.ts +2 -2
- package/dist/cjs/index.js +4 -4
- package/dist/dynamic/DataViewTableHead/package.json +1 -0
- package/dist/esm/DataView/DataView.d.ts +1 -1
- package/dist/esm/DataViewTableBasic/DataViewTableBasic.d.ts +4 -2
- package/dist/esm/DataViewTableBasic/DataViewTableBasic.js +24 -23
- package/dist/esm/DataViewTableBasic/DataViewTableBasic.test.js +8 -3
- package/dist/esm/{DataViewTableHeader/DataViewTableHeader.d.ts → DataViewTableHead/DataViewTableHead.d.ts} +3 -3
- package/dist/esm/{DataViewTableHeader/DataViewTableHeader.js → DataViewTableHead/DataViewTableHead.js} +4 -4
- package/dist/esm/{DataViewTableHeader/DataViewTableHeader.test.js → DataViewTableHead/DataViewTableHead.test.js} +5 -5
- package/dist/esm/DataViewTableHead/index.d.ts +2 -0
- package/dist/esm/DataViewTableHead/index.js +2 -0
- package/dist/esm/DataViewTableTree/DataViewTableTree.d.ts +4 -2
- package/dist/esm/DataViewTableTree/DataViewTableTree.js +7 -6
- package/dist/esm/DataViewTableTree/DataViewTableTree.test.js +7 -2
- package/dist/esm/DataViewToolbar/DataViewToolbar.js +2 -2
- package/dist/esm/InternalContext/InternalContext.d.ts +9 -3
- package/dist/esm/InternalContext/InternalContext.js +7 -3
- package/dist/esm/index.d.ts +2 -2
- package/dist/esm/index.js +2 -2
- package/package.json +5 -5
- package/patternfly-docs/content/extensions/data-view/examples/Components/Components.md +26 -8
- package/patternfly-docs/content/extensions/data-view/examples/Components/DataViewTableEmptyExample.tsx +21 -14
- package/patternfly-docs/content/extensions/data-view/examples/Components/DataViewTableErrorExample.tsx +9 -2
- package/patternfly-docs/content/extensions/data-view/examples/Components/DataViewTableLoadingExample.tsx +27 -0
- package/patternfly-docs/content/extensions/data-view/examples/Components/DataViewToolbarActionsExample.tsx +27 -0
- package/patternfly-docs/content/extensions/data-view/examples/Components/DataViewToolbarExample.tsx +4 -4
- package/patternfly-docs/content/extensions/data-view/examples/Functionality/Functionality.md +1 -2
- package/src/DataView/DataView.tsx +1 -1
- package/src/DataViewTable/DataViewTable.tsx +1 -1
- package/src/DataViewTableBasic/DataViewTableBasic.test.tsx +12 -3
- package/src/DataViewTableBasic/DataViewTableBasic.tsx +46 -48
- package/src/DataViewTableBasic/__snapshots__/DataViewTableBasic.test.tsx.snap +71 -30
- package/src/{DataViewTableHeader/DataViewTableHeader.test.tsx → DataViewTableHead/DataViewTableHead.test.tsx} +5 -7
- package/src/{DataViewTableHeader/DataViewTableHeader.tsx → DataViewTableHead/DataViewTableHead.tsx} +6 -6
- package/src/{DataViewTableHeader/__snapshots__/DataViewTableHeader.test.tsx.snap → DataViewTableHead/__snapshots__/DataViewTableHead.test.tsx.snap} +4 -4
- package/src/DataViewTableHead/index.ts +2 -0
- package/src/DataViewTableTree/DataViewTableTree.test.tsx +11 -2
- package/src/DataViewTableTree/DataViewTableTree.tsx +12 -16
- package/src/DataViewTableTree/__snapshots__/DataViewTableTree.test.tsx.snap +71 -30
- package/src/DataViewToolbar/DataViewToolbar.tsx +7 -3
- package/src/DataViewToolbar/__snapshots__/DataViewToolbar.test.tsx.snap +86 -84
- package/src/InternalContext/InternalContext.tsx +24 -12
- package/src/index.ts +2 -2
- package/dist/cjs/DataViewTableHeader/index.d.ts +0 -2
- package/dist/dynamic/DataViewTableHeader/package.json +0 -1
- package/dist/esm/DataViewTableHeader/index.d.ts +0 -2
- package/dist/esm/DataViewTableHeader/index.js +0 -2
- package/src/DataViewTableHeader/index.ts +0 -2
- /package/dist/cjs/{DataViewTableHeader/DataViewTableHeader.test.d.ts → DataViewTableHead/DataViewTableHead.test.d.ts} +0 -0
- /package/dist/esm/{DataViewTableHeader/DataViewTableHeader.test.d.ts → DataViewTableHead/DataViewTableHead.test.d.ts} +0 -0
|
@@ -10,9 +10,9 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
10
10
|
return t;
|
|
11
11
|
};
|
|
12
12
|
import React, { useMemo } from 'react';
|
|
13
|
-
import { Table, Tbody, Td,
|
|
13
|
+
import { Table, Tbody, Td, TreeRowWrapper, } from '@patternfly/react-table';
|
|
14
14
|
import { useInternalContext } from '../InternalContext';
|
|
15
|
-
import {
|
|
15
|
+
import { DataViewTableHead } from '../DataViewTableHead';
|
|
16
16
|
import { isDataViewTdObject } from '../DataViewTable';
|
|
17
17
|
const getDescendants = (node) => (!node.children || !node.children.length) ? [node] : node.children.flatMap(getDescendants);
|
|
18
18
|
const isNodeChecked = (node, isSelected) => {
|
|
@@ -29,11 +29,13 @@ const isNodeChecked = (node, isSelected) => {
|
|
|
29
29
|
return allSelected;
|
|
30
30
|
};
|
|
31
31
|
export const DataViewTableTree = (_a) => {
|
|
32
|
-
var { columns, rows,
|
|
32
|
+
var { columns, rows, headStates, bodyStates, leafIcon = null, expandedIcon = null, collapsedIcon = null, ouiaId = 'DataViewTableTree' } = _a, props = __rest(_a, ["columns", "rows", "headStates", "bodyStates", "leafIcon", "expandedIcon", "collapsedIcon", "ouiaId"]);
|
|
33
33
|
const { selection, activeState } = useInternalContext();
|
|
34
34
|
const { onSelect, isSelected, isSelectDisabled } = selection !== null && selection !== void 0 ? selection : {};
|
|
35
35
|
const [expandedNodeIds, setExpandedNodeIds] = React.useState([]);
|
|
36
36
|
const [expandedDetailsNodeNames, setExpandedDetailsNodeIds] = React.useState([]);
|
|
37
|
+
const activeHeadState = useMemo(() => activeState ? headStates === null || headStates === void 0 ? void 0 : headStates[activeState] : undefined, [activeState, headStates]);
|
|
38
|
+
const activeBodyState = useMemo(() => activeState ? bodyStates === null || bodyStates === void 0 ? void 0 : bodyStates[activeState] : undefined, [activeState, bodyStates]);
|
|
37
39
|
const nodes = useMemo(() => {
|
|
38
40
|
const renderRows = ([node, ...remainingNodes], level = 1, posinset = 1, rowIndex = 0, isHidden = false) => {
|
|
39
41
|
var _a, _b, _c, _d;
|
|
@@ -97,8 +99,7 @@ export const DataViewTableTree = (_a) => {
|
|
|
97
99
|
ouiaId
|
|
98
100
|
]);
|
|
99
101
|
return (React.createElement(Table, Object.assign({ isTreeTable: true, "aria-label": "Data table", ouiaId: ouiaId }, props),
|
|
100
|
-
React.createElement(
|
|
101
|
-
React.createElement(Tbody, null,
|
|
102
|
-
React.createElement(Td, { colSpan: columns.length }, states[activeState]))) : nodes)));
|
|
102
|
+
activeHeadState || React.createElement(DataViewTableHead, { isTreeTable: true, columns: columns, ouiaId: ouiaId }),
|
|
103
|
+
activeBodyState || React.createElement(Tbody, null, nodes)));
|
|
103
104
|
};
|
|
104
105
|
export default DataViewTableTree;
|
|
@@ -69,12 +69,17 @@ describe('DataViewTableTree component', () => {
|
|
|
69
69
|
});
|
|
70
70
|
test('should render tree table with an empty state', () => {
|
|
71
71
|
const { container } = render(React.createElement(DataView, { activeState: "empty" },
|
|
72
|
-
React.createElement(DataViewTable, { isTreeTable: true, "aria-label": 'Repositories table', ouiaId: ouiaId, columns: columns,
|
|
72
|
+
React.createElement(DataViewTable, { isTreeTable: true, "aria-label": 'Repositories table', ouiaId: ouiaId, columns: columns, bodyStates: { empty: "No data found" }, rows: [] })));
|
|
73
73
|
expect(container).toMatchSnapshot();
|
|
74
74
|
});
|
|
75
75
|
test('should render tree table with an error state', () => {
|
|
76
76
|
const { container } = render(React.createElement(DataView, { activeState: "error" },
|
|
77
|
-
React.createElement(DataViewTable, { isTreeTable: true, "aria-label": 'Repositories table', ouiaId: ouiaId, columns: columns,
|
|
77
|
+
React.createElement(DataViewTable, { isTreeTable: true, "aria-label": 'Repositories table', ouiaId: ouiaId, columns: columns, bodyStates: { error: "Some error" }, rows: [] })));
|
|
78
|
+
expect(container).toMatchSnapshot();
|
|
79
|
+
});
|
|
80
|
+
test('should render tree table with a loading state', () => {
|
|
81
|
+
const { container } = render(React.createElement(DataView, { activeState: "loading" },
|
|
82
|
+
React.createElement(DataViewTable, { isTreeTable: true, "aria-label": 'Repositories table', ouiaId: ouiaId, columns: columns, bodyStates: { loading: "Data is loading" }, rows: [] })));
|
|
78
83
|
expect(container).toMatchSnapshot();
|
|
79
84
|
});
|
|
80
85
|
});
|
|
@@ -12,11 +12,11 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
12
12
|
import React from 'react';
|
|
13
13
|
import { Toolbar, ToolbarContent, ToolbarItem, ToolbarItemVariant } from '@patternfly/react-core';
|
|
14
14
|
export const DataViewToolbar = (_a) => {
|
|
15
|
-
var { className, ouiaId = 'DataViewToolbar', bulkSelect, actions
|
|
15
|
+
var { className, ouiaId = 'DataViewToolbar', bulkSelect, actions, pagination, children } = _a, props = __rest(_a, ["className", "ouiaId", "bulkSelect", "actions", "pagination", "children"]);
|
|
16
16
|
return (React.createElement(Toolbar, Object.assign({ ouiaId: ouiaId, className: className }, props),
|
|
17
17
|
React.createElement(ToolbarContent, null,
|
|
18
18
|
bulkSelect && (React.createElement(ToolbarItem, { "data-ouia-component-id": `${ouiaId}-bulk-select` }, bulkSelect)),
|
|
19
|
-
actions,
|
|
19
|
+
actions && (React.createElement(ToolbarItem, { variant: ToolbarItemVariant['overflow-menu'] }, actions)),
|
|
20
20
|
pagination && (React.createElement(ToolbarItem, { variant: ToolbarItemVariant.pagination, "data-ouia-component-id": `${ouiaId}-pagination` }, pagination)),
|
|
21
21
|
children)));
|
|
22
22
|
};
|
|
@@ -8,12 +8,18 @@ export interface DataViewSelection {
|
|
|
8
8
|
/** Determines if selection is disabled for a given item */
|
|
9
9
|
isSelectDisabled?: (item: any) => boolean;
|
|
10
10
|
}
|
|
11
|
-
export interface
|
|
11
|
+
export interface InternalContextProps {
|
|
12
|
+
/** Data selection props */
|
|
12
13
|
selection?: DataViewSelection;
|
|
13
|
-
|
|
14
|
+
/** Currently active state */
|
|
15
|
+
activeState?: DataViewState | string;
|
|
16
|
+
}
|
|
17
|
+
export interface InternalContextValue extends InternalContextProps {
|
|
18
|
+
/** Flag indicating if data view is selectable (auto-calculated) */
|
|
19
|
+
isSelectable: boolean;
|
|
14
20
|
}
|
|
15
21
|
export declare const InternalContext: React.Context<InternalContextValue>;
|
|
16
|
-
export type InternalProviderProps = PropsWithChildren<
|
|
22
|
+
export type InternalProviderProps = PropsWithChildren<InternalContextProps>;
|
|
17
23
|
export declare const InternalContextProvider: React.FC<InternalProviderProps>;
|
|
18
24
|
export declare const useInternalContext: () => InternalContextValue;
|
|
19
25
|
export default InternalContext;
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
import React, { createContext, useContext } from 'react';
|
|
1
|
+
import React, { createContext, useContext, useMemo } from 'react';
|
|
2
2
|
export const InternalContext = createContext({
|
|
3
3
|
selection: undefined,
|
|
4
|
-
activeState: undefined
|
|
4
|
+
activeState: undefined,
|
|
5
|
+
isSelectable: false,
|
|
5
6
|
});
|
|
6
|
-
export const InternalContextProvider = ({ children, selection, activeState }) =>
|
|
7
|
+
export const InternalContextProvider = ({ children, selection, activeState }) => {
|
|
8
|
+
const isSelectable = useMemo(() => Boolean((selection === null || selection === void 0 ? void 0 : selection.onSelect) && (selection === null || selection === void 0 ? void 0 : selection.isSelected)), [selection === null || selection === void 0 ? void 0 : selection.onSelect, selection === null || selection === void 0 ? void 0 : selection.isSelected]);
|
|
9
|
+
return (React.createElement(InternalContext.Provider, { value: { selection, activeState, isSelectable } }, children));
|
|
10
|
+
};
|
|
7
11
|
export const useInternalContext = () => useContext(InternalContext);
|
|
8
12
|
export default InternalContext;
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -5,8 +5,8 @@ export { default as DataViewToolbar } from './DataViewToolbar';
|
|
|
5
5
|
export * from './DataViewToolbar';
|
|
6
6
|
export { default as DataViewTableTree } from './DataViewTableTree';
|
|
7
7
|
export * from './DataViewTableTree';
|
|
8
|
-
export { default as
|
|
9
|
-
export * from './
|
|
8
|
+
export { default as DataViewTableHead } from './DataViewTableHead';
|
|
9
|
+
export * from './DataViewTableHead';
|
|
10
10
|
export { default as DataViewTableBasic } from './DataViewTableBasic';
|
|
11
11
|
export * from './DataViewTableBasic';
|
|
12
12
|
export { default as DataViewTable } from './DataViewTable';
|
package/dist/esm/index.js
CHANGED
|
@@ -6,8 +6,8 @@ export { default as DataViewToolbar } from './DataViewToolbar';
|
|
|
6
6
|
export * from './DataViewToolbar';
|
|
7
7
|
export { default as DataViewTableTree } from './DataViewTableTree';
|
|
8
8
|
export * from './DataViewTableTree';
|
|
9
|
-
export { default as
|
|
10
|
-
export * from './
|
|
9
|
+
export { default as DataViewTableHead } from './DataViewTableHead';
|
|
10
|
+
export * from './DataViewTableHead';
|
|
11
11
|
export { default as DataViewTableBasic } from './DataViewTableBasic';
|
|
12
12
|
export * from './DataViewTableBasic';
|
|
13
13
|
export { default as DataViewTable } from './DataViewTable';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@patternfly/react-data-view",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.4.0",
|
|
4
4
|
"description": "Data view used for Red Hat projects.",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -30,10 +30,10 @@
|
|
|
30
30
|
"access": "public"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@patternfly/react-core": "^5.
|
|
34
|
-
"@patternfly/react-icons": "^5.
|
|
35
|
-
"@patternfly/react-table": "^5.
|
|
36
|
-
"@patternfly/react-component-groups": "^5.
|
|
33
|
+
"@patternfly/react-core": "^5.4.1",
|
|
34
|
+
"@patternfly/react-icons": "^5.4.0",
|
|
35
|
+
"@patternfly/react-table": "^5.4.1",
|
|
36
|
+
"@patternfly/react-component-groups": "^5.5.2",
|
|
37
37
|
"react-jss": "^10.10.0",
|
|
38
38
|
"clsx": "^2.1.1"
|
|
39
39
|
},
|
|
@@ -16,7 +16,7 @@ sourceLink: https://github.com/patternfly/react-data-view/blob/main/packages/mod
|
|
|
16
16
|
---
|
|
17
17
|
import { Button, EmptyState, EmptyStateActions, EmptyStateBody, EmptyStateFooter, EmptyStateHeader, EmptyStateIcon } from '@patternfly/react-core';
|
|
18
18
|
import { CubesIcon, FolderIcon, FolderOpenIcon, LeafIcon, ExclamationCircleIcon } from '@patternfly/react-icons';
|
|
19
|
-
import { BulkSelect, ErrorState } from '@patternfly/react-component-groups';
|
|
19
|
+
import { BulkSelect, ErrorState, ResponsiveAction, ResponsiveActions, SkeletonTableHead, SkeletonTableBody } from '@patternfly/react-component-groups';
|
|
20
20
|
import { DataViewToolbar } from '@patternfly/react-data-view/dist/dynamic/DataViewToolbar';
|
|
21
21
|
import { DataViewTable } from '@patternfly/react-data-view/dist/dynamic/DataViewTable';
|
|
22
22
|
import { useDataViewSelection } from '@patternfly/react-data-view/dist/dynamic/Hooks';
|
|
@@ -26,7 +26,7 @@ import { DataView, DataViewState } from '@patternfly/react-data-view/dist/dynami
|
|
|
26
26
|
|
|
27
27
|
The **data view toolbar** component renders a default opinionated data view toolbar above or below the data section.
|
|
28
28
|
|
|
29
|
-
Data view toolbar can contain a `pagination`, `bulkSelect` or
|
|
29
|
+
Data view toolbar can contain a `pagination`, `bulkSelect`, `actions` or other children content passed. The preffered way of passing children toolbar items is using the [toolbar item](/components/toolbar#toolbar-items) component.
|
|
30
30
|
|
|
31
31
|
### Basic toolbar example
|
|
32
32
|
|
|
@@ -34,13 +34,24 @@ Data view toolbar can contain a `pagination`, `bulkSelect` or any other children
|
|
|
34
34
|
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
+
# Toolbar actions
|
|
38
|
+
Data view toolbar can display actions using the `actions` property accepting a React node. You can make use of a predefined [responsive actions](/extensions/component-groups/responsive-actions) component from the [component groups](/extensions/component-groups/about-component-groups) extension.
|
|
39
|
+
|
|
40
|
+
### Actions configuration
|
|
41
|
+
|
|
42
|
+
### Actions example
|
|
43
|
+
|
|
44
|
+
```js file="./DataViewToolbarActionsExample.tsx"
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
|
|
37
48
|
## Data view table
|
|
38
49
|
|
|
39
50
|
The **data view table** component renders your columns and rows definition into a [table](/components/table) component.
|
|
40
51
|
|
|
41
52
|
### Rows and columns customization
|
|
42
53
|
|
|
43
|
-
This example shows possible formats of `rows` and `columns` passed to the `DataViewTable` which allow you various customizations of the table
|
|
54
|
+
This example shows possible formats of `rows` and `columns` passed to the `DataViewTable` which allow you various customizations of the table head and body.
|
|
44
55
|
|
|
45
56
|
```js file="./DataViewTableExample.tsx"
|
|
46
57
|
|
|
@@ -48,9 +59,9 @@ This example shows possible formats of `rows` and `columns` passed to the `DataV
|
|
|
48
59
|
|
|
49
60
|
The `DataViewTable` component accepts the following props:
|
|
50
61
|
|
|
51
|
-
- `columns` defining the column
|
|
52
|
-
- `cell` (`ReactNode`) content to display in the column
|
|
53
|
-
- optional `props` (`ThProps`) to pass to the `<Th>` component, such as `width`, `sort`, and other table
|
|
62
|
+
- `columns` defining the column heads of the table. Each item in the array can be a `ReactNode` (for simple heads) or an object with the following properties:
|
|
63
|
+
- `cell` (`ReactNode`) content to display in the column head.
|
|
64
|
+
- optional `props` (`ThProps`) to pass to the `<Th>` component, such as `width`, `sort`, and other table head cell properties.
|
|
54
65
|
|
|
55
66
|
- `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:
|
|
56
67
|
- `row` (`DataViewTd[]`) defining the content for each cell in the row.
|
|
@@ -74,15 +85,22 @@ It is also possible to disable row selection using the `isSelectDisabled` functi
|
|
|
74
85
|
```
|
|
75
86
|
|
|
76
87
|
### Empty state example
|
|
77
|
-
The data view table supports displaying a custom empty state. You can pass it using the `
|
|
88
|
+
The data view table supports displaying a custom empty state. You can pass it using the the `headStates` and `bodyStates` properties and their `empty` key. It will be automatically displayed in case there are no rows to be rendered.
|
|
78
89
|
|
|
79
90
|
```js file="./DataViewTableEmptyExample.tsx"
|
|
80
91
|
|
|
81
92
|
```
|
|
82
93
|
|
|
83
94
|
### Error state example
|
|
84
|
-
The data view table also supports displaying an error state. You can pass it using the `
|
|
95
|
+
The data view table also supports displaying an error state. You can pass it using the the `headStates` and `bodyStates` properties and their `error` key. It will be displayed in case the data view recieves its `state` property set to `error`.
|
|
85
96
|
|
|
86
97
|
```js file="./DataViewTableErrorExample.tsx"
|
|
87
98
|
|
|
88
99
|
```
|
|
100
|
+
|
|
101
|
+
### Loading state example
|
|
102
|
+
The data view table also supports displaying a custom loading state. You can pass it using the `headStates` and `bodyStates` properties and their `loading` key. Your state will be displayed in case the data view recieves its `state` property set to `loading`.
|
|
103
|
+
|
|
104
|
+
```js file="./DataViewTableLoadingExample.tsx"
|
|
105
|
+
|
|
106
|
+
```
|
|
@@ -3,6 +3,7 @@ import { DataView, DataViewState } from '@patternfly/react-data-view/dist/dynami
|
|
|
3
3
|
import { DataViewTable, DataViewTr, DataViewTh } from '@patternfly/react-data-view/dist/dynamic/DataViewTable';
|
|
4
4
|
import { CubesIcon } from '@patternfly/react-icons';
|
|
5
5
|
import { Button, EmptyState, EmptyStateActions, EmptyStateBody, EmptyStateFooter, EmptyStateHeader, EmptyStateIcon } from '@patternfly/react-core';
|
|
6
|
+
import { Tbody, Td, Tr } from '@patternfly/react-table';
|
|
6
7
|
|
|
7
8
|
interface Repository {
|
|
8
9
|
id: number;
|
|
@@ -23,19 +24,25 @@ const columns: DataViewTh[] = [ 'Repositories', 'Branches', 'Pull requests', 'Wo
|
|
|
23
24
|
const ouiaId = 'TableExample';
|
|
24
25
|
|
|
25
26
|
const empty = (
|
|
26
|
-
<
|
|
27
|
-
<
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
27
|
+
<Tbody>
|
|
28
|
+
<Tr key="loading" ouiaId={`${ouiaId}-tr-loading`}>
|
|
29
|
+
<Td colSpan={columns.length}>
|
|
30
|
+
<EmptyState>
|
|
31
|
+
<EmptyStateHeader titleText="No data found" headingLevel="h4" icon={<EmptyStateIcon icon={CubesIcon} />} />
|
|
32
|
+
<EmptyStateBody>There are no matching data to be displayed.</EmptyStateBody>
|
|
33
|
+
<EmptyStateFooter>
|
|
34
|
+
<EmptyStateActions>
|
|
35
|
+
<Button variant="primary">Primary action</Button>
|
|
36
|
+
</EmptyStateActions>
|
|
37
|
+
<EmptyStateActions>
|
|
38
|
+
<Button variant="link">Multiple</Button>
|
|
39
|
+
<Button variant="link">Action Buttons</Button>
|
|
40
|
+
</EmptyStateActions>
|
|
41
|
+
</EmptyStateFooter>
|
|
42
|
+
</EmptyState>
|
|
43
|
+
</Td>
|
|
44
|
+
</Tr>
|
|
45
|
+
</Tbody>
|
|
39
46
|
);
|
|
40
47
|
|
|
41
48
|
export const BasicExample: React.FunctionComponent = () => (
|
|
@@ -45,7 +52,7 @@ export const BasicExample: React.FunctionComponent = () => (
|
|
|
45
52
|
ouiaId={ouiaId}
|
|
46
53
|
columns={columns}
|
|
47
54
|
rows={rows}
|
|
48
|
-
|
|
55
|
+
bodyStates={{ empty }}
|
|
49
56
|
/>
|
|
50
57
|
</DataView>
|
|
51
58
|
);
|
|
@@ -2,6 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import { DataView, DataViewState } from '@patternfly/react-data-view/dist/dynamic/DataView';
|
|
3
3
|
import { DataViewTable, DataViewTr, DataViewTh } from '@patternfly/react-data-view/dist/dynamic/DataViewTable';
|
|
4
4
|
import { ErrorState } from '@patternfly/react-component-groups';
|
|
5
|
+
import { Tbody, Td, Tr } from '@patternfly/react-table';
|
|
5
6
|
|
|
6
7
|
interface Repository {
|
|
7
8
|
id: number;
|
|
@@ -22,7 +23,13 @@ const columns: DataViewTh[] = [ 'Repositories', 'Branches', 'Pull requests', 'Wo
|
|
|
22
23
|
const ouiaId = 'TableErrorExample';
|
|
23
24
|
|
|
24
25
|
const error = (
|
|
25
|
-
<
|
|
26
|
+
<Tbody>
|
|
27
|
+
<Tr key="loading" ouiaId={`${ouiaId}-tr-loading`}>
|
|
28
|
+
<Td colSpan={columns.length}>
|
|
29
|
+
<ErrorState errorTitle='Unable to load data' errorDescription='There was an error retrieving data. Check your connection and reload the page.' />
|
|
30
|
+
</Td>
|
|
31
|
+
</Tr>
|
|
32
|
+
</Tbody>
|
|
26
33
|
);
|
|
27
34
|
|
|
28
35
|
export const BasicExample: React.FunctionComponent = () => (
|
|
@@ -32,7 +39,7 @@ export const BasicExample: React.FunctionComponent = () => (
|
|
|
32
39
|
ouiaId={ouiaId}
|
|
33
40
|
columns={columns}
|
|
34
41
|
rows={rows}
|
|
35
|
-
|
|
42
|
+
bodyStates={{ error }}
|
|
36
43
|
/>
|
|
37
44
|
</DataView>
|
|
38
45
|
);
|
|
@@ -0,0 +1,27 @@
|
|
|
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 { SkeletonTableBody, SkeletonTableHead } from '@patternfly/react-component-groups';
|
|
5
|
+
|
|
6
|
+
// you can also pass props to Tr by returning { row: DataViewTd[], props: TrProps } }
|
|
7
|
+
const rows: DataViewTr[] = [];
|
|
8
|
+
|
|
9
|
+
const columns: DataViewTh[] = [ 'Repositories', 'Branches', 'Pull requests', 'Workspaces', 'Last commit' ];
|
|
10
|
+
|
|
11
|
+
const ouiaId = 'TableExample';
|
|
12
|
+
|
|
13
|
+
const headLoading = <SkeletonTableHead columns={columns} />
|
|
14
|
+
const bodyLoading = <SkeletonTableBody rowsCount={5} columnsCount={columns.length} />;
|
|
15
|
+
|
|
16
|
+
export const BasicExample: React.FunctionComponent = () => (
|
|
17
|
+
<DataView activeState={DataViewState.loading}>
|
|
18
|
+
<DataViewTable
|
|
19
|
+
aria-label='Repositories table'
|
|
20
|
+
ouiaId={ouiaId}
|
|
21
|
+
columns={columns}
|
|
22
|
+
rows={rows}
|
|
23
|
+
headStates={{ loading: headLoading }}
|
|
24
|
+
bodyStates={{ loading: bodyLoading }}
|
|
25
|
+
/>
|
|
26
|
+
</DataView>
|
|
27
|
+
);
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Pagination } from '@patternfly/react-core';
|
|
3
|
+
import { BulkSelect, ResponsiveAction, ResponsiveActions } from '@patternfly/react-component-groups';
|
|
4
|
+
import { DataViewToolbar } from '@patternfly/react-data-view/dist/dynamic/DataViewToolbar';
|
|
5
|
+
|
|
6
|
+
export const BasicExample: React.FunctionComponent = () => (
|
|
7
|
+
<DataViewToolbar
|
|
8
|
+
bulkSelect={
|
|
9
|
+
<BulkSelect
|
|
10
|
+
selectedCount={0}
|
|
11
|
+
pageCount={5}
|
|
12
|
+
onSelect={() => null}
|
|
13
|
+
/>
|
|
14
|
+
}
|
|
15
|
+
actions={
|
|
16
|
+
<ResponsiveActions breakpoint="lg" ouiaId="example-actions">
|
|
17
|
+
<ResponsiveAction isPersistent variant="primary">Persistent</ResponsiveAction>
|
|
18
|
+
<ResponsiveAction isPinned variant="secondary">Pinned</ResponsiveAction>
|
|
19
|
+
<ResponsiveAction>Action three</ResponsiveAction>
|
|
20
|
+
<ResponsiveAction>Action four</ResponsiveAction>
|
|
21
|
+
</ResponsiveActions>
|
|
22
|
+
}
|
|
23
|
+
pagination={
|
|
24
|
+
<Pagination page={1} perPage={10} />
|
|
25
|
+
}
|
|
26
|
+
/>
|
|
27
|
+
)
|
package/patternfly-docs/content/extensions/data-view/examples/Components/DataViewToolbarExample.tsx
CHANGED
|
@@ -6,15 +6,15 @@ import DataViewToolbar from '@patternfly/react-data-view/dist/dynamic/DataViewTo
|
|
|
6
6
|
|
|
7
7
|
export const BasicExample: React.FunctionComponent = () => (
|
|
8
8
|
<DataViewToolbar
|
|
9
|
-
pagination={
|
|
10
|
-
<Pagination page={1} perPage={10} />
|
|
11
|
-
}
|
|
12
9
|
bulkSelect={
|
|
13
10
|
<BulkSelect
|
|
14
11
|
selectedCount={0}
|
|
15
12
|
pageCount={5}
|
|
16
13
|
onSelect={() => null}
|
|
17
14
|
/>
|
|
18
|
-
}
|
|
15
|
+
}
|
|
16
|
+
pagination={
|
|
17
|
+
<Pagination page={1} perPage={10} />
|
|
18
|
+
}
|
|
19
19
|
/>
|
|
20
20
|
)
|
package/patternfly-docs/content/extensions/data-view/examples/Functionality/Functionality.md
CHANGED
|
@@ -62,7 +62,7 @@ This example uses the URL for persisting the pagination state.
|
|
|
62
62
|
Allows to select data records inside the data view and show the selection state.
|
|
63
63
|
|
|
64
64
|
### Toolbar usage
|
|
65
|
-
Data view toolbar can display a bulk selection component using the `bulkSelect` property accepting a React node. You can make use of a predefined [bulk select](/extensions/component-groups/bulk-select) from the [component groups](/extensions/component-groups/about-component-groups) extension.
|
|
65
|
+
Data view toolbar can display a bulk selection component using the `bulkSelect` property accepting a React node. You can make use of a predefined [bulk select](/extensions/component-groups/bulk-select) component from the [component groups](/extensions/component-groups/about-component-groups) extension.
|
|
66
66
|
|
|
67
67
|
### Selection state
|
|
68
68
|
|
|
@@ -84,4 +84,3 @@ The `useDataViewSelection` hook manages the selection state of the data view.
|
|
|
84
84
|
```js file="./SelectionExample.tsx"
|
|
85
85
|
|
|
86
86
|
```
|
|
87
|
-
|
|
@@ -18,7 +18,7 @@ export interface DataViewProps {
|
|
|
18
18
|
/** Selection context configuration */
|
|
19
19
|
selection?: DataViewSelection;
|
|
20
20
|
/** Currently active state */
|
|
21
|
-
activeState?: DataViewState;
|
|
21
|
+
activeState?: DataViewState | string;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
export type DataViewImpementationProps = Omit<DataViewProps, 'onSelect' | 'isItemSelected' | 'isItemSelectDisabled'>;
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
import { DataViewTableTree, DataViewTableTreeProps } from '../DataViewTableTree';
|
|
8
8
|
import { DataViewTableBasic, DataViewTableBasicProps } from '../DataViewTableBasic';
|
|
9
9
|
|
|
10
|
-
// Table
|
|
10
|
+
// Table head typings
|
|
11
11
|
export type DataViewTh = ReactNode | { cell: ReactNode; props?: ThProps };
|
|
12
12
|
export const isDataViewThObject = (value: DataViewTh): value is { cell: ReactNode; props?: ThProps } => value != null && typeof value === 'object' && 'cell' in value;
|
|
13
13
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { render } from '@testing-library/react';
|
|
3
|
+
import { DataView } from '../DataView';
|
|
3
4
|
import { DataViewTableBasic } from './DataViewTableBasic';
|
|
4
|
-
import DataView from '../DataView/DataView';
|
|
5
5
|
|
|
6
6
|
interface Repository {
|
|
7
7
|
name: string;
|
|
@@ -39,7 +39,7 @@ describe('DataViewTable component', () => {
|
|
|
39
39
|
test('should render with an empty state', () => {
|
|
40
40
|
const { container } = render(
|
|
41
41
|
<DataView activeState="empty">
|
|
42
|
-
<DataViewTableBasic aria-label='Repositories table' ouiaId={ouiaId} columns={columns}
|
|
42
|
+
<DataViewTableBasic aria-label='Repositories table' ouiaId={ouiaId} columns={columns} bodyStates={{ empty: "No data found" }} rows={[]} />
|
|
43
43
|
</DataView>
|
|
44
44
|
);
|
|
45
45
|
expect(container).toMatchSnapshot();
|
|
@@ -48,9 +48,18 @@ describe('DataViewTable component', () => {
|
|
|
48
48
|
test('should render with an error state', () => {
|
|
49
49
|
const { container } = render(
|
|
50
50
|
<DataView activeState="error">
|
|
51
|
-
<DataViewTableBasic aria-label='Repositories table' ouiaId={ouiaId} columns={columns}
|
|
51
|
+
<DataViewTableBasic aria-label='Repositories table' ouiaId={ouiaId} columns={columns} bodyStates={{ error: "Some error" }} rows={[]} />
|
|
52
52
|
</DataView>
|
|
53
53
|
);
|
|
54
54
|
expect(container).toMatchSnapshot();
|
|
55
55
|
});
|
|
56
|
+
|
|
57
|
+
test('should render with a loading state', () => {
|
|
58
|
+
const { container } = render(
|
|
59
|
+
<DataView activeState="loading">
|
|
60
|
+
<DataViewTableBasic aria-label='Repositories table' ouiaId={ouiaId} columns={columns} bodyStates={{ loading: "Data is loading" }} rows={[]} />
|
|
61
|
+
</DataView>
|
|
62
|
+
);
|
|
63
|
+
expect(container).toMatchSnapshot();
|
|
64
|
+
});
|
|
56
65
|
});
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
Tr,
|
|
8
8
|
} from '@patternfly/react-table';
|
|
9
9
|
import { useInternalContext } from '../InternalContext';
|
|
10
|
-
import {
|
|
10
|
+
import { DataViewTableHead } from '../DataViewTableHead';
|
|
11
11
|
import { DataViewTh, DataViewTr, isDataViewTdObject, isDataViewTrObject } from '../DataViewTable';
|
|
12
12
|
import { DataViewState } from '../DataView/DataView';
|
|
13
13
|
|
|
@@ -16,8 +16,10 @@ export interface DataViewTableBasicProps extends Omit<TableProps, 'onSelect' | '
|
|
|
16
16
|
columns: DataViewTh[];
|
|
17
17
|
/** Current page rows */
|
|
18
18
|
rows: DataViewTr[];
|
|
19
|
-
/**
|
|
20
|
-
|
|
19
|
+
/** Table head states to be displayed when active */
|
|
20
|
+
headStates?: Partial<Record<DataViewState | string, React.ReactNode>>
|
|
21
|
+
/** Table body states to be displayed when active */
|
|
22
|
+
bodyStates?: Partial<Record<DataViewState | string, React.ReactNode>>
|
|
21
23
|
/** Custom OUIA ID */
|
|
22
24
|
ouiaId?: string;
|
|
23
25
|
}
|
|
@@ -26,57 +28,53 @@ export const DataViewTableBasic: React.FC<DataViewTableBasicProps> = ({
|
|
|
26
28
|
columns,
|
|
27
29
|
rows,
|
|
28
30
|
ouiaId = 'DataViewTableBasic',
|
|
29
|
-
|
|
31
|
+
headStates,
|
|
32
|
+
bodyStates,
|
|
30
33
|
...props
|
|
31
34
|
}: DataViewTableBasicProps) => {
|
|
32
|
-
const { selection, activeState } = useInternalContext();
|
|
35
|
+
const { selection, activeState, isSelectable } = useInternalContext();
|
|
33
36
|
const { onSelect, isSelected, isSelectDisabled } = selection ?? {};
|
|
34
|
-
|
|
37
|
+
|
|
38
|
+
const activeHeadState = useMemo(() => activeState ? headStates?.[activeState] : undefined, [ activeState, headStates ]);
|
|
39
|
+
const activeBodyState = useMemo(() => activeState ? bodyStates?.[activeState] : undefined, [ activeState, bodyStates ]);
|
|
40
|
+
|
|
41
|
+
const renderedRows = useMemo(() => rows.map((row, rowIndex) => {
|
|
42
|
+
const rowIsObject = isDataViewTrObject(row);
|
|
43
|
+
return (
|
|
44
|
+
<Tr key={rowIndex} ouiaId={`${ouiaId}-tr-${rowIndex}`} {...(rowIsObject && row?.props)}>
|
|
45
|
+
{isSelectable && (
|
|
46
|
+
<Td
|
|
47
|
+
key={`select-${rowIndex}`}
|
|
48
|
+
select={{
|
|
49
|
+
rowIndex,
|
|
50
|
+
onSelect: (_event, isSelecting) => {
|
|
51
|
+
onSelect?.(isSelecting, rowIsObject ? row : [ row ]);
|
|
52
|
+
},
|
|
53
|
+
isSelected: isSelected?.(row) || false,
|
|
54
|
+
isDisabled: isSelectDisabled?.(row) || false,
|
|
55
|
+
}}
|
|
56
|
+
/>
|
|
57
|
+
)}
|
|
58
|
+
{(rowIsObject ? row.row : row).map((cell, colIndex) => {
|
|
59
|
+
const cellIsObject = isDataViewTdObject(cell);
|
|
60
|
+
return (
|
|
61
|
+
<Td
|
|
62
|
+
key={colIndex}
|
|
63
|
+
{...(cellIsObject && (cell?.props ?? {}))}
|
|
64
|
+
data-ouia-component-id={`${ouiaId}-td-${rowIndex}-${colIndex}`}
|
|
65
|
+
>
|
|
66
|
+
{cellIsObject ? cell.cell : cell}
|
|
67
|
+
</Td>
|
|
68
|
+
);
|
|
69
|
+
})}
|
|
70
|
+
</Tr>
|
|
71
|
+
);
|
|
72
|
+
}), [ rows, isSelectable, isSelected, isSelectDisabled, onSelect, ouiaId ]);
|
|
35
73
|
|
|
36
74
|
return (
|
|
37
75
|
<Table aria-label="Data table" ouiaId={ouiaId} {...props}>
|
|
38
|
-
<
|
|
39
|
-
<Tbody>
|
|
40
|
-
{activeState && Object.keys(states).includes(activeState) ? (
|
|
41
|
-
<Tr key={activeState} ouiaId={`${ouiaId}-tr-${activeState}`}>
|
|
42
|
-
<Td colSpan={columns.length + Number(isSelectable)}>
|
|
43
|
-
{states[activeState]}
|
|
44
|
-
</Td>
|
|
45
|
-
</Tr>
|
|
46
|
-
) : (
|
|
47
|
-
rows.map((row, rowIndex) => {
|
|
48
|
-
const rowIsObject = isDataViewTrObject(row);
|
|
49
|
-
return (
|
|
50
|
-
<Tr key={rowIndex} ouiaId={`${ouiaId}-tr-${rowIndex}`} {...(rowIsObject && row?.props)}>
|
|
51
|
-
{isSelectable && (
|
|
52
|
-
<Td
|
|
53
|
-
key={`select-${rowIndex}`}
|
|
54
|
-
select={{
|
|
55
|
-
rowIndex,
|
|
56
|
-
onSelect: (_event, isSelecting) => {
|
|
57
|
-
onSelect?.(isSelecting, rowIsObject ? row : [ row ]);
|
|
58
|
-
},
|
|
59
|
-
isSelected: isSelected?.(row) || false,
|
|
60
|
-
isDisabled: isSelectDisabled?.(row) || false,
|
|
61
|
-
}}
|
|
62
|
-
/>
|
|
63
|
-
)}
|
|
64
|
-
{(rowIsObject ? row.row : row).map((cell, colIndex) => {
|
|
65
|
-
const cellIsObject = isDataViewTdObject(cell);
|
|
66
|
-
return (
|
|
67
|
-
<Td
|
|
68
|
-
key={colIndex}
|
|
69
|
-
{...(cellIsObject && (cell?.props ?? {}))}
|
|
70
|
-
data-ouia-component-id={`${ouiaId}-td-${rowIndex}-${colIndex}`}
|
|
71
|
-
>
|
|
72
|
-
{cellIsObject ? cell.cell : cell}
|
|
73
|
-
</Td>
|
|
74
|
-
);
|
|
75
|
-
})}
|
|
76
|
-
</Tr>
|
|
77
|
-
);
|
|
78
|
-
}))}
|
|
79
|
-
</Tbody>
|
|
76
|
+
{ activeHeadState || <DataViewTableHead columns={columns} ouiaId={ouiaId} /> }
|
|
77
|
+
{ activeBodyState || <Tbody>{renderedRows}</Tbody> }
|
|
80
78
|
</Table>
|
|
81
79
|
);
|
|
82
80
|
};
|