From 19a7e696fdca4d1d23624b1a39e6a5f34e982887 Mon Sep 17 00:00:00 2001 From: Aleksi Hietanen Date: Tue, 23 May 2017 16:14:34 +0300 Subject: Make select all work with TreeGrid (#9412) Fixes #9403 --- .../components/grid/MultiSelectionModelImpl.java | 63 ++++++++++++++++++++-- .../components/treegrid/TreeGridBasicFeatures.java | 13 +++++ .../components/treegrid/TreeGridSelectTest.java | 60 +++++++++++++++++++++ 3 files changed, 133 insertions(+), 3 deletions(-) create mode 100644 uitest/src/test/java/com/vaadin/tests/components/treegrid/TreeGridSelectTest.java diff --git a/server/src/main/java/com/vaadin/ui/components/grid/MultiSelectionModelImpl.java b/server/src/main/java/com/vaadin/ui/components/grid/MultiSelectionModelImpl.java index 01635302f0..289db2a04f 100644 --- a/server/src/main/java/com/vaadin/ui/components/grid/MultiSelectionModelImpl.java +++ b/server/src/main/java/com/vaadin/ui/components/grid/MultiSelectionModelImpl.java @@ -29,6 +29,8 @@ import java.util.stream.Stream; import com.vaadin.data.provider.DataCommunicator; import com.vaadin.data.provider.DataProvider; +import com.vaadin.data.provider.HierarchicalDataProvider; +import com.vaadin.data.provider.HierarchicalQuery; import com.vaadin.data.provider.Query; import com.vaadin.event.selection.MultiSelectionEvent; import com.vaadin.event.selection.MultiSelectionListener; @@ -312,14 +314,69 @@ public class MultiSelectionModelImpl extends AbstractSelectionModel getState().allSelected = true; } - DataProvider dataSource = getGrid().getDataProvider(); + Stream allItemsStream; + DataProvider dataProvider = getGrid().getDataProvider(); // this will fetch everything from backend - Stream stream = dataSource.fetch(new Query<>()); + if (dataProvider instanceof HierarchicalDataProvider) { + allItemsStream = fetchAllHierarchical( + (HierarchicalDataProvider) dataProvider); + } else { + allItemsStream = fetchAll(dataProvider); + } LinkedHashSet allItems = new LinkedHashSet<>(); - stream.forEach(allItems::add); + allItemsStream.forEach(allItems::add); updateSelection(allItems, Collections.emptySet(), userOriginated); } + /** + * Fetch all items from the given hierarchical data provider. + * + * @since 8.1 + * @param dataProvider + * the data provider to fetch from + * @return all items in the data provider + */ + private Stream fetchAllHierarchical( + HierarchicalDataProvider dataProvider) { + return fetchAllDescendants(null, dataProvider); + } + + /** + * Fetch all the descendants of the given parent item from the given data + * provider. + * + * @since 8.1 + * @param parent + * the parent item to fetch descendants for + * @param dataProvider + * the data provider to fetch from + * @return the stream of all descendant items + */ + private Stream fetchAllDescendants(T parent, + HierarchicalDataProvider dataProvider) { + List children = dataProvider + .fetchChildren(new HierarchicalQuery<>(null, parent)) + .collect(Collectors.toList()); + if (children.isEmpty()) { + return Stream.empty(); + } + return children.stream() + .flatMap(child -> Stream.concat(Stream.of(child), + fetchAllDescendants(child, dataProvider))); + } + + /** + * Fetch all items from the given data provider. + * + * @since 8.1 + * @param dataProvider + * the data provider to fetch from + * @return all items in this data provider + */ + private Stream fetchAll(DataProvider dataProvider) { + return dataProvider.fetch(new Query<>()); + } + /** * Triggered when the user unchecks the select all checkbox. * diff --git a/uitest/src/main/java/com/vaadin/tests/components/treegrid/TreeGridBasicFeatures.java b/uitest/src/main/java/com/vaadin/tests/components/treegrid/TreeGridBasicFeatures.java index 911c13f449..0c29f71294 100644 --- a/uitest/src/main/java/com/vaadin/tests/components/treegrid/TreeGridBasicFeatures.java +++ b/uitest/src/main/java/com/vaadin/tests/components/treegrid/TreeGridBasicFeatures.java @@ -17,6 +17,7 @@ import com.vaadin.server.SerializablePredicate; import com.vaadin.shared.Range; import com.vaadin.tests.components.AbstractComponentTest; import com.vaadin.tests.data.bean.HierarchicalTestBean; +import com.vaadin.ui.Grid.SelectionMode; import com.vaadin.ui.ItemCollapseAllowedProvider; import com.vaadin.ui.TreeGrid; @@ -68,6 +69,7 @@ public class TreeGridBasicFeatures extends AbstractComponentTest { createExpandMenu(); createCollapseMenu(); createListenerMenu(); + createSelectionModeMenu(); } private void initializeDataProviders() { @@ -137,6 +139,7 @@ public class TreeGridBasicFeatures extends AbstractComponentTest { (treeGrid, value, data) -> treeGrid.setHierarchyColumn(value)); } + @SuppressWarnings("unchecked") private void createCollapseAllowedSelect() { LinkedHashMap> options = new LinkedHashMap<>(); options.put("all allowed", t -> true); @@ -190,4 +193,14 @@ public class TreeGridBasicFeatures extends AbstractComponentTest { + event.isUserOriginated() + "): " + event.getExpandedItem()))); } + + private void createSelectionModeMenu() { + LinkedHashMap options = new LinkedHashMap<>(); + options.put("none", SelectionMode.NONE); + options.put("single", SelectionMode.SINGLE); + options.put("multi", SelectionMode.MULTI); + + createSelectAction("Selection mode", "State", options, "single", + (treeGrid, value, data) -> treeGrid.setSelectionMode(value)); + } } diff --git a/uitest/src/test/java/com/vaadin/tests/components/treegrid/TreeGridSelectTest.java b/uitest/src/test/java/com/vaadin/tests/components/treegrid/TreeGridSelectTest.java new file mode 100644 index 0000000000..e167dc6ac5 --- /dev/null +++ b/uitest/src/test/java/com/vaadin/tests/components/treegrid/TreeGridSelectTest.java @@ -0,0 +1,60 @@ +package com.vaadin.tests.components.treegrid; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.testbench.By; +import com.vaadin.testbench.elements.TreeGridElement; +import com.vaadin.tests.tb3.SingleBrowserTest; + +public class TreeGridSelectTest extends SingleBrowserTest { + + @Override + public Class getUIClass() { + return TreeGridBasicFeatures.class; + } + + @Test + public void select_and_deselect_all() { + openTestURL(); + + selectMenuPath("Component", "Features", "Set data provider", + "TreeDataProvider"); + selectMenuPath("Component", "State", "Selection mode", "multi"); + + TreeGridElement grid = $(TreeGridElement.class).first(); + + assertAllRowsDeselected(grid); + clickSelectAll(grid); + assertAllRowsSelected(grid); + grid.expandWithClick(1, 1); + grid.expandWithClick(2, 1); + assertAllRowsSelected(grid); + clickSelectAll(grid); + assertAllRowsDeselected(grid); + clickSelectAll(grid); + grid.collapseWithClick(2, 1); + grid.expandWithClick(2, 1); + assertAllRowsSelected(grid); + grid.collapseWithClick(2, 1); + clickSelectAll(grid); + grid.expandWithClick(2, 1); + assertAllRowsDeselected(grid); + } + + private void assertAllRowsSelected(TreeGridElement grid) { + for (int i = 0; i < grid.getRowCount(); i++) { + Assert.assertTrue(grid.getRow(i).isSelected()); + } + } + + private void assertAllRowsDeselected(TreeGridElement grid) { + for (int i = 0; i < grid.getRowCount(); i++) { + Assert.assertFalse(grid.getRow(i).isSelected()); + } + } + + private void clickSelectAll(TreeGridElement grid) { + grid.getHeaderCell(0, 0).findElement(By.tagName("input")).click(); + } +} -- cgit v1.2.3