Skip to content

Commit c9fd2d8

Browse files
committed
fix: fixing lint errors
1 parent 5c863e2 commit c9fd2d8

File tree

2 files changed

+63
-72
lines changed

2 files changed

+63
-72
lines changed

packages/module/patternfly-docs/content/extensions/data-view/examples/Toolbar/TreeFilterExample.tsx

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -41,19 +41,6 @@ const repositories: Repository[] = [
4141
{ name: 'Server-009', workspace: 'Testing Workspace', tags: ['test', 'backend'], os: 'Fedora 38', lastSeen: '4 hours ago' }
4242
];
4343

44-
const treeOptions: TreeViewDataItem[] = [
45-
{
46-
name: 'Production Workspace',
47-
id: 'workspace-prod',
48-
checkProps: { 'aria-label': 'prod-workspace-check', checked: false }
49-
},
50-
{
51-
name: 'Testing Workspace',
52-
id: 'workspace-test',
53-
checkProps: { 'aria-label': 'test-workspace-check', checked: false }
54-
}
55-
];
56-
5744
const osOptions: TreeViewDataItem[] = [
5845
{
5946
name: 'Linux',
@@ -231,19 +218,13 @@ const MyTable: React.FunctionComponent = () => {
231218
title="Operating System"
232219
items={osOptions}
233220
defaultExpanded={true}
234-
onSelect={(selectedItems: TreeViewDataItem[]) => {
235-
console.log('Selected OS items:', selectedItems);
236-
}}
237221
/>
238222
<DataViewTreeFilter
239223
filterId="tags"
240224
title="Tags"
241225
items={tagOptions}
242226
defaultExpanded={false}
243227
defaultSelected={['tag-web', 'tag-api']}
244-
onSelect={(selectedItems: TreeViewDataItem[]) => {
245-
console.log('Selected tag items:', selectedItems);
246-
}}
247228
/>
248229
</DataViewFilters>
249230
}

packages/module/src/DataViewTreeFilter/DataViewTreeFilter.tsx

Lines changed: 63 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Dropdown, MenuToggle, MenuToggleElement, ToolbarFilter, ToolbarFilterProps, TreeView, TreeViewDataItem } from '@patternfly/react-core'
2-
import React, { FC, useState, useRef, useEffect } from 'react'
2+
import React, { FC, useState, useRef, useEffect, useCallback } from 'react'
33
import { createUseStyles } from 'react-jss'
44

55
/** This style is needed so the tree filter dropdown looks like the basic filter dropdow */
@@ -59,17 +59,16 @@ export const DataViewTreeFilter: FC<DataViewTreeFilterProps> = ({
5959
const hasCalledInitialOnChange = useRef(false);
6060

6161
// Helper function to expand all nodes in the tree
62-
const expandAllNodes = (items: TreeViewDataItem[]): TreeViewDataItem[] => {
63-
return items.map(item => ({
62+
const expandAllNodes = useCallback((items: TreeViewDataItem[]): TreeViewDataItem[] =>
63+
items.map(item => ({
6464
...item,
6565
defaultExpanded: true,
6666
children: item.children ? expandAllNodes(item.children) : undefined
67-
}));
68-
};
67+
})), []);
6968

7069
// Helper function to set pre-selected items
71-
const setPreSelectedItems = (items: TreeViewDataItem[], selectedIds: string[]): TreeViewDataItem[] => {
72-
return items.map(item => {
70+
const setPreSelectedItems = useCallback((items: TreeViewDataItem[], selectedIds: string[]): TreeViewDataItem[] =>
71+
items.map(item => {
7372
const isSelected = selectedIds.includes(String(item.id));
7473
const hasSelectedChildren = item.children?.some(child => selectedIds.includes(String(child.id))) ?? false;
7574

@@ -81,11 +80,10 @@ export const DataViewTreeFilter: FC<DataViewTreeFilterProps> = ({
8180
} : undefined,
8281
children: item.children ? setPreSelectedItems(item.children, selectedIds) : undefined
8382
};
84-
});
85-
};
83+
}), []);
8684

8785
// Generic helper to collect items from tree based on predicate
88-
const collectTreeItems = (
86+
const collectTreeItems = useCallback((
8987
items: TreeViewDataItem[],
9088
predicate: (item: TreeViewDataItem) => boolean,
9189
leafOnly = false
@@ -104,16 +102,25 @@ export const DataViewTreeFilter: FC<DataViewTreeFilterProps> = ({
104102

105103
items.forEach(item => collect(item));
106104
return collected;
107-
};
105+
}, []);
108106

109107
// Helper function to get all checked items (not just leaf nodes)
110-
const getAllCheckedItems = (items: TreeViewDataItem[]): TreeViewDataItem[] => {
111-
return collectTreeItems(items, item => item.checkProps?.checked === true, false);
112-
};
108+
const getAllCheckedItems = useCallback((items: TreeViewDataItem[]): TreeViewDataItem[] =>
109+
collectTreeItems(items, item => item.checkProps?.checked === true, false), [collectTreeItems]);
110+
111+
// Get all checked leaf items (returns array of names)
112+
const getAllCheckedLeafItems = useCallback((items: TreeViewDataItem[]): string[] =>
113+
collectTreeItems(
114+
items,
115+
item => item.checkProps?.checked === true,
116+
true
117+
).map(item => String(item.name)), [collectTreeItems]);
113118

114119
// Initialize tree data with defaultExpanded and defaultSelected (only on first mount)
115120
useEffect(() => {
116-
if (!items) return;
121+
if (!items) {
122+
return;
123+
}
117124

118125
let initializedData = [...items];
119126

@@ -132,7 +139,7 @@ export const DataViewTreeFilter: FC<DataViewTreeFilterProps> = ({
132139
if (isInitialMount.current) {
133140
isInitialMount.current = false;
134141
}
135-
}, [items, defaultExpanded]);
142+
}, [items, defaultExpanded, expandAllNodes, setPreSelectedItems, defaultSelected]);
136143

137144
// Call onChange and onSelect after tree data is initialized with default selections
138145
useEffect(() => {
@@ -156,7 +163,7 @@ export const DataViewTreeFilter: FC<DataViewTreeFilterProps> = ({
156163
hasCalledInitialOnChange.current = true;
157164
}
158165
}
159-
}, [treeData]);
166+
}, [treeData, defaultSelected.length, onChange, onSelect, getAllCheckedItems, getAllCheckedLeafItems]);
160167

161168
// Sync tree checkboxes when value prop changes (when clearAllFilters is called)
162169
useEffect(() => {
@@ -165,18 +172,17 @@ export const DataViewTreeFilter: FC<DataViewTreeFilterProps> = ({
165172

166173
// Only update if there are checked items that need to be unchecked
167174
if (currentCheckedItems.length > 0) {
168-
const uncheckRecursive = (items: TreeViewDataItem[]): TreeViewDataItem[] => {
169-
return items.map(item => ({
175+
const uncheckRecursive = (items: TreeViewDataItem[]): TreeViewDataItem[] =>
176+
items.map(item => ({
170177
...item,
171178
checkProps: item.checkProps ? { ...item.checkProps, checked: false } : undefined,
172179
children: item.children ? uncheckRecursive(item.children) : undefined
173180
}));
174-
};
175181

176182
setTreeData(uncheckRecursive(treeData));
177183
}
178184
}
179-
}, [value]);
185+
}, [value, treeData, getAllCheckedLeafItems]);
180186

181187
// Check if all children are checked (recursive)
182188
const areAllChildrenChecked = (item: TreeViewDataItem): boolean => {
@@ -202,7 +208,9 @@ export const DataViewTreeFilter: FC<DataViewTreeFilterProps> = ({
202208
}
203209
if (item.children) {
204210
const found = findItemByName(item.children, name);
205-
if (found) return found;
211+
if (found) {
212+
return found;
213+
}
206214
}
207215
}
208216
return null;
@@ -216,31 +224,32 @@ export const DataViewTreeFilter: FC<DataViewTreeFilterProps> = ({
216224
}
217225
if (item.children) {
218226
const found = findParentById(item.children, childId);
219-
if (found) return found;
227+
if (found) {
228+
return found;
229+
}
220230
}
221231
}
222232
return null;
223233
};
224234

225-
// Get all checked leaf items (returns array of names)
226-
const getAllCheckedLeafItems = (items: TreeViewDataItem[]): string[] => {
227-
return collectTreeItems(
228-
items,
229-
item => item.checkProps?.checked === true,
230-
true
231-
).map(item => String(item.name));
232-
};
233-
234235
// Update parent checkbox states based on children (recursive)
235236
const onCheckParentHandle = (childId: string): void => {
236237
const parent = findParentById(treeData, childId);
237-
if (!parent) return;
238+
if (!parent) {
239+
return;
240+
}
238241

239242
if (parent.checkProps) {
240243
const allChildrenChecked = areAllChildrenChecked(parent);
241244
const someChildrenChecked = areSomeChildrenChecked(parent);
242245

243-
parent.checkProps.checked = allChildrenChecked ? true : someChildrenChecked ? null : false;
246+
if (allChildrenChecked) {
247+
parent.checkProps.checked = true;
248+
} else if (someChildrenChecked) {
249+
parent.checkProps.checked = null;
250+
} else {
251+
parent.checkProps.checked = false;
252+
}
244253
}
245254

246255
if (parent.id) {
@@ -270,7 +279,7 @@ export const DataViewTreeFilter: FC<DataViewTreeFilterProps> = ({
270279
setTreeData(prev => [...prev]);
271280

272281
const selectedValues = getAllCheckedLeafItems(treeData);
273-
onChange?.(event as any, selectedValues);
282+
onChange?.(undefined, selectedValues);
274283

275284
if (onSelect) {
276285
const selectedItems = getAllCheckedItems(treeData);
@@ -281,7 +290,9 @@ export const DataViewTreeFilter: FC<DataViewTreeFilterProps> = ({
281290
// Clear a specific filter by name (when label chip is removed)
282291
const onFilterSelectorClear = (itemName: string) => {
283292
const treeViewItem = findItemByName(treeData, itemName);
284-
if (!treeViewItem) return;
293+
if (!treeViewItem) {
294+
return;
295+
}
285296

286297
onCheckHandle(treeViewItem, false);
287298
if (treeViewItem.id) {
@@ -291,13 +302,12 @@ export const DataViewTreeFilter: FC<DataViewTreeFilterProps> = ({
291302

292303
// Uncheck all items in the tree
293304
const uncheckAllItems = () => {
294-
const uncheckRecursive = (items: TreeViewDataItem[]): TreeViewDataItem[] => {
295-
return items.map(item => ({
305+
const uncheckRecursive = (items: TreeViewDataItem[]): TreeViewDataItem[] =>
306+
items.map(item => ({
296307
...item,
297308
checkProps: item.checkProps ? { ...item.checkProps, checked: false } : undefined,
298309
children: item.children ? uncheckRecursive(item.children) : undefined
299310
}));
300-
};
301311

302312
const updatedTreeData = uncheckRecursive(treeData);
303313
setTreeData(updatedTreeData);
@@ -329,20 +339,20 @@ export const DataViewTreeFilter: FC<DataViewTreeFilterProps> = ({
329339

330340
return (
331341
<ToolbarFilter
332-
key={filterId}
333-
data-ouia-component-id={ouiaId}
334-
labels={value.map(item => ({ key: item, node: item }))}
335-
deleteLabel={(_, label) => {
336-
const labelKey = typeof label === 'string' ? label : label.key;
337-
onChange?.(undefined, value.filter(item => item !== labelKey));
338-
onFilterSelectorClear(labelKey);
339-
}}
340-
deleteLabelGroup={uncheckAllItems}
341-
categoryName={title}
342-
showToolbarItem={showToolbarItem}>
343-
{dropdown}
344-
</ToolbarFilter>
342+
key={filterId}
343+
data-ouia-component-id={ouiaId}
344+
labels={value.map(item => ({ key: item, node: item }))}
345+
deleteLabel={(_, label) => {
346+
const labelKey = typeof label === 'string' ? label : label.key;
347+
onChange?.(undefined, value.filter(item => item !== labelKey));
348+
onFilterSelectorClear(labelKey);
349+
}}
350+
deleteLabelGroup={uncheckAllItems}
351+
categoryName={title}
352+
showToolbarItem={showToolbarItem}>
353+
{dropdown}
354+
</ToolbarFilter>
345355
)
346356
}
347357

348-
export default DataViewTreeFilter;
358+
export default DataViewTreeFilter;

0 commit comments

Comments
 (0)