]> source.dussan.org Git - vaadin-framework.git/commitdiff
Fix Grid not using getId on select all
authorTeemu Suo-Anttila <teemusa@vaadin.com>
Thu, 26 Jul 2018 07:33:32 +0000 (10:33 +0300)
committerTeemu Suo-Anttila <tsuoanttila@users.noreply.github.com>
Mon, 30 Jul 2018 13:45:46 +0000 (16:45 +0300)
(cherry picked from commit 69c235f)

server/src/main/java/com/vaadin/ui/components/grid/MultiSelectionModelImpl.java
server/src/test/java/com/vaadin/tests/components/grid/GridMultiSelectionModelTest.java

index 3979a25a1a5d3334308a05816a1b56e8c9b2ed8d..408b133426ddc41a5c497ea8ff29e64b1062cd8e 100644 (file)
@@ -445,9 +445,15 @@ public class MultiSelectionModelImpl<T> extends AbstractSelectionModel<T>
         }
 
         doUpdateSelection(set -> {
+            DataProvider<T, ?> dataProvider = getGrid().getDataProvider();
             // order of add / remove does not matter since no duplicates
-            set.removeAll(removedItems);
-            set.addAll(addedItems);
+            Set<Object> removedItemIds = removedItems.stream()
+                    .map(dataProvider::getId).collect(Collectors.toSet());
+            set.removeIf(
+                    item -> removedItemIds.contains(dataProvider.getId(item)));
+            addedItems.stream().filter(
+                    item -> !selectionContainsId(dataProvider.getId(item)))
+                    .forEach(set::add);
 
             // refresh method is NOOP for items that are not present client side
             DataCommunicator<T> dataCommunicator = getGrid()
index 131dc2025bdc07e954478ea9ebb8a64ee1058e0e..7250f02dd3c78710ed5b2b4a04f919d9358f5e87 100644 (file)
@@ -17,8 +17,11 @@ import java.util.Optional;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicReference;
+import java.util.stream.Collectors;
 import java.util.stream.IntStream;
+import java.util.stream.Stream;
 
+import com.vaadin.data.provider.CallbackDataProvider;
 import org.easymock.Capture;
 import org.junit.Before;
 import org.junit.Test;
@@ -703,6 +706,34 @@ public class GridMultiSelectionModelTest {
         assertFalse(model.isSelectAllCheckBoxVisible());
         assertEquals(SelectAllCheckBoxVisibility.DEFAULT,
                 model.getSelectAllCheckBoxVisibility());
+    }
+
+    @Test
+    public void testSelectAllWithProxyDataProvider() {
+        List<String> data = IntStream.range(0, 100).boxed()
+                .map(i -> "String " + i).collect(Collectors.toList());
+        Grid<AtomicReference<String>> proxyGrid = new Grid<>();
+        proxyGrid.setDataProvider(new CallbackDataProvider<>(
+                q -> data.stream().map(AtomicReference::new).skip(q.getOffset())
+                        .limit(q.getLimit()),
+                q -> data.size(), AtomicReference::get));
+        MultiSelectionModel<AtomicReference<String>> model = (MultiSelectionModel<AtomicReference<String>>) proxyGrid
+                .setSelectionMode(SelectionMode.MULTI);
+        List<Set<AtomicReference<String>>> selections = new ArrayList<>();
+        model.addSelectionListener(e -> {
+            selections.add(e.getAllSelectedItems());
+        });
+        model.selectAll();
+        model.deselect(model.getFirstSelectedItem().orElseThrow(
+                () -> new IllegalStateException("Items should be selected")));
+        model.selectAll();
+
+        assertEquals("Item count mismatch on first select all", 100,
+                selections.get(0).size());
+        assertEquals("Item count mismatch on deselect", 99,
+                selections.get(1).size());
+        assertEquals("Item count mismatch on second select all", 100,
+                selections.get(2).size());
 
     }
 }