Skip to content

Commit 77bff59

Browse files
authored
fix: prevent client updates when handling events from client (#6982)
* fix: prevent client updates when handling events from client * address sonar issue
1 parent 9a3fc8e commit 77bff59

4 files changed

Lines changed: 58 additions & 7 deletions

File tree

vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/main/java/com/vaadin/flow/component/dashboard/Dashboard.java

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@
6464
@NpmPackage(value = "@vaadin/dashboard", version = "24.7.0-alpha2")
6565
public class Dashboard extends Component implements HasWidgets, HasSize {
6666

67+
private static final ThreadLocal<Boolean> suppressClientUpdates = ThreadLocal
68+
.withInitial(() -> false);
69+
6770
private final List<Component> childrenComponents = new ArrayList<>();
6871

6972
private final DashboardChildDetachHandler childDetachHandler;
@@ -541,8 +544,17 @@ Component getItem(int nodeId) {
541544
}).filter(Objects::nonNull).findAny().orElseThrow();
542545
}
543546

547+
private void withoutClientUpdate(Runnable action) {
548+
suppressClientUpdates.set(true);
549+
try {
550+
action.run();
551+
} finally {
552+
suppressClientUpdates.remove();
553+
}
554+
}
555+
544556
void updateClient() {
545-
if (pendingUpdate) {
557+
if (suppressClientUpdates.get() || pendingUpdate) {
546558
return;
547559
}
548560
pendingUpdate = true;
@@ -661,7 +673,6 @@ private void initItemMovedClientEventListener() {
661673
return;
662674
}
663675
handleItemMovedClientEvent(e, itemKey, itemsKey, sectionKey);
664-
updateClient();
665676
}).addEventData(itemKey).addEventData(itemsKey)
666677
.addEventData(sectionKey);
667678
}
@@ -705,7 +716,6 @@ private void initItemResizedClientEventListener() {
705716
return;
706717
}
707718
handleItemResizedClientEvent(e, idKey, colspanKey, rowspanKey);
708-
updateClient();
709719
}).addEventData(idKey).addEventData(colspanKey)
710720
.addEventData(rowspanKey);
711721
}
@@ -718,8 +728,10 @@ private void handleItemResizedClientEvent(DomEvent e, String idKey,
718728
DashboardWidget resizedWidget = getWidgets().stream()
719729
.filter(child -> nodeId == child.getElement().getNode().getId())
720730
.findAny().orElseThrow();
721-
resizedWidget.setRowspan(rowspan);
722-
resizedWidget.setColspan(colspan);
731+
withoutClientUpdate(() -> {
732+
resizedWidget.setColspan(colspan);
733+
resizedWidget.setRowspan(rowspan);
734+
});
723735
fireEvent(new DashboardItemResizedEvent(this, true, resizedWidget,
724736
getChildren().toList()));
725737
}
@@ -731,14 +743,13 @@ private void initItemRemovedClientEventListener() {
731743
return;
732744
}
733745
handleItemRemovedClientEvent(e, idKey);
734-
updateClient();
735746
}).addEventData(idKey);
736747
}
737748

738749
private void handleItemRemovedClientEvent(DomEvent e, String idKey) {
739750
int nodeId = (int) e.getEventData().getNumber(idKey);
740751
Component removedItem = getItem(nodeId);
741-
removedItem.removeFromParent();
752+
withoutClientUpdate(removedItem::removeFromParent);
742753
fireEvent(new DashboardItemRemovedEvent(this, true, removedItem,
743754
getChildren().toList()));
744755
}

vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/test/java/com/vaadin/flow/component/dashboard/DashboardItemMoveTest.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,18 @@ public void setDashboardNotEditable_moveWidget_orderIsNotUpdated() {
8383
Assert.assertEquals(expectedRootLevelNodeIds, getRootLevelNodeIds());
8484
}
8585

86+
@Test
87+
public void moveWidget_noClientUpdate() {
88+
getUi().getInternals().dumpPendingJavaScriptInvocations();
89+
90+
assertRootLevelItemMoved(0, 1);
91+
92+
fakeClientCommunication();
93+
94+
Assert.assertTrue(getUi().getInternals()
95+
.dumpPendingJavaScriptInvocations().isEmpty());
96+
}
97+
8698
@Test
8799
public void moveWidget_eventCorrectlyFired() {
88100
int initialIndex = 0;

vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/test/java/com/vaadin/flow/component/dashboard/DashboardItemResizeTest.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,18 @@ public void setDashboardNotEditable_resizeWidget_sizeIsNotUpdated() {
7474
Assert.assertEquals(1, widgetToResize.getRowspan());
7575
}
7676

77+
@Test
78+
public void resizeWidget_noClientUpdate() {
79+
getUi().getInternals().dumpPendingJavaScriptInvocations();
80+
81+
assertWidgetResized(0, 2, 1);
82+
83+
fakeClientCommunication();
84+
85+
Assert.assertTrue(getUi().getInternals()
86+
.dumpPendingJavaScriptInvocations().isEmpty());
87+
}
88+
7789
@Test
7890
public void resizeWidget_eventCorrectlyFired() {
7991
DashboardWidget resizedWidget = (DashboardWidget) dashboard

vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/test/java/com/vaadin/flow/component/dashboard/DashboardTest.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -955,6 +955,22 @@ public void setDashboardEditable_removeWidget_widgetIsRemoved() {
955955
Assert.assertFalse(actualNodeIds.contains(nodeIdToBeRemoved));
956956
}
957957

958+
@Test
959+
public void setDashboardEditable_removeWidget_noClientUpdate() {
960+
DashboardWidget widgetToRemove = getNewWidget();
961+
dashboard.add(widgetToRemove);
962+
dashboard.setEditable(true);
963+
fakeClientCommunication();
964+
getUi().getInternals().dumpPendingJavaScriptInvocations();
965+
966+
int nodeIdToBeRemoved = widgetToRemove.getElement().getNode().getId();
967+
DashboardTestHelper.fireItemRemovedEvent(dashboard, nodeIdToBeRemoved);
968+
fakeClientCommunication();
969+
970+
Assert.assertTrue(getUi().getInternals()
971+
.dumpPendingJavaScriptInvocations().isEmpty());
972+
}
973+
958974
@Test
959975
public void setDashboardEditable_removeWidget_eventCorrectlyFired() {
960976
dashboard.setEditable(true);

0 commit comments

Comments
 (0)