Skip to content

Commit 437e838

Browse files
vaadin-botvursen
andauthored
feat: add protected API to regenerate data in viewport (#23043) (#23045)
The PR adds a protected `refreshViewport` method to both DataCommunicator and HierarchicalDataCommunicator. This method regenerates and resends data for items that are currently visible in the viewport. Co-authored-by: Sergey Vinogradov <mr.vursen@gmail.com>
1 parent 079719e commit 437e838

File tree

4 files changed

+68
-0
lines changed

4 files changed

+68
-0
lines changed

flow-data/src/main/java/com/vaadin/flow/data/provider/DataCommunicator.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,14 @@ public void refresh(T data) {
435435
requestFlushUpdatedData();
436436
}
437437

438+
/**
439+
* Regenerates and resends data for all items in the current viewport.
440+
*/
441+
protected void refreshViewport() {
442+
resendEntireRange = true;
443+
requestFlush();
444+
}
445+
438446
/**
439447
* Confirm update with the given {@code updateId}.
440448
*

flow-data/src/main/java/com/vaadin/flow/data/provider/hierarchy/HierarchicalDataCommunicator.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,11 @@ public void refresh(T item, boolean refreshChildren) {
256256
requestFlush().invalidateItem(item);
257257
}
258258

259+
@Override
260+
protected void refreshViewport() {
261+
requestFlush().invalidateViewport();
262+
}
263+
259264
@Override
260265
public Stream<T> fetchFromProvider(int offset, int limit) {
261266
return fetchDataProviderChildren(null, Range.withLength(offset, limit))

flow-data/src/test/java/com/vaadin/flow/data/provider/DataCommunicatorTest.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import org.mockito.Mockito;
4242
import org.mockito.MockitoAnnotations;
4343
import tools.jackson.databind.JsonNode;
44+
import tools.jackson.databind.node.ObjectNode;
4445

4546
import com.vaadin.flow.component.Component;
4647
import com.vaadin.flow.component.ComponentEventListener;
@@ -246,6 +247,33 @@ public void reattach_same_roundtrip_refresh_nothing() {
246247
Assert.assertNull("Expected no communication after reattach", lastSet);
247248
}
248249

250+
@Test
251+
public void refreshViewport_updatedRangeSent() {
252+
var compositeDataGenerator = new CompositeDataGenerator<Item>();
253+
dataCommunicator = new DataCommunicator<>(compositeDataGenerator,
254+
arrayUpdater, data -> {
255+
}, element.getNode()) {
256+
};
257+
dataCommunicator.setDataProvider(createDataProvider(), null);
258+
dataCommunicator.setViewportRange(0, 6);
259+
260+
var count = new AtomicInteger(0);
261+
compositeDataGenerator.addDataGenerator(new DataGenerator<Item>() {
262+
@Override
263+
public void generateData(Item item, ObjectNode json) {
264+
json.put("count", String.valueOf(count.get()));
265+
}
266+
});
267+
268+
fakeClientCommunication();
269+
Assert.assertEquals(Range.withLength(0, 6), lastSet);
270+
lastSet = null;
271+
272+
dataCommunicator.refreshViewport();
273+
fakeClientCommunication();
274+
Assert.assertEquals(Range.withLength(0, 6), lastSet);
275+
}
276+
249277
@Test
250278
public void setFlushRequest_remove_setFlushRequest_reattach_noEndlessFlushLoop() {
251279
AtomicInteger listenerInvocationCounter = new AtomicInteger(0);

flow-data/src/test/java/com/vaadin/flow/data/provider/hierarchy/HierarchicalDataCommunicatorDataRefreshTest.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import java.util.Arrays;
1919
import java.util.Map;
20+
import java.util.concurrent.atomic.AtomicInteger;
2021

2122
import org.junit.Assert;
2223
import org.junit.Before;
@@ -362,4 +363,30 @@ public void refreshAllItems_allItemsRemovedFromKeyMapper() {
362363
Assert.assertFalse(keyMapper.has(new Item("Item 0-0")));
363364
Assert.assertFalse(keyMapper.has(new Item("Item 0-0-0")));
364365
}
366+
367+
@Test
368+
public void refreshViewport_updatedRangeSent() {
369+
populateTreeData(treeData, 6, 1, 1);
370+
dataCommunicator.expand(
371+
Arrays.asList(new Item("Item 1"), new Item("Item 1-0")));
372+
dataCommunicator.setViewportRange(0, 6);
373+
374+
var count = new AtomicInteger(0);
375+
compositeDataGenerator.addDataGenerator(new DataGenerator<Item>() {
376+
@Override
377+
public void generateData(Item item, ObjectNode json) {
378+
json.put("count", String.valueOf(count.get()));
379+
}
380+
});
381+
382+
fakeClientCommunication();
383+
assertArrayUpdateItems("count", "0", "0", "0", "0", "0", "0");
384+
385+
Mockito.clearInvocations(arrayUpdater, arrayUpdate);
386+
387+
count.incrementAndGet();
388+
dataCommunicator.refreshViewport();
389+
fakeClientCommunication();
390+
assertArrayUpdateItems("count", "1", "1", "1", "1", "1", "1");
391+
}
365392
}

0 commit comments

Comments
 (0)