@patternfly/react-data-view 6.1.0-prerelease.1 → 7.0.0-prerelease.1
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.test.js +4 -3
- package/dist/cjs/Hooks/pagination.d.ts +9 -1
- package/dist/cjs/Hooks/pagination.js +36 -4
- package/dist/cjs/Hooks/pagination.test.js +53 -1
- package/dist/esm/DataView/DataView.test.js +4 -3
- package/dist/esm/Hooks/pagination.d.ts +9 -1
- package/dist/esm/Hooks/pagination.js +36 -4
- package/dist/esm/Hooks/pagination.test.js +53 -1
- package/package.json +8 -9
- package/patternfly-docs/content/extensions/data-view/examples/Functionality/Functionality.md +9 -2
- package/patternfly-docs/content/extensions/data-view/examples/Functionality/PaginationExample.tsx +12 -4
- package/patternfly-docs/content/extensions/data-view/examples/Layout/AbstractLayoutExample.tsx +4 -3
- package/patternfly-docs/pages/index.js +1 -1
- package/release.config.js +5 -1
- package/src/DataView/DataView.test.tsx +4 -3
- package/src/DataView/__snapshots__/DataView.test.tsx.snap +14 -14
- package/src/DataViewToolbar/__snapshots__/DataViewToolbar.test.tsx.snap +166 -208
- package/src/Hooks/pagination.test.tsx +81 -1
- package/src/Hooks/pagination.ts +65 -15
|
@@ -9,14 +9,15 @@ const DataView_1 = __importDefault(require("./DataView"));
|
|
|
9
9
|
const layoutItemStyling = {
|
|
10
10
|
width: '100%',
|
|
11
11
|
height: '5rem',
|
|
12
|
-
padding: 'var(--pf-
|
|
13
|
-
|
|
12
|
+
padding: 'var(--pf-v5-global--spacer--md)',
|
|
13
|
+
borderStyle: 'dashed',
|
|
14
|
+
borderWidth: '2px',
|
|
14
15
|
};
|
|
15
16
|
describe('DataView component', () => {
|
|
16
17
|
test('should render correctly', () => {
|
|
17
18
|
expect((0, react_2.render)(react_1.default.createElement(DataView_1.default, null,
|
|
18
19
|
react_1.default.createElement("div", { style: layoutItemStyling }, "Header"),
|
|
19
|
-
react_1.default.createElement("div", { style: layoutItemStyling }, "Data representation"),
|
|
20
|
+
react_1.default.createElement("div", { style: Object.assign(Object.assign({}, layoutItemStyling), { borderTopWidth: 0, borderBottomWidth: 0 }) }, "Data representation"),
|
|
20
21
|
react_1.default.createElement("div", { style: layoutItemStyling }, "Footer")))).toMatchSnapshot();
|
|
21
22
|
});
|
|
22
23
|
});
|
|
@@ -1,14 +1,22 @@
|
|
|
1
|
+
export declare enum PaginationParams {
|
|
2
|
+
PAGE = "page",
|
|
3
|
+
PER_PAGE = "perPage"
|
|
4
|
+
}
|
|
1
5
|
export interface UseDataViewPaginationProps {
|
|
2
6
|
/** Initial page */
|
|
3
7
|
page?: number;
|
|
4
8
|
/** Items per page */
|
|
5
9
|
perPage: number;
|
|
10
|
+
/** Current search parameters as a string */
|
|
11
|
+
searchParams?: URLSearchParams;
|
|
12
|
+
/** Function to set search parameters */
|
|
13
|
+
setSearchParams?: (params: URLSearchParams) => void;
|
|
6
14
|
}
|
|
7
15
|
export interface DataViewPaginationProps extends UseDataViewPaginationProps {
|
|
8
16
|
/** Current page number */
|
|
9
17
|
page: number;
|
|
10
18
|
}
|
|
11
|
-
export declare const useDataViewPagination: ({ page, perPage }: UseDataViewPaginationProps) => {
|
|
19
|
+
export declare const useDataViewPagination: ({ page, perPage, searchParams, setSearchParams, }: UseDataViewPaginationProps) => {
|
|
12
20
|
onPerPageSelect: (_event: React.MouseEvent | React.KeyboardEvent | MouseEvent | undefined, newPerPage: number) => void;
|
|
13
21
|
onSetPage: (_event: React.MouseEvent | React.KeyboardEvent | MouseEvent | undefined, newPage: number) => void;
|
|
14
22
|
page: number;
|
|
@@ -1,13 +1,45 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.useDataViewPagination = void 0;
|
|
3
|
+
exports.useDataViewPagination = exports.PaginationParams = void 0;
|
|
4
4
|
const react_1 = require("react");
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
var PaginationParams;
|
|
6
|
+
(function (PaginationParams) {
|
|
7
|
+
PaginationParams["PAGE"] = "page";
|
|
8
|
+
PaginationParams["PER_PAGE"] = "perPage";
|
|
9
|
+
})(PaginationParams || (exports.PaginationParams = PaginationParams = {}));
|
|
10
|
+
const useDataViewPagination = ({ page = 1, perPage, searchParams, setSearchParams, }) => {
|
|
11
|
+
const [state, setState] = (0, react_1.useState)({
|
|
12
|
+
page: parseInt((searchParams === null || searchParams === void 0 ? void 0 : searchParams.get(PaginationParams.PAGE)) || `${page}`),
|
|
13
|
+
perPage: parseInt((searchParams === null || searchParams === void 0 ? void 0 : searchParams.get(PaginationParams.PER_PAGE)) || `${perPage}`),
|
|
14
|
+
});
|
|
15
|
+
const updateSearchParams = (page, perPage) => {
|
|
16
|
+
if (searchParams && setSearchParams) {
|
|
17
|
+
const params = new URLSearchParams(searchParams);
|
|
18
|
+
params.set(PaginationParams.PAGE, `${page}`);
|
|
19
|
+
params.set(PaginationParams.PER_PAGE, `${perPage}`);
|
|
20
|
+
setSearchParams(params);
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
(0, react_1.useEffect)(() => {
|
|
24
|
+
// Make sure search params are loaded or set if not present on mount
|
|
25
|
+
updateSearchParams(state.page, state.perPage);
|
|
26
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
27
|
+
}, []);
|
|
28
|
+
(0, react_1.useEffect)(() => {
|
|
29
|
+
// Listen on URL params changes
|
|
30
|
+
const currentPage = parseInt((searchParams === null || searchParams === void 0 ? void 0 : searchParams.get(PaginationParams.PAGE)) || `${state.page}`);
|
|
31
|
+
const currentPerPage = parseInt((searchParams === null || searchParams === void 0 ? void 0 : searchParams.get(PaginationParams.PER_PAGE)) || `${state.perPage}`);
|
|
32
|
+
if (currentPage !== state.page || currentPerPage !== state.perPage) {
|
|
33
|
+
setState({ page: currentPage, perPage: currentPerPage });
|
|
34
|
+
}
|
|
35
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
36
|
+
}, [searchParams]);
|
|
7
37
|
const onPerPageSelect = (_event, newPerPage) => {
|
|
8
|
-
|
|
38
|
+
updateSearchParams(1, newPerPage);
|
|
39
|
+
setState({ perPage: newPerPage, page: 1 });
|
|
9
40
|
};
|
|
10
41
|
const onSetPage = (_event, newPage) => {
|
|
42
|
+
updateSearchParams(newPage, state.perPage);
|
|
11
43
|
setState(prev => (Object.assign(Object.assign({}, prev), { page: newPage })));
|
|
12
44
|
};
|
|
13
45
|
return Object.assign(Object.assign({}, state), { onPerPageSelect,
|
|
@@ -42,8 +42,60 @@ describe('useDataViewPagination', () => {
|
|
|
42
42
|
expect(result.current).toEqual({
|
|
43
43
|
onPerPageSelect: expect.any(Function),
|
|
44
44
|
onSetPage: expect.any(Function),
|
|
45
|
-
page:
|
|
45
|
+
page: 1,
|
|
46
46
|
perPage: 50
|
|
47
47
|
});
|
|
48
48
|
});
|
|
49
|
+
it('should read pagination state from URL', () => {
|
|
50
|
+
const mockSearchParams = new URLSearchParams('page=2&perPage=10');
|
|
51
|
+
const { result } = (0, react_1.renderHook)(() => (0, pagination_1.useDataViewPagination)({
|
|
52
|
+
searchParams: mockSearchParams,
|
|
53
|
+
setSearchParams: jest.fn(),
|
|
54
|
+
page: 1,
|
|
55
|
+
perPage: 5,
|
|
56
|
+
}));
|
|
57
|
+
expect(result.current).toEqual({
|
|
58
|
+
onPerPageSelect: expect.any(Function),
|
|
59
|
+
onSetPage: expect.any(Function),
|
|
60
|
+
page: 2,
|
|
61
|
+
perPage: 10,
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
it('should set pagination state in URL when page changes', () => {
|
|
65
|
+
const mockSetSearchParams = jest.fn();
|
|
66
|
+
const { result } = (0, react_1.renderHook)(() => (0, pagination_1.useDataViewPagination)({
|
|
67
|
+
searchParams: new URLSearchParams(),
|
|
68
|
+
setSearchParams: mockSetSearchParams,
|
|
69
|
+
page: 1,
|
|
70
|
+
perPage: 5,
|
|
71
|
+
}));
|
|
72
|
+
expect(mockSetSearchParams).toHaveBeenNthCalledWith(1, new URLSearchParams('page=1&perPage=5'));
|
|
73
|
+
(0, react_1.act)(() => {
|
|
74
|
+
result.current.onSetPage(undefined, 4);
|
|
75
|
+
});
|
|
76
|
+
expect(mockSetSearchParams).toHaveBeenNthCalledWith(2, new URLSearchParams('page=4&perPage=5'));
|
|
77
|
+
});
|
|
78
|
+
it('should set pagination state in URL when perPage changes', () => {
|
|
79
|
+
const mockSetSearchParams = jest.fn();
|
|
80
|
+
const { result } = (0, react_1.renderHook)(() => (0, pagination_1.useDataViewPagination)({
|
|
81
|
+
searchParams: new URLSearchParams('page=2'),
|
|
82
|
+
setSearchParams: mockSetSearchParams,
|
|
83
|
+
page: 1,
|
|
84
|
+
perPage: 5,
|
|
85
|
+
}));
|
|
86
|
+
(0, react_1.act)(() => {
|
|
87
|
+
result.current.onPerPageSelect(undefined, 20);
|
|
88
|
+
});
|
|
89
|
+
expect(mockSetSearchParams).toHaveBeenCalledWith(new URLSearchParams('page=1&perPage=20'));
|
|
90
|
+
});
|
|
91
|
+
it('should initialize URL with default values if not present', () => {
|
|
92
|
+
const mockSetSearchParams = jest.fn();
|
|
93
|
+
(0, react_1.renderHook)(() => (0, pagination_1.useDataViewPagination)({
|
|
94
|
+
searchParams: new URLSearchParams(),
|
|
95
|
+
setSearchParams: mockSetSearchParams,
|
|
96
|
+
page: 1,
|
|
97
|
+
perPage: 5,
|
|
98
|
+
}));
|
|
99
|
+
expect(mockSetSearchParams).toHaveBeenCalledWith(new URLSearchParams('page=1&perPage=5'));
|
|
100
|
+
});
|
|
49
101
|
});
|
|
@@ -4,14 +4,15 @@ import DataView from './DataView';
|
|
|
4
4
|
const layoutItemStyling = {
|
|
5
5
|
width: '100%',
|
|
6
6
|
height: '5rem',
|
|
7
|
-
padding: 'var(--pf-
|
|
8
|
-
|
|
7
|
+
padding: 'var(--pf-v5-global--spacer--md)',
|
|
8
|
+
borderStyle: 'dashed',
|
|
9
|
+
borderWidth: '2px',
|
|
9
10
|
};
|
|
10
11
|
describe('DataView component', () => {
|
|
11
12
|
test('should render correctly', () => {
|
|
12
13
|
expect(render(React.createElement(DataView, null,
|
|
13
14
|
React.createElement("div", { style: layoutItemStyling }, "Header"),
|
|
14
|
-
React.createElement("div", { style: layoutItemStyling }, "Data representation"),
|
|
15
|
+
React.createElement("div", { style: Object.assign(Object.assign({}, layoutItemStyling), { borderTopWidth: 0, borderBottomWidth: 0 }) }, "Data representation"),
|
|
15
16
|
React.createElement("div", { style: layoutItemStyling }, "Footer")))).toMatchSnapshot();
|
|
16
17
|
});
|
|
17
18
|
});
|
|
@@ -1,14 +1,22 @@
|
|
|
1
|
+
export declare enum PaginationParams {
|
|
2
|
+
PAGE = "page",
|
|
3
|
+
PER_PAGE = "perPage"
|
|
4
|
+
}
|
|
1
5
|
export interface UseDataViewPaginationProps {
|
|
2
6
|
/** Initial page */
|
|
3
7
|
page?: number;
|
|
4
8
|
/** Items per page */
|
|
5
9
|
perPage: number;
|
|
10
|
+
/** Current search parameters as a string */
|
|
11
|
+
searchParams?: URLSearchParams;
|
|
12
|
+
/** Function to set search parameters */
|
|
13
|
+
setSearchParams?: (params: URLSearchParams) => void;
|
|
6
14
|
}
|
|
7
15
|
export interface DataViewPaginationProps extends UseDataViewPaginationProps {
|
|
8
16
|
/** Current page number */
|
|
9
17
|
page: number;
|
|
10
18
|
}
|
|
11
|
-
export declare const useDataViewPagination: ({ page, perPage }: UseDataViewPaginationProps) => {
|
|
19
|
+
export declare const useDataViewPagination: ({ page, perPage, searchParams, setSearchParams, }: UseDataViewPaginationProps) => {
|
|
12
20
|
onPerPageSelect: (_event: React.MouseEvent | React.KeyboardEvent | MouseEvent | undefined, newPerPage: number) => void;
|
|
13
21
|
onSetPage: (_event: React.MouseEvent | React.KeyboardEvent | MouseEvent | undefined, newPage: number) => void;
|
|
14
22
|
page: number;
|
|
@@ -1,10 +1,42 @@
|
|
|
1
|
-
import { useState } from "react";
|
|
2
|
-
export
|
|
3
|
-
|
|
1
|
+
import { useState, useEffect } from "react";
|
|
2
|
+
export var PaginationParams;
|
|
3
|
+
(function (PaginationParams) {
|
|
4
|
+
PaginationParams["PAGE"] = "page";
|
|
5
|
+
PaginationParams["PER_PAGE"] = "perPage";
|
|
6
|
+
})(PaginationParams || (PaginationParams = {}));
|
|
7
|
+
export const useDataViewPagination = ({ page = 1, perPage, searchParams, setSearchParams, }) => {
|
|
8
|
+
const [state, setState] = useState({
|
|
9
|
+
page: parseInt((searchParams === null || searchParams === void 0 ? void 0 : searchParams.get(PaginationParams.PAGE)) || `${page}`),
|
|
10
|
+
perPage: parseInt((searchParams === null || searchParams === void 0 ? void 0 : searchParams.get(PaginationParams.PER_PAGE)) || `${perPage}`),
|
|
11
|
+
});
|
|
12
|
+
const updateSearchParams = (page, perPage) => {
|
|
13
|
+
if (searchParams && setSearchParams) {
|
|
14
|
+
const params = new URLSearchParams(searchParams);
|
|
15
|
+
params.set(PaginationParams.PAGE, `${page}`);
|
|
16
|
+
params.set(PaginationParams.PER_PAGE, `${perPage}`);
|
|
17
|
+
setSearchParams(params);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
// Make sure search params are loaded or set if not present on mount
|
|
22
|
+
updateSearchParams(state.page, state.perPage);
|
|
23
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
24
|
+
}, []);
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
// Listen on URL params changes
|
|
27
|
+
const currentPage = parseInt((searchParams === null || searchParams === void 0 ? void 0 : searchParams.get(PaginationParams.PAGE)) || `${state.page}`);
|
|
28
|
+
const currentPerPage = parseInt((searchParams === null || searchParams === void 0 ? void 0 : searchParams.get(PaginationParams.PER_PAGE)) || `${state.perPage}`);
|
|
29
|
+
if (currentPage !== state.page || currentPerPage !== state.perPage) {
|
|
30
|
+
setState({ page: currentPage, perPage: currentPerPage });
|
|
31
|
+
}
|
|
32
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
33
|
+
}, [searchParams]);
|
|
4
34
|
const onPerPageSelect = (_event, newPerPage) => {
|
|
5
|
-
|
|
35
|
+
updateSearchParams(1, newPerPage);
|
|
36
|
+
setState({ perPage: newPerPage, page: 1 });
|
|
6
37
|
};
|
|
7
38
|
const onSetPage = (_event, newPage) => {
|
|
39
|
+
updateSearchParams(newPage, state.perPage);
|
|
8
40
|
setState(prev => (Object.assign(Object.assign({}, prev), { page: newPage })));
|
|
9
41
|
};
|
|
10
42
|
return Object.assign(Object.assign({}, state), { onPerPageSelect,
|
|
@@ -40,8 +40,60 @@ describe('useDataViewPagination', () => {
|
|
|
40
40
|
expect(result.current).toEqual({
|
|
41
41
|
onPerPageSelect: expect.any(Function),
|
|
42
42
|
onSetPage: expect.any(Function),
|
|
43
|
-
page:
|
|
43
|
+
page: 1,
|
|
44
44
|
perPage: 50
|
|
45
45
|
});
|
|
46
46
|
});
|
|
47
|
+
it('should read pagination state from URL', () => {
|
|
48
|
+
const mockSearchParams = new URLSearchParams('page=2&perPage=10');
|
|
49
|
+
const { result } = renderHook(() => useDataViewPagination({
|
|
50
|
+
searchParams: mockSearchParams,
|
|
51
|
+
setSearchParams: jest.fn(),
|
|
52
|
+
page: 1,
|
|
53
|
+
perPage: 5,
|
|
54
|
+
}));
|
|
55
|
+
expect(result.current).toEqual({
|
|
56
|
+
onPerPageSelect: expect.any(Function),
|
|
57
|
+
onSetPage: expect.any(Function),
|
|
58
|
+
page: 2,
|
|
59
|
+
perPage: 10,
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
it('should set pagination state in URL when page changes', () => {
|
|
63
|
+
const mockSetSearchParams = jest.fn();
|
|
64
|
+
const { result } = renderHook(() => useDataViewPagination({
|
|
65
|
+
searchParams: new URLSearchParams(),
|
|
66
|
+
setSearchParams: mockSetSearchParams,
|
|
67
|
+
page: 1,
|
|
68
|
+
perPage: 5,
|
|
69
|
+
}));
|
|
70
|
+
expect(mockSetSearchParams).toHaveBeenNthCalledWith(1, new URLSearchParams('page=1&perPage=5'));
|
|
71
|
+
act(() => {
|
|
72
|
+
result.current.onSetPage(undefined, 4);
|
|
73
|
+
});
|
|
74
|
+
expect(mockSetSearchParams).toHaveBeenNthCalledWith(2, new URLSearchParams('page=4&perPage=5'));
|
|
75
|
+
});
|
|
76
|
+
it('should set pagination state in URL when perPage changes', () => {
|
|
77
|
+
const mockSetSearchParams = jest.fn();
|
|
78
|
+
const { result } = renderHook(() => useDataViewPagination({
|
|
79
|
+
searchParams: new URLSearchParams('page=2'),
|
|
80
|
+
setSearchParams: mockSetSearchParams,
|
|
81
|
+
page: 1,
|
|
82
|
+
perPage: 5,
|
|
83
|
+
}));
|
|
84
|
+
act(() => {
|
|
85
|
+
result.current.onPerPageSelect(undefined, 20);
|
|
86
|
+
});
|
|
87
|
+
expect(mockSetSearchParams).toHaveBeenCalledWith(new URLSearchParams('page=1&perPage=20'));
|
|
88
|
+
});
|
|
89
|
+
it('should initialize URL with default values if not present', () => {
|
|
90
|
+
const mockSetSearchParams = jest.fn();
|
|
91
|
+
renderHook(() => useDataViewPagination({
|
|
92
|
+
searchParams: new URLSearchParams(),
|
|
93
|
+
setSearchParams: mockSetSearchParams,
|
|
94
|
+
page: 1,
|
|
95
|
+
perPage: 5,
|
|
96
|
+
}));
|
|
97
|
+
expect(mockSetSearchParams).toHaveBeenCalledWith(new URLSearchParams('page=1&perPage=5'));
|
|
98
|
+
});
|
|
47
99
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@patternfly/react-data-view",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "7.0.0-prerelease.1",
|
|
4
4
|
"description": "Data view used for Red Hat projects.",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -27,14 +27,13 @@
|
|
|
27
27
|
},
|
|
28
28
|
"homepage": "https://github.com/patternfly/react-data-view#readme",
|
|
29
29
|
"publishConfig": {
|
|
30
|
-
"access": "public"
|
|
31
|
-
"tag": "prerelease"
|
|
30
|
+
"access": "public"
|
|
32
31
|
},
|
|
33
32
|
"dependencies": {
|
|
34
|
-
"@patternfly/react-core": "
|
|
35
|
-
"@patternfly/react-icons": "
|
|
36
|
-
"@patternfly/react-table": "
|
|
37
|
-
"@patternfly/react-component-groups": "
|
|
33
|
+
"@patternfly/react-core": "^5.3.3",
|
|
34
|
+
"@patternfly/react-icons": "^5.3.1",
|
|
35
|
+
"@patternfly/react-table": "^5.3.3",
|
|
36
|
+
"@patternfly/react-component-groups": "^5.3.0-prerelease.2",
|
|
38
37
|
"react-jss": "^10.10.0",
|
|
39
38
|
"clsx": "^2.1.1"
|
|
40
39
|
},
|
|
@@ -44,8 +43,8 @@
|
|
|
44
43
|
},
|
|
45
44
|
"devDependencies": {
|
|
46
45
|
"@patternfly/patternfly-a11y": "^4.3.1",
|
|
47
|
-
"@patternfly/
|
|
48
|
-
"@patternfly/
|
|
46
|
+
"@patternfly/documentation-framework": "5.16.9",
|
|
47
|
+
"@patternfly/patternfly": "^5.3.1",
|
|
49
48
|
"@types/react": "^18.3.1",
|
|
50
49
|
"@types/react-dom": "^18.3.0",
|
|
51
50
|
"@types/react-router-dom": "^5.3.3",
|
package/patternfly-docs/content/extensions/data-view/examples/Functionality/Functionality.md
CHANGED
|
@@ -18,6 +18,7 @@ import { useDataViewPagination, useDataViewSelection } from '@patternfly/react-d
|
|
|
18
18
|
import { DataView } from '@patternfly/react-data-view/dist/dynamic/DataView';
|
|
19
19
|
import { BulkSelect, BulkSelectValue } from '@patternfly/react-component-groups/dist/dynamic/BulkSelect';
|
|
20
20
|
import { DataViewToolbar } from '@patternfly/react-data-view/dist/dynamic/DataViewToolbar';
|
|
21
|
+
import { BrowserRouter, useSearchParams } from 'react-router-dom';
|
|
21
22
|
|
|
22
23
|
This is a list of functionality you can use to manage data displayed in the **data view**.
|
|
23
24
|
|
|
@@ -25,7 +26,7 @@ This is a list of functionality you can use to manage data displayed in the **da
|
|
|
25
26
|
Allows to display data records on multiple pages and display the pagination state.
|
|
26
27
|
|
|
27
28
|
### Toolbar usage
|
|
28
|
-
Data view toolbar can display a pagination using the `pagination` property accepting a React node. You can also pass a custom `ouiaId` for testing purposes.
|
|
29
|
+
Data view toolbar can display a pagination using the `pagination` property accepting a React node. You can also pass a custom `ouiaId` for testing purposes. Additionally, it offers an option to persist pagination values in the URL, which makes it easier to share or bookmark specific pages of your data.
|
|
29
30
|
|
|
30
31
|
### Pagination state
|
|
31
32
|
|
|
@@ -34,8 +35,12 @@ The `useDataViewPagination` hook manages the pagination state of the data view.
|
|
|
34
35
|
**Initial values:**
|
|
35
36
|
- `perPage` initial value
|
|
36
37
|
- (optional) `page` initial value
|
|
38
|
+
- (optional) `searchParams` object
|
|
39
|
+
- (optional) `seSearchParams` function
|
|
37
40
|
|
|
38
|
-
|
|
41
|
+
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.
|
|
42
|
+
|
|
43
|
+
The retrieved values are named to match the PatternFly [pagination](/components/pagination) component props, so you can easily spread them to the component.
|
|
39
44
|
|
|
40
45
|
**Return values:**
|
|
41
46
|
- current `page` number
|
|
@@ -44,6 +49,8 @@ The retrieved values are named to match the PatternFly [pagination](/components/
|
|
|
44
49
|
- `onPerPageSelect` to modify per page value
|
|
45
50
|
|
|
46
51
|
### Pagination example
|
|
52
|
+
This example uses the URL for persisting the pagination state.
|
|
53
|
+
|
|
47
54
|
```js file="./PaginationExample.tsx"
|
|
48
55
|
|
|
49
56
|
```
|
package/patternfly-docs/content/extensions/data-view/examples/Functionality/PaginationExample.tsx
CHANGED
|
@@ -4,6 +4,7 @@ import { Table, Tbody, Th, Thead, Tr, Td } from '@patternfly/react-table';
|
|
|
4
4
|
import { useDataViewPagination } from '@patternfly/react-data-view/dist/dynamic/Hooks';
|
|
5
5
|
import DataView from '@patternfly/react-data-view/dist/dynamic/DataView';
|
|
6
6
|
import DataViewToolbar from '@patternfly/react-data-view/dist/dynamic/DataViewToolbar';
|
|
7
|
+
import { BrowserRouter, useSearchParams } from 'react-router-dom';
|
|
7
8
|
|
|
8
9
|
const perPageOptions = [
|
|
9
10
|
{ title: '5', value: 5 },
|
|
@@ -37,12 +38,12 @@ const cols = {
|
|
|
37
38
|
|
|
38
39
|
const ouiaId = 'LayoutExample';
|
|
39
40
|
|
|
40
|
-
|
|
41
|
-
const
|
|
41
|
+
const MyTable: React.FunctionComponent = () => {
|
|
42
|
+
const [ searchParams, setSearchParams ] = useSearchParams()
|
|
43
|
+
const pagination = useDataViewPagination({ perPage: 5, searchParams, setSearchParams });
|
|
42
44
|
const { page, perPage } = pagination;
|
|
43
45
|
|
|
44
46
|
const data = useMemo(() => repositories.slice((page - 1) * perPage, ((page - 1) * perPage) + perPage), [ page, perPage ]);
|
|
45
|
-
|
|
46
47
|
return (
|
|
47
48
|
<DataView>
|
|
48
49
|
<DataViewToolbar ouiaId='DataViewHeader' pagination={<Pagination perPageOptions={perPageOptions} itemCount={repositories.length} {...pagination} />} />
|
|
@@ -62,4 +63,11 @@ export const BasicExample: React.FunctionComponent = () => {
|
|
|
62
63
|
</Table>
|
|
63
64
|
<DataViewToolbar ouiaId='DataViewFooter' pagination={<Pagination isCompact perPageOptions={perPageOptions} itemCount={repositories.length} {...pagination} />} />
|
|
64
65
|
</DataView>
|
|
65
|
-
)
|
|
66
|
+
)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export const BasicExample: React.FunctionComponent = () => (
|
|
70
|
+
<BrowserRouter>
|
|
71
|
+
<MyTable/>
|
|
72
|
+
</BrowserRouter>
|
|
73
|
+
)
|
package/patternfly-docs/content/extensions/data-view/examples/Layout/AbstractLayoutExample.tsx
CHANGED
|
@@ -4,14 +4,15 @@ import DataView from '@patternfly/react-data-view/dist/dynamic/DataView';
|
|
|
4
4
|
const layoutItemStyling = {
|
|
5
5
|
width: '100%',
|
|
6
6
|
height: '5rem',
|
|
7
|
-
padding: 'var(--pf-
|
|
8
|
-
|
|
7
|
+
padding: 'var(--pf-v5-global--spacer--md)',
|
|
8
|
+
borderStyle: 'dashed',
|
|
9
|
+
borderWidth: '2px',
|
|
9
10
|
};
|
|
10
11
|
|
|
11
12
|
export const BasicExample: React.FunctionComponent = () => (
|
|
12
13
|
<DataView>
|
|
13
14
|
<div style={layoutItemStyling}>Header</div>
|
|
14
|
-
<div style={layoutItemStyling}>Data representation</div>
|
|
15
|
+
<div style={{ ...layoutItemStyling, borderTopWidth: 0, borderBottomWidth: 0 }}>Data representation</div>
|
|
15
16
|
<div style={layoutItemStyling}>Footer</div>
|
|
16
17
|
</DataView>
|
|
17
18
|
)
|
|
@@ -10,7 +10,7 @@ const centerStyle = {
|
|
|
10
10
|
|
|
11
11
|
const IndexPage = () => {
|
|
12
12
|
return (
|
|
13
|
-
<PageSection style={centerStyle}>
|
|
13
|
+
<PageSection variant="light" style={centerStyle}>
|
|
14
14
|
<div style={{ flex: 'none', textAlign: 'center' }}>
|
|
15
15
|
<Title size="4xl" headingLevel="h1">
|
|
16
16
|
My extension docs
|
package/release.config.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
module.exports = {
|
|
2
|
-
branches: [
|
|
2
|
+
branches: [
|
|
3
|
+
'do-not-delete',
|
|
4
|
+
{ name: 'main', channel: 'prerelease', prerelease: 'prerelease' },
|
|
5
|
+
{ name: 'v5', channel: 'prerelease-v5', range: '5.x' },
|
|
6
|
+
],
|
|
3
7
|
analyzeCommits: {
|
|
4
8
|
preset: 'angular'
|
|
5
9
|
},
|
|
@@ -5,8 +5,9 @@ import DataView from './DataView';
|
|
|
5
5
|
const layoutItemStyling = {
|
|
6
6
|
width: '100%',
|
|
7
7
|
height: '5rem',
|
|
8
|
-
padding: 'var(--pf-
|
|
9
|
-
|
|
8
|
+
padding: 'var(--pf-v5-global--spacer--md)',
|
|
9
|
+
borderStyle: 'dashed',
|
|
10
|
+
borderWidth: '2px',
|
|
10
11
|
};
|
|
11
12
|
|
|
12
13
|
describe('DataView component', () => {
|
|
@@ -14,7 +15,7 @@ describe('DataView component', () => {
|
|
|
14
15
|
expect(render(
|
|
15
16
|
<DataView>
|
|
16
17
|
<div style={layoutItemStyling}>Header</div>
|
|
17
|
-
<div style={layoutItemStyling}>Data representation</div>
|
|
18
|
+
<div style={{ ...layoutItemStyling, borderTopWidth: 0, borderBottomWidth: 0 }}>Data representation</div>
|
|
18
19
|
<div style={layoutItemStyling}>Footer</div>
|
|
19
20
|
</DataView>)).toMatchSnapshot();
|
|
20
21
|
});
|
|
@@ -6,35 +6,35 @@ exports[`DataView component should render correctly 1`] = `
|
|
|
6
6
|
"baseElement": <body>
|
|
7
7
|
<div>
|
|
8
8
|
<div
|
|
9
|
-
class="pf-
|
|
9
|
+
class="pf-v5-l-stack"
|
|
10
10
|
data-ouia-component-id="DataView-stack}"
|
|
11
11
|
>
|
|
12
12
|
<div
|
|
13
|
-
class="pf-
|
|
13
|
+
class="pf-v5-l-stack__item"
|
|
14
14
|
data-ouia-component-id="DataView-stack-item-0"
|
|
15
15
|
>
|
|
16
16
|
<div
|
|
17
|
-
style="width: 100%; height: 5rem;"
|
|
17
|
+
style="width: 100%; height: 5rem; border-style: dashed; border-width: 2px;"
|
|
18
18
|
>
|
|
19
19
|
Header
|
|
20
20
|
</div>
|
|
21
21
|
</div>
|
|
22
22
|
<div
|
|
23
|
-
class="pf-
|
|
23
|
+
class="pf-v5-l-stack__item"
|
|
24
24
|
data-ouia-component-id="DataView-stack-item-1"
|
|
25
25
|
>
|
|
26
26
|
<div
|
|
27
|
-
style="width: 100%; height: 5rem;"
|
|
27
|
+
style="width: 100%; height: 5rem; border-style: dashed; border-width: 2px; border-top-width: 0; border-bottom-width: 0;"
|
|
28
28
|
>
|
|
29
29
|
Data representation
|
|
30
30
|
</div>
|
|
31
31
|
</div>
|
|
32
32
|
<div
|
|
33
|
-
class="pf-
|
|
33
|
+
class="pf-v5-l-stack__item"
|
|
34
34
|
data-ouia-component-id="DataView-stack-item-2"
|
|
35
35
|
>
|
|
36
36
|
<div
|
|
37
|
-
style="width: 100%; height: 5rem;"
|
|
37
|
+
style="width: 100%; height: 5rem; border-style: dashed; border-width: 2px;"
|
|
38
38
|
>
|
|
39
39
|
Footer
|
|
40
40
|
</div>
|
|
@@ -44,35 +44,35 @@ exports[`DataView component should render correctly 1`] = `
|
|
|
44
44
|
</body>,
|
|
45
45
|
"container": <div>
|
|
46
46
|
<div
|
|
47
|
-
class="pf-
|
|
47
|
+
class="pf-v5-l-stack"
|
|
48
48
|
data-ouia-component-id="DataView-stack}"
|
|
49
49
|
>
|
|
50
50
|
<div
|
|
51
|
-
class="pf-
|
|
51
|
+
class="pf-v5-l-stack__item"
|
|
52
52
|
data-ouia-component-id="DataView-stack-item-0"
|
|
53
53
|
>
|
|
54
54
|
<div
|
|
55
|
-
style="width: 100%; height: 5rem;"
|
|
55
|
+
style="width: 100%; height: 5rem; border-style: dashed; border-width: 2px;"
|
|
56
56
|
>
|
|
57
57
|
Header
|
|
58
58
|
</div>
|
|
59
59
|
</div>
|
|
60
60
|
<div
|
|
61
|
-
class="pf-
|
|
61
|
+
class="pf-v5-l-stack__item"
|
|
62
62
|
data-ouia-component-id="DataView-stack-item-1"
|
|
63
63
|
>
|
|
64
64
|
<div
|
|
65
|
-
style="width: 100%; height: 5rem;"
|
|
65
|
+
style="width: 100%; height: 5rem; border-style: dashed; border-width: 2px; border-top-width: 0; border-bottom-width: 0;"
|
|
66
66
|
>
|
|
67
67
|
Data representation
|
|
68
68
|
</div>
|
|
69
69
|
</div>
|
|
70
70
|
<div
|
|
71
|
-
class="pf-
|
|
71
|
+
class="pf-v5-l-stack__item"
|
|
72
72
|
data-ouia-component-id="DataView-stack-item-2"
|
|
73
73
|
>
|
|
74
74
|
<div
|
|
75
|
-
style="width: 100%; height: 5rem;"
|
|
75
|
+
style="width: 100%; height: 5rem; border-style: dashed; border-width: 2px;"
|
|
76
76
|
>
|
|
77
77
|
Footer
|
|
78
78
|
</div>
|