@patternfly/react-data-view 5.5.0 → 5.6.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/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/DataViewFilters/DataViewFilters.d.ts +7 -1
- package/dist/cjs/DataViewFilters/DataViewFilters.js +16 -1
- package/dist/cjs/DataViewTableTree/DataViewTableTree.js +26 -14
- package/dist/cjs/DataViewTextFilter/DataViewTextFilter.js +1 -1
- package/dist/cjs/Hooks/filters.js +13 -14
- package/dist/cjs/index.d.ts +2 -0
- package/dist/cjs/index.js +4 -1
- package/dist/dynamic/DataViewCheckboxFilter/package.json +1 -0
- 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/DataViewFilters/DataViewFilters.d.ts +7 -1
- package/dist/esm/DataViewFilters/DataViewFilters.js +16 -1
- package/dist/esm/DataViewTableTree/DataViewTableTree.js +26 -14
- package/dist/esm/DataViewTextFilter/DataViewTextFilter.js +1 -1
- package/dist/esm/Hooks/filters.js +13 -14
- package/dist/esm/index.d.ts +2 -0
- package/dist/esm/index.js +2 -0
- package/package.json +1 -1
- package/patternfly-docs/content/extensions/data-view/examples/Functionality/FiltersExample.tsx +31 -16
- package/patternfly-docs/content/extensions/data-view/examples/Functionality/Functionality.md +4 -3
- package/src/DataViewCheckboxFilter/DataViewCheckboxFilter.test.tsx +24 -0
- package/src/DataViewCheckboxFilter/DataViewCheckboxFilter.tsx +175 -0
- package/src/DataViewCheckboxFilter/__snapshots__/DataViewCheckboxFilter.test.tsx.snap +194 -0
- package/src/DataViewCheckboxFilter/index.ts +2 -0
- package/src/DataViewFilters/DataViewFilters.tsx +26 -7
- package/src/DataViewTableTree/DataViewTableTree.tsx +39 -18
- package/src/DataViewTextFilter/DataViewTextFilter.tsx +1 -0
- package/src/Hooks/filters.ts +14 -13
- package/src/index.ts +3 -0
|
@@ -12,24 +12,45 @@ import { DataViewTableHead } from '../DataViewTableHead';
|
|
|
12
12
|
import { DataViewTh, DataViewTrTree, isDataViewTdObject } from '../DataViewTable';
|
|
13
13
|
import { DataViewState } from '../DataView/DataView';
|
|
14
14
|
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
15
|
+
const getNodesAffectedBySelection = (
|
|
16
|
+
allRows: DataViewTrTree[],
|
|
17
|
+
node: DataViewTrTree,
|
|
18
|
+
isChecking: boolean,
|
|
19
|
+
isSelected?: (item: DataViewTrTree) => boolean
|
|
20
|
+
): DataViewTrTree[] => {
|
|
21
|
+
|
|
22
|
+
const getDescendants = (node: DataViewTrTree): DataViewTrTree[] =>
|
|
23
|
+
node.children ? node.children.flatMap(getDescendants).concat(node) : [ node ];
|
|
24
|
+
|
|
25
|
+
const findParent = (child: DataViewTrTree, rows: DataViewTrTree[]): DataViewTrTree | undefined =>
|
|
26
|
+
rows.find(row => row.children?.some(c => c === child)) ??
|
|
27
|
+
rows.flatMap(row => row.children ?? []).map(c => findParent(child, [ c ])).find(p => p);
|
|
28
|
+
|
|
29
|
+
const getAncestors = (node: DataViewTrTree): DataViewTrTree[] => {
|
|
30
|
+
const ancestors: DataViewTrTree[] = [];
|
|
31
|
+
let parent = findParent(node, allRows);
|
|
32
|
+
while (parent) {
|
|
33
|
+
ancestors.push(parent);
|
|
34
|
+
parent = findParent(parent, allRows);
|
|
35
|
+
}
|
|
36
|
+
return ancestors;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const affectedNodes = new Set([ node, ...getDescendants(node) ]);
|
|
40
|
+
|
|
41
|
+
getAncestors(node).forEach(ancestor => {
|
|
42
|
+
const allChildrenSelected = ancestor.children?.every(child => isSelected?.(child) || affectedNodes.has(child));
|
|
43
|
+
const anyChildAffected = ancestor.children?.some(child => affectedNodes.has(child) || child.id === node.id);
|
|
44
|
+
|
|
45
|
+
if (isChecking ? !isSelected?.(ancestor) && allChildrenSelected : isSelected?.(ancestor) && anyChildAffected) {
|
|
46
|
+
affectedNodes.add(ancestor);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
return Array.from(affectedNodes);
|
|
31
51
|
};
|
|
32
52
|
|
|
53
|
+
|
|
33
54
|
/** extends TableProps */
|
|
34
55
|
export interface DataViewTableTreeProps extends Omit<TableProps, 'onSelect' | 'rows'> {
|
|
35
56
|
/** Columns definition */
|
|
@@ -83,7 +104,7 @@ export const DataViewTableTree: React.FC<DataViewTableTreeProps> = ({
|
|
|
83
104
|
}
|
|
84
105
|
const isExpanded = expandedNodeIds.includes(node.id);
|
|
85
106
|
const isDetailsExpanded = expandedDetailsNodeNames.includes(node.id);
|
|
86
|
-
const isChecked = isSelected
|
|
107
|
+
const isChecked = isSelected?.(node);
|
|
87
108
|
let icon = leafIcon;
|
|
88
109
|
if (node.children) {
|
|
89
110
|
icon = isExpanded ? expandedIcon : collapsedIcon;
|
|
@@ -100,7 +121,7 @@ export const DataViewTableTree: React.FC<DataViewTableTreeProps> = ({
|
|
|
100
121
|
const otherDetailsExpandedNodeIds = prevDetailsExpanded.filter(id => id !== node.id);
|
|
101
122
|
return isDetailsExpanded ? otherDetailsExpandedNodeIds : [ ...otherDetailsExpandedNodeIds, node.id ];
|
|
102
123
|
}),
|
|
103
|
-
onCheckChange: (isSelectDisabled?.(node) || !onSelect) ? undefined : (_event, isChecking) => onSelect?.(isChecking,
|
|
124
|
+
onCheckChange: (isSelectDisabled?.(node) || !onSelect) ? undefined : (_event, isChecking) => onSelect?.(isChecking, getNodesAffectedBySelection(rows, node, isChecking, isSelected)),
|
|
104
125
|
rowIndex,
|
|
105
126
|
props: {
|
|
106
127
|
isExpanded,
|
|
@@ -31,6 +31,7 @@ export const DataViewTextFilter: React.FC<DataViewTextFilterProps> = ({
|
|
|
31
31
|
...props
|
|
32
32
|
}: DataViewTextFilterProps) => (
|
|
33
33
|
<ToolbarFilter
|
|
34
|
+
key={ouiaId}
|
|
34
35
|
data-ouia-component-id={ouiaId}
|
|
35
36
|
chips={value.length > 0 ? [ { key: title, node: value } ] : []}
|
|
36
37
|
deleteChip={() => onChange?.(undefined, '')}
|
package/src/Hooks/filters.ts
CHANGED
|
@@ -16,15 +16,19 @@ export const useDataViewFilters = <T extends object>({
|
|
|
16
16
|
}: UseDataViewFiltersProps<T>) => {
|
|
17
17
|
const isUrlSyncEnabled = useMemo(() => searchParams && !!setSearchParams, [ searchParams, setSearchParams ]);
|
|
18
18
|
|
|
19
|
-
const getInitialFilters = useCallback((): T => isUrlSyncEnabled
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
: initialFilters[key as keyof T];
|
|
24
|
-
return loadedFilters;
|
|
25
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
26
|
-
}, { ...initialFilters }) : initialFilters, [ isUrlSyncEnabled, JSON.stringify(initialFilters), searchParams?.toString() ]);
|
|
19
|
+
const getInitialFilters = useCallback((): T => isUrlSyncEnabled
|
|
20
|
+
? Object.keys(initialFilters).reduce((loadedFilters, key) => {
|
|
21
|
+
const urlValue = searchParams?.get(key);
|
|
22
|
+
const isArrayFilter = Array.isArray(initialFilters[key]);
|
|
27
23
|
|
|
24
|
+
// eslint-disable-next-line no-nested-ternary
|
|
25
|
+
loadedFilters[key] = urlValue
|
|
26
|
+
? (isArrayFilter && !Array.isArray(urlValue) ? [ urlValue ] : urlValue)
|
|
27
|
+
: initialFilters[key];
|
|
28
|
+
|
|
29
|
+
return loadedFilters;
|
|
30
|
+
}, { ...initialFilters })
|
|
31
|
+
: initialFilters, [ isUrlSyncEnabled, initialFilters, searchParams ]);
|
|
28
32
|
const [ filters, setFilters ] = useState<T>(getInitialFilters());
|
|
29
33
|
|
|
30
34
|
const updateSearchParams = useCallback(
|
|
@@ -32,11 +36,8 @@ export const useDataViewFilters = <T extends object>({
|
|
|
32
36
|
if (isUrlSyncEnabled) {
|
|
33
37
|
const params = new URLSearchParams(searchParams);
|
|
34
38
|
Object.entries(newFilters).forEach(([ key, value ]) => {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
} else {
|
|
38
|
-
params.delete(key);
|
|
39
|
-
}
|
|
39
|
+
params.delete(key);
|
|
40
|
+
(Array.isArray(value) ? value : [ value ]).forEach((val) => value && params.append(key, val));
|
|
40
41
|
});
|
|
41
42
|
setSearchParams?.(params);
|
|
42
43
|
}
|
package/src/index.ts
CHANGED
|
@@ -25,5 +25,8 @@ export * from './DataViewTable';
|
|
|
25
25
|
export { default as DataViewEventsContext } from './DataViewEventsContext';
|
|
26
26
|
export * from './DataViewEventsContext';
|
|
27
27
|
|
|
28
|
+
export { default as DataViewCheckboxFilter } from './DataViewCheckboxFilter';
|
|
29
|
+
export * from './DataViewCheckboxFilter';
|
|
30
|
+
|
|
28
31
|
export { default as DataView } from './DataView';
|
|
29
32
|
export * from './DataView';
|