@patternfly/react-data-view 6.1.0-prerelease.1 → 6.1.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 +15 -1
- package/dist/cjs/DataView/DataView.js +14 -3
- package/dist/cjs/DataViewCheckboxFilter/DataViewCheckboxFilter.d.ts +29 -0
- package/dist/cjs/DataViewCheckboxFilter/DataViewCheckboxFilter.js +70 -0
- package/dist/cjs/DataViewCheckboxFilter/DataViewCheckboxFilter.test.d.ts +1 -0
- package/dist/cjs/DataViewCheckboxFilter/DataViewCheckboxFilter.test.js +25 -0
- package/dist/cjs/DataViewCheckboxFilter/index.d.ts +2 -0
- package/dist/cjs/DataViewCheckboxFilter/index.js +23 -0
- package/dist/cjs/DataViewEventsContext/DataViewEventsContext.d.ts +16 -0
- package/dist/cjs/DataViewEventsContext/DataViewEventsContext.js +62 -0
- package/dist/cjs/DataViewEventsContext/DataViewEventsContext.test.d.ts +1 -0
- package/dist/cjs/DataViewEventsContext/DataViewEventsContext.test.js +72 -0
- package/dist/cjs/DataViewEventsContext/index.d.ts +2 -0
- package/dist/cjs/DataViewEventsContext/index.js +23 -0
- package/dist/cjs/DataViewFilters/DataViewFilters.d.ts +25 -0
- package/dist/cjs/DataViewFilters/DataViewFilters.js +85 -0
- package/dist/cjs/DataViewFilters/DataViewFilters.test.d.ts +1 -0
- package/dist/cjs/DataViewFilters/DataViewFilters.test.js +19 -0
- package/dist/cjs/DataViewFilters/index.d.ts +2 -0
- package/dist/cjs/DataViewFilters/index.js +23 -0
- package/dist/cjs/DataViewTable/DataViewTable.d.ts +49 -0
- package/dist/cjs/DataViewTable/DataViewTable.js +18 -0
- package/dist/cjs/DataViewTable/DataViewTable.test.d.ts +1 -0
- package/dist/cjs/DataViewTable/DataViewTable.test.js +57 -0
- package/dist/cjs/DataViewTable/index.d.ts +2 -0
- package/dist/cjs/DataViewTable/index.js +23 -0
- package/dist/cjs/DataViewTableBasic/DataViewTableBasic.d.ts +19 -0
- package/dist/cjs/DataViewTableBasic/DataViewTableBasic.js +71 -0
- package/dist/cjs/DataViewTableBasic/DataViewTableBasic.test.d.ts +1 -0
- package/dist/cjs/DataViewTableBasic/DataViewTableBasic.test.js +43 -0
- package/dist/cjs/DataViewTableBasic/index.d.ts +2 -0
- package/dist/cjs/DataViewTableBasic/index.js +23 -0
- package/dist/cjs/DataViewTableHead/DataViewTableHead.d.ts +14 -0
- package/dist/cjs/DataViewTableHead/DataViewTableHead.js +57 -0
- package/dist/cjs/DataViewTableHead/DataViewTableHead.test.d.ts +1 -0
- package/dist/cjs/DataViewTableHead/DataViewTableHead.test.js +36 -0
- package/dist/cjs/DataViewTableHead/index.d.ts +2 -0
- package/dist/cjs/DataViewTableHead/index.js +23 -0
- package/dist/cjs/DataViewTableTree/DataViewTableTree.d.ts +25 -0
- package/dist/cjs/DataViewTableTree/DataViewTableTree.js +144 -0
- package/dist/cjs/DataViewTableTree/DataViewTableTree.test.d.ts +1 -0
- package/dist/cjs/DataViewTableTree/DataViewTableTree.test.js +90 -0
- package/dist/cjs/DataViewTableTree/index.d.ts +2 -0
- package/dist/cjs/DataViewTableTree/index.js +23 -0
- package/dist/cjs/DataViewTextFilter/DataViewTextFilter.d.ts +21 -0
- package/dist/cjs/DataViewTextFilter/DataViewTextFilter.js +26 -0
- package/dist/cjs/DataViewTextFilter/DataViewTextFilter.test.d.ts +1 -0
- package/dist/cjs/DataViewTextFilter/DataViewTextFilter.test.js +22 -0
- package/dist/cjs/DataViewTextFilter/index.d.ts +2 -0
- package/dist/cjs/DataViewTextFilter/index.js +23 -0
- package/dist/cjs/DataViewToolbar/DataViewToolbar.d.ts +11 -3
- package/dist/cjs/DataViewToolbar/DataViewToolbar.js +30 -6
- package/dist/cjs/Hooks/filters.d.ts +14 -0
- package/dist/cjs/Hooks/filters.js +69 -0
- package/dist/cjs/Hooks/filters.test.d.ts +1 -0
- package/dist/cjs/Hooks/filters.test.js +50 -0
- package/dist/cjs/Hooks/index.d.ts +2 -0
- package/dist/cjs/Hooks/index.js +2 -0
- package/dist/cjs/Hooks/pagination.d.ts +14 -1
- package/dist/cjs/Hooks/pagination.js +36 -4
- package/dist/cjs/Hooks/pagination.test.js +1 -1
- package/dist/cjs/Hooks/selection.d.ts +3 -3
- package/dist/cjs/Hooks/selection.js +4 -4
- package/dist/cjs/Hooks/selection.test.js +4 -4
- package/dist/cjs/Hooks/sort.d.ts +32 -0
- package/dist/cjs/Hooks/sort.js +47 -0
- package/dist/cjs/Hooks/sort.test.d.ts +1 -0
- package/dist/cjs/Hooks/sort.test.js +68 -0
- package/dist/cjs/InternalContext/InternalContext.d.ts +26 -0
- package/dist/cjs/InternalContext/InternalContext.js +40 -0
- package/dist/cjs/InternalContext/InternalContext.test.d.ts +1 -0
- package/dist/cjs/InternalContext/InternalContext.test.js +56 -0
- package/dist/cjs/InternalContext/index.d.ts +2 -0
- package/dist/cjs/InternalContext/index.js +23 -0
- package/dist/cjs/index.d.ts +16 -0
- package/dist/cjs/index.js +26 -2
- package/dist/dynamic/DataViewCheckboxFilter/package.json +1 -0
- package/dist/dynamic/DataViewEventsContext/package.json +1 -0
- package/dist/dynamic/DataViewFilters/package.json +1 -0
- package/dist/dynamic/DataViewTable/package.json +1 -0
- package/dist/dynamic/DataViewTableBasic/package.json +1 -0
- package/dist/dynamic/DataViewTableHead/package.json +1 -0
- package/dist/dynamic/DataViewTableTree/package.json +1 -0
- package/dist/dynamic/DataViewTextFilter/package.json +1 -0
- package/dist/dynamic/InternalContext/package.json +1 -0
- package/dist/esm/DataView/DataView.d.ts +15 -1
- package/dist/esm/DataView/DataView.js +13 -2
- package/dist/esm/DataViewCheckboxFilter/DataViewCheckboxFilter.d.ts +29 -0
- package/dist/esm/DataViewCheckboxFilter/DataViewCheckboxFilter.js +62 -0
- package/dist/esm/DataViewCheckboxFilter/DataViewCheckboxFilter.test.d.ts +1 -0
- package/dist/esm/DataViewCheckboxFilter/DataViewCheckboxFilter.test.js +20 -0
- package/dist/esm/DataViewCheckboxFilter/index.d.ts +2 -0
- package/dist/esm/DataViewCheckboxFilter/index.js +2 -0
- package/dist/esm/DataViewEventsContext/DataViewEventsContext.d.ts +16 -0
- package/dist/esm/DataViewEventsContext/DataViewEventsContext.js +34 -0
- package/dist/esm/DataViewEventsContext/DataViewEventsContext.test.d.ts +1 -0
- package/dist/esm/DataViewEventsContext/DataViewEventsContext.test.js +67 -0
- package/dist/esm/DataViewEventsContext/index.d.ts +2 -0
- package/dist/esm/DataViewEventsContext/index.js +2 -0
- package/dist/esm/DataViewFilters/DataViewFilters.d.ts +25 -0
- package/dist/esm/DataViewFilters/DataViewFilters.js +58 -0
- package/dist/esm/DataViewFilters/DataViewFilters.test.d.ts +1 -0
- package/dist/esm/DataViewFilters/DataViewFilters.test.js +14 -0
- package/dist/esm/DataViewFilters/index.d.ts +2 -0
- package/dist/esm/DataViewFilters/index.js +2 -0
- package/dist/esm/DataViewTable/DataViewTable.d.ts +49 -0
- package/dist/esm/DataViewTable/DataViewTable.js +8 -0
- package/dist/esm/DataViewTable/DataViewTable.test.d.ts +1 -0
- package/dist/esm/DataViewTable/DataViewTable.test.js +52 -0
- package/dist/esm/DataViewTable/index.d.ts +2 -0
- package/dist/esm/DataViewTable/index.js +2 -0
- package/dist/esm/DataViewTableBasic/DataViewTableBasic.d.ts +19 -0
- package/dist/esm/DataViewTableBasic/DataViewTableBasic.js +44 -0
- package/dist/esm/DataViewTableBasic/DataViewTableBasic.test.d.ts +1 -0
- package/dist/esm/DataViewTableBasic/DataViewTableBasic.test.js +38 -0
- package/dist/esm/DataViewTableBasic/index.d.ts +2 -0
- package/dist/esm/DataViewTableBasic/index.js +2 -0
- package/dist/esm/DataViewTableHead/DataViewTableHead.d.ts +14 -0
- package/dist/esm/DataViewTableHead/DataViewTableHead.js +30 -0
- package/dist/esm/DataViewTableHead/DataViewTableHead.test.d.ts +1 -0
- package/dist/esm/DataViewTableHead/DataViewTableHead.test.js +31 -0
- package/dist/esm/DataViewTableHead/index.d.ts +2 -0
- package/dist/esm/DataViewTableHead/index.js +2 -0
- package/dist/esm/DataViewTableTree/DataViewTableTree.d.ts +25 -0
- package/dist/esm/DataViewTableTree/DataViewTableTree.js +117 -0
- package/dist/esm/DataViewTableTree/DataViewTableTree.test.d.ts +1 -0
- package/dist/esm/DataViewTableTree/DataViewTableTree.test.js +85 -0
- package/dist/esm/DataViewTableTree/index.d.ts +2 -0
- package/dist/esm/DataViewTableTree/index.js +2 -0
- package/dist/esm/DataViewTextFilter/DataViewTextFilter.d.ts +21 -0
- package/dist/esm/DataViewTextFilter/DataViewTextFilter.js +19 -0
- package/dist/esm/DataViewTextFilter/DataViewTextFilter.test.d.ts +1 -0
- package/dist/esm/DataViewTextFilter/DataViewTextFilter.test.js +17 -0
- package/dist/esm/DataViewTextFilter/index.d.ts +2 -0
- package/dist/esm/DataViewTextFilter/index.js +2 -0
- package/dist/esm/DataViewToolbar/DataViewToolbar.d.ts +11 -3
- package/dist/esm/DataViewToolbar/DataViewToolbar.js +8 -4
- package/dist/esm/Hooks/filters.d.ts +14 -0
- package/dist/esm/Hooks/filters.js +65 -0
- package/dist/esm/Hooks/filters.test.d.ts +1 -0
- package/dist/esm/Hooks/filters.test.js +48 -0
- package/dist/esm/Hooks/index.d.ts +2 -0
- package/dist/esm/Hooks/index.js +2 -0
- package/dist/esm/Hooks/pagination.d.ts +14 -1
- package/dist/esm/Hooks/pagination.js +36 -4
- package/dist/esm/Hooks/pagination.test.js +1 -1
- package/dist/esm/Hooks/selection.d.ts +3 -3
- package/dist/esm/Hooks/selection.js +4 -4
- package/dist/esm/Hooks/selection.test.js +4 -4
- package/dist/esm/Hooks/sort.d.ts +32 -0
- package/dist/esm/Hooks/sort.js +43 -0
- package/dist/esm/Hooks/sort.test.d.ts +1 -0
- package/dist/esm/Hooks/sort.test.js +66 -0
- package/dist/esm/InternalContext/InternalContext.d.ts +26 -0
- package/dist/esm/InternalContext/InternalContext.js +12 -0
- package/dist/esm/InternalContext/InternalContext.test.d.ts +1 -0
- package/dist/esm/InternalContext/InternalContext.test.js +51 -0
- package/dist/esm/InternalContext/index.d.ts +2 -0
- package/dist/esm/InternalContext/index.js +2 -0
- package/dist/esm/index.d.ts +16 -0
- package/dist/esm/index.js +16 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +16 -15
- package/patternfly-docs/content/extensions/data-view/examples/DataView/DataView.md +63 -0
- package/patternfly-docs/content/extensions/data-view/examples/DataView/EventsExample.tsx +130 -0
- package/patternfly-docs/content/extensions/data-view/examples/DataView/PredefinedLayoutFullExample.tsx +275 -0
- package/patternfly-docs/content/extensions/data-view/examples/Table/DataViewTableEmptyExample.tsx +57 -0
- package/patternfly-docs/content/extensions/data-view/examples/Table/DataViewTableErrorExample.tsx +45 -0
- package/patternfly-docs/content/extensions/data-view/examples/Table/DataViewTableExample.tsx +67 -0
- package/patternfly-docs/content/extensions/data-view/examples/Table/DataViewTableLoadingExample.tsx +27 -0
- package/patternfly-docs/content/extensions/data-view/examples/Table/DataViewTableTreeExample.tsx +71 -0
- package/patternfly-docs/content/extensions/data-view/examples/Table/SortingExample.tsx +87 -0
- package/patternfly-docs/content/extensions/data-view/examples/Table/Table.md +130 -0
- package/patternfly-docs/content/extensions/data-view/examples/Toolbar/DataViewToolbarActionsExample.tsx +27 -0
- package/patternfly-docs/content/extensions/data-view/examples/Toolbar/DataViewToolbarExample.tsx +36 -0
- package/patternfly-docs/content/extensions/data-view/examples/Toolbar/FiltersExample.tsx +107 -0
- package/patternfly-docs/content/extensions/data-view/examples/Toolbar/PaginationExample.tsx +56 -0
- package/patternfly-docs/content/extensions/data-view/examples/Toolbar/SelectionExample.tsx +57 -0
- package/patternfly-docs/content/extensions/data-view/examples/Toolbar/Toolbar.md +142 -0
- package/patternfly-docs/pages/index.js +1 -1
- package/src/DataView/DataView.tsx +28 -5
- package/src/DataView/__snapshots__/DataView.test.tsx.snap +2 -2
- package/src/DataViewCheckboxFilter/DataViewCheckboxFilter.test.tsx +24 -0
- package/src/DataViewCheckboxFilter/DataViewCheckboxFilter.tsx +175 -0
- package/src/DataViewCheckboxFilter/__snapshots__/DataViewCheckboxFilter.test.tsx.snap +197 -0
- package/src/DataViewCheckboxFilter/index.ts +2 -0
- package/src/DataViewEventsContext/DataViewEventsContext.test.tsx +105 -0
- package/src/DataViewEventsContext/DataViewEventsContext.tsx +70 -0
- package/src/DataViewEventsContext/index.ts +2 -0
- package/src/DataViewFilters/DataViewFilters.test.tsx +21 -0
- package/src/DataViewFilters/DataViewFilters.tsx +144 -0
- package/src/DataViewFilters/__snapshots__/DataViewFilters.test.tsx.snap +194 -0
- package/src/DataViewFilters/index.tsx +2 -0
- package/src/DataViewTable/DataViewTable.test.tsx +80 -0
- package/src/DataViewTable/DataViewTable.tsx +57 -0
- package/src/DataViewTable/__snapshots__/DataViewTable.test.tsx.snap +1042 -0
- package/src/DataViewTable/index.ts +2 -0
- package/src/DataViewTableBasic/DataViewTableBasic.test.tsx +65 -0
- package/src/DataViewTableBasic/DataViewTableBasic.tsx +83 -0
- package/src/DataViewTableBasic/__snapshots__/DataViewTableBasic.test.tsx.snap +555 -0
- package/src/DataViewTableBasic/index.ts +2 -0
- package/src/DataViewTableHead/DataViewTableHead.test.tsx +50 -0
- package/src/DataViewTableHead/DataViewTableHead.tsx +54 -0
- package/src/DataViewTableHead/__snapshots__/DataViewTableHead.test.tsx.snap +227 -0
- package/src/DataViewTableHead/index.ts +2 -0
- package/src/DataViewTableTree/DataViewTableTree.test.tsx +113 -0
- package/src/DataViewTableTree/DataViewTableTree.tsx +186 -0
- package/src/DataViewTableTree/__snapshots__/DataViewTableTree.test.tsx.snap +1200 -0
- package/src/DataViewTableTree/index.ts +2 -0
- package/src/DataViewTextFilter/DataViewTextFilter.test.tsx +24 -0
- package/src/DataViewTextFilter/DataViewTextFilter.tsx +54 -0
- package/src/DataViewTextFilter/__snapshots__/DataViewTextFilter.test.tsx.snap +203 -0
- package/src/DataViewTextFilter/index.ts +2 -0
- package/src/DataViewToolbar/DataViewToolbar.tsx +48 -22
- package/src/DataViewToolbar/__snapshots__/DataViewToolbar.test.tsx.snap +52 -8
- package/src/Hooks/filters.test.tsx +62 -0
- package/src/Hooks/filters.ts +97 -0
- package/src/Hooks/index.ts +2 -0
- package/src/Hooks/pagination.test.tsx +1 -1
- package/src/Hooks/pagination.ts +69 -12
- package/src/Hooks/selection.test.tsx +5 -5
- package/src/Hooks/selection.ts +7 -7
- package/src/Hooks/sort.test.tsx +84 -0
- package/src/Hooks/sort.ts +87 -0
- package/src/InternalContext/InternalContext.test.tsx +89 -0
- package/src/InternalContext/InternalContext.tsx +52 -0
- package/src/InternalContext/index.ts +2 -0
- package/src/index.ts +24 -0
- package/patternfly-docs/content/extensions/data-view/about-data-view.md +0 -14
- package/patternfly-docs/content/extensions/data-view/examples/Components/Components.md +0 -31
- package/patternfly-docs/content/extensions/data-view/examples/Components/DataViewToolbarExample.tsx +0 -20
- package/patternfly-docs/content/extensions/data-view/examples/Functionality/Functionality.md +0 -77
- package/patternfly-docs/content/extensions/data-view/examples/Functionality/PaginationExample.tsx +0 -65
- package/patternfly-docs/content/extensions/data-view/examples/Functionality/SelectionExample.tsx +0 -88
- package/patternfly-docs/content/extensions/data-view/examples/Layout/Layout.md +0 -39
- package/patternfly-docs/content/extensions/data-view/examples/Layout/PredefinedLayoutExample.tsx +0 -120
- /package/patternfly-docs/content/extensions/data-view/examples/{Layout → DataView}/AbstractLayoutExample.tsx +0 -0
|
@@ -12,7 +12,7 @@ import { renderHook, act } from '@testing-library/react';
|
|
|
12
12
|
import { useDataViewSelection } from './selection';
|
|
13
13
|
describe('useDataViewSelection', () => {
|
|
14
14
|
it('should get initial state correctly - no initialSelected', () => {
|
|
15
|
-
const { result } = renderHook(() => useDataViewSelection({}));
|
|
15
|
+
const { result } = renderHook(() => useDataViewSelection({ matchOption: (a, b) => a.id === b.id }));
|
|
16
16
|
expect(result.current).toEqual({
|
|
17
17
|
selected: [],
|
|
18
18
|
onSelect: expect.any(Function),
|
|
@@ -21,7 +21,7 @@ describe('useDataViewSelection', () => {
|
|
|
21
21
|
});
|
|
22
22
|
it('should get initial state correctly - with initialSelected', () => {
|
|
23
23
|
const initialSelected = [{ id: 1, name: 'test1' }];
|
|
24
|
-
const { result } = renderHook(() => useDataViewSelection({ initialSelected }));
|
|
24
|
+
const { result } = renderHook(() => useDataViewSelection({ initialSelected, matchOption: (a, b) => a.id === b.id }));
|
|
25
25
|
expect(result.current).toEqual({
|
|
26
26
|
selected: initialSelected,
|
|
27
27
|
onSelect: expect.any(Function),
|
|
@@ -30,7 +30,7 @@ describe('useDataViewSelection', () => {
|
|
|
30
30
|
});
|
|
31
31
|
it('should select items correctly - objects', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
32
32
|
const initialSelected = [{ id: 1, name: 'test1' }];
|
|
33
|
-
const { result } = renderHook(() => useDataViewSelection({ initialSelected }));
|
|
33
|
+
const { result } = renderHook(() => useDataViewSelection({ initialSelected, matchOption: (a, b) => a.id === b.id }));
|
|
34
34
|
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
35
35
|
result.current.onSelect(true, { id: 2, name: 'test2' });
|
|
36
36
|
}));
|
|
@@ -38,7 +38,7 @@ describe('useDataViewSelection', () => {
|
|
|
38
38
|
}));
|
|
39
39
|
it('should deselect items correctly - strings', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
40
40
|
const initialSelected = ['test1', 'test2'];
|
|
41
|
-
const { result } = renderHook(() => useDataViewSelection({ initialSelected }));
|
|
41
|
+
const { result } = renderHook(() => useDataViewSelection({ initialSelected, matchOption: (a, b) => a === b }));
|
|
42
42
|
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
43
43
|
result.current.onSelect(false, 'test2');
|
|
44
44
|
}));
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { ISortBy } from "@patternfly/react-table";
|
|
2
|
+
export declare enum DataViewSortParams {
|
|
3
|
+
SORT_BY = "sortBy",
|
|
4
|
+
DIRECTION = "direction"
|
|
5
|
+
}
|
|
6
|
+
export interface DataViewSortConfig {
|
|
7
|
+
/** Attribute to sort the entries by */
|
|
8
|
+
sortBy: string | undefined;
|
|
9
|
+
/** Sort direction */
|
|
10
|
+
direction: ISortBy['direction'];
|
|
11
|
+
}
|
|
12
|
+
export interface UseDataViewSortProps {
|
|
13
|
+
/** Initial sort config */
|
|
14
|
+
initialSort?: DataViewSortConfig;
|
|
15
|
+
/** Current search parameters as a string */
|
|
16
|
+
searchParams?: URLSearchParams;
|
|
17
|
+
/** Function to set search parameters */
|
|
18
|
+
setSearchParams?: (params: URLSearchParams) => void;
|
|
19
|
+
/** Default direction */
|
|
20
|
+
defaultDirection?: ISortBy['direction'];
|
|
21
|
+
/** Sort by URL param name */
|
|
22
|
+
sortByParam?: string;
|
|
23
|
+
/** Direction URL param name */
|
|
24
|
+
directionParam?: string;
|
|
25
|
+
}
|
|
26
|
+
export declare const useDataViewSort: (props?: UseDataViewSortProps) => {
|
|
27
|
+
onSort: (_event: React.MouseEvent | React.KeyboardEvent | MouseEvent | undefined, newSortBy: string, newSortDirection: ISortBy["direction"]) => void;
|
|
28
|
+
/** Attribute to sort the entries by */
|
|
29
|
+
sortBy: string | undefined;
|
|
30
|
+
/** Sort direction */
|
|
31
|
+
direction: ISortBy["direction"];
|
|
32
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { useState, useEffect, useMemo } from "react";
|
|
2
|
+
export var DataViewSortParams;
|
|
3
|
+
(function (DataViewSortParams) {
|
|
4
|
+
DataViewSortParams["SORT_BY"] = "sortBy";
|
|
5
|
+
DataViewSortParams["DIRECTION"] = "direction";
|
|
6
|
+
})(DataViewSortParams || (DataViewSortParams = {}));
|
|
7
|
+
;
|
|
8
|
+
const validateDirection = (direction, defaultDirection) => (direction === 'asc' || direction === 'desc' ? direction : defaultDirection);
|
|
9
|
+
;
|
|
10
|
+
;
|
|
11
|
+
export const useDataViewSort = (props) => {
|
|
12
|
+
var _a;
|
|
13
|
+
const { initialSort, searchParams, setSearchParams, defaultDirection = 'asc', sortByParam = DataViewSortParams.SORT_BY, directionParam = DataViewSortParams.DIRECTION } = props !== null && props !== void 0 ? props : {};
|
|
14
|
+
const isUrlSyncEnabled = useMemo(() => searchParams && !!setSearchParams, [searchParams, setSearchParams]);
|
|
15
|
+
const [state, setState] = useState({
|
|
16
|
+
sortBy: (_a = searchParams === null || searchParams === void 0 ? void 0 : searchParams.get(sortByParam)) !== null && _a !== void 0 ? _a : initialSort === null || initialSort === void 0 ? void 0 : initialSort.sortBy,
|
|
17
|
+
direction: validateDirection(searchParams === null || searchParams === void 0 ? void 0 : searchParams.get(directionParam), initialSort === null || initialSort === void 0 ? void 0 : initialSort.direction),
|
|
18
|
+
});
|
|
19
|
+
const updateSearchParams = (sortBy, direction) => {
|
|
20
|
+
if (isUrlSyncEnabled && sortBy) {
|
|
21
|
+
const params = new URLSearchParams(searchParams);
|
|
22
|
+
params.set(sortByParam, `${sortBy}`);
|
|
23
|
+
params.set(directionParam, `${direction}`);
|
|
24
|
+
setSearchParams === null || setSearchParams === void 0 ? void 0 : setSearchParams(params);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
state.sortBy && state.direction && updateSearchParams(state.sortBy, state.direction);
|
|
29
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
30
|
+
}, []);
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
const currentSortBy = (searchParams === null || searchParams === void 0 ? void 0 : searchParams.get(sortByParam)) || state.sortBy;
|
|
33
|
+
const currentDirection = (searchParams === null || searchParams === void 0 ? void 0 : searchParams.get(directionParam)) || state.direction;
|
|
34
|
+
const validDirection = validateDirection(currentDirection, defaultDirection);
|
|
35
|
+
currentSortBy !== state.sortBy || validDirection !== state.direction && setState({ sortBy: currentSortBy, direction: validDirection });
|
|
36
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
37
|
+
}, [searchParams === null || searchParams === void 0 ? void 0 : searchParams.toString()]);
|
|
38
|
+
const onSort = (_event, newSortBy, newSortDirection) => {
|
|
39
|
+
setState({ sortBy: newSortBy, direction: newSortDirection });
|
|
40
|
+
updateSearchParams(newSortBy, newSortDirection);
|
|
41
|
+
};
|
|
42
|
+
return Object.assign(Object.assign({}, state), { onSort });
|
|
43
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import '@testing-library/jest-dom';
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import '@testing-library/jest-dom';
|
|
2
|
+
import { renderHook, act } from '@testing-library/react';
|
|
3
|
+
import { useDataViewSort, DataViewSortParams } from './sort';
|
|
4
|
+
describe('useDataViewSort', () => {
|
|
5
|
+
const initialSort = { sortBy: 'name', direction: 'asc' };
|
|
6
|
+
it('should initialize with provided initial sort config', () => {
|
|
7
|
+
const { result } = renderHook(() => useDataViewSort({ initialSort }));
|
|
8
|
+
expect(result.current).toEqual(expect.objectContaining(initialSort));
|
|
9
|
+
});
|
|
10
|
+
it('should initialize with empty sort config if no initialSort is provided', () => {
|
|
11
|
+
const { result } = renderHook(() => useDataViewSort());
|
|
12
|
+
expect(result.current).toEqual(expect.objectContaining({ sortBy: undefined, direction: 'asc' }));
|
|
13
|
+
});
|
|
14
|
+
it('should update sort state when onSort is called', () => {
|
|
15
|
+
const { result } = renderHook(() => useDataViewSort({ initialSort }));
|
|
16
|
+
act(() => {
|
|
17
|
+
result.current.onSort(undefined, 'age', 'desc');
|
|
18
|
+
});
|
|
19
|
+
expect(result.current).toEqual(expect.objectContaining({ sortBy: 'age', direction: 'desc' }));
|
|
20
|
+
});
|
|
21
|
+
it('should sync with URL search params if isUrlSyncEnabled', () => {
|
|
22
|
+
const searchParams = new URLSearchParams();
|
|
23
|
+
const setSearchParams = jest.fn();
|
|
24
|
+
const props = {
|
|
25
|
+
initialSort,
|
|
26
|
+
searchParams,
|
|
27
|
+
setSearchParams,
|
|
28
|
+
};
|
|
29
|
+
const { result } = renderHook(() => useDataViewSort(props));
|
|
30
|
+
expect(setSearchParams).toHaveBeenCalledTimes(1);
|
|
31
|
+
expect(result.current).toEqual(expect.objectContaining(initialSort));
|
|
32
|
+
});
|
|
33
|
+
it('should validate direction and fallback to default direction if invalid direction is provided', () => {
|
|
34
|
+
const searchParams = new URLSearchParams();
|
|
35
|
+
searchParams.set(DataViewSortParams.SORT_BY, 'name');
|
|
36
|
+
searchParams.set(DataViewSortParams.DIRECTION, 'invalid-direction');
|
|
37
|
+
const { result } = renderHook(() => useDataViewSort({ searchParams, defaultDirection: 'desc' }));
|
|
38
|
+
expect(result.current).toEqual(expect.objectContaining({ sortBy: 'name', direction: 'desc' }));
|
|
39
|
+
});
|
|
40
|
+
it('should update search params when URL sync is enabled and sort changes', () => {
|
|
41
|
+
const searchParams = new URLSearchParams();
|
|
42
|
+
const setSearchParams = jest.fn();
|
|
43
|
+
const props = {
|
|
44
|
+
initialSort,
|
|
45
|
+
searchParams,
|
|
46
|
+
setSearchParams,
|
|
47
|
+
};
|
|
48
|
+
const { result } = renderHook(() => useDataViewSort(props));
|
|
49
|
+
act(() => {
|
|
50
|
+
expect(setSearchParams).toHaveBeenCalledTimes(1);
|
|
51
|
+
result.current.onSort(undefined, 'priority', 'desc');
|
|
52
|
+
});
|
|
53
|
+
expect(setSearchParams).toHaveBeenCalledTimes(2);
|
|
54
|
+
expect(result.current).toEqual(expect.objectContaining({ sortBy: 'priority', direction: 'desc' }));
|
|
55
|
+
});
|
|
56
|
+
it('should prioritize searchParams values', () => {
|
|
57
|
+
const searchParams = new URLSearchParams();
|
|
58
|
+
searchParams.set(DataViewSortParams.SORT_BY, 'category');
|
|
59
|
+
searchParams.set(DataViewSortParams.DIRECTION, 'desc');
|
|
60
|
+
const { result } = renderHook((props) => useDataViewSort(props), { initialProps: { initialSort, searchParams } });
|
|
61
|
+
expect(result.current).toEqual(expect.objectContaining({
|
|
62
|
+
sortBy: 'category',
|
|
63
|
+
direction: 'desc',
|
|
64
|
+
}));
|
|
65
|
+
});
|
|
66
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React, { PropsWithChildren } from 'react';
|
|
2
|
+
import { DataViewState } from '../DataView';
|
|
3
|
+
export interface DataViewSelection {
|
|
4
|
+
/** Called when the selection of items changes */
|
|
5
|
+
onSelect: (isSelecting: boolean, items?: any[] | any) => void;
|
|
6
|
+
/** Checks if a specific item is currently selected */
|
|
7
|
+
isSelected: (item: any) => boolean;
|
|
8
|
+
/** Determines if selection is disabled for a given item */
|
|
9
|
+
isSelectDisabled?: (item: any) => boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface InternalContextProps {
|
|
12
|
+
/** Data selection props */
|
|
13
|
+
selection?: DataViewSelection;
|
|
14
|
+
/** Currently active state */
|
|
15
|
+
activeState?: DataViewState | string;
|
|
16
|
+
}
|
|
17
|
+
/** extends InternalContextProps */
|
|
18
|
+
export interface InternalContextValue extends InternalContextProps {
|
|
19
|
+
/** Flag indicating if data view is selectable (auto-calculated) */
|
|
20
|
+
isSelectable: boolean;
|
|
21
|
+
}
|
|
22
|
+
export declare const InternalContext: React.Context<InternalContextValue>;
|
|
23
|
+
export type InternalProviderProps = PropsWithChildren<InternalContextProps>;
|
|
24
|
+
export declare const InternalContextProvider: React.FC<InternalProviderProps>;
|
|
25
|
+
export declare const useInternalContext: () => InternalContextValue;
|
|
26
|
+
export default InternalContext;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React, { createContext, useContext, useMemo } from 'react';
|
|
2
|
+
export const InternalContext = createContext({
|
|
3
|
+
selection: undefined,
|
|
4
|
+
activeState: undefined,
|
|
5
|
+
isSelectable: false,
|
|
6
|
+
});
|
|
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
|
+
};
|
|
11
|
+
export const useInternalContext = () => useContext(InternalContext);
|
|
12
|
+
export default InternalContext;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import '@testing-library/jest-dom';
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render, fireEvent } from '@testing-library/react';
|
|
3
|
+
import '@testing-library/jest-dom';
|
|
4
|
+
import { useInternalContext } from './InternalContext';
|
|
5
|
+
import { DataView } from '../DataView';
|
|
6
|
+
describe('InternalContext', () => {
|
|
7
|
+
const mockSelection = {
|
|
8
|
+
onSelect: jest.fn(),
|
|
9
|
+
isSelected: jest.fn(),
|
|
10
|
+
isSelectDisabled: jest.fn(),
|
|
11
|
+
};
|
|
12
|
+
test('should provide context value and allow consuming it', () => {
|
|
13
|
+
const TestComponent = () => {
|
|
14
|
+
const { selection } = useInternalContext();
|
|
15
|
+
return (React.createElement("div", null,
|
|
16
|
+
React.createElement("button", { onClick: () => selection === null || selection === void 0 ? void 0 : selection.onSelect(true, ['item1']) }, "Select item"),
|
|
17
|
+
React.createElement("span", null, (selection === null || selection === void 0 ? void 0 : selection.isSelected('item1')) ? 'Selected' : 'Not selected')));
|
|
18
|
+
};
|
|
19
|
+
const { getByText } = render(React.createElement(DataView, { selection: mockSelection },
|
|
20
|
+
React.createElement(TestComponent, null)));
|
|
21
|
+
fireEvent.click(getByText('Select item'));
|
|
22
|
+
expect(mockSelection.onSelect).toHaveBeenCalledWith(true, ['item1']);
|
|
23
|
+
});
|
|
24
|
+
test('should handle selection state correctly', () => {
|
|
25
|
+
const mockSelectionState = Object.assign(Object.assign({}, mockSelection), { isSelected: jest.fn((item) => item === 'item1') });
|
|
26
|
+
const TestComponent = () => {
|
|
27
|
+
const { selection } = useInternalContext();
|
|
28
|
+
return (React.createElement("div", null,
|
|
29
|
+
React.createElement("span", null, (selection === null || selection === void 0 ? void 0 : selection.isSelected('item1')) ? 'Item 1 is selected' : 'Item 1 is not selected'),
|
|
30
|
+
React.createElement("span", null, (selection === null || selection === void 0 ? void 0 : selection.isSelected('item2')) ? 'Item 2 is selected' : 'Item 2 is not selected')));
|
|
31
|
+
};
|
|
32
|
+
const { getByText } = render(React.createElement(DataView, { selection: mockSelectionState },
|
|
33
|
+
React.createElement(TestComponent, null)));
|
|
34
|
+
expect(getByText('Item 1 is selected')).toBeInTheDocument();
|
|
35
|
+
expect(getByText('Item 2 is not selected')).toBeInTheDocument();
|
|
36
|
+
});
|
|
37
|
+
test('should handle selection disabled correctly', () => {
|
|
38
|
+
const mockSelectionWithDisabled = Object.assign(Object.assign({}, mockSelection), { isSelectDisabled: jest.fn((item) => item === 'item3') });
|
|
39
|
+
const TestComponent = () => {
|
|
40
|
+
var _a, _b;
|
|
41
|
+
const { selection } = useInternalContext();
|
|
42
|
+
return (React.createElement("div", null,
|
|
43
|
+
React.createElement("span", null, ((_a = selection === null || selection === void 0 ? void 0 : selection.isSelectDisabled) === null || _a === void 0 ? void 0 : _a.call(selection, 'item3')) ? 'Item 3 is disabled' : 'Item 3 is enabled'),
|
|
44
|
+
React.createElement("span", null, ((_b = selection === null || selection === void 0 ? void 0 : selection.isSelectDisabled) === null || _b === void 0 ? void 0 : _b.call(selection, 'item1')) ? 'Item 1 is disabled' : 'Item 1 is enabled')));
|
|
45
|
+
};
|
|
46
|
+
const { getByText } = render(React.createElement(DataView, { selection: mockSelectionWithDisabled },
|
|
47
|
+
React.createElement(TestComponent, null)));
|
|
48
|
+
expect(getByText('Item 3 is disabled')).toBeInTheDocument();
|
|
49
|
+
expect(getByText('Item 1 is enabled')).toBeInTheDocument();
|
|
50
|
+
});
|
|
51
|
+
});
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
|
+
export { default as InternalContext } from './InternalContext';
|
|
2
|
+
export * from './InternalContext';
|
|
1
3
|
export * from './Hooks';
|
|
2
4
|
export { default as DataViewToolbar } from './DataViewToolbar';
|
|
3
5
|
export * from './DataViewToolbar';
|
|
6
|
+
export { default as DataViewTextFilter } from './DataViewTextFilter';
|
|
7
|
+
export * from './DataViewTextFilter';
|
|
8
|
+
export { default as DataViewTableTree } from './DataViewTableTree';
|
|
9
|
+
export * from './DataViewTableTree';
|
|
10
|
+
export { default as DataViewTableHead } from './DataViewTableHead';
|
|
11
|
+
export * from './DataViewTableHead';
|
|
12
|
+
export { default as DataViewTableBasic } from './DataViewTableBasic';
|
|
13
|
+
export * from './DataViewTableBasic';
|
|
14
|
+
export { default as DataViewTable } from './DataViewTable';
|
|
15
|
+
export * from './DataViewTable';
|
|
16
|
+
export { default as DataViewEventsContext } from './DataViewEventsContext';
|
|
17
|
+
export * from './DataViewEventsContext';
|
|
18
|
+
export { default as DataViewCheckboxFilter } from './DataViewCheckboxFilter';
|
|
19
|
+
export * from './DataViewCheckboxFilter';
|
|
4
20
|
export { default as DataView } from './DataView';
|
|
5
21
|
export * from './DataView';
|
package/dist/esm/index.js
CHANGED
|
@@ -1,6 +1,22 @@
|
|
|
1
1
|
// this file is autogenerated by generate-index.js, modifying it manually will have no effect
|
|
2
|
+
export { default as InternalContext } from './InternalContext';
|
|
3
|
+
export * from './InternalContext';
|
|
2
4
|
export * from './Hooks';
|
|
3
5
|
export { default as DataViewToolbar } from './DataViewToolbar';
|
|
4
6
|
export * from './DataViewToolbar';
|
|
7
|
+
export { default as DataViewTextFilter } from './DataViewTextFilter';
|
|
8
|
+
export * from './DataViewTextFilter';
|
|
9
|
+
export { default as DataViewTableTree } from './DataViewTableTree';
|
|
10
|
+
export * from './DataViewTableTree';
|
|
11
|
+
export { default as DataViewTableHead } from './DataViewTableHead';
|
|
12
|
+
export * from './DataViewTableHead';
|
|
13
|
+
export { default as DataViewTableBasic } from './DataViewTableBasic';
|
|
14
|
+
export * from './DataViewTableBasic';
|
|
15
|
+
export { default as DataViewTable } from './DataViewTable';
|
|
16
|
+
export * from './DataViewTable';
|
|
17
|
+
export { default as DataViewEventsContext } from './DataViewEventsContext';
|
|
18
|
+
export * from './DataViewEventsContext';
|
|
19
|
+
export { default as DataViewCheckboxFilter } from './DataViewCheckboxFilter';
|
|
20
|
+
export * from './DataViewCheckboxFilter';
|
|
5
21
|
export { default as DataView } from './DataView';
|
|
6
22
|
export * from './DataView';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"root":["../src/index.ts","../src/dataview/dataview.test.tsx","../src/dataview/dataview.tsx","../src/dataview/index.ts","../src/dataviewcheckboxfilter/dataviewcheckboxfilter.test.tsx","../src/dataviewcheckboxfilter/dataviewcheckboxfilter.tsx","../src/dataviewcheckboxfilter/index.ts","../src/datavieweventscontext/datavieweventscontext.test.tsx","../src/datavieweventscontext/datavieweventscontext.tsx","../src/datavieweventscontext/index.ts","../src/dataviewfilters/dataviewfilters.test.tsx","../src/dataviewfilters/dataviewfilters.tsx","../src/dataviewfilters/index.tsx","../src/dataviewtable/dataviewtable.test.tsx","../src/dataviewtable/dataviewtable.tsx","../src/dataviewtable/index.ts","../src/dataviewtablebasic/dataviewtablebasic.test.tsx","../src/dataviewtablebasic/dataviewtablebasic.tsx","../src/dataviewtablebasic/index.ts","../src/dataviewtablehead/dataviewtablehead.test.tsx","../src/dataviewtablehead/dataviewtablehead.tsx","../src/dataviewtablehead/index.ts","../src/dataviewtabletree/dataviewtabletree.test.tsx","../src/dataviewtabletree/dataviewtabletree.tsx","../src/dataviewtabletree/index.ts","../src/dataviewtextfilter/dataviewtextfilter.test.tsx","../src/dataviewtextfilter/dataviewtextfilter.tsx","../src/dataviewtextfilter/index.ts","../src/dataviewtoolbar/dataviewtoolbar.test.tsx","../src/dataviewtoolbar/dataviewtoolbar.tsx","../src/dataviewtoolbar/index.ts","../src/hooks/filters.test.tsx","../src/hooks/filters.ts","../src/hooks/index.ts","../src/hooks/pagination.test.tsx","../src/hooks/pagination.ts","../src/hooks/selection.test.tsx","../src/hooks/selection.ts","../src/hooks/sort.test.tsx","../src/hooks/sort.ts","../src/internalcontext/internalcontext.test.tsx","../src/internalcontext/internalcontext.tsx","../src/internalcontext/index.ts"],"version":"5.6.3"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@patternfly/react-data-view",
|
|
3
|
-
"version": "6.1.0
|
|
3
|
+
"version": "6.1.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",
|
|
@@ -31,29 +31,30 @@
|
|
|
31
31
|
"tag": "prerelease"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@patternfly/react-
|
|
35
|
-
"@patternfly/react-
|
|
36
|
-
"@patternfly/react-
|
|
37
|
-
"@patternfly/react-
|
|
38
|
-
"
|
|
39
|
-
"
|
|
34
|
+
"@patternfly/react-component-groups": "^6.1.0",
|
|
35
|
+
"@patternfly/react-core": "^6.0.0",
|
|
36
|
+
"@patternfly/react-icons": "^6.0.0",
|
|
37
|
+
"@patternfly/react-table": "^6.0.0",
|
|
38
|
+
"clsx": "^2.1.1",
|
|
39
|
+
"react-jss": "^10.10.0"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
42
|
"react": "^17 || ^18",
|
|
43
43
|
"react-dom": "^17 || ^18"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
|
-
"@patternfly/
|
|
47
|
-
"@patternfly/patternfly": "6.0.0
|
|
48
|
-
"@patternfly/
|
|
49
|
-
"@
|
|
50
|
-
"@types/react
|
|
46
|
+
"@patternfly/documentation-framework": "^6.5.0",
|
|
47
|
+
"@patternfly/patternfly": "^6.0.0",
|
|
48
|
+
"@patternfly/react-code-editor": "^6.0.0",
|
|
49
|
+
"@patternfly/patternfly-a11y": "^5.0.0",
|
|
50
|
+
"@types/react": "^18.3.18",
|
|
51
|
+
"@types/react-dom": "^18.3.5",
|
|
51
52
|
"@types/react-router-dom": "^5.3.3",
|
|
52
53
|
"react": "^18.3.1",
|
|
53
54
|
"react-dom": "^18.3.1",
|
|
54
|
-
"react-router": "^6.
|
|
55
|
-
"react-router-dom": "^6.
|
|
56
|
-
"rimraf": "^
|
|
55
|
+
"react-router": "^6.28.1",
|
|
56
|
+
"react-router-dom": "^6.28.1",
|
|
57
|
+
"rimraf": "^6.0.1",
|
|
57
58
|
"typescript": "^5.4.5"
|
|
58
59
|
}
|
|
59
60
|
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
---
|
|
2
|
+
section: extensions
|
|
3
|
+
subsection: Data view
|
|
4
|
+
id: Overview
|
|
5
|
+
title: Data view overview
|
|
6
|
+
propComponents: ['DataView']
|
|
7
|
+
sortValue: 1
|
|
8
|
+
sourceLink: https://github.com/patternfly/react-data-view/blob/main/packages/module/patternfly-docs/content/extensions/data-view/examples/DataView/DataView.md
|
|
9
|
+
---
|
|
10
|
+
import { useState, useEffect, useRef, useMemo } from 'react';
|
|
11
|
+
import { Drawer, DrawerContent, DrawerContentBody } from '@patternfly/react-core';
|
|
12
|
+
import { CubesIcon } from '@patternfly/react-icons';
|
|
13
|
+
import { useDataViewPagination, useDataViewSelection, useDataViewFilters, useDataViewSort } from '@patternfly/react-data-view/dist/dynamic/Hooks';
|
|
14
|
+
import { BulkSelect, BulkSelectValue, ErrorState, ResponsiveAction, ResponsiveActions, SkeletonTableHead, SkeletonTableBody } from '@patternfly/react-component-groups';
|
|
15
|
+
import { DataView } from '@patternfly/react-data-view/dist/dynamic/DataView';
|
|
16
|
+
import { DataViewToolbar } from '@patternfly/react-data-view/dist/dynamic/DataViewToolbar';
|
|
17
|
+
import { DataViewTable } from '@patternfly/react-data-view/dist/dynamic/DataViewTable';
|
|
18
|
+
import { useDataViewEventsContext, DataViewEventsContext, DataViewEventsProvider, EventTypes } from '@patternfly/react-data-view/dist/dynamic/DataViewEventsContext';
|
|
19
|
+
import { DataViewFilters } from '@patternfly/react-data-view/dist/dynamic/DataViewFilters';
|
|
20
|
+
import { DataViewTextFilter } from '@patternfly/react-data-view/dist/dynamic/DataViewTextFilter';
|
|
21
|
+
import { DataViewCheckboxFilter } from '@patternfly/react-data-view/dist/dynamic/DataViewCheckboxFilter';
|
|
22
|
+
|
|
23
|
+
**Note:** Data view lives in its own package [`@patternfly/react-data-view`](https://www.npmjs.com/package/@patternfly/react-data-view)
|
|
24
|
+
|
|
25
|
+
If you notice a bug, or if you have a suggestion for improving the data view extension or its documentation, please file an issue in the [react-data-view](https://github.com/patternfly/react-data-view/issues) repository. Before doing so, please make sure there is not already a pre-existing issue.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
The **data view** extension enables you to display datasets in organized layouts, with data representations and interactive toolbars for actions like selection and pagination.
|
|
30
|
+
|
|
31
|
+
### Layout
|
|
32
|
+
|
|
33
|
+
A data view should contain a header, the data representation, and a footer. These parts are organized in a [stack layout](/layouts/stack).
|
|
34
|
+
|
|
35
|
+
The data view toolbars and sub-components that display the data (like a card view or table) are always passed as `children` to the `<DataView>` component.
|
|
36
|
+
|
|
37
|
+
```js file="./AbstractLayoutExample.tsx"
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Modularity
|
|
42
|
+
|
|
43
|
+
The extension's modular architecture lets you efficiently create consistent data views, either by using predefined sub-components and hooks, or by defining your own. You can choose the tools that suit your needs and easily replace any part with a custom implementation.
|
|
44
|
+
|
|
45
|
+
The `<DataViewToolbar>` component extends the [PatternFly toolbar](/components/toolbar) to support the most common needs. For more details, refer to the [data view toolbar](/extensions/data-view/toolbar) examples. You can also use a custom toolbar component if needed for your use case.
|
|
46
|
+
|
|
47
|
+
Data can be presented using the predefined `<DataViewTable>` component, which is an abstraction above the [PatternFly table](/components/table). For more details, refer to the [data view table](/extensions/data-view/table) examples. If you have more specific data display needs, you can pass a custom implementation as a `<DataView>` child. In the near future, we are also planning to introduce a predefined card view component.
|
|
48
|
+
|
|
49
|
+
```js file="./PredefinedLayoutFullExample.tsx"
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Events context
|
|
54
|
+
|
|
55
|
+
The `<DataViewEventsContext>` component is an advanced feature that enables external listening of data view events. In order to share data view context with your other UI components, both your components and your data view should be wrapped with the `<DataViewEventsProvider>`. This is demonstrated in the following example.
|
|
56
|
+
|
|
57
|
+
### Row click subscription example
|
|
58
|
+
This example uses the `<DataViewEventsProvider>` to display details about a selected row in a [drawer component](/components/drawer).
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
```js file="./EventsExample.tsx"
|
|
62
|
+
|
|
63
|
+
```
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import React, { useEffect, useState, useRef, useMemo } from 'react';
|
|
2
|
+
import { Drawer, DrawerActions, DrawerCloseButton, DrawerContent, DrawerContentBody, DrawerHead, DrawerPanelContent, Title, Content } from '@patternfly/react-core';
|
|
3
|
+
import { DataView } from '@patternfly/react-data-view/dist/dynamic/DataView';
|
|
4
|
+
import { DataViewTable } from '@patternfly/react-data-view/dist/dynamic/DataViewTable';
|
|
5
|
+
import { DataViewEventsProvider, EventTypes, useDataViewEventsContext } from '@patternfly/react-data-view/dist/dynamic/DataViewEventsContext';
|
|
6
|
+
import { useDataViewSelection } from '@patternfly/react-data-view/dist/dynamic/Hooks';
|
|
7
|
+
import { ActionsColumn } from '@patternfly/react-table';
|
|
8
|
+
|
|
9
|
+
interface Repository {
|
|
10
|
+
name: string;
|
|
11
|
+
branches: string | null;
|
|
12
|
+
prs: string | null;
|
|
13
|
+
workspaces: string;
|
|
14
|
+
lastCommit: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const repositories: Repository[] = [
|
|
18
|
+
{ name: 'Repository one', branches: 'Branch one', prs: 'Pull request one', workspaces: 'Workspace one', lastCommit: 'Timestamp one' },
|
|
19
|
+
{ name: 'Repository two', branches: 'Branch two', prs: 'Pull request two', workspaces: 'Workspace two', lastCommit: 'Timestamp two' },
|
|
20
|
+
{ name: 'Repository three', branches: 'Branch three', prs: 'Pull request three', workspaces: 'Workspace three', lastCommit: 'Timestamp three' },
|
|
21
|
+
{ name: 'Repository four', branches: 'Branch four', prs: 'Pull request four', workspaces: 'Workspace four', lastCommit: 'Timestamp four' },
|
|
22
|
+
{ name: 'Repository five', branches: 'Branch five', prs: 'Pull request five', workspaces: 'Workspace five', lastCommit: 'Timestamp five' },
|
|
23
|
+
{ name: 'Repository six', branches: 'Branch six', prs: 'Pull request six', workspaces: 'Workspace six', lastCommit: 'Timestamp six' }
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
const columns = [ 'Repositories', 'Branches', 'Pull requests', 'Workspaces', 'Last commit' ];
|
|
27
|
+
|
|
28
|
+
const ouiaId = 'ContextExample';
|
|
29
|
+
|
|
30
|
+
interface RepositoryDetailProps {
|
|
31
|
+
selectedRepo?: Repository;
|
|
32
|
+
setSelectedRepo: React.Dispatch<React.SetStateAction<Repository | undefined>>;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const RepositoryDetail: React.FunctionComponent<RepositoryDetailProps> = ({ selectedRepo, setSelectedRepo }) => {
|
|
36
|
+
const context = useDataViewEventsContext();
|
|
37
|
+
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
const unsubscribe = context.subscribe(EventTypes.rowClick, (repo: Repository) => {
|
|
40
|
+
setSelectedRepo(repo);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
return () => unsubscribe();
|
|
44
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
45
|
+
}, []);
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<DrawerPanelContent>
|
|
49
|
+
<DrawerHead>
|
|
50
|
+
<Title className="pf-v6-u-mb-md" headingLevel="h2" ouiaId="detail-drawer-title">
|
|
51
|
+
Detail of {selectedRepo?.name}
|
|
52
|
+
</Title>
|
|
53
|
+
<Content component="p">Branches: {selectedRepo?.branches}</Content>
|
|
54
|
+
<Content component="p">Pull requests: {selectedRepo?.prs}</Content>
|
|
55
|
+
<Content component="p">Workspaces: {selectedRepo?.workspaces}</Content>
|
|
56
|
+
<Content component="p">Last commit: {selectedRepo?.lastCommit}</Content>
|
|
57
|
+
<DrawerActions>
|
|
58
|
+
<DrawerCloseButton onClick={() => setSelectedRepo(undefined)} data-ouia-component-id="detail-drawer-close-btn"/>
|
|
59
|
+
</DrawerActions>
|
|
60
|
+
</DrawerHead>
|
|
61
|
+
</DrawerPanelContent>
|
|
62
|
+
);
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
interface RepositoriesTableProps {
|
|
66
|
+
selectedRepo?: Repository;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const rowActions = [
|
|
70
|
+
{
|
|
71
|
+
title: 'Some action',
|
|
72
|
+
onClick: () => console.log('clicked on Some action') // eslint-disable-line no-console
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
title: <div>Another action</div>,
|
|
76
|
+
onClick: () => console.log('clicked on Another action') // eslint-disable-line no-console
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
isSeparator: true
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
title: 'Third action',
|
|
83
|
+
onClick: () => console.log('clicked on Third action') // eslint-disable-line no-console
|
|
84
|
+
}
|
|
85
|
+
];
|
|
86
|
+
|
|
87
|
+
const RepositoriesTable: React.FunctionComponent<RepositoriesTableProps> = ({ selectedRepo = undefined }) => {
|
|
88
|
+
const selection = useDataViewSelection({ matchOption: (a, b) => a.row[0] === b.row[0] });
|
|
89
|
+
const { trigger } = useDataViewEventsContext();
|
|
90
|
+
const rows = useMemo(() => {
|
|
91
|
+
const handleRowClick = (event, repo: Repository | undefined) => {
|
|
92
|
+
// prevents drawer toggle on actions or checkbox click
|
|
93
|
+
(event.target.matches('td') || event.target.matches('tr')) && trigger(EventTypes.rowClick, repo);
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
return repositories.map(repo => ({
|
|
97
|
+
row: [ ...Object.values(repo), { cell: <ActionsColumn items={rowActions}/>, props: { isActionCell: true } } ],
|
|
98
|
+
props: {
|
|
99
|
+
isClickable: true,
|
|
100
|
+
onRowClick: (event) => handleRowClick(event, selectedRepo?.name === repo.name ? undefined : repo),
|
|
101
|
+
isRowSelected: selectedRepo?.name === repo.name
|
|
102
|
+
}
|
|
103
|
+
}));
|
|
104
|
+
}, [ selectedRepo?.name, trigger ]);
|
|
105
|
+
|
|
106
|
+
return (
|
|
107
|
+
<DataView selection={selection}>
|
|
108
|
+
<DataViewTable aria-label='Repositories table' ouiaId={ouiaId} columns={columns} rows={rows} />
|
|
109
|
+
</DataView>
|
|
110
|
+
);
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
export const BasicExample: React.FunctionComponent = () => {
|
|
114
|
+
const [ selectedRepo, setSelectedRepo ] = useState<Repository>();
|
|
115
|
+
const drawerRef = useRef<HTMLDivElement>(null);
|
|
116
|
+
|
|
117
|
+
return (
|
|
118
|
+
<DataViewEventsProvider>
|
|
119
|
+
<Drawer isExpanded={Boolean(selectedRepo)} onExpand={() => drawerRef.current?.focus()} data-ouia-component-id="detail-drawer" >
|
|
120
|
+
<DrawerContent
|
|
121
|
+
panelContent={<RepositoryDetail selectedRepo={selectedRepo} setSelectedRepo={setSelectedRepo} />}
|
|
122
|
+
>
|
|
123
|
+
<DrawerContentBody>
|
|
124
|
+
<RepositoriesTable selectedRepo={selectedRepo} />
|
|
125
|
+
</DrawerContentBody>
|
|
126
|
+
</DrawerContent>
|
|
127
|
+
</Drawer>
|
|
128
|
+
</DataViewEventsProvider>
|
|
129
|
+
);
|
|
130
|
+
};
|