diff --git a/client/src/common/MenuBar.tsx b/client/src/common/MenuBar.tsx index c7e788991..7677e50fc 100644 --- a/client/src/common/MenuBar.tsx +++ b/client/src/common/MenuBar.tsx @@ -222,7 +222,7 @@ const MenuBar: React.FC = function ({ filter, setFilter }) { borderColor={ PythonFilter.fromFilterBoxInput( filter, - )?.isFiltering() + )?.isFilteringModules() ? 'green' : 'inherit' } @@ -230,7 +230,7 @@ const MenuBar: React.FC = function ({ filter, setFilter }) { /> {PythonFilter.fromFilterBoxInput( filter, - )?.isFiltering() && ( + )?.isFilteringModules() && ( diff --git a/client/src/features/packageData/model/PythonClass.ts b/client/src/features/packageData/model/PythonClass.ts index 8761402c5..91ba54115 100644 --- a/client/src/features/packageData/model/PythonClass.ts +++ b/client/src/features/packageData/model/PythonClass.ts @@ -66,7 +66,7 @@ export default class PythonClass extends PythonDeclaration { } filter(pythonFilter: PythonFilter | void): PythonClass { - if (!pythonFilter) { + if (!pythonFilter || !pythonFilter.isFilteringFunctions()) { return this; } @@ -78,7 +78,10 @@ export default class PythonClass extends PythonDeclaration { .toLowerCase() .includes( (pythonFilter.pythonFunction || '').toLowerCase(), - ) && !isEmptyList(it.parameters), + ) && + // Don't exclude functions without parameters when we don't filter parameters + (!pythonFilter.isFilteringParameters() || + !isEmptyList(it.parameters)), ); return new PythonClass( diff --git a/client/src/features/packageData/model/PythonFilter.ts b/client/src/features/packageData/model/PythonFilter.ts index 818de954f..573893299 100644 --- a/client/src/features/packageData/model/PythonFilter.ts +++ b/client/src/features/packageData/model/PythonFilter.ts @@ -70,7 +70,7 @@ export class PythonFilter { ); } - isFiltering(): boolean { + isFilteringModules(): boolean { return ( Boolean(this.pythonModule) || Boolean(this.pythonClass) || @@ -78,4 +78,20 @@ export class PythonFilter { Boolean(this.pythonParameter) ); } + + isFilteringClasses(): boolean { + return ( + Boolean(this.pythonClass) || + Boolean(this.pythonFunction) || + Boolean(this.pythonParameter) + ); + } + + isFilteringFunctions(): boolean { + return Boolean(this.pythonFunction) || Boolean(this.pythonParameter); + } + + isFilteringParameters(): boolean { + return Boolean(this.pythonParameter); + } } diff --git a/client/src/features/packageData/model/PythonFunction.ts b/client/src/features/packageData/model/PythonFunction.ts index fb12d6f9a..9083be666 100644 --- a/client/src/features/packageData/model/PythonFunction.ts +++ b/client/src/features/packageData/model/PythonFunction.ts @@ -91,7 +91,7 @@ export default class PythonFunction extends PythonDeclaration { } filter(pythonFilter: PythonFilter | void): PythonFunction { - if (!pythonFilter) { + if (!pythonFilter || !pythonFilter.isFilteringParameters()) { return this; } diff --git a/client/src/features/packageData/model/PythonModule.ts b/client/src/features/packageData/model/PythonModule.ts index 356bc9a2c..f026c10f8 100644 --- a/client/src/features/packageData/model/PythonModule.ts +++ b/client/src/features/packageData/model/PythonModule.ts @@ -54,7 +54,8 @@ export default class PythonModule extends PythonDeclaration { } filter(pythonFilter: PythonFilter | void): PythonModule { - if (!pythonFilter) { + // isFilteringClasses is also true if we are filtering functions + if (!pythonFilter || !pythonFilter.isFilteringClasses()) { return this; } @@ -66,7 +67,10 @@ export default class PythonModule extends PythonDeclaration { .toLowerCase() .includes( (pythonFilter.pythonClass || '').toLowerCase(), - ) && !isEmptyList(it.methods), + ) && + // Don't exclude empty classes when we only filter modules or classes + (!pythonFilter.isFilteringFunctions() || + !isEmptyList(it.methods)), ); const functions = this.functions @@ -79,7 +83,9 @@ export default class PythonModule extends PythonDeclaration { .includes( (pythonFilter.pythonFunction || '').toLowerCase(), ) && - !isEmptyList(it.parameters), + // Don't exclude functions without parameters when we don't filter parameters + (!pythonFilter.isFilteringParameters() || + !isEmptyList(it.parameters)), ); return new PythonModule( diff --git a/client/src/features/packageData/model/PythonPackage.ts b/client/src/features/packageData/model/PythonPackage.ts index 0f6199130..11dddd2c8 100644 --- a/client/src/features/packageData/model/PythonPackage.ts +++ b/client/src/features/packageData/model/PythonPackage.ts @@ -31,7 +31,7 @@ export default class PythonPackage extends PythonDeclaration { } filter(pythonFilter: PythonFilter | void): PythonPackage { - if (!pythonFilter) { + if (!pythonFilter || !pythonFilter.isFilteringModules()) { return this; } @@ -44,7 +44,10 @@ export default class PythonPackage extends PythonDeclaration { .includes( (pythonFilter.pythonModule || '').toLowerCase(), ) && - (!isEmptyList(it.classes) || !isEmptyList(it.functions)), + // Don't exclude empty modules when we only filter modules + (!pythonFilter.isFilteringClasses() || + !isEmptyList(it.classes) || + !isEmptyList(it.functions)), ); return new PythonPackage(this.name, modules); diff --git a/client/src/features/packageData/treeView/TreeNode.tsx b/client/src/features/packageData/treeView/TreeNode.tsx index 77009f7ab..428fb6ad0 100644 --- a/client/src/features/packageData/treeView/TreeNode.tsx +++ b/client/src/features/packageData/treeView/TreeNode.tsx @@ -19,7 +19,6 @@ interface TreeNodeProps extends ChildrenProp { } const TreeNode: React.FC = function ({ - children, declaration, icon, isExpandable, @@ -47,25 +46,22 @@ const TreeNode: React.FC = function ({ }; return ( - <> - - - - {declaration.name} - - {showChildren && children} - + + + + {declaration.name} + ); }; diff --git a/client/src/features/packageData/treeView/TreeView.tsx b/client/src/features/packageData/treeView/TreeView.tsx index fce1c9fad..a43dcc08f 100644 --- a/client/src/features/packageData/treeView/TreeView.tsx +++ b/client/src/features/packageData/treeView/TreeView.tsx @@ -31,7 +31,7 @@ const TreeView: React.FC = memo(({ pythonPackage }) => { const dispatch = useAppDispatch(); const allExpanded = useAppSelector(selectAllExpandedInTreeView); - const children = walkChildrenWithPreOrder(allExpanded, pythonPackage); + const children = walkChildrenInPreorder(allExpanded, pythonPackage); const previousScrollOffset = useAppSelector(selectTreeViewScrollOffset); // Keep a reference to the last FixedSizeList before everything is dismounted @@ -85,13 +85,16 @@ const TreeView: React.FC = memo(({ pythonPackage }) => { ); }); -const walkChildrenWithPreOrder = function ( - allExpandedInTreeView: { [target: string]: true }, +const walkChildrenInPreorder = function ( + allExpandedItemsInTreeView: { [target: string]: true }, declaration: PythonDeclaration, ): PythonDeclaration[] { return declaration.children().flatMap((it) => { - if (allExpandedInTreeView[it.pathAsString()]) { - return [it, ...walkChildrenWithPreOrder(allExpandedInTreeView, it)]; + if (allExpandedItemsInTreeView[it.pathAsString()]) { + return [ + it, + ...walkChildrenInPreorder(allExpandedItemsInTreeView, it), + ]; } else { return [it]; }