From 866133c85cdd6adeefb3ae805ebf2e15dd0ad022 Mon Sep 17 00:00:00 2001 From: ugur-vaadin Date: Mon, 16 Sep 2024 17:23:17 +0300 Subject: [PATCH 1/4] feat: add drag resize support to dashboard --- ...age.java => DashboardDragReorderPage.java} | 6 +- .../tests/DashboardDragResizePage.java | 58 +++++++ ...ropIT.java => DashboardDragReorderIT.java} | 28 ++-- .../tests/DashboardDragResizeIT.java | 157 ++++++++++++++++++ .../flow/component/dashboard/Dashboard.java | 36 ++++ .../DashboardItemResizeEndEvent.java | 82 +++++++++ .../DashboardItemResizeStartEvent.java | 52 ++++++ ...est.java => DashboardDragReorderTest.java} | 2 +- .../tests/DashboardDragResizeTest.java | 87 ++++++++++ 9 files changed, 489 insertions(+), 19 deletions(-) rename vaadin-dashboard-flow-parent/vaadin-dashboard-flow-integration-tests/src/main/java/com/vaadin/flow/component/dashboard/tests/{DashboardDragDropPage.java => DashboardDragReorderPage.java} (94%) create mode 100644 vaadin-dashboard-flow-parent/vaadin-dashboard-flow-integration-tests/src/main/java/com/vaadin/flow/component/dashboard/tests/DashboardDragResizePage.java rename vaadin-dashboard-flow-parent/vaadin-dashboard-flow-integration-tests/src/test/java/com/vaadin/flow/component/dashboard/tests/{DashboardDragDropIT.java => DashboardDragReorderIT.java} (78%) create mode 100644 vaadin-dashboard-flow-parent/vaadin-dashboard-flow-integration-tests/src/test/java/com/vaadin/flow/component/dashboard/tests/DashboardDragResizeIT.java create mode 100644 vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/main/java/com/vaadin/flow/component/dashboard/DashboardItemResizeEndEvent.java create mode 100644 vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/main/java/com/vaadin/flow/component/dashboard/DashboardItemResizeStartEvent.java rename vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/test/java/com/vaadin/flow/component/dashboard/tests/{DashboardDragDropTest.java => DashboardDragReorderTest.java} (98%) create mode 100644 vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/test/java/com/vaadin/flow/component/dashboard/tests/DashboardDragResizeTest.java diff --git a/vaadin-dashboard-flow-parent/vaadin-dashboard-flow-integration-tests/src/main/java/com/vaadin/flow/component/dashboard/tests/DashboardDragDropPage.java b/vaadin-dashboard-flow-parent/vaadin-dashboard-flow-integration-tests/src/main/java/com/vaadin/flow/component/dashboard/tests/DashboardDragReorderPage.java similarity index 94% rename from vaadin-dashboard-flow-parent/vaadin-dashboard-flow-integration-tests/src/main/java/com/vaadin/flow/component/dashboard/tests/DashboardDragDropPage.java rename to vaadin-dashboard-flow-parent/vaadin-dashboard-flow-integration-tests/src/main/java/com/vaadin/flow/component/dashboard/tests/DashboardDragReorderPage.java index 71fd88d187d..3228dae5a0d 100644 --- a/vaadin-dashboard-flow-parent/vaadin-dashboard-flow-integration-tests/src/main/java/com/vaadin/flow/component/dashboard/tests/DashboardDragDropPage.java +++ b/vaadin-dashboard-flow-parent/vaadin-dashboard-flow-integration-tests/src/main/java/com/vaadin/flow/component/dashboard/tests/DashboardDragReorderPage.java @@ -18,10 +18,10 @@ /** * @author Vaadin Ltd */ -@Route("vaadin-dashboard/drag-drop") -public class DashboardDragDropPage extends Div { +@Route("vaadin-dashboard/drag-reorder") +public class DashboardDragReorderPage extends Div { - public DashboardDragDropPage() { + public DashboardDragReorderPage() { Dashboard dashboard = new Dashboard(); dashboard.setEditable(true); dashboard.setMinimumRowHeight("100px"); diff --git a/vaadin-dashboard-flow-parent/vaadin-dashboard-flow-integration-tests/src/main/java/com/vaadin/flow/component/dashboard/tests/DashboardDragResizePage.java b/vaadin-dashboard-flow-parent/vaadin-dashboard-flow-integration-tests/src/main/java/com/vaadin/flow/component/dashboard/tests/DashboardDragResizePage.java new file mode 100644 index 00000000000..db35d91ea0f --- /dev/null +++ b/vaadin-dashboard-flow-parent/vaadin-dashboard-flow-integration-tests/src/main/java/com/vaadin/flow/component/dashboard/tests/DashboardDragResizePage.java @@ -0,0 +1,58 @@ +/** + * 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.tests; + +import com.vaadin.flow.component.dashboard.Dashboard; +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.component.html.NativeButton; +import com.vaadin.flow.router.Route; + +/** + * @author Vaadin Ltd + */ +@Route("vaadin-dashboard/drag-resize") +public class DashboardDragResizePage extends Div { + + public DashboardDragResizePage() { + Dashboard dashboard = new Dashboard(); + dashboard.setEditable(true); + dashboard.setMinimumRowHeight("200px"); + dashboard.setMinimumColumnWidth("250px"); + dashboard.setMaximumColumnWidth("250px"); + + DashboardWidget smallWidget = new DashboardWidget(); + smallWidget.setTitle("Small widget"); + + DashboardWidget largeWidget = new DashboardWidget(); + largeWidget.setTitle("Large widget"); + largeWidget.setColspan(2); + largeWidget.setRowspan(2); + + dashboard.add(smallWidget, largeWidget); + + DashboardWidget smallWidgetInSection = new DashboardWidget(); + smallWidgetInSection.setTitle("Small widget in section"); + + DashboardWidget largeWidgetInSection = new DashboardWidget(); + largeWidgetInSection.setTitle("Large widget in section"); + largeWidgetInSection.setColspan(2); + largeWidgetInSection.setRowspan(2); + + DashboardSection section = dashboard.addSection("Section"); + section.add(smallWidgetInSection, largeWidgetInSection); + + NativeButton toggleEditable = new NativeButton("Toggle editable", + e -> dashboard.setEditable(!dashboard.isEditable())); + toggleEditable.setId("toggle-editable"); + + add(toggleEditable, dashboard); + } +} diff --git a/vaadin-dashboard-flow-parent/vaadin-dashboard-flow-integration-tests/src/test/java/com/vaadin/flow/component/dashboard/tests/DashboardDragDropIT.java b/vaadin-dashboard-flow-parent/vaadin-dashboard-flow-integration-tests/src/test/java/com/vaadin/flow/component/dashboard/tests/DashboardDragReorderIT.java similarity index 78% rename from vaadin-dashboard-flow-parent/vaadin-dashboard-flow-integration-tests/src/test/java/com/vaadin/flow/component/dashboard/tests/DashboardDragDropIT.java rename to vaadin-dashboard-flow-parent/vaadin-dashboard-flow-integration-tests/src/test/java/com/vaadin/flow/component/dashboard/tests/DashboardDragReorderIT.java index 3812195cb5a..8b9c4eaf041 100644 --- a/vaadin-dashboard-flow-parent/vaadin-dashboard-flow-integration-tests/src/test/java/com/vaadin/flow/component/dashboard/tests/DashboardDragDropIT.java +++ b/vaadin-dashboard-flow-parent/vaadin-dashboard-flow-integration-tests/src/test/java/com/vaadin/flow/component/dashboard/tests/DashboardDragReorderIT.java @@ -21,8 +21,8 @@ /** * @author Vaadin Ltd */ -@TestPath("vaadin-dashboard/drag-drop") -public class DashboardDragDropIT extends AbstractComponentIT { +@TestPath("vaadin-dashboard/drag-reorder") +public class DashboardDragReorderIT extends AbstractComponentIT { private DashboardElement dashboardElement; @@ -36,7 +36,7 @@ public void init() { public void reorderWidgetOnClientSide_itemsAreReorderedCorrectly() { var draggedWidget = dashboardElement.getWidgets().get(0); var targetWidget = dashboardElement.getWidgets().get(1); - dragDropElement(draggedWidget, targetWidget); + dragResizeElement(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); - dragDropElement(draggedSection, targetWidget); + dragResizeElement(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); - dragDropElement(draggedWidget, targetWidget); + dragResizeElement(draggedWidget, targetWidget); firstSection = dashboardElement.getSections().get(0); Assert.assertEquals(draggedWidget.getTitle(), firstSection.getWidgets().get(1).getTitle()); @@ -70,22 +70,22 @@ public void detachReattach_reorderWidgetOnClientSide_itemsAreReorderedCorrectly( } @Test - public void setDashboardNotEditable_widgetCannotBeDragged() { + public void setDashboardNotEditable_dragHandleNotVisible() { var widget = dashboardElement.getWidgets().get(0); - Assert.assertTrue(isHeaderActionsVisible(widget)); + Assert.assertTrue(isDragHandleVisible(widget)); clickElementWithJs("toggle-editable"); - Assert.assertFalse(isHeaderActionsVisible(widget)); + Assert.assertFalse(isDragHandleVisible(widget)); } @Test - public void setDashboardEditable_widgetCanBeDragged() { + public void setDashboardEditable_dragHandleNotVisible() { clickElementWithJs("toggle-editable"); clickElementWithJs("toggle-editable"); Assert.assertTrue( - isHeaderActionsVisible(dashboardElement.getWidgets().get(0))); + isDragHandleVisible(dashboardElement.getWidgets().get(0))); } - private void dragDropElement(TestBenchElement draggedElement, + private void dragResizeElement(TestBenchElement draggedElement, TestBenchElement targetElement) { var dragHandle = getDragHandle(draggedElement); @@ -99,10 +99,8 @@ private void dragDropElement(TestBenchElement draggedElement, .release(targetElement).build().perform(); } - private static boolean isHeaderActionsVisible(TestBenchElement element) { - TestBenchElement headerActions = element.$("*").withId("header-actions") - .first(); - return !"none".equals(headerActions.getCssValue("display")); + private static boolean isDragHandleVisible(TestBenchElement element) { + return !"none".equals(getDragHandle(element).getCssValue("display")); } private static TestBenchElement getDragHandle(TestBenchElement element) { 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 new file mode 100644 index 00000000000..75feb0ef10b --- /dev/null +++ b/vaadin-dashboard-flow-parent/vaadin-dashboard-flow-integration-tests/src/test/java/com/vaadin/flow/component/dashboard/tests/DashboardDragResizeIT.java @@ -0,0 +1,157 @@ +/** + * 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.tests; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.openqa.selenium.interactions.Actions; + +import com.vaadin.flow.component.dashboard.testbench.DashboardElement; +import com.vaadin.flow.component.dashboard.testbench.DashboardWidgetElement; +import com.vaadin.flow.testutil.TestPath; +import com.vaadin.testbench.TestBenchElement; +import com.vaadin.tests.AbstractComponentIT; + +/** + * @author Vaadin Ltd + */ +@TestPath("vaadin-dashboard/drag-resize") +public class DashboardDragResizeIT extends AbstractComponentIT { + + private DashboardElement dashboardElement; + + @Before + public void init() { + open(); + dashboardElement = $(DashboardElement.class).waitForFirst(); + } + + @Test + public void enlargeWidgetHorizontally_widgetIsEnlargedCorrectly() { + assertWidgetResized(0, 2, 1); + } + + @Test + public void enlargeWidgetVertically_widgetIsEnlargedCorrectly() { + assertWidgetResized(0, 1, 2); + } + + @Test + public void enlargeWidgetBothHorizontallyAndVertically_widgetIsEnlargedCorrectly() { + assertWidgetResized(0, 2, 2); + } + + @Test + public void shrinkWidgetHorizontally_widgetIsShrunkCorrectly() { + assertWidgetResized(1, 0.5, 1); + } + + @Test + public void shrinkWidgetVertically_widgetIsShrunkCorrectly() { + assertWidgetResized(1, 1, 0.5); + } + + @Test + public void shrinkWidgetBothHorizontallyAndVertically_widgetIsShrunkCorrectly() { + assertWidgetResized(1, 0.5, 0.5); + } + + @Test + public void enlargeWidgetInSectionHorizontally_widgetIsEnlargedCorrectly() { + assertWidgetResized(2, 2, 1); + } + + @Test + public void enlargeWidgetInSectionVertically_widgetIsEnlargedCorrectly() { + assertWidgetResized(2, 1, 2); + } + + @Test + public void enlargeWidgetInSectionBothHorizontallyAndVertically_widgetIsEnlargedCorrectly() { + assertWidgetResized(2, 2, 2); + } + + @Test + public void shrinkWidgetInSectionHorizontally_widgetIsShrunkCorrectly() { + assertWidgetResized(3, 0.5, 1); + } + + @Test + public void shrinkWidgetInSectionVertically_widgetIsShrunkCorrectly() { + assertWidgetResized(3, 1, 0.5); + } + + @Test + public void shrinkWidgetInSectionBothHorizontallyAndVertically_widgetIsShrunkCorrectly() { + assertWidgetResized(3, 0.5, 0.5); + } + + @Test + public void setDashboardNotEditable_resizeHandleNotVisible() { + var widget = dashboardElement.getWidgets().get(0); + Assert.assertTrue(isResizeHandleVisible(widget)); + clickElementWithJs("toggle-editable"); + Assert.assertFalse(isResizeHandleVisible(widget)); + } + + @Test + public void setDashboardEditable_resizeHandleNotVisible() { + clickElementWithJs("toggle-editable"); + clickElementWithJs("toggle-editable"); + Assert.assertTrue( + isResizeHandleVisible(dashboardElement.getWidgets().get(0))); + } + + private void assertWidgetResized(int widgetIndexToResize, + double xResizeRatio, double yResizeRatio) { + var widgetToResize = dashboardElement.getWidgets() + .get(widgetIndexToResize); + var expectedWidth = widgetToResize.getSize().getWidth() * xResizeRatio; + var expectedHeight = widgetToResize.getSize().getHeight() + * yResizeRatio; + resizeWidget(widgetIndexToResize, xResizeRatio, yResizeRatio); + var resizedWidget = dashboardElement.getWidgets() + .get(widgetIndexToResize); + var delta = 20; + Assert.assertEquals(expectedWidth, resizedWidget.getSize().getWidth(), + delta); + Assert.assertEquals(expectedHeight, resizedWidget.getSize().getHeight(), + delta); + } + + private void resizeWidget(int widgetIndexToResize, double xResizeRatio, + double yResizeRatio) { + var widgetToResize = dashboardElement.getWidgets() + .get(widgetIndexToResize); + var xOffset = (int) (widgetToResize.getSize().getWidth() + * (xResizeRatio - 1)); + var yOffset = (int) (widgetToResize.getSize().getHeight() + * (yResizeRatio - 1)); + TestBenchElement resizeHandle = getResizeHandle(widgetToResize); + int trackStartOffset = 5; + new Actions(driver).moveToElement(resizeHandle).clickAndHold() + // This is necessary for the Polymer track event to be fired. + .moveByOffset(trackStartOffset, trackStartOffset) + .moveByOffset(xOffset - trackStartOffset, + yOffset - trackStartOffset) + .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 b15ae3bff47..82779550bbc 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 @@ -55,6 +55,7 @@ public class Dashboard extends Component implements HasWidgets { public Dashboard() { childDetachHandler = getChildDetachHandler(); addItemReorderEndListener(this::onItemReorderEnd); + addItemResizeEndListener(this::onItemResizeEnd); } /** @@ -325,6 +326,30 @@ public Registration addItemReorderEndListener( 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); + } + @Override public Stream getChildren() { return childrenComponents.stream(); @@ -447,6 +472,17 @@ private void onItemReorderEnd( updateClient(); } + private void onItemResizeEnd( + DashboardItemResizeEndEvent dashboardItemResizeEndEvent) { + int nodeId = dashboardItemResizeEndEvent.getNodeId(); + getWidgets().stream().filter( + widget -> nodeId == widget.getElement().getNode().getId()) + .findAny().ifPresent(widget -> { + widget.setRowspan(dashboardItemResizeEndEvent.getRowspan()); + widget.setColspan(dashboardItemResizeEndEvent.getColspan()); + }); + } + private void reorderItems(JsonArray orderedItemsFromClient) { // Keep references to the root level children before clearing them Map nodeIdToComponent = childrenComponents.stream() 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 new file mode 100644 index 00000000000..5d2aeb3f905 --- /dev/null +++ b/vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/main/java/com/vaadin/flow/component/dashboard/DashboardItemResizeEndEvent.java @@ -0,0 +1,82 @@ +/** + * 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 int nodeId; + + private final int colspan; + + private final int rowspan; + + /** + * 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 + * @param nodeId + * Node ID the resized item + * @param colspan + * New colspan of the resized item + * @param rowspan + * New rowspan of the resized item + */ + 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.nodeId = nodeId; + this.colspan = colspan; + this.rowspan = rowspan; + } + + /** + * Returns the node ID of the resized item + * + * @return node ID of the resized item + */ + public int getNodeId() { + return nodeId; + } + + /** + * 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 new file mode 100644 index 00000000000..ff5cec26062 --- /dev/null +++ b/vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/main/java/com/vaadin/flow/component/dashboard/DashboardItemResizeStartEvent.java @@ -0,0 +1,52 @@ +/** + * 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 int nodeId; + + /** + * 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 + * @param nodeId + * Node ID the resized item + */ + public DashboardItemResizeStartEvent(Dashboard source, boolean fromClient, + @EventData("event.detail.item.nodeid") int nodeId) { + super(source, fromClient); + this.nodeId = nodeId; + } + + /** + * Returns the node ID of the resized item + * + * @return node ID of the resized item + */ + public int getNodeId() { + return nodeId; + } +} diff --git a/vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/test/java/com/vaadin/flow/component/dashboard/tests/DashboardDragDropTest.java b/vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/test/java/com/vaadin/flow/component/dashboard/tests/DashboardDragReorderTest.java similarity index 98% rename from vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/test/java/com/vaadin/flow/component/dashboard/tests/DashboardDragDropTest.java rename to vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/test/java/com/vaadin/flow/component/dashboard/tests/DashboardDragReorderTest.java index a1924235508..e61af6cee62 100644 --- a/vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/test/java/com/vaadin/flow/component/dashboard/tests/DashboardDragDropTest.java +++ b/vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/test/java/com/vaadin/flow/component/dashboard/tests/DashboardDragReorderTest.java @@ -26,7 +26,7 @@ import elemental.json.JsonArray; import elemental.json.JsonObject; -public class DashboardDragDropTest extends DashboardTestBase { +public class DashboardDragReorderTest extends DashboardTestBase { private Dashboard dashboard; private JsonArray itemsArray; 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 new file mode 100644 index 00000000000..3a8771341c2 --- /dev/null +++ b/vaadin-dashboard-flow-parent/vaadin-dashboard-flow/src/test/java/com/vaadin/flow/component/dashboard/tests/DashboardDragResizeTest.java @@ -0,0 +1,87 @@ +/** + * 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.tests; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.vaadin.flow.component.ComponentUtil; +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; + +public class DashboardDragResizeTest extends DashboardTestBase { + private Dashboard dashboard; + + @Before + @Override + public void setup() { + super.setup(); + dashboard = new Dashboard(); + dashboard.add(new DashboardWidget()); + DashboardSection section = dashboard.addSection(); + section.add(new DashboardWidget()); + getUi().add(dashboard); + fakeClientCommunication(); + } + + @Test + public void resizeWidgetHorizontally_sizeIsUpdated() { + assertWidgetResized(0, 2, 1); + } + + @Test + public void resizeWidgetVertically_sizeIsUpdated() { + assertWidgetResized(0, 1, 2); + } + + @Test + public void resizeWidgetBothHorizontallyAndVertically_sizeIsUpdated() { + assertWidgetResized(0, 2, 2); + } + + @Test + public void resizeWidgetInSectionHorizontally_sizeIsUpdated() { + assertWidgetResized(1, 2, 1); + } + + @Test + public void resizeWidgetInSectionVertically_sizeIsUpdated() { + assertWidgetResized(1, 1, 2); + } + + @Test + public void resizeWidgetInSectionBothHorizontallyAndVertically_sizeIsUpdated() { + assertWidgetResized(1, 2, 2); + } + + private void assertWidgetResized(int widgetIndexToResize, int targetColspan, + int targetRowspan) { + DashboardWidget widgetToResize = dashboard.getWidgets() + .get(widgetIndexToResize); + // Assert widget is enlarged + fireItemResizeEndEvent(widgetToResize, targetColspan, targetRowspan); + Assert.assertEquals(targetColspan, widgetToResize.getColspan()); + Assert.assertEquals(targetRowspan, widgetToResize.getRowspan()); + // Assert widget is shrunk + fireItemResizeEndEvent(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)); + } +} From 9bcbe9b2ba3f5e4df0d2e07ef910ce14ca910c99 Mon Sep 17 00:00:00 2001 From: ugur-vaadin Date: Tue, 17 Sep 2024 09:49:51 +0300 Subject: [PATCH 2/4] refactor: make resize events return the item instead of node id --- .../flow/component/dashboard/Dashboard.java | 11 ++++------- .../dashboard/DashboardItemResizeEndEvent.java | 15 +++++++++------ .../dashboard/DashboardItemResizeStartEvent.java | 15 +++++++++------ 3 files changed, 22 insertions(+), 19 deletions(-) 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 82779550bbc..f1f428b086d 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 @@ -474,13 +474,10 @@ private void onItemReorderEnd( private void onItemResizeEnd( DashboardItemResizeEndEvent dashboardItemResizeEndEvent) { - int nodeId = dashboardItemResizeEndEvent.getNodeId(); - getWidgets().stream().filter( - widget -> nodeId == widget.getElement().getNode().getId()) - .findAny().ifPresent(widget -> { - widget.setRowspan(dashboardItemResizeEndEvent.getRowspan()); - widget.setColspan(dashboardItemResizeEndEvent.getColspan()); - }); + DashboardWidget resizedWidget = (DashboardWidget) dashboardItemResizeEndEvent + .getResizedItem(); + resizedWidget.setRowspan(dashboardItemResizeEndEvent.getRowspan()); + resizedWidget.setColspan(dashboardItemResizeEndEvent.getColspan()); } private void reorderItems(JsonArray orderedItemsFromClient) { 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 index 5d2aeb3f905..3e6442a6418 100644 --- 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 @@ -8,6 +8,7 @@ */ package com.vaadin.flow.component.dashboard; +import com.vaadin.flow.component.Component; import com.vaadin.flow.component.ComponentEvent; import com.vaadin.flow.component.ComponentEventListener; import com.vaadin.flow.component.DomEvent; @@ -22,7 +23,7 @@ @DomEvent("dashboard-item-resize-end") public class DashboardItemResizeEndEvent extends ComponentEvent { - private final int nodeId; + private final Component resizedItem; private final int colspan; @@ -48,18 +49,20 @@ public DashboardItemResizeEndEvent(Dashboard source, boolean fromClient, @EventData("event.detail.item.colspan") int colspan, @EventData("event.detail.item.rowspan") int rowspan) { super(source, fromClient); - this.nodeId = nodeId; + this.resizedItem = source.getWidgets().stream() + .filter(child -> nodeId == child.getElement().getNode().getId()) + .findAny().orElse(null); this.colspan = colspan; this.rowspan = rowspan; } /** - * Returns the node ID of the resized item + * Returns the resized item * - * @return node ID of the resized item + * @return the resized item */ - public int getNodeId() { - return nodeId; + public Component getResizedItem() { + return resizedItem; } /** 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 index ff5cec26062..f592cee8bb5 100644 --- 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 @@ -8,6 +8,7 @@ */ package com.vaadin.flow.component.dashboard; +import com.vaadin.flow.component.Component; import com.vaadin.flow.component.ComponentEvent; import com.vaadin.flow.component.ComponentEventListener; import com.vaadin.flow.component.DomEvent; @@ -22,7 +23,7 @@ @DomEvent("dashboard-item-resize-start") public class DashboardItemResizeStartEvent extends ComponentEvent { - private final int nodeId; + private final Component resizedItem; /** * Creates a dashboard item reorder start event. @@ -38,15 +39,17 @@ public class DashboardItemResizeStartEvent extends ComponentEvent { public DashboardItemResizeStartEvent(Dashboard source, boolean fromClient, @EventData("event.detail.item.nodeid") int nodeId) { super(source, fromClient); - this.nodeId = nodeId; + this.resizedItem = source.getWidgets().stream() + .filter(child -> nodeId == child.getElement().getNode().getId()) + .findAny().orElse(null); } /** - * Returns the node ID of the resized item + * Returns the resized item * - * @return node ID of the resized item + * @return the resized item */ - public int getNodeId() { - return nodeId; + public Component getResizedItem() { + return resizedItem; } } From 46b7b5e4b4a8fdacc8cc666bf910de9d9ebd3a70 Mon Sep 17 00:00:00 2001 From: ugur-vaadin Date: Tue, 17 Sep 2024 10:09:17 +0300 Subject: [PATCH 3/4] refactor: return widget instead of component in resize events --- .../flow/component/dashboard/Dashboard.java | 4 ++-- .../DashboardItemResizeEndEvent.java | 23 +++++++++---------- .../DashboardItemResizeStartEvent.java | 19 ++++++++------- 3 files changed, 22 insertions(+), 24 deletions(-) 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 f1f428b086d..4a337e8be42 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 @@ -474,8 +474,8 @@ private void onItemReorderEnd( private void onItemResizeEnd( DashboardItemResizeEndEvent dashboardItemResizeEndEvent) { - DashboardWidget resizedWidget = (DashboardWidget) dashboardItemResizeEndEvent - .getResizedItem(); + DashboardWidget resizedWidget = dashboardItemResizeEndEvent + .getResizedWidget(); resizedWidget.setRowspan(dashboardItemResizeEndEvent.getRowspan()); resizedWidget.setColspan(dashboardItemResizeEndEvent.getColspan()); } 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 index 3e6442a6418..013ec38963c 100644 --- 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 @@ -8,7 +8,6 @@ */ package com.vaadin.flow.component.dashboard; -import com.vaadin.flow.component.Component; import com.vaadin.flow.component.ComponentEvent; import com.vaadin.flow.component.ComponentEventListener; import com.vaadin.flow.component.DomEvent; @@ -23,33 +22,33 @@ @DomEvent("dashboard-item-resize-end") public class DashboardItemResizeEndEvent extends ComponentEvent { - private final Component resizedItem; + private final DashboardWidget resizedWidget; private final int colspan; private final int rowspan; /** - * Creates a dashboard item reorder end event. + * Creates a dashboard item resize end event. * * @param source - * Dashboard that contains the item that was dragged + * 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 item + * Node ID the resized widget * @param colspan - * New colspan of the resized item + * New colspan of the resized widget * @param rowspan - * New rowspan of the resized item + * 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.resizedItem = source.getWidgets().stream() + this.resizedWidget = source.getWidgets().stream() .filter(child -> nodeId == child.getElement().getNode().getId()) .findAny().orElse(null); this.colspan = colspan; @@ -57,12 +56,12 @@ public DashboardItemResizeEndEvent(Dashboard source, boolean fromClient, } /** - * Returns the resized item + * Returns the resized widget * - * @return the resized item + * @return the resized widget */ - public Component getResizedItem() { - return resizedItem; + public DashboardWidget getResizedWidget() { + return resizedWidget; } /** 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 index f592cee8bb5..ce762351439 100644 --- 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 @@ -8,7 +8,6 @@ */ package com.vaadin.flow.component.dashboard; -import com.vaadin.flow.component.Component; import com.vaadin.flow.component.ComponentEvent; import com.vaadin.flow.component.ComponentEventListener; import com.vaadin.flow.component.DomEvent; @@ -23,33 +22,33 @@ @DomEvent("dashboard-item-resize-start") public class DashboardItemResizeStartEvent extends ComponentEvent { - private final Component resizedItem; + private final DashboardWidget resizedWidget; /** - * Creates a dashboard item reorder start event. + * Creates a dashboard item resize start event. * * @param source - * Dashboard that contains the item that was dragged + * 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 item + * Node ID the resized widget */ public DashboardItemResizeStartEvent(Dashboard source, boolean fromClient, @EventData("event.detail.item.nodeid") int nodeId) { super(source, fromClient); - this.resizedItem = source.getWidgets().stream() + this.resizedWidget = source.getWidgets().stream() .filter(child -> nodeId == child.getElement().getNode().getId()) .findAny().orElse(null); } /** - * Returns the resized item + * Returns the resized widget * - * @return the resized item + * @return the resized widget */ - public Component getResizedItem() { - return resizedItem; + public DashboardWidget getResizedWidget() { + return resizedWidget; } } From 70442d12a6c174fe805a3305d358822050ce2589 Mon Sep 17 00:00:00 2001 From: ugur-vaadin Date: Tue, 17 Sep 2024 10:27:10 +0300 Subject: [PATCH 4/4] test: simplify resize it page and tests --- .../tests/DashboardDragResizePage.java | 24 ++----- .../tests/DashboardDragResizeIT.java | 65 +++---------------- 2 files changed, 15 insertions(+), 74 deletions(-) diff --git a/vaadin-dashboard-flow-parent/vaadin-dashboard-flow-integration-tests/src/main/java/com/vaadin/flow/component/dashboard/tests/DashboardDragResizePage.java b/vaadin-dashboard-flow-parent/vaadin-dashboard-flow-integration-tests/src/main/java/com/vaadin/flow/component/dashboard/tests/DashboardDragResizePage.java index db35d91ea0f..d8a54a95117 100644 --- a/vaadin-dashboard-flow-parent/vaadin-dashboard-flow-integration-tests/src/main/java/com/vaadin/flow/component/dashboard/tests/DashboardDragResizePage.java +++ b/vaadin-dashboard-flow-parent/vaadin-dashboard-flow-integration-tests/src/main/java/com/vaadin/flow/component/dashboard/tests/DashboardDragResizePage.java @@ -28,26 +28,14 @@ public DashboardDragResizePage() { dashboard.setMinimumColumnWidth("250px"); dashboard.setMaximumColumnWidth("250px"); - DashboardWidget smallWidget = new DashboardWidget(); - smallWidget.setTitle("Small widget"); - - DashboardWidget largeWidget = new DashboardWidget(); - largeWidget.setTitle("Large widget"); - largeWidget.setColspan(2); - largeWidget.setRowspan(2); - - dashboard.add(smallWidget, largeWidget); - - DashboardWidget smallWidgetInSection = new DashboardWidget(); - smallWidgetInSection.setTitle("Small widget in section"); - - DashboardWidget largeWidgetInSection = new DashboardWidget(); - largeWidgetInSection.setTitle("Large widget in section"); - largeWidgetInSection.setColspan(2); - largeWidgetInSection.setRowspan(2); + DashboardWidget widget = new DashboardWidget(); + widget.setTitle("Widget"); + dashboard.add(widget); + DashboardWidget widgetInSection = new DashboardWidget(); + widgetInSection.setTitle("Widget in section"); DashboardSection section = dashboard.addSection("Section"); - section.add(smallWidgetInSection, largeWidgetInSection); + section.add(widgetInSection); NativeButton toggleEditable = new NativeButton("Toggle editable", e -> dashboard.setEditable(!dashboard.isEditable())); 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 75feb0ef10b..7e10446592c 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 @@ -11,6 +11,7 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; +import org.openqa.selenium.Dimension; import org.openqa.selenium.interactions.Actions; import com.vaadin.flow.component.dashboard.testbench.DashboardElement; @@ -30,67 +31,18 @@ public class DashboardDragResizeIT extends AbstractComponentIT { @Before public void init() { open(); + getDriver().manage().window().setSize(new Dimension(1920, 1080)); dashboardElement = $(DashboardElement.class).waitForFirst(); } @Test - public void enlargeWidgetHorizontally_widgetIsEnlargedCorrectly() { - assertWidgetResized(0, 2, 1); + public void resizeWidgetBothHorizontallyAndVertically_widgetIsResizedCorrectly() { + assertWidgetResized(0); } @Test - public void enlargeWidgetVertically_widgetIsEnlargedCorrectly() { - assertWidgetResized(0, 1, 2); - } - - @Test - public void enlargeWidgetBothHorizontallyAndVertically_widgetIsEnlargedCorrectly() { - assertWidgetResized(0, 2, 2); - } - - @Test - public void shrinkWidgetHorizontally_widgetIsShrunkCorrectly() { - assertWidgetResized(1, 0.5, 1); - } - - @Test - public void shrinkWidgetVertically_widgetIsShrunkCorrectly() { - assertWidgetResized(1, 1, 0.5); - } - - @Test - public void shrinkWidgetBothHorizontallyAndVertically_widgetIsShrunkCorrectly() { - assertWidgetResized(1, 0.5, 0.5); - } - - @Test - public void enlargeWidgetInSectionHorizontally_widgetIsEnlargedCorrectly() { - assertWidgetResized(2, 2, 1); - } - - @Test - public void enlargeWidgetInSectionVertically_widgetIsEnlargedCorrectly() { - assertWidgetResized(2, 1, 2); - } - - @Test - public void enlargeWidgetInSectionBothHorizontallyAndVertically_widgetIsEnlargedCorrectly() { - assertWidgetResized(2, 2, 2); - } - - @Test - public void shrinkWidgetInSectionHorizontally_widgetIsShrunkCorrectly() { - assertWidgetResized(3, 0.5, 1); - } - - @Test - public void shrinkWidgetInSectionVertically_widgetIsShrunkCorrectly() { - assertWidgetResized(3, 1, 0.5); - } - - @Test - public void shrinkWidgetInSectionBothHorizontallyAndVertically_widgetIsShrunkCorrectly() { - assertWidgetResized(3, 0.5, 0.5); + public void resizeWidgetInSectionBothHorizontallyAndVertically_widgetIsResizedCorrectly() { + assertWidgetResized(1); } @Test @@ -109,10 +61,11 @@ public void setDashboardEditable_resizeHandleNotVisible() { isResizeHandleVisible(dashboardElement.getWidgets().get(0))); } - private void assertWidgetResized(int widgetIndexToResize, - double xResizeRatio, double yResizeRatio) { + private void assertWidgetResized(int widgetIndexToResize) { var widgetToResize = dashboardElement.getWidgets() .get(widgetIndexToResize); + int xResizeRatio = 2; + int yResizeRatio = 2; var expectedWidth = widgetToResize.getSize().getWidth() * xResizeRatio; var expectedHeight = widgetToResize.getSize().getHeight() * yResizeRatio;