From 4946c6493812c293ca912f825098aacf35a6918e Mon Sep 17 00:00:00 2001 From: "Ahmad K. Bawaneh" Date: Wed, 19 Feb 2025 19:37:06 +0300 Subject: [PATCH] fix #1013 Tree filter does not work for more than two layers --- .../domino/ui/collapsible/Collapsible.java | 24 ++---- .../domino/ui/tree/IsParentNode.java | 17 +++++ .../dominokit/domino/ui/tree/TreeNode.java | 76 +++++++++++++++++-- .../dominokit/domino/ui/tree/TreeRoot.java | 24 +++++- 4 files changed, 115 insertions(+), 26 deletions(-) diff --git a/domino-ui/src/main/java/org/dominokit/domino/ui/collapsible/Collapsible.java b/domino-ui/src/main/java/org/dominokit/domino/ui/collapsible/Collapsible.java index d082dd48..bc2f6d75 100644 --- a/domino-ui/src/main/java/org/dominokit/domino/ui/collapsible/Collapsible.java +++ b/domino-ui/src/main/java/org/dominokit/domino/ui/collapsible/Collapsible.java @@ -33,10 +33,6 @@ */ public class Collapsible implements IsElement, IsCollapsible { - /** Constant DUI_SCROLL_HEIGHT="dui-scroll-height" */ - public static final String DUI_SCROLL_HEIGHT = "dui-scroll-height"; - /** Constant DUI_COLLAPSE_HEIGHT="dom-ui-collapse-height" */ - public static final String DUI_COLLAPSE_HEIGHT = "dom-ui-collapse-height"; /** Constant DUI_COLLAPSED="dui-collapsed" */ public static final String DUI_COLLAPSED = "dui-collapsed"; @@ -51,7 +47,6 @@ public class Collapsible implements IsElement, IsCollapsible expandHandlers = new ArrayList<>(); private List beforeExpandHandlers = new ArrayList<>(); private CollapseStrategy strategy = new DisplayCollapseStrategy(); - private boolean expandingCollapsing = false; /** * Creates a collapsible wrapping the element @@ -138,8 +133,7 @@ public Collapsible setForceCollapsed(boolean forceHidden) { */ @Override public Collapsible expand() { - if (!forceHidden && isCollapsed() && !expandingCollapsing) { - expandingCollapsing = true; + if (!forceHidden && isCollapsed()) { strategy.expand(element); element.setAttribute("aria-expanded", "true"); this.collapsed = false; @@ -154,8 +148,7 @@ public Collapsible expand() { */ @Override public Collapsible collapse() { - if (!forceHidden && !isCollapsed() && !expandingCollapsing) { - expandingCollapsing = true; + if (!forceHidden && !isCollapsed()) { strategy.collapse(element); element.setAttribute("aria-expanded", "false"); this.collapsed = true; @@ -164,7 +157,6 @@ public Collapsible collapse() { } private void onCollapseCompleted() { - expandingCollapsing = false; if (nonNull(collapseHandlers)) { collapseHandlers.forEach(CollapseHandler::apply); } @@ -177,7 +169,6 @@ private void onBeforeCollapse() { } private void onExpandCompleted() { - expandingCollapsing = false; if (nonNull(expandHandlers)) { expandHandlers.forEach(ExpandHandler::apply); } @@ -206,14 +197,11 @@ public boolean isCollapsed() { */ @Override public Collapsible toggleCollapse() { - if (!expandingCollapsing) { - if (isCollapsed()) { - expand(); - } else { - collapse(); - } + if (isCollapsed()) { + expand(); + } else { + collapse(); } - return this; } diff --git a/domino-ui/src/main/java/org/dominokit/domino/ui/tree/IsParentNode.java b/domino-ui/src/main/java/org/dominokit/domino/ui/tree/IsParentNode.java index 3a7b8632..bb4f314c 100644 --- a/domino-ui/src/main/java/org/dominokit/domino/ui/tree/IsParentNode.java +++ b/domino-ui/src/main/java/org/dominokit/domino/ui/tree/IsParentNode.java @@ -69,6 +69,23 @@ public interface IsParentNode, S> extends HasActi */ IsParentNode expandNode(boolean expandParent); + /** + * Expands this node to show its children (if any). Behavior may vary depending on the tree + * configuration (e.g., auto-collapse of siblings, etc.). + * + * @return this node (for method chaining) + */ + IsParentNode collapseNode(); + + /** + * Expands this node, optionally also expanding all parent nodes up the hierarchy. Useful for + * ensuring a path is fully visible from the root down to this node. + * + * @param expandParent if true, also expands parent nodes + * @return this node (for method chaining) + */ + IsParentNode collapseNode(boolean expandParent); + /** * Retrieves the filter logic that determines if this node (and its subtree) match certain * criteria (e.g., a search token). Often implemented at the root node, then inherited by diff --git a/domino-ui/src/main/java/org/dominokit/domino/ui/tree/TreeNode.java b/domino-ui/src/main/java/org/dominokit/domino/ui/tree/TreeNode.java index e8200ece..b6a179e2 100644 --- a/domino-ui/src/main/java/org/dominokit/domino/ui/tree/TreeNode.java +++ b/domino-ui/src/main/java/org/dominokit/domino/ui/tree/TreeNode.java @@ -95,6 +95,7 @@ public abstract class TreeNode, S> private final DivElement contentElement; private final LazyChild textElement; private final UListElement subTree; + private String lastSearchToken = ""; private V value; private OriginalState originalState; @@ -240,8 +241,14 @@ public TreeNode(Icon icon, V value) { * extend this method for further setup. */ protected void init() { - addBeforeCollapseListener(() -> updateIcon(true)); - addBeforeExpandListener(() -> updateIcon(false)); + addBeforeCollapseListener( + () -> { + updateIcon(true); + }); + addBeforeExpandListener( + () -> { + updateIcon(false); + }); anchorElement.addClickListener(anchorListener); applyWaves(); } @@ -727,6 +734,17 @@ public N expandNode() { return show(false); } + /** + * Collapses this node (hiding children if any) by calling {@link #collapse()} from {@link + * Collapsible}. + * + * @return this node (for fluent API) + */ + @Override + public N collapseNode() { + return hide(false); + } + /** * Expands this node. If {@code expandParent} is {@code true}, also expands all ancestors. * @@ -738,6 +756,17 @@ public N expandNode(boolean expandParent) { return show(expandParent); } + /** + * Collapse this node. If {@code collapseParent} is {@code true}, also collapse all ancestors. + * + * @param collapseParent whether to collapse parent nodes too + * @return this node (for fluent API) + */ + @Override + public N collapseNode(boolean collapseParent) { + return hide(collapseParent); + } + /** * Ensures this node is shown (expanded) in the tree. Optionally expands the parent chain, then * calls {@link #expand()} if this node has children. @@ -753,6 +782,26 @@ public N show(boolean expandParent) { if (isParent()) { super.expand(); } + updateIcon(isCollapsed()); + return (N) this; + } + + /** + * Ensures this node is shown (collapsed) in the tree. Optionally collapses the parent chain, then + * calls {@link #collapse()} if this node has children. + * + * @param collapseParent if true, parent nodes are also expanded + * @return this node (for fluent API) + */ + public N hide(boolean collapseParent) { + if (collapseParent) { + getParent().ifPresent(itemParent -> itemParent.collapseNode(true)); + } + + if (isParent()) { + super.collapse(); + } + updateIcon(isCollapsed()); return (N) this; } @@ -783,13 +832,27 @@ public void clearFilter() { * @return true if this node or any child matches the search token, false otherwise */ public boolean filter(String searchToken) { + boolean found; - if (isNull(this.originalState)) { + if (lastSearchToken.isEmpty()) { this.originalState = new TreeNode.OriginalState(isExpanded()); } + this.lastSearchToken = searchToken; + if (searchToken.isEmpty()) { + if (this.originalState.expanded) { + expandNode(); + } else { + if (isParent()) { + collapseAll(); + } + } + dui_hidden.remove(this); + filterChildren(searchToken); + return true; + } if (isParent()) { - found = getFilter().filter((N) this, searchToken) | filterChildren(searchToken); + found = filterChildren(searchToken) | getFilter().filter((N) this, searchToken); } else { found = getFilter().filter((N) this, searchToken); } @@ -797,13 +860,12 @@ public boolean filter(String searchToken) { if (found) { dui_hidden.remove(this); if (isParent() && isAutoExpandFound() && isCollapsed()) { - this.expandNode(); + this.expandNode(true); } - return true; } else { addCss(dui_hidden); - return false; } + return found; } /** diff --git a/domino-ui/src/main/java/org/dominokit/domino/ui/tree/TreeRoot.java b/domino-ui/src/main/java/org/dominokit/domino/ui/tree/TreeRoot.java index 964f0b11..9cd67e9a 100644 --- a/domino-ui/src/main/java/org/dominokit/domino/ui/tree/TreeRoot.java +++ b/domino-ui/src/main/java/org/dominokit/domino/ui/tree/TreeRoot.java @@ -59,7 +59,7 @@ public abstract class TreeRoot, C extends TreeRoo private ToggleTarget toggleTarget = ToggleTarget.ANY; private CollapseStrategy collapseStrategy; private boolean autoCollapse = true; - private boolean autoExpandFound; + private boolean autoExpandFound = true; private LazyChild> collapseExpandAllIcon; private NodeIconSupplier iconSupplier; protected N activeNode; @@ -681,6 +681,28 @@ public C expandNode() { return (C) this; } + /** + * Collapse the node within the tree, indicating that it should be expanded or collapsed. This + * method has no effect on the root tree. + * + * @param collapseParent {@code true} to collapse the parent node, {@code false} to expand it. + * @return A reference to this tree. + */ + @Override + public C collapseNode(boolean collapseParent) { + return (C) this; + } + + /** + * Collapse the node within the tree. This method has no effect on the root tree. + * + * @return A reference to this tree. + */ + @Override + public C collapseNode() { + return (C) this; + } + /** * Pauses the selection listeners of the tree, preventing them from reacting to selection events. *