@patternfly/react-data-view 6.4.0-prerelease.9 → 6.5.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.
Files changed (52) hide show
  1. package/dist/cjs/DataViewTextFilter/DataViewTextFilter.d.ts +2 -0
  2. package/dist/cjs/DataViewTextFilter/DataViewTextFilter.js +29 -1
  3. package/dist/cjs/DataViewTextFilter/DataViewTextFilter.test.d.ts +1 -1
  4. package/dist/cjs/DataViewTextFilter/DataViewTextFilter.test.js +83 -0
  5. package/dist/cjs/DataViewTh/DataViewTh.d.ts +4 -4
  6. package/dist/cjs/DataViewTh/DataViewTh.js +8 -1
  7. package/dist/cjs/DataViewToolbar/DataViewToolbar.js +13 -1
  8. package/dist/cjs/DataViewTreeFilter/DataViewTreeFilter.d.ts +26 -0
  9. package/dist/cjs/DataViewTreeFilter/DataViewTreeFilter.js +229 -0
  10. package/dist/cjs/DataViewTreeFilter/DataViewTreeFilter.test.d.ts +1 -0
  11. package/dist/cjs/DataViewTreeFilter/DataViewTreeFilter.test.js +171 -0
  12. package/dist/cjs/DataViewTreeFilter/index.d.ts +2 -0
  13. package/dist/cjs/DataViewTreeFilter/index.js +23 -0
  14. package/dist/cjs/Hooks/selection.d.ts +8 -8
  15. package/dist/cjs/index.d.ts +2 -0
  16. package/dist/cjs/index.js +4 -1
  17. package/dist/dynamic/DataViewTreeFilter/package.json +1 -0
  18. package/dist/dynamic-modules.json +2 -0
  19. package/dist/esm/DataViewTextFilter/DataViewTextFilter.d.ts +2 -0
  20. package/dist/esm/DataViewTextFilter/DataViewTextFilter.js +29 -1
  21. package/dist/esm/DataViewTextFilter/DataViewTextFilter.test.d.ts +1 -1
  22. package/dist/esm/DataViewTextFilter/DataViewTextFilter.test.js +84 -1
  23. package/dist/esm/DataViewTh/DataViewTh.d.ts +4 -4
  24. package/dist/esm/DataViewTh/DataViewTh.js +8 -1
  25. package/dist/esm/DataViewToolbar/DataViewToolbar.js +13 -1
  26. package/dist/esm/DataViewTreeFilter/DataViewTreeFilter.d.ts +26 -0
  27. package/dist/esm/DataViewTreeFilter/DataViewTreeFilter.js +225 -0
  28. package/dist/esm/DataViewTreeFilter/DataViewTreeFilter.test.d.ts +1 -0
  29. package/dist/esm/DataViewTreeFilter/DataViewTreeFilter.test.js +166 -0
  30. package/dist/esm/DataViewTreeFilter/index.d.ts +2 -0
  31. package/dist/esm/DataViewTreeFilter/index.js +2 -0
  32. package/dist/esm/Hooks/selection.d.ts +8 -8
  33. package/dist/esm/index.d.ts +2 -0
  34. package/dist/esm/index.js +2 -0
  35. package/dist/tsconfig.tsbuildinfo +1 -1
  36. package/package.json +1 -1
  37. package/patternfly-docs/content/extensions/data-view/examples/DataView/PredefinedLayoutFullExample.tsx +2 -1
  38. package/patternfly-docs/content/extensions/data-view/examples/Toolbar/FiltersExample.tsx +2 -1
  39. package/patternfly-docs/content/extensions/data-view/examples/Toolbar/PaginationExample.tsx +1 -1
  40. package/patternfly-docs/content/extensions/data-view/examples/Toolbar/Toolbar.md +8 -1
  41. package/patternfly-docs/content/extensions/data-view/examples/Toolbar/TreeFilterExample.tsx +248 -0
  42. package/src/DataViewTextFilter/DataViewTextFilter.test.tsx +129 -0
  43. package/src/DataViewTextFilter/DataViewTextFilter.tsx +58 -22
  44. package/src/DataViewTh/DataViewTh.tsx +15 -7
  45. package/src/DataViewToolbar/DataViewToolbar.tsx +17 -2
  46. package/src/DataViewToolbar/__snapshots__/DataViewToolbar.test.tsx.snap +288 -280
  47. package/src/DataViewTreeFilter/DataViewTreeFilter.test.tsx +222 -0
  48. package/src/DataViewTreeFilter/DataViewTreeFilter.tsx +361 -0
  49. package/src/DataViewTreeFilter/__snapshots__/DataViewTreeFilter.test.tsx.snap +199 -0
  50. package/src/DataViewTreeFilter/index.ts +2 -0
  51. package/src/Hooks/selection.ts +8 -8
  52. package/src/index.ts +3 -0
@@ -0,0 +1,166 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { jsx as _jsx } from "react/jsx-runtime";
11
+ import { render, screen, waitFor } from '@testing-library/react';
12
+ import '@testing-library/jest-dom';
13
+ import userEvent from '@testing-library/user-event';
14
+ import DataViewTreeFilter from './DataViewTreeFilter';
15
+ import DataViewToolbar from '../DataViewToolbar';
16
+ describe('DataViewTreeFilter component', () => {
17
+ const treeItems = [
18
+ {
19
+ name: 'Linux',
20
+ id: 'os-linux',
21
+ checkProps: { 'aria-label': 'linux-check', checked: false },
22
+ children: [
23
+ {
24
+ name: 'Ubuntu 22.04',
25
+ id: 'os-ubuntu',
26
+ checkProps: { checked: false }
27
+ },
28
+ {
29
+ name: 'RHEL 9',
30
+ id: 'os-rhel',
31
+ checkProps: { checked: false }
32
+ },
33
+ {
34
+ name: 'Debian 12',
35
+ id: 'os-debian',
36
+ checkProps: { checked: false }
37
+ },
38
+ {
39
+ name: 'CentOS 8',
40
+ id: 'os-centos',
41
+ checkProps: { checked: false }
42
+ },
43
+ {
44
+ name: 'Fedora 38',
45
+ id: 'os-fedora',
46
+ checkProps: { checked: false }
47
+ }
48
+ ],
49
+ defaultExpanded: true
50
+ },
51
+ {
52
+ name: 'Windows',
53
+ id: 'os-windows',
54
+ checkProps: { 'aria-label': 'windows-check', checked: false },
55
+ children: [
56
+ {
57
+ name: 'Windows Server 2022',
58
+ id: 'os-windows-2022',
59
+ checkProps: { checked: false }
60
+ }
61
+ ]
62
+ },
63
+ {
64
+ name: 'macOS',
65
+ id: 'os-macos',
66
+ checkProps: { 'aria-label': 'macos-check', checked: false },
67
+ children: [
68
+ {
69
+ name: 'macOS Ventura',
70
+ id: 'os-macos-ventura',
71
+ checkProps: { checked: false }
72
+ },
73
+ {
74
+ name: 'macOS Sonoma',
75
+ id: 'os-macos-sonoma',
76
+ checkProps: { checked: false }
77
+ }
78
+ ]
79
+ }
80
+ ];
81
+ const defaultProps = {
82
+ filterId: 'test-tree-filter',
83
+ title: 'Test Tree Filter',
84
+ value: ['Linux'],
85
+ items: treeItems
86
+ };
87
+ beforeEach(() => {
88
+ jest.clearAllMocks();
89
+ });
90
+ it('should render correctly', () => {
91
+ const { container } = render(_jsx(DataViewToolbar, { filters: _jsx(DataViewTreeFilter, Object.assign({}, defaultProps)) }));
92
+ expect(container).toMatchSnapshot();
93
+ });
94
+ describe('defaultExpanded', () => {
95
+ it('should have expanded items by default', () => __awaiter(void 0, void 0, void 0, function* () {
96
+ render(_jsx(DataViewToolbar, { filters: _jsx(DataViewTreeFilter, { filterId: "os", title: "Operating System", items: treeItems, defaultExpanded: true }) }));
97
+ const openMenu = screen.getByRole('button', { name: /operating system/i });
98
+ yield userEvent.click(openMenu);
99
+ yield waitFor(() => {
100
+ const node = screen.getByText('Ubuntu 22.04');
101
+ expect(node).toHaveClass('pf-v6-c-tree-view__node-text');
102
+ expect(node).toBeInTheDocument();
103
+ });
104
+ }));
105
+ });
106
+ describe('onChange callback', () => {
107
+ it('onChange should be called on toggle of node', () => __awaiter(void 0, void 0, void 0, function* () {
108
+ const mockOnChange = jest.fn();
109
+ render(_jsx(DataViewToolbar, { filters: _jsx(DataViewTreeFilter, { filterId: "os", title: "Operating System", items: treeItems, defaultExpanded: true, onChange: mockOnChange }) }));
110
+ const openMenu = screen.getByRole('button', { name: /operating system/i });
111
+ yield userEvent.click(openMenu);
112
+ yield waitFor(() => {
113
+ const node = screen.getByText('Ubuntu 22.04');
114
+ expect(node).toBeInTheDocument();
115
+ });
116
+ const node = screen.getByText('Ubuntu 22.04');
117
+ yield userEvent.click(node);
118
+ yield waitFor(() => {
119
+ expect(mockOnChange).toHaveBeenCalled();
120
+ });
121
+ }));
122
+ });
123
+ describe('onSelect callback', () => {
124
+ it('onSelect should return list of selected items when item is selected', () => __awaiter(void 0, void 0, void 0, function* () {
125
+ const mockOnSelect = jest.fn();
126
+ render(_jsx(DataViewToolbar, { filters: _jsx(DataViewTreeFilter, { filterId: "os", title: "Operating System", items: treeItems, defaultExpanded: true, onSelect: mockOnSelect }) }));
127
+ const openMenu = screen.getByRole('button', { name: /operating system/i });
128
+ yield userEvent.click(openMenu);
129
+ yield waitFor(() => {
130
+ const node = screen.getByText('Ubuntu 22.04');
131
+ expect(node).toBeInTheDocument();
132
+ });
133
+ const node = screen.getByText('Ubuntu 22.04');
134
+ yield userEvent.click(node);
135
+ yield waitFor(() => {
136
+ expect(mockOnSelect).toHaveBeenCalled();
137
+ expect(mockOnSelect).toHaveBeenCalledWith(expect.arrayContaining([
138
+ expect.objectContaining({
139
+ name: 'Ubuntu 22.04',
140
+ id: 'os-ubuntu'
141
+ })
142
+ ]));
143
+ });
144
+ }));
145
+ });
146
+ describe('rendering all items', () => {
147
+ it('all tree items should be rendered', () => __awaiter(void 0, void 0, void 0, function* () {
148
+ render(_jsx(DataViewToolbar, { filters: _jsx(DataViewTreeFilter, { filterId: "os", title: "Operating System", items: treeItems, defaultExpanded: true }) }));
149
+ const openMenu = screen.getByRole('button', { name: /operating system/i });
150
+ yield userEvent.click(openMenu);
151
+ yield waitFor(() => {
152
+ expect(screen.getByText('Linux')).toBeInTheDocument();
153
+ expect(screen.getByText('Windows')).toBeInTheDocument();
154
+ expect(screen.getByText('macOS')).toBeInTheDocument();
155
+ expect(screen.getByText('Ubuntu 22.04')).toBeInTheDocument();
156
+ expect(screen.getByText('RHEL 9')).toBeInTheDocument();
157
+ expect(screen.getByText('Debian 12')).toBeInTheDocument();
158
+ expect(screen.getByText('CentOS 8')).toBeInTheDocument();
159
+ expect(screen.getByText('Fedora 38')).toBeInTheDocument();
160
+ expect(screen.getByText('Windows Server 2022')).toBeInTheDocument();
161
+ expect(screen.getByText('macOS Ventura')).toBeInTheDocument();
162
+ expect(screen.getByText('macOS Sonoma')).toBeInTheDocument();
163
+ });
164
+ }));
165
+ });
166
+ });
@@ -0,0 +1,2 @@
1
+ export { default } from './DataViewTreeFilter';
2
+ export * from './DataViewTreeFilter';
@@ -0,0 +1,2 @@
1
+ export { default } from './DataViewTreeFilter';
2
+ export * from './DataViewTreeFilter';
@@ -1,12 +1,12 @@
1
- export interface UseDataViewSelectionProps {
1
+ export interface UseDataViewSelectionProps<T = any> {
2
2
  /** Function to compare items when checking if item is selected */
3
- matchOption: (item: any, another: any) => boolean;
3
+ matchOption: (item: T, another: T) => boolean;
4
4
  /** Array of initially selected entries */
5
- initialSelected?: (any)[];
5
+ initialSelected?: (T)[];
6
6
  }
7
- export declare const useDataViewSelection: (props?: UseDataViewSelectionProps) => {
8
- selected: any[];
9
- onSelect: (isSelecting: boolean, items?: any[] | any) => void;
10
- isSelected: (item: any) => boolean;
11
- setSelected: (items: any[]) => void;
7
+ export declare const useDataViewSelection: <T = any>(props?: UseDataViewSelectionProps<T>) => {
8
+ selected: T[];
9
+ onSelect: (isSelecting: boolean, items?: T[] | T) => void;
10
+ isSelected: (item: T) => boolean;
11
+ setSelected: (items: T[]) => void;
12
12
  };
@@ -1,6 +1,8 @@
1
1
  export { default as InternalContext } from './InternalContext';
2
2
  export * from './InternalContext';
3
3
  export * from './Hooks';
4
+ export { default as DataViewTreeFilter } from './DataViewTreeFilter';
5
+ export * from './DataViewTreeFilter';
4
6
  export { default as DataViewToolbar } from './DataViewToolbar';
5
7
  export * from './DataViewToolbar';
6
8
  export { default as DataViewTh } from './DataViewTh';
package/dist/esm/index.js CHANGED
@@ -2,6 +2,8 @@
2
2
  export { default as InternalContext } from './InternalContext';
3
3
  export * from './InternalContext';
4
4
  export * from './Hooks';
5
+ export { default as DataViewTreeFilter } from './DataViewTreeFilter';
6
+ export * from './DataViewTreeFilter';
5
7
  export { default as DataViewToolbar } from './DataViewToolbar';
6
8
  export * from './DataViewToolbar';
7
9
  export { default as DataViewTh } from './DataViewTh';
@@ -1 +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/DataViewTh/DataViewTh.tsx","../src/DataViewTh/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.9.3"}
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/DataViewTh/DataViewTh.tsx","../src/DataViewTh/index.ts","../src/DataViewToolbar/DataViewToolbar.test.tsx","../src/DataViewToolbar/DataViewToolbar.tsx","../src/DataViewToolbar/index.ts","../src/DataViewTreeFilter/DataViewTreeFilter.test.tsx","../src/DataViewTreeFilter/DataViewTreeFilter.tsx","../src/DataViewTreeFilter/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.9.3"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patternfly/react-data-view",
3
- "version": "6.4.0-prerelease.9",
3
+ "version": "6.5.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",
@@ -244,7 +244,8 @@ const RepositoriesTable: FunctionComponent<RepositoriesTableProps> = ({ selected
244
244
  ouiaId='LayoutExampleFooter'
245
245
  pagination={
246
246
  <Pagination
247
- isCompact
247
+ isCompact
248
+ variant="bottom"
248
249
  perPageOptions={perPageOptions}
249
250
  itemCount={repositories.length}
250
251
  {...pagination}
@@ -89,7 +89,8 @@ const MyTable: React.FunctionComponent = () => {
89
89
  ouiaId='LayoutExampleFooter'
90
90
  pagination={
91
91
  <Pagination
92
- isCompact
92
+ isCompact
93
+ variant="bottom"
93
94
  perPageOptions={perPageOptions}
94
95
  itemCount={filteredData.length}
95
96
  {...pagination}
@@ -44,7 +44,7 @@ const MyTable: React.FunctionComponent = () => {
44
44
  <DataView>
45
45
  <DataViewToolbar ouiaId='DataViewHeader' pagination={<Pagination perPageOptions={perPageOptions} itemCount={repositories.length} {...pagination} />} />
46
46
  <DataViewTable aria-label='Repositories table' ouiaId={ouiaId} columns={columns} rows={pageRows} />
47
- <DataViewToolbar ouiaId='DataViewFooter' pagination={<Pagination isCompact perPageOptions={perPageOptions} itemCount={repositories.length} {...pagination} />} />
47
+ <DataViewToolbar ouiaId='DataViewFooter' pagination={<Pagination isCompact variant="bottom" perPageOptions={perPageOptions} itemCount={repositories.length} {...pagination} />} />
48
48
  </DataView>
49
49
  );
50
50
  };
@@ -12,7 +12,7 @@ source: react
12
12
  # If you use typescript, the name of the interface to display props for
13
13
  # These are found through the sourceProps function provided in patternfly-docs.source.js
14
14
  sortValue: 2
15
- propComponents: ['DataViewToolbar', 'DataViewFilters', 'DataViewTextFilter', 'DataViewCheckboxFilter']
15
+ propComponents: ['DataViewToolbar', 'DataViewFilters', 'DataViewTextFilter', 'DataViewCheckboxFilter', 'DataViewTreeFilter']
16
16
  sourceLink: https://github.com/patternfly/react-data-view/blob/main/packages/module/patternfly-docs/content/extensions/data-view/examples/Toolbar/Toolbar.md
17
17
  ---
18
18
  import { useMemo, useState, useEffect } from 'react';
@@ -26,6 +26,7 @@ import { DataViewTable } from '@patternfly/react-data-view/dist/dynamic/DataView
26
26
  import { DataViewFilters } from '@patternfly/react-data-view/dist/dynamic/DataViewFilters';
27
27
  import { DataViewTextFilter } from '@patternfly/react-data-view/dist/dynamic/DataViewTextFilter';
28
28
  import { DataViewCheckboxFilter } from '@patternfly/react-data-view/dist/dynamic/DataViewCheckboxFilter';
29
+ import { DataViewTreeFilter } from '@patternfly/react-data-view/dist/dynamic/DataViewTreeFilter';
29
30
 
30
31
  The **data view toolbar** component renders a default opinionated data view toolbar above or below the data section.
31
32
 
@@ -143,6 +144,12 @@ This example demonstrates the setup and usage of filters within the data view. I
143
144
 
144
145
  ```
145
146
 
147
+ ### Tree filter example
148
+ This example demonstrates the usage of a tree filter with hierarchical data. The tree filter allows users to select items from a nested structure, making it ideal for categorized or grouped filtering options.
149
+
150
+ ```js file="./TreeFilterExample.tsx"
151
+
152
+ ```
146
153
 
147
154
  ## All/selected data switch
148
155
  All/selected data switch allows users to toggle between displaying the entire table (All) and only the rows they have selected (Selected). If the user deselects the last selected row, the filter automatically switches back to All, displaying all table rows again. Until at least one row is selected, a tooltip with guidance is displayed, and the Selected button does not perform any action. The Selected button is intentionally not disabled for accessibility reasons but instead has `aria-disabled` set.
@@ -0,0 +1,248 @@
1
+ import React, { useMemo } from 'react';
2
+ import { Pagination } from '@patternfly/react-core';
3
+ import { BrowserRouter, useSearchParams } from 'react-router-dom';
4
+ import { TreeViewDataItem } from '@patternfly/react-core';
5
+ import { useDataViewFilters, useDataViewPagination } from '@patternfly/react-data-view/dist/dynamic/Hooks';
6
+ import { DataView } from '@patternfly/react-data-view/dist/dynamic/DataView';
7
+ import { DataViewTable } from '@patternfly/react-data-view/dist/dynamic/DataViewTable';
8
+ import { DataViewToolbar } from '@patternfly/react-data-view/dist/dynamic/DataViewToolbar';
9
+ import { DataViewFilters } from '@patternfly/react-data-view/dist/dynamic/DataViewFilters';
10
+ import { DataViewTreeFilter } from '@patternfly/react-data-view/dist/dynamic/DataViewTreeFilter';
11
+
12
+ const perPageOptions = [
13
+ { title: '5', value: 5 },
14
+ { title: '10', value: 10 }
15
+ ];
16
+
17
+ interface Repository {
18
+ name: string;
19
+ workspace: string;
20
+ tags: string[];
21
+ os: string;
22
+ lastSeen: string;
23
+ }
24
+
25
+ interface RepositoryFilters {
26
+ name: string;
27
+ workspace: string[];
28
+ os: string[];
29
+ tags: string[];
30
+ }
31
+
32
+ const repositories: Repository[] = [
33
+ { name: 'Server-001', workspace: 'Development Workspace', tags: ['web', 'frontend'], os: 'Ubuntu 22.04', lastSeen: '2 hours ago' },
34
+ { name: 'Server-002', workspace: 'Development Workspace', tags: ['api', 'backend'], os: 'RHEL 9', lastSeen: '5 hours ago' },
35
+ { name: 'Server-003', workspace: 'Development Workspace', tags: ['database'], os: 'Windows Server 2022', lastSeen: '1 day ago' },
36
+ { name: 'Server-004', workspace: 'Production Workspace', tags: ['web', 'frontend'], os: 'Ubuntu 22.04', lastSeen: '30 minutes ago' },
37
+ { name: 'Server-005', workspace: 'Production Workspace', tags: ['api', 'backend'], os: 'Debian 12', lastSeen: '1 hour ago' },
38
+ { name: 'Server-006', workspace: 'Production Workspace', tags: ['monitoring'], os: 'macOS Ventura', lastSeen: '3 hours ago' },
39
+ { name: 'Server-007', workspace: 'Production Workspace', tags: ['cache'], os: 'macOS Sonoma', lastSeen: '2 days ago' },
40
+ { name: 'Server-008', workspace: 'Testing Workspace', tags: ['test', 'frontend'], os: 'CentOS 8', lastSeen: '6 hours ago' },
41
+ { name: 'Server-009', workspace: 'Testing Workspace', tags: ['test', 'backend'], os: 'Fedora 38', lastSeen: '4 hours ago' }
42
+ ];
43
+
44
+
45
+ const osOptions: TreeViewDataItem[] = [
46
+ {
47
+ name: 'Linux',
48
+ id: 'os-linux',
49
+ checkProps: { 'aria-label': 'linux-check', checked: false },
50
+ children: [
51
+ {
52
+ name: 'Ubuntu 22.04',
53
+ id: 'os-ubuntu',
54
+ checkProps: { checked: false }
55
+ },
56
+ {
57
+ name: 'RHEL 9',
58
+ id: 'os-rhel',
59
+ checkProps: { checked: false }
60
+ },
61
+ {
62
+ name: 'Debian 12',
63
+ id: 'os-debian',
64
+ checkProps: { checked: false }
65
+ },
66
+ {
67
+ name: 'CentOS 8',
68
+ id: 'os-centos',
69
+ checkProps: { checked: false }
70
+ },
71
+ {
72
+ name: 'Fedora 38',
73
+ id: 'os-fedora',
74
+ checkProps: { checked: false }
75
+ }
76
+ ],
77
+ defaultExpanded: true
78
+ },
79
+ {
80
+ name: 'Windows',
81
+ id: 'os-windows',
82
+ checkProps: { 'aria-label': 'windows-check', checked: false },
83
+ children: [
84
+ {
85
+ name: 'Windows Server 2022',
86
+ id: 'os-windows-2022',
87
+ checkProps: { checked: false }
88
+ }
89
+ ]
90
+ },
91
+ {
92
+ name: 'macOS',
93
+ id: 'os-macos',
94
+ checkProps: { 'aria-label': 'macos-check', checked: false },
95
+ children: [
96
+ {
97
+ name: 'macOS Ventura',
98
+ id: 'os-macos-ventura',
99
+ checkProps: { checked: false }
100
+ },
101
+ {
102
+ name: 'macOS Sonoma',
103
+ id: 'os-macos-sonoma',
104
+ checkProps: { checked: false }
105
+ }
106
+ ]
107
+ }
108
+ ];
109
+
110
+ const tagOptions: TreeViewDataItem[] = [
111
+ {
112
+ name: 'Environment',
113
+ id: 'tags-env',
114
+ checkProps: { 'aria-label': 'env-check', checked: false },
115
+ children: [
116
+ {
117
+ name: 'web',
118
+ id: 'tag-web',
119
+ checkProps: { checked: false }
120
+ },
121
+ {
122
+ name: 'api',
123
+ id: 'tag-api',
124
+ checkProps: { checked: false }
125
+ },
126
+ {
127
+ name: 'database',
128
+ id: 'tag-database',
129
+ checkProps: { checked: false }
130
+ }
131
+ ],
132
+ defaultExpanded: true
133
+ },
134
+ {
135
+ name: 'Layer',
136
+ id: 'tags-layer',
137
+ checkProps: { 'aria-label': 'layer-check', checked: false },
138
+ children: [
139
+ {
140
+ name: 'frontend',
141
+ id: 'tag-frontend',
142
+ checkProps: { checked: false }
143
+ },
144
+ {
145
+ name: 'backend',
146
+ id: 'tag-backend',
147
+ checkProps: { checked: false }
148
+ }
149
+ ]
150
+ },
151
+ {
152
+ name: 'Other',
153
+ id: 'tags-other',
154
+ checkProps: { 'aria-label': 'other-check', checked: false },
155
+ children: [
156
+ {
157
+ name: 'monitoring',
158
+ id: 'tag-monitoring',
159
+ checkProps: { checked: false }
160
+ },
161
+ {
162
+ name: 'cache',
163
+ id: 'tag-cache',
164
+ checkProps: { checked: false }
165
+ },
166
+ {
167
+ name: 'test',
168
+ id: 'tag-test',
169
+ checkProps: { checked: false }
170
+ }
171
+ ]
172
+ }
173
+ ];
174
+
175
+ const columns = ['Name', 'Workspace', 'Tags', 'OS', 'Last seen'];
176
+
177
+ const ouiaId = 'TreeFilterExample';
178
+
179
+ const MyTable: React.FunctionComponent = () => {
180
+ const [searchParams, setSearchParams] = useSearchParams();
181
+ const { filters, onSetFilters, clearAllFilters } = useDataViewFilters<RepositoryFilters>({
182
+ initialFilters: { name: '', workspace: [], os: [], tags: [] },
183
+ searchParams,
184
+ setSearchParams,
185
+ });
186
+ const pagination = useDataViewPagination({ perPage: 5 });
187
+ const { page, perPage } = pagination;
188
+
189
+ const filteredData = useMemo(
190
+ () =>
191
+ repositories.filter(
192
+ (item) =>
193
+ (!filters.name || item.name?.toLocaleLowerCase().includes(filters.name?.toLocaleLowerCase())) &&
194
+ (!filters.workspace || filters.workspace.length === 0 || filters.workspace.includes(item.workspace)) &&
195
+ (!filters.os || filters.os.length === 0 || filters.os.includes(item.os)) &&
196
+ (!filters.tags || filters.tags.length === 0 || filters.tags.some(tag => item.tags.includes(tag)))
197
+ ),
198
+ [filters]
199
+ );
200
+
201
+ const pageRows = useMemo(
202
+ () =>
203
+ filteredData
204
+ .slice((page - 1) * perPage, (page - 1) * perPage + perPage)
205
+ .map((item) => [item.name, item.workspace, item.tags.join(', '), item.os, item.lastSeen]),
206
+ [page, perPage, filteredData]
207
+ );
208
+
209
+ return (
210
+ <DataView>
211
+ <DataViewToolbar
212
+ ouiaId="TreeFilterExampleHeader"
213
+ clearAllFilters={clearAllFilters}
214
+ pagination={<Pagination perPageOptions={perPageOptions} itemCount={filteredData.length} {...pagination} />}
215
+ filters={
216
+ <DataViewFilters onChange={(_e, values) => onSetFilters(values)} values={filters}>
217
+ <DataViewTreeFilter
218
+ filterId="os"
219
+ title="Operating System"
220
+ items={osOptions}
221
+ defaultExpanded={false}
222
+ />
223
+ <DataViewTreeFilter
224
+ filterId="tags"
225
+ title="Tags"
226
+ items={tagOptions}
227
+ defaultExpanded={false}
228
+ defaultSelected={['tag-web', 'tag-api']}
229
+ />
230
+ </DataViewFilters>
231
+ }
232
+ />
233
+ <DataViewTable aria-label="Repositories table" ouiaId={ouiaId} columns={columns} rows={pageRows} />
234
+ <DataViewToolbar
235
+ ouiaId="TreeFilterExampleFooter"
236
+ pagination={
237
+ <Pagination isCompact variant="bottom" perPageOptions={perPageOptions} itemCount={filteredData.length} {...pagination} />
238
+ }
239
+ />
240
+ </DataView>
241
+ );
242
+ };
243
+
244
+ export const TreeFilterExample: React.FunctionComponent = () => (
245
+ <BrowserRouter>
246
+ <MyTable />
247
+ </BrowserRouter>
248
+ );