diff --git a/vaadin-dashboard-flow-parent/vaadin-dashboard-flow-integration-tests/src/test/java/com/vaadin/flow/component/dashboard/tests/DashboardDragReorderIT.java b/vaadin-dashboard-flow-parent/vaadin-dashboard-flow-integration-tests/src/test/java/com/vaadin/flow/component/dashboard/tests/DashboardDragReorderIT.java
index fb5cdc82a6b..ac316882bb5 100644
--- a/vaadin-dashboard-flow-parent/vaadin-dashboard-flow-integration-tests/src/test/java/com/vaadin/flow/component/dashboard/tests/DashboardDragReorderIT.java
+++ b/vaadin-dashboard-flow-parent/vaadin-dashboard-flow-integration-tests/src/test/java/com/vaadin/flow/component/dashboard/tests/DashboardDragReorderIT.java
@@ -36,7 +36,7 @@ public void init() {
public void reorderWidgetOnClientSide_itemsAreReorderedCorrectly() {
var draggedWidget = dashboardElement.getWidgets().get(0);
var targetWidget = dashboardElement.getWidgets().get(1);
- dragResizeElement(draggedWidget, targetWidget);
+ dragReorderElement(draggedWidget, targetWidget);
Assert.assertEquals(draggedWidget.getTitle(),
dashboardElement.getWidgets().get(1).getTitle());
}
@@ -45,7 +45,7 @@ public void reorderWidgetOnClientSide_itemsAreReorderedCorrectly() {
public void reorderSectionOnClientSide_itemsAreReorderedCorrectly() {
var draggedSection = dashboardElement.getSections().get(1);
var targetWidget = dashboardElement.getWidgets().get(0);
- dragResizeElement(draggedSection, targetWidget);
+ dragReorderElement(draggedSection, targetWidget);
Assert.assertEquals(draggedSection.getTitle(),
dashboardElement.getSections().get(0).getTitle());
}
@@ -55,7 +55,7 @@ public void reorderWidgetInSectionOnClientSide_itemsAreReorderedCorrectly() {
var firstSection = dashboardElement.getSections().get(0);
var draggedWidget = firstSection.getWidgets().get(0);
var targetWidget = firstSection.getWidgets().get(1);
- dragResizeElement(draggedWidget, targetWidget);
+ dragReorderElement(draggedWidget, targetWidget);
firstSection = dashboardElement.getSections().get(0);
Assert.assertEquals(draggedWidget.getTitle(),
firstSection.getWidgets().get(1).getTitle());
@@ -69,7 +69,7 @@ public void detachReattach_reorderWidgetOnClientSide_itemsAreReorderedCorrectly(
reorderWidgetOnClientSide_itemsAreReorderedCorrectly();
}
- private void dragResizeElement(TestBenchElement draggedElement,
+ private void dragReorderElement(TestBenchElement draggedElement,
TestBenchElement targetElement) {
var dragHandle = getDragHandle(draggedElement);
@@ -83,10 +83,6 @@ private void dragResizeElement(TestBenchElement draggedElement,
.release(targetElement).build().perform();
}
- private static boolean isDragHandleVisible(TestBenchElement element) {
- return !"none".equals(getDragHandle(element).getCssValue("display"));
- }
-
private static TestBenchElement getDragHandle(TestBenchElement element) {
return element.$("*").withClassName("drag-handle").first();
}
diff --git a/vaadin-dashboard-flow-parent/vaadin-dashboard-flow-integration-tests/src/test/java/com/vaadin/flow/component/dashboard/tests/DashboardDragResizeIT.java b/vaadin-dashboard-flow-parent/vaadin-dashboard-flow-integration-tests/src/test/java/com/vaadin/flow/component/dashboard/tests/DashboardDragResizeIT.java
index 371b641d566..32698305e27 100644
--- a/vaadin-dashboard-flow-parent/vaadin-dashboard-flow-integration-tests/src/test/java/com/vaadin/flow/component/dashboard/tests/DashboardDragResizeIT.java
+++ b/vaadin-dashboard-flow-parent/vaadin-dashboard-flow-integration-tests/src/test/java/com/vaadin/flow/component/dashboard/tests/DashboardDragResizeIT.java
@@ -81,12 +81,6 @@ private void resizeWidget(int widgetIndexToResize, double xResizeRatio,
.release().build().perform();
}
- private boolean isResizeHandleVisible(
- DashboardWidgetElement widgetElement) {
- return !"none"
- .equals(getResizeHandle(widgetElement).getCssValue("display"));
- }
-
private static TestBenchElement getResizeHandle(
DashboardWidgetElement widgetElement) {
return widgetElement.$("*").withClassName("resize-handle").first();
diff --git a/vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/main/java/com/vaadin/flow/component/dashboard/Dashboard.java b/vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/main/java/com/vaadin/flow/component/dashboard/Dashboard.java
index fbb51ed726e..d13a30bc5bd 100644
--- a/vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/main/java/com/vaadin/flow/component/dashboard/Dashboard.java
+++ b/vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/main/java/com/vaadin/flow/component/dashboard/Dashboard.java
@@ -27,6 +27,8 @@
import com.vaadin.flow.component.Tag;
import com.vaadin.flow.component.dependency.JsModule;
import com.vaadin.flow.component.dependency.NpmPackage;
+import com.vaadin.flow.dom.DomEvent;
+import com.vaadin.flow.dom.DomListenerRegistration;
import com.vaadin.flow.dom.Element;
import com.vaadin.flow.shared.Registration;
@@ -55,9 +57,9 @@ public class Dashboard extends Component implements HasWidgets, HasSize {
*/
public Dashboard() {
childDetachHandler = getChildDetachHandler();
- addItemReorderEndListener(this::onItemReorderEnd);
- addItemResizeEndListener(this::onItemResizeEnd);
- addItemRemovedListener(this::onItemRemoved);
+ initItemMovedClientEventListener();
+ initItemResizedClientEventListener();
+ initItemRemovedClientEventListener();
}
/**
@@ -305,51 +307,27 @@ public boolean isEditable() {
}
/**
- * Adds an item reorder start listener to this dashboard.
+ * Adds an item moved listener to this dashboard.
*
* @param listener
* the listener to add, not null
* @return a handle that can be used for removing the listener
*/
- public Registration addItemReorderStartListener(
- ComponentEventListener listener) {
- return addListener(DashboardItemReorderStartEvent.class, listener);
+ public Registration addItemMovedListener(
+ ComponentEventListener listener) {
+ return addListener(DashboardItemMovedEvent.class, listener);
}
/**
- * Adds an item reorder end listener to this dashboard.
+ * Adds an item resized listener to this dashboard.
*
* @param listener
* the listener to add, not null
* @return a handle that can be used for removing the listener
*/
- public Registration addItemReorderEndListener(
- ComponentEventListener listener) {
- return addListener(DashboardItemReorderEndEvent.class, listener);
- }
-
- /**
- * Adds an item resize start listener to this dashboard.
- *
- * @param listener
- * the listener to add, not null
- * @return a handle that can be used for removing the listener
- */
- public Registration addItemResizeStartListener(
- ComponentEventListener listener) {
- return addListener(DashboardItemResizeStartEvent.class, listener);
- }
-
- /**
- * Adds an item resize end listener to this dashboard.
- *
- * @param listener
- * the listener to add, not null
- * @return a handle that can be used for removing the listener
- */
- public Registration addItemResizeEndListener(
- ComponentEventListener listener) {
- return addListener(DashboardItemResizeEndEvent.class, listener);
+ public Registration addItemResizedListener(
+ ComponentEventListener listener) {
+ return addListener(DashboardItemResizedEvent.class, listener);
}
/**
@@ -389,7 +367,7 @@ protected void onAttach(AttachEvent attachEvent) {
super.onAttach(attachEvent);
getElement().executeJs(
"Vaadin.FlowComponentHost.patchVirtualContainer(this);");
- customizeItemReorderEndEvent();
+ customizeItemMovedEvent();
doUpdateClient();
}
@@ -493,95 +471,166 @@ void removeChild(Component child) {
};
}
- private void onItemReorderEnd(
- DashboardItemReorderEndEvent dashboardItemReorderEndEvent) {
- if (!isEditable()) {
- return;
- }
- JsonArray orderedItemsFromClient = dashboardItemReorderEndEvent
- .getItems();
- reorderItems(orderedItemsFromClient);
- updateClient();
- }
-
- private void onItemResizeEnd(
- DashboardItemResizeEndEvent dashboardItemResizeEndEvent) {
- if (!isEditable()) {
- return;
- }
- DashboardWidget resizedWidget = dashboardItemResizeEndEvent
- .getResizedWidget();
- resizedWidget.setRowspan(dashboardItemResizeEndEvent.getRowspan());
- resizedWidget.setColspan(dashboardItemResizeEndEvent.getColspan());
- }
-
- private void onItemRemoved(
- DashboardItemRemovedEvent dashboardItemRemovedEvent) {
- if (!isEditable()) {
- return;
- }
- dashboardItemRemovedEvent.getRemovedItem().removeFromParent();
- }
-
- private void reorderItems(JsonArray orderedItemsFromClient) {
- // Keep references to the root level children before clearing them
- Map nodeIdToComponent = childrenComponents.stream()
- .collect(Collectors.toMap(
- component -> component.getElement().getNode().getId(),
- Function.identity()));
- // Remove all children and add them back using the node IDs from client
- // items
- childrenComponents.clear();
- for (int rootLevelItemIdx = 0; rootLevelItemIdx < orderedItemsFromClient
- .length(); rootLevelItemIdx++) {
- JsonObject rootLevelItemFromClient = orderedItemsFromClient
- .getObject(rootLevelItemIdx);
- int rootLevelItemNodeId = (int) rootLevelItemFromClient
- .getNumber("nodeid");
- Component componentMatch = nodeIdToComponent
- .get(rootLevelItemNodeId);
- childrenComponents.add(componentMatch);
- // Reorder the widgets in sections separately
- if (componentMatch instanceof DashboardSection sectionMatch) {
- reorderSectionWidgets(sectionMatch, rootLevelItemFromClient);
+ private void initItemMovedClientEventListener() {
+ String itemKey = "event.detail.item";
+ String itemsKey = "event.detail.items";
+ String sectionKey = "event.detail.section";
+ getElement().addEventListener("dashboard-item-moved-flow", e -> {
+ if (!isEditable()) {
+ return;
}
+ handleItemMovedClientEvent(e, itemKey, itemsKey, sectionKey);
+ updateClient();
+ }).addEventData(itemKey).addEventData(itemsKey)
+ .addEventData(sectionKey);
+ }
+
+ private void handleItemMovedClientEvent(DomEvent e, String itemKey,
+ String itemsKey, String sectionKey) {
+ int itemNodeId = (int) e.getEventData().getNumber(itemKey);
+ JsonArray itemsNodeIds = e.getEventData().getArray(itemsKey);
+ Integer sectionNodeId = e.getEventData().hasKey(sectionKey)
+ ? (int) e.getEventData().getNumber(sectionKey)
+ : null;
+ DashboardSection section = null;
+ List reorderedItems;
+ if (sectionNodeId == null) {
+ reorderedItems = getReorderedItemsList(itemsNodeIds, this);
+ childrenComponents.clear();
+ childrenComponents.addAll(reorderedItems);
+ } else {
+ section = getChildren()
+ .filter(child -> sectionNodeId
+ .equals(child.getElement().getNode().getId()))
+ .map(DashboardSection.class::cast).findAny().orElseThrow();
+ reorderedItems = getReorderedItemsList(
+ getSectionItems(itemsNodeIds, sectionNodeId), section);
+ section.removeAll();
+ reorderedItems.stream().map(DashboardWidget.class::cast)
+ .forEach(section::add);
}
+ Component movedItem = reorderedItems.stream().filter(
+ item -> itemNodeId == item.getElement().getNode().getId())
+ .findAny().orElseThrow();
+ fireEvent(new DashboardItemMovedEvent(this, true, movedItem,
+ getChildren().toList(), section));
+ }
+
+ private void initItemResizedClientEventListener() {
+ String nodeIdKey = "event.detail.item.nodeid";
+ String colspanKey = "event.detail.item.colspan";
+ String rowspanKey = "event.detail.item.rowspan";
+ getElement().addEventListener("dashboard-item-resized", e -> {
+ if (!isEditable()) {
+ return;
+ }
+ handleItemResizedClientEvent(e, nodeIdKey, colspanKey, rowspanKey);
+ updateClient();
+ }).addEventData(nodeIdKey).addEventData(colspanKey)
+ .addEventData(rowspanKey);
+ }
+
+ private void handleItemResizedClientEvent(DomEvent e, String nodeIdKey,
+ String colspanKey, String rowspanKey) {
+ int nodeId = (int) e.getEventData().getNumber(nodeIdKey);
+ int colspan = (int) e.getEventData().getNumber(colspanKey);
+ int rowspan = (int) e.getEventData().getNumber(rowspanKey);
+ DashboardWidget resizedWidget = getWidgets().stream()
+ .filter(child -> nodeId == child.getElement().getNode().getId())
+ .findAny().orElseThrow();
+ resizedWidget.setRowspan(rowspan);
+ resizedWidget.setColspan(colspan);
+ fireEvent(new DashboardItemResizedEvent(this, true, resizedWidget,
+ getChildren().toList()));
+ }
+
+ private void initItemRemovedClientEventListener() {
+ String nodeIdKey = "event.detail.item.nodeid";
+ DomListenerRegistration registration = getElement()
+ .addEventListener("dashboard-item-removed", e -> {
+ if (!isEditable()) {
+ return;
+ }
+ handleItemRemovedClientEvent(e, nodeIdKey);
+ updateClient();
+ });
+ registration.addEventData(nodeIdKey);
+ }
+
+ private void handleItemRemovedClientEvent(DomEvent e, String nodeIdKey) {
+ int nodeId = (int) e.getEventData().getNumber(nodeIdKey);
+ Component removedItem = getRemovedItem(nodeId);
+ removedItem.removeFromParent();
+ fireEvent(new DashboardItemRemovedEvent(this, true, removedItem,
+ getChildren().toList()));
+ }
+
+ private Component getRemovedItem(int nodeId) {
+ return getChildren().map(item -> {
+ if (nodeId == item.getElement().getNode().getId()) {
+ return item;
+ }
+ if (item instanceof DashboardSection section) {
+ return section.getWidgets().stream()
+ .filter(sectionItem -> nodeId == sectionItem
+ .getElement().getNode().getId())
+ .findAny().orElse(null);
+ }
+ return null;
+ }).filter(Objects::nonNull).findAny().orElseThrow();
}
- private void reorderSectionWidgets(DashboardSection section,
- JsonObject rootLevelItem) {
- // Keep references to the widgets before clearing them
- Map nodeIdToWidget = section.getWidgets()
- .stream()
- .collect(Collectors.toMap(
- widget -> widget.getElement().getNode().getId(),
- Function.identity()));
- // Remove all widgets and add them back using the node IDs from client
- // items
- section.removeAll();
- JsonArray sectionWidgetsFromClient = rootLevelItem.getArray("items");
- for (int sectionWidgetIdx = 0; sectionWidgetIdx < sectionWidgetsFromClient
- .length(); sectionWidgetIdx++) {
- int sectionItemNodeId = (int) sectionWidgetsFromClient
- .getObject(sectionWidgetIdx).getNumber("nodeid");
- section.add(nodeIdToWidget.get(sectionItemNodeId));
- }
- }
-
- private void customizeItemReorderEndEvent() {
+ private void customizeItemMovedEvent() {
getElement().executeJs(
"""
- this.addEventListener('dashboard-item-reorder-end', (e) => {
+ this.addEventListener('dashboard-item-moved', (e) => {
function mapItems(items) {
return items.map(({nodeid, items}) => ({
nodeid,
...(items && { items: mapItems(items) })
}));
}
- const flowReorderEvent = new CustomEvent('dashboard-item-reorder-end-flow', {
- detail: { items: mapItems(this.items) }
+ const flowItemMovedEvent = new CustomEvent('dashboard-item-moved-flow', {
+ detail: {
+ item: e.detail.item.nodeid,
+ items: mapItems(e.detail.items),
+ section: e.detail.section?.nodeid
+ }
});
- this.dispatchEvent(flowReorderEvent);
+ this.dispatchEvent(flowItemMovedEvent);
});""");
}
+
+ private static List getReorderedItemsList(
+ JsonArray reorderedItemsFromClient,
+ Component reorderedItemsParent) {
+ Objects.requireNonNull(reorderedItemsFromClient);
+ Map nodeIdToItems = reorderedItemsParent
+ .getChildren()
+ .collect(Collectors.toMap(
+ item -> item.getElement().getNode().getId(),
+ Function.identity()));
+ List items = new ArrayList<>();
+ for (int index = 0; index < reorderedItemsFromClient
+ .length(); index++) {
+ int nodeIdFromClient = (int) ((JsonObject) reorderedItemsFromClient
+ .get(index)).getNumber("nodeid");
+ items.add(nodeIdToItems.get(nodeIdFromClient));
+ }
+ return items;
+ }
+
+ private static JsonArray getSectionItems(JsonArray items,
+ int sectionNodeId) {
+ for (int rootLevelIdx = 0; rootLevelIdx < items
+ .length(); rootLevelIdx++) {
+ JsonObject item = items.get(rootLevelIdx);
+ int itemNodeId = (int) item.getNumber("nodeid");
+ if (sectionNodeId == itemNodeId) {
+ JsonObject sectionObj = items.get(rootLevelIdx);
+ return sectionObj.getArray("items");
+ }
+ }
+ return null;
+ }
}
diff --git a/vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/main/java/com/vaadin/flow/component/dashboard/DashboardItemMovedEvent.java b/vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/main/java/com/vaadin/flow/component/dashboard/DashboardItemMovedEvent.java
new file mode 100644
index 00000000000..4bc081bffea
--- /dev/null
+++ b/vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/main/java/com/vaadin/flow/component/dashboard/DashboardItemMovedEvent.java
@@ -0,0 +1,84 @@
+/**
+ * Copyright 2000-2024 Vaadin Ltd.
+ *
+ * This program is available under Vaadin Commercial License and Service Terms.
+ *
+ * See {@literal } for the full
+ * license.
+ */
+package com.vaadin.flow.component.dashboard;
+
+import java.util.List;
+import java.util.Optional;
+
+import com.vaadin.flow.component.Component;
+import com.vaadin.flow.component.ComponentEvent;
+import com.vaadin.flow.component.ComponentEventListener;
+
+/**
+ * Widget or section moved event of {@link Dashboard}.
+ *
+ * @author Vaadin Ltd.
+ * @see Dashboard#addItemMovedListener(ComponentEventListener)
+ */
+public class DashboardItemMovedEvent extends ComponentEvent {
+
+ private final Component item;
+
+ private final List items;
+
+ private final DashboardSection section;
+
+ /**
+ * Creates a dashboard item moved event.
+ *
+ * @param source
+ * Dashboard that contains the item that was moved
+ * @param fromClient
+ * {@code true} if the event originated from the client side,
+ * {@code false} otherwise
+ * @param item
+ * The moved item
+ * @param items
+ * The root level items of the dashboard
+ * @param section
+ * The section that contains the moved item, {@code null} if the
+ * item is a direct child of the dashboard
+ */
+ public DashboardItemMovedEvent(Dashboard source, boolean fromClient,
+ Component item, List items, DashboardSection section) {
+ super(source, fromClient);
+ this.item = item;
+ this.items = items;
+ this.section = section;
+ }
+
+ /**
+ * Returns the moved item
+ *
+ * @return the moved item
+ */
+ public Component getItem() {
+ return item;
+ }
+
+ /**
+ * Returns the root level items of the dashboard
+ *
+ * @return the root level items of the dashboard
+ */
+ public List getItems() {
+ return items;
+ }
+
+ /**
+ * Returns the section that contains the moved item, or an empty optional if
+ * the item is a direct child of the dashboard
+ *
+ * @return the section that contains the moved item, or an empty optional if
+ * the item is a direct child of the dashboard
+ */
+ public Optional getSection() {
+ return Optional.ofNullable(section);
+ }
+}
diff --git a/vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/main/java/com/vaadin/flow/component/dashboard/DashboardItemRemovedEvent.java b/vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/main/java/com/vaadin/flow/component/dashboard/DashboardItemRemovedEvent.java
index 8702a08ecfe..e270d45554b 100644
--- a/vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/main/java/com/vaadin/flow/component/dashboard/DashboardItemRemovedEvent.java
+++ b/vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/main/java/com/vaadin/flow/component/dashboard/DashboardItemRemovedEvent.java
@@ -8,13 +8,11 @@
*/
package com.vaadin.flow.component.dashboard;
-import java.util.Objects;
+import java.util.List;
import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.ComponentEvent;
import com.vaadin.flow.component.ComponentEventListener;
-import com.vaadin.flow.component.DomEvent;
-import com.vaadin.flow.component.EventData;
/**
* Widget or section removed event of {@link Dashboard}.
@@ -22,10 +20,11 @@
* @author Vaadin Ltd.
* @see Dashboard#addItemRemovedListener(ComponentEventListener)
*/
-@DomEvent("dashboard-item-removed")
public class DashboardItemRemovedEvent extends ComponentEvent {
- private final Component removedItem;
+ private final Component item;
+
+ private final List items;
/**
* Creates a dashboard item removed event.
@@ -33,13 +32,18 @@ public class DashboardItemRemovedEvent extends ComponentEvent {
* @param source
* Dashboard that contains the item that was removed
* @param fromClient
- * true
if the event originated from the client
- * side, false
otherwise
+ * {@code true} if the event originated from the client side,
+ * {@code false} otherwise
+ * @param item
+ * The removed item
+ * @param items
+ * The root level items of the dashboard
*/
public DashboardItemRemovedEvent(Dashboard source, boolean fromClient,
- @EventData("event.detail.item.nodeid") int nodeId) {
+ Component item, List items) {
super(source, fromClient);
- this.removedItem = getRemovedItem(source, nodeId);
+ this.item = item;
+ this.items = items;
}
/**
@@ -47,22 +51,16 @@ public DashboardItemRemovedEvent(Dashboard source, boolean fromClient,
*
* @return the removed item
*/
- public Component getRemovedItem() {
- return removedItem;
+ public Component getItem() {
+ return item;
}
- private static Component getRemovedItem(Dashboard dashboard, int nodeId) {
- return dashboard.getChildren().map(item -> {
- if (nodeId == item.getElement().getNode().getId()) {
- return item;
- }
- if (item instanceof DashboardSection section) {
- return section.getWidgets().stream()
- .filter(sectionItem -> nodeId == sectionItem
- .getElement().getNode().getId())
- .findAny().orElse(null);
- }
- return null;
- }).filter(Objects::nonNull).findAny().orElse(null);
+ /**
+ * Returns the root level items of the dashboard
+ *
+ * @return the root level items of the dashboard
+ */
+ public List getItems() {
+ return items;
}
}
diff --git a/vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/main/java/com/vaadin/flow/component/dashboard/DashboardItemReorderEndEvent.java b/vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/main/java/com/vaadin/flow/component/dashboard/DashboardItemReorderEndEvent.java
deleted file mode 100644
index 22ff4dbf79e..00000000000
--- a/vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/main/java/com/vaadin/flow/component/dashboard/DashboardItemReorderEndEvent.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * Copyright 2000-2024 Vaadin Ltd.
- *
- * This program is available under Vaadin Commercial License and Service Terms.
- *
- * See {@literal } for the full
- * license.
- */
-package com.vaadin.flow.component.dashboard;
-
-import com.vaadin.flow.component.ComponentEvent;
-import com.vaadin.flow.component.ComponentEventListener;
-import com.vaadin.flow.component.DomEvent;
-import com.vaadin.flow.component.EventData;
-
-import elemental.json.JsonArray;
-
-/**
- * Widget or section reorder end event of {@link Dashboard}.
- *
- * @author Vaadin Ltd.
- * @see Dashboard#addItemReorderEndListener(ComponentEventListener)
- */
-@DomEvent("dashboard-item-reorder-end-flow")
-public class DashboardItemReorderEndEvent extends ComponentEvent {
-
- private final JsonArray items;
-
- /**
- * Creates a dashboard item reorder end event.
- *
- * @param source
- * Dashboard that contains the item that was dragged
- * @param fromClient
- * true
if the event originated from the client
- * side, false
otherwise
- */
- public DashboardItemReorderEndEvent(Dashboard source, boolean fromClient,
- @EventData("event.detail.items") JsonArray items) {
- super(source, fromClient);
- this.items = items;
- }
-
- /**
- * Returns the ordered items from the client side
- *
- * @return items the ordered items as a {@link JsonArray}
- */
- public JsonArray getItems() {
- return items;
- }
-}
diff --git a/vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/main/java/com/vaadin/flow/component/dashboard/DashboardItemReorderStartEvent.java b/vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/main/java/com/vaadin/flow/component/dashboard/DashboardItemReorderStartEvent.java
deleted file mode 100644
index d2910539cfb..00000000000
--- a/vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/main/java/com/vaadin/flow/component/dashboard/DashboardItemReorderStartEvent.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * Copyright 2000-2024 Vaadin Ltd.
- *
- * This program is available under Vaadin Commercial License and Service Terms.
- *
- * See {@literal } for the full
- * license.
- */
-package com.vaadin.flow.component.dashboard;
-
-import com.vaadin.flow.component.ComponentEvent;
-import com.vaadin.flow.component.ComponentEventListener;
-import com.vaadin.flow.component.DomEvent;
-
-/**
- * Widget or section reorder start event of {@link Dashboard}.
- *
- * @author Vaadin Ltd.
- * @see Dashboard#addItemReorderStartListener(ComponentEventListener)
- */
-@DomEvent("dashboard-item-reorder-start")
-public class DashboardItemReorderStartEvent extends ComponentEvent {
-
- /**
- * Creates a dashboard item reorder start event.
- *
- * @param source
- * Dashboard that contains the item that was dragged
- * @param fromClient
- * true
if the event originated from the client
- * side, false
otherwise
- */
- public DashboardItemReorderStartEvent(Dashboard source,
- boolean fromClient) {
- super(source, fromClient);
- }
-}
diff --git a/vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/main/java/com/vaadin/flow/component/dashboard/DashboardItemResizeEndEvent.java b/vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/main/java/com/vaadin/flow/component/dashboard/DashboardItemResizeEndEvent.java
deleted file mode 100644
index 013ec38963c..00000000000
--- a/vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/main/java/com/vaadin/flow/component/dashboard/DashboardItemResizeEndEvent.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/**
- * Copyright 2000-2024 Vaadin Ltd.
- *
- * This program is available under Vaadin Commercial License and Service Terms.
- *
- * See {@literal } for the full
- * license.
- */
-package com.vaadin.flow.component.dashboard;
-
-import com.vaadin.flow.component.ComponentEvent;
-import com.vaadin.flow.component.ComponentEventListener;
-import com.vaadin.flow.component.DomEvent;
-import com.vaadin.flow.component.EventData;
-
-/**
- * Widget resize end event of {@link Dashboard}.
- *
- * @author Vaadin Ltd.
- * @see Dashboard#addItemResizeEndListener(ComponentEventListener)
- */
-@DomEvent("dashboard-item-resize-end")
-public class DashboardItemResizeEndEvent extends ComponentEvent {
-
- private final DashboardWidget resizedWidget;
-
- private final int colspan;
-
- private final int rowspan;
-
- /**
- * Creates a dashboard item resize end event.
- *
- * @param source
- * Dashboard that contains the widget that was dragged
- * @param fromClient
- * true
if the event originated from the client
- * side, false
otherwise
- * @param nodeId
- * Node ID the resized widget
- * @param colspan
- * New colspan of the resized widget
- * @param rowspan
- * New rowspan of the resized widget
- */
- public DashboardItemResizeEndEvent(Dashboard source, boolean fromClient,
- @EventData("event.detail.item.nodeid") int nodeId,
- @EventData("event.detail.item.colspan") int colspan,
- @EventData("event.detail.item.rowspan") int rowspan) {
- super(source, fromClient);
- this.resizedWidget = source.getWidgets().stream()
- .filter(child -> nodeId == child.getElement().getNode().getId())
- .findAny().orElse(null);
- this.colspan = colspan;
- this.rowspan = rowspan;
- }
-
- /**
- * Returns the resized widget
- *
- * @return the resized widget
- */
- public DashboardWidget getResizedWidget() {
- return resizedWidget;
- }
-
- /**
- * Returns the new colspan of the resized item
- *
- * @return new colspan of the resized item
- */
- public int getColspan() {
- return colspan;
- }
-
- /**
- * Returns the new rowspan of the resized item
- *
- * @return new rowspan of the resized item
- */
- public int getRowspan() {
- return rowspan;
- }
-}
diff --git a/vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/main/java/com/vaadin/flow/component/dashboard/DashboardItemResizeStartEvent.java b/vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/main/java/com/vaadin/flow/component/dashboard/DashboardItemResizeStartEvent.java
deleted file mode 100644
index ce762351439..00000000000
--- a/vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/main/java/com/vaadin/flow/component/dashboard/DashboardItemResizeStartEvent.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/**
- * Copyright 2000-2024 Vaadin Ltd.
- *
- * This program is available under Vaadin Commercial License and Service Terms.
- *
- * See {@literal } for the full
- * license.
- */
-package com.vaadin.flow.component.dashboard;
-
-import com.vaadin.flow.component.ComponentEvent;
-import com.vaadin.flow.component.ComponentEventListener;
-import com.vaadin.flow.component.DomEvent;
-import com.vaadin.flow.component.EventData;
-
-/**
- * Widget resize start event of {@link Dashboard}.
- *
- * @author Vaadin Ltd.
- * @see Dashboard#addItemResizeStartListener(ComponentEventListener)
- */
-@DomEvent("dashboard-item-resize-start")
-public class DashboardItemResizeStartEvent extends ComponentEvent {
-
- private final DashboardWidget resizedWidget;
-
- /**
- * Creates a dashboard item resize start event.
- *
- * @param source
- * Dashboard that contains the widget that was dragged
- * @param fromClient
- * true
if the event originated from the client
- * side, false
otherwise
- * @param nodeId
- * Node ID the resized widget
- */
- public DashboardItemResizeStartEvent(Dashboard source, boolean fromClient,
- @EventData("event.detail.item.nodeid") int nodeId) {
- super(source, fromClient);
- this.resizedWidget = source.getWidgets().stream()
- .filter(child -> nodeId == child.getElement().getNode().getId())
- .findAny().orElse(null);
- }
-
- /**
- * Returns the resized widget
- *
- * @return the resized widget
- */
- public DashboardWidget getResizedWidget() {
- return resizedWidget;
- }
-}
diff --git a/vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/main/java/com/vaadin/flow/component/dashboard/DashboardItemResizedEvent.java b/vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/main/java/com/vaadin/flow/component/dashboard/DashboardItemResizedEvent.java
new file mode 100644
index 00000000000..ba34d7976e9
--- /dev/null
+++ b/vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/main/java/com/vaadin/flow/component/dashboard/DashboardItemResizedEvent.java
@@ -0,0 +1,66 @@
+/**
+ * Copyright 2000-2024 Vaadin Ltd.
+ *
+ * This program is available under Vaadin Commercial License and Service Terms.
+ *
+ * See {@literal } for the full
+ * license.
+ */
+package com.vaadin.flow.component.dashboard;
+
+import java.util.List;
+
+import com.vaadin.flow.component.Component;
+import com.vaadin.flow.component.ComponentEvent;
+import com.vaadin.flow.component.ComponentEventListener;
+
+/**
+ * Widget resized event of {@link Dashboard}.
+ *
+ * @author Vaadin Ltd.
+ * @see Dashboard#addItemResizedListener(ComponentEventListener)
+ */
+public class DashboardItemResizedEvent extends ComponentEvent {
+
+ private final DashboardWidget item;
+
+ private final List items;
+
+ /**
+ * Creates a dashboard item resized event.
+ *
+ * @param source
+ * Dashboard that contains the widget that was resized
+ * @param fromClient
+ * {@code true} if the event originated from the client side,
+ * {@code false} otherwise
+ * @param item
+ * The resized widget
+ * @param items
+ * The root level items of the dashboard
+ */
+ public DashboardItemResizedEvent(Dashboard source, boolean fromClient,
+ DashboardWidget item, List items) {
+ super(source, fromClient);
+ this.item = item;
+ this.items = items;
+ }
+
+ /**
+ * Returns the resized widget
+ *
+ * @return the resized widget
+ */
+ public DashboardWidget getItem() {
+ return item;
+ }
+
+ /**
+ * Returns the root level items of the dashboard
+ *
+ * @return the root level items of the dashboard
+ */
+ public List getItems() {
+ return items;
+ }
+}
diff --git a/vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/test/java/com/vaadin/flow/component/dashboard/tests/DashboardDragReorderTest.java b/vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/test/java/com/vaadin/flow/component/dashboard/tests/DashboardDragReorderTest.java
index bdddead6019..35f036a0641 100644
--- a/vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/test/java/com/vaadin/flow/component/dashboard/tests/DashboardDragReorderTest.java
+++ b/vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/test/java/com/vaadin/flow/component/dashboard/tests/DashboardDragReorderTest.java
@@ -10,17 +10,21 @@
import java.util.ArrayList;
import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
-import com.vaadin.flow.component.ComponentUtil;
+import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.dashboard.Dashboard;
-import com.vaadin.flow.component.dashboard.DashboardItemReorderEndEvent;
import com.vaadin.flow.component.dashboard.DashboardSection;
import com.vaadin.flow.component.dashboard.DashboardWidget;
+import com.vaadin.flow.dom.DomEvent;
+import com.vaadin.flow.internal.nodefeature.ElementListenerMap;
import elemental.json.Json;
import elemental.json.JsonArray;
@@ -50,6 +54,11 @@ public void reorderWidget_orderIsUpdated() {
assertRootLevelItemReorder(0, 1);
}
+ @Test
+ public void reorderWidgetToSamePosition_orderIsNotUpdated() {
+ assertRootLevelItemReorder(0, 0);
+ }
+
@Test
public void reorderSection_orderIsUpdated() {
assertRootLevelItemReorder(2, 1);
@@ -60,18 +69,132 @@ public void reorderWidgetInSection_orderIsUpdated() {
assertSectionWidgetReorder(2, 0, 1);
}
+ @Test
+ public void reorderWidgetInSectionToSamePosition_orderIsNotUpdated() {
+ assertSectionWidgetReorder(2, 0, 0);
+ }
+
@Test
public void setDashboardNotEditable_reorderWidget_orderIsNotUpdated() {
dashboard.setEditable(false);
+ int movedWidgetNodeId = dashboard.getChildren().toList().get(0)
+ .getElement().getNode().getId();
List expectedRootLevelNodeIds = getRootLevelNodeIds();
reorderRootLevelItem(0, 1);
- fireItemReorderEndEvent();
+ fireItemMovedEvent(movedWidgetNodeId);
Assert.assertEquals(expectedRootLevelNodeIds, getRootLevelNodeIds());
}
- private void fireItemReorderEndEvent() {
- ComponentUtil.fireEvent(dashboard,
- new DashboardItemReorderEndEvent(dashboard, false, itemsArray));
+ @Test
+ public void reorderWidget_eventCorrectlyFired() {
+ int initialIndex = 0;
+ int finalIndex = 1;
+ Component movedItem = dashboard.getChildren().toList()
+ .get(initialIndex);
+ int movedItemNodeId = movedItem.getElement().getNode().getId();
+ List expectedItems = dashboard.getChildren()
+ .collect(Collectors.toCollection(ArrayList::new));
+ expectedItems.add(finalIndex, expectedItems.remove(initialIndex));
+ Runnable itemMoveAction = () -> {
+ reorderRootLevelItem(initialIndex, finalIndex);
+ fireItemMovedEvent(movedItemNodeId);
+ };
+ assertEventCorrectlyFired(itemMoveAction, 1, movedItem, expectedItems,
+ null);
+ }
+
+ @Test
+ public void reorderSection_eventCorrectlyFired() {
+ int initialIndex = 2;
+ int finalIndex = 1;
+ Component movedItem = dashboard.getChildren().toList()
+ .get(initialIndex);
+ int movedItemNodeId = movedItem.getElement().getNode().getId();
+ List expectedItems = dashboard.getChildren()
+ .collect(Collectors.toCollection(ArrayList::new));
+ expectedItems.add(finalIndex, expectedItems.remove(initialIndex));
+ Runnable itemMoveAction = () -> {
+ reorderRootLevelItem(initialIndex, finalIndex);
+ fireItemMovedEvent(movedItemNodeId);
+ };
+ assertEventCorrectlyFired(itemMoveAction, 1, movedItem, expectedItems,
+ null);
+ }
+
+ @Test
+ public void reorderWidgetInSection_eventCorrectlyFired() {
+ int sectionIndex = 2;
+ int initialIndex = 0;
+ int finalIndex = 1;
+ List expectedItems = dashboard.getChildren().toList();
+ DashboardSection section = (DashboardSection) expectedItems
+ .get(sectionIndex);
+ int sectionNodeId = section.getElement().getNode().getId();
+ Component movedItem = section.getWidgets().get(initialIndex);
+ int movedItemNodeId = movedItem.getElement().getNode().getId();
+ Runnable itemMoveAction = () -> {
+ reorderSectionWidget(sectionIndex, initialIndex, finalIndex);
+ fireItemMovedEvent(movedItemNodeId, sectionNodeId);
+ };
+ assertEventCorrectlyFired(itemMoveAction, 1, movedItem, expectedItems,
+ section);
+ }
+
+ @Test
+ public void setDashboardNotEditable_reorderWidget_eventNotFired() {
+ dashboard.setEditable(false);
+ int initialIndex = 0;
+ int finalIndex = 1;
+ Component movedItem = dashboard.getChildren().toList()
+ .get(initialIndex);
+ int movedItemNodeId = movedItem.getElement().getNode().getId();
+ Runnable itemMoveAction = () -> {
+ reorderRootLevelItem(initialIndex, finalIndex);
+ fireItemMovedEvent(movedItemNodeId);
+ };
+ assertEventCorrectlyFired(itemMoveAction, 0, null, null, null);
+ }
+
+ private void assertEventCorrectlyFired(Runnable itemMoveAction,
+ int expectedListenerInvokedCount, Component expectedItem,
+ List expectedItems, DashboardSection expectedSection) {
+ AtomicInteger listenerInvokedCount = new AtomicInteger(0);
+ AtomicReference eventItem = new AtomicReference<>();
+ AtomicReference> eventItems = new AtomicReference<>();
+ AtomicReference> eventSection = new AtomicReference<>();
+ dashboard.addItemMovedListener(e -> {
+ listenerInvokedCount.incrementAndGet();
+ eventItem.set(e.getItem());
+ eventItems.set(e.getItems());
+ eventSection.set(e.getSection());
+ e.unregisterListener();
+ });
+ itemMoveAction.run();
+ Assert.assertEquals(expectedListenerInvokedCount,
+ listenerInvokedCount.get());
+ if (expectedListenerInvokedCount > 0) {
+ Assert.assertEquals(expectedItem, eventItem.get());
+ Assert.assertEquals(expectedItems, eventItems.get());
+ Assert.assertEquals(Optional.ofNullable(expectedSection),
+ eventSection.get());
+ }
+ }
+
+ private void fireItemMovedEvent(int itemNodeId) {
+ fireItemMovedEvent(itemNodeId, null);
+ }
+
+ private void fireItemMovedEvent(int itemNodeId, Integer sectionNodeId) {
+ JsonObject eventData = Json.createObject();
+ eventData.put("event.detail.item", itemNodeId);
+ eventData.put("event.detail.items", itemsArray);
+ if (sectionNodeId != null) {
+ eventData.put("event.detail.section", sectionNodeId);
+ }
+ DomEvent itemMovedDomEvent = new DomEvent(dashboard.getElement(),
+ "dashboard-item-moved-flow", eventData);
+ dashboard.getElement().getNode().getFeature(ElementListenerMap.class)
+ .fireEvent(itemMovedDomEvent);
}
private List getSectionWidgetNodeIds(int sectionIndex) {
@@ -122,19 +245,26 @@ private void reorderRootLevelItem(int initialIndex, int finalIndex) {
private void assertSectionWidgetReorder(int sectionIndex, int initialIndex,
int finalIndex) {
+ DashboardSection section = (DashboardSection) dashboard.getChildren()
+ .toList().get(sectionIndex);
+ int sectionNodeId = section.getElement().getNode().getId();
+ int movedWidgetNodeId = section.getWidgets().get(initialIndex)
+ .getElement().getNode().getId();
reorderSectionWidget(sectionIndex, initialIndex, finalIndex);
List expectedSectionWidgetNodeIds = getExpectedSectionWidgetNodeIds(
sectionIndex, initialIndex, finalIndex);
- fireItemReorderEndEvent();
+ fireItemMovedEvent(movedWidgetNodeId, sectionNodeId);
Assert.assertEquals(expectedSectionWidgetNodeIds,
getSectionWidgetNodeIds(sectionIndex));
}
private void assertRootLevelItemReorder(int initialIndex, int finalIndex) {
+ int movedItemNodeId = dashboard.getChildren().toList().get(initialIndex)
+ .getElement().getNode().getId();
reorderRootLevelItem(initialIndex, finalIndex);
List expectedRootLevelNodeIds = getExpectedRootLevelItemNodeIds(
initialIndex, finalIndex);
- fireItemReorderEndEvent();
+ fireItemMovedEvent(movedItemNodeId);
Assert.assertEquals(expectedRootLevelNodeIds, getRootLevelNodeIds());
}
diff --git a/vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/test/java/com/vaadin/flow/component/dashboard/tests/DashboardDragResizeTest.java b/vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/test/java/com/vaadin/flow/component/dashboard/tests/DashboardDragResizeTest.java
index 8a901a0f961..7a396a7e4bb 100644
--- a/vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/test/java/com/vaadin/flow/component/dashboard/tests/DashboardDragResizeTest.java
+++ b/vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/test/java/com/vaadin/flow/component/dashboard/tests/DashboardDragResizeTest.java
@@ -8,15 +8,23 @@
*/
package com.vaadin.flow.component.dashboard.tests;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
+
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
-import com.vaadin.flow.component.ComponentUtil;
+import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.dashboard.Dashboard;
-import com.vaadin.flow.component.dashboard.DashboardItemResizeEndEvent;
import com.vaadin.flow.component.dashboard.DashboardSection;
import com.vaadin.flow.component.dashboard.DashboardWidget;
+import com.vaadin.flow.dom.DomEvent;
+import com.vaadin.flow.internal.nodefeature.ElementListenerMap;
+
+import elemental.json.Json;
+import elemental.json.JsonObject;
public class DashboardDragResizeTest extends DashboardTestBase {
private Dashboard dashboard;
@@ -68,30 +76,82 @@ public void resizeWidgetInSectionBothHorizontallyAndVertically_sizeIsUpdated() {
public void setDashboardNotEditable_resizeWidget_sizeIsNotUpdated() {
dashboard.setEditable(false);
DashboardWidget widgetToResize = dashboard.getWidgets().get(0);
- fireItemResizeEndEvent(widgetToResize, 2, 2);
+ fireItemResizedEvent(widgetToResize, 2, 2);
Assert.assertEquals(1, widgetToResize.getColspan());
Assert.assertEquals(1, widgetToResize.getRowspan());
}
+ @Test
+ public void resizeWidget_eventCorrectlyFired() {
+ DashboardWidget resizedWidget = (DashboardWidget) dashboard
+ .getChildren().toList().get(0);
+ assertEventCorrectlyFired(resizedWidget, 1, resizedWidget,
+ dashboard.getChildren().toList());
+ }
+
+ @Test
+ public void resizeWidgetInSection_eventCorrectlyFired() {
+ DashboardSection section = (DashboardSection) dashboard.getChildren()
+ .toList().get(1);
+ DashboardWidget resizedWidget = section.getWidgets().get(0);
+ assertEventCorrectlyFired(resizedWidget, 1, resizedWidget,
+ dashboard.getChildren().toList());
+ }
+
+ @Test
+ public void setDashboardNotEditable_resizeWidget_eventNotFired() {
+ dashboard.setEditable(false);
+ DashboardWidget resizedWidget = (DashboardWidget) dashboard
+ .getChildren().toList().get(0);
+ assertEventCorrectlyFired(resizedWidget, 0, null, null);
+ }
+
+ private void assertEventCorrectlyFired(DashboardWidget widgetToResize,
+ int expectedListenerInvokedCount, Component expectedResizedWidget,
+ List expectedItems) {
+ AtomicInteger listenerInvokedCount = new AtomicInteger(0);
+ AtomicReference eventResizedWidget = new AtomicReference<>();
+ AtomicReference> eventItems = new AtomicReference<>();
+ dashboard.addItemResizedListener(e -> {
+ listenerInvokedCount.incrementAndGet();
+ eventResizedWidget.set(e.getItem());
+ eventItems.set(e.getItems());
+ e.unregisterListener();
+ });
+ fireItemResizedEvent(widgetToResize, 2, 2);
+ Assert.assertEquals(expectedListenerInvokedCount,
+ listenerInvokedCount.get());
+ if (expectedListenerInvokedCount > 0) {
+ Assert.assertEquals(expectedResizedWidget,
+ eventResizedWidget.get());
+ Assert.assertEquals(expectedItems, eventItems.get());
+ }
+ }
+
private void assertWidgetResized(int widgetIndexToResize, int targetColspan,
int targetRowspan) {
DashboardWidget widgetToResize = dashboard.getWidgets()
.get(widgetIndexToResize);
// Assert widget is enlarged
- fireItemResizeEndEvent(widgetToResize, targetColspan, targetRowspan);
+ fireItemResizedEvent(widgetToResize, targetColspan, targetRowspan);
Assert.assertEquals(targetColspan, widgetToResize.getColspan());
Assert.assertEquals(targetRowspan, widgetToResize.getRowspan());
// Assert widget is shrunk
- fireItemResizeEndEvent(widgetToResize, 1, 1);
+ fireItemResizedEvent(widgetToResize, 1, 1);
Assert.assertEquals(1, widgetToResize.getColspan());
Assert.assertEquals(1, widgetToResize.getRowspan());
}
- private void fireItemResizeEndEvent(DashboardWidget widget,
- int targetColspan, int targetRowspan) {
- ComponentUtil.fireEvent(dashboard,
- new DashboardItemResizeEndEvent(dashboard, false,
- widget.getElement().getNode().getId(), targetColspan,
- targetRowspan));
+ private void fireItemResizedEvent(DashboardWidget widget, int targetColspan,
+ int targetRowspan) {
+ JsonObject eventData = Json.createObject();
+ eventData.put("event.detail.item.nodeid",
+ widget.getElement().getNode().getId());
+ eventData.put("event.detail.item.rowspan", targetRowspan);
+ eventData.put("event.detail.item.colspan", targetColspan);
+ DomEvent itemResizedDomEvent = new DomEvent(dashboard.getElement(),
+ "dashboard-item-resized", eventData);
+ dashboard.getElement().getNode().getFeature(ElementListenerMap.class)
+ .fireEvent(itemResizedDomEvent);
}
}
diff --git a/vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/test/java/com/vaadin/flow/component/dashboard/tests/DashboardTest.java b/vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/test/java/com/vaadin/flow/component/dashboard/tests/DashboardTest.java
index b6cdaf46836..8c73e5eabd5 100644
--- a/vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/test/java/com/vaadin/flow/component/dashboard/tests/DashboardTest.java
+++ b/vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/test/java/com/vaadin/flow/component/dashboard/tests/DashboardTest.java
@@ -8,19 +8,27 @@
*/
package com.vaadin.flow.component.dashboard.tests;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
-import com.vaadin.flow.component.ComponentUtil;
+import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.dashboard.Dashboard;
-import com.vaadin.flow.component.dashboard.DashboardItemRemovedEvent;
import com.vaadin.flow.component.dashboard.DashboardSection;
import com.vaadin.flow.component.dashboard.DashboardWidget;
import com.vaadin.flow.component.html.Div;
+import com.vaadin.flow.dom.DomEvent;
+import com.vaadin.flow.internal.nodefeature.ElementListenerMap;
+
+import elemental.json.Json;
+import elemental.json.JsonObject;
public class DashboardTest extends DashboardTestBase {
private Dashboard dashboard;
@@ -852,6 +860,56 @@ public void setDashboardEditable_removeWidget_widgetIsRemoved() {
Assert.assertFalse(actualNodeIds.contains(nodeIdToBeRemoved));
}
+ public void setDashboardEditable_removeWidget_eventCorrectlyFired() {
+ dashboard.setEditable(true);
+ DashboardWidget widget = new DashboardWidget();
+ dashboard.add(widget);
+ fakeClientCommunication();
+ int removedWidgetNodeId = widget.getElement().getNode().getId();
+ List expectedItems = dashboard.getChildren()
+ .collect(Collectors.toCollection(ArrayList::new));
+ expectedItems.remove(widget);
+ assertItemRemoveEventCorrectlyFired(removedWidgetNodeId, 1, widget,
+ expectedItems);
+ }
+
+ @Test
+ public void setDashboardEditable_removeSection_eventCorrectlyFired() {
+ dashboard.setEditable(true);
+ DashboardSection section = dashboard.addSection();
+ fakeClientCommunication();
+ int removedSectionNodeId = section.getElement().getNode().getId();
+ List expectedItems = dashboard.getChildren()
+ .collect(Collectors.toCollection(ArrayList::new));
+ expectedItems.remove(section);
+ assertItemRemoveEventCorrectlyFired(removedSectionNodeId, 1, section,
+ expectedItems);
+ }
+
+ @Test
+ public void setDashboardEditable_removeWidgetInSection_eventCorrectlyFired() {
+ dashboard.setEditable(true);
+ DashboardSection section = dashboard.addSection();
+ DashboardWidget widget = new DashboardWidget();
+ section.add(widget);
+ fakeClientCommunication();
+ int removedWidgetNodeId = widget.getElement().getNode().getId();
+ List expectedItems = dashboard.getChildren()
+ .collect(Collectors.toCollection(ArrayList::new));
+ expectedItems.remove(widget);
+ assertItemRemoveEventCorrectlyFired(removedWidgetNodeId, 1, widget,
+ expectedItems);
+ }
+
+ @Test
+ public void dashboardNotEditable_removeWidget_eventNotFired() {
+ DashboardWidget widget = new DashboardWidget();
+ dashboard.add(widget);
+ fakeClientCommunication();
+ int removedWidgetNodeId = widget.getElement().getNode().getId();
+ assertItemRemoveEventCorrectlyFired(removedWidgetNodeId, 0, null, null);
+ }
+
@Test
public void setDashboardVisibility_exceptionIsThrown() {
Assert.assertThrows(UnsupportedOperationException.class,
@@ -880,8 +938,33 @@ public void getSectionVisibility_returnsTrue() {
Assert.assertTrue(section.isVisible());
}
+ private void assertItemRemoveEventCorrectlyFired(int nodeIdToRemove,
+ int expectedListenerInvokedCount, Component expectedRemovedItem,
+ List expectedItems) {
+ AtomicInteger listenerInvokedCount = new AtomicInteger(0);
+ AtomicReference eventRemovedItem = new AtomicReference<>();
+ AtomicReference> eventItems = new AtomicReference<>();
+ dashboard.addItemRemovedListener(e -> {
+ listenerInvokedCount.incrementAndGet();
+ eventRemovedItem.set(e.getItem());
+ eventItems.set(e.getItems());
+ e.unregisterListener();
+ });
+ fireItemRemovedEvent(nodeIdToRemove);
+ Assert.assertEquals(expectedListenerInvokedCount,
+ listenerInvokedCount.get());
+ if (expectedListenerInvokedCount > 0) {
+ Assert.assertEquals(expectedRemovedItem, eventRemovedItem.get());
+ Assert.assertEquals(expectedItems, eventItems.get());
+ }
+ }
+
private void fireItemRemovedEvent(int nodeId) {
- ComponentUtil.fireEvent(dashboard,
- new DashboardItemRemovedEvent(dashboard, false, nodeId));
+ JsonObject eventData = Json.createObject();
+ eventData.put("event.detail.item.nodeid", nodeId);
+ DomEvent itemRemovedDomEvent = new DomEvent(dashboard.getElement(),
+ "dashboard-item-removed", eventData);
+ dashboard.getElement().getNode().getFeature(ElementListenerMap.class)
+ .fireEvent(itemRemovedDomEvent);
}
}