Skip to content

Commit

Permalink
feat: add dashboard sections support (#6606)
Browse files Browse the repository at this point in the history
* feat: add dashboard sections support

* feat: use components to set items on the client side (#6610)

* refactor: restore patching virtual container to fix its

* test: add its that cover more cases updating the client

* refactor: make detach handler implement detach listener
  • Loading branch information
ugur-vaadin committed Oct 10, 2024
1 parent 8560327 commit 621ec81
Show file tree
Hide file tree
Showing 10 changed files with 1,128 additions and 207 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
package com.vaadin.flow.component.dashboard.tests;

import java.util.List;
import java.util.Optional;

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;
Expand All @@ -23,6 +25,8 @@
public class DashboardPage extends Div {

public DashboardPage() {
Dashboard dashboard = new Dashboard();

DashboardWidget widget1 = new DashboardWidget();
widget1.setTitle("Widget 1");
widget1.setId("widget-1");
Expand All @@ -35,18 +39,39 @@ public DashboardPage() {
widget3.setTitle("Widget 3");
widget3.setId("widget-3");

Dashboard dashboard = new Dashboard();
DashboardWidget widget1InSection1 = new DashboardWidget();
widget1InSection1.setTitle("Widget 1 in Section 1");
widget1InSection1.setId("widget-1-in-section-1");

DashboardWidget widget2InSection1 = new DashboardWidget();
widget2InSection1.setTitle("Widget 2 in Section 1");
widget2InSection1.setId("widget-2-in-section-1");

DashboardWidget widget1InSection2 = new DashboardWidget();
widget1InSection2.setTitle("Widget 1 in Section 2");
widget1InSection2.setId("widget-1-in-section-2");

dashboard.add(widget1, widget2, widget3);

NativeButton addWidgetAtIndex1 = new NativeButton(
"Add widget at index 1");
addWidgetAtIndex1.addClickListener(click -> {
DashboardWidget widgetAtIndex1 = new DashboardWidget();
widgetAtIndex1.setTitle("Widget at index 1");
widgetAtIndex1.setId("widget-at-index-1");
dashboard.addWidgetAtIndex(1, widgetAtIndex1);
DashboardSection section1 = new DashboardSection("Section 1");
section1.add(widget1InSection1, widget2InSection1);
dashboard.addSection(section1);

DashboardSection section2 = dashboard.addSection("Section 2");
section2.add(widget1InSection2);

NativeButton addMultipleWidgets = new NativeButton(
"Add multiple widgets");
addMultipleWidgets.addClickListener(click -> {
DashboardWidget newWidget1 = new DashboardWidget();
newWidget1.setTitle("New widget 1");
DashboardWidget newWidget2 = new DashboardWidget();
newWidget2.setTitle("New widget 2");
dashboard.add(newWidget2);
dashboard.addWidgetAtIndex(
(int) (dashboard.getChildren().count() - 1), newWidget1);
});
addWidgetAtIndex1.setId("add-widget-at-index-1");
addMultipleWidgets.setId("add-multiple-widgets");

NativeButton removeFirstAndLastWidgets = new NativeButton(
"Remove first and last widgets");
Expand All @@ -57,17 +82,69 @@ public DashboardPage() {
}
int currentWidgetCount = currentWidgets.size();
if (currentWidgetCount == 1) {
dashboard.remove(dashboard.getWidgets().get(0));
dashboard.getWidgets().get(0).removeFromParent();
} else {
dashboard.remove(dashboard.getWidgets().get(0),
dashboard.getWidgets().get(currentWidgetCount - 1));
dashboard.getWidgets().get(currentWidgetCount - 1)
.removeFromParent();
dashboard.getWidgets().get(0).removeFromParent();
}
});
removeFirstAndLastWidgets.setId("remove-first-and-last-widgets");

NativeButton removeAllWidgets = new NativeButton("Remove all widgets");
removeAllWidgets.addClickListener(click -> dashboard.removeAll());
removeAllWidgets.setId("remove-all-widgets");
NativeButton removeAll = new NativeButton("Remove all");
removeAll.addClickListener(click -> dashboard.removeAll());
removeAll.setId("remove-all");

NativeButton addSectionWithMultipleWidgets = new NativeButton(
"Add section with multiple widgets");
addSectionWithMultipleWidgets.addClickListener(click -> {
DashboardSection section = dashboard
.addSection("New section with multiple widgets");
DashboardWidget newWidget1 = new DashboardWidget();
newWidget1.setTitle("New widget 1");
DashboardWidget newWidget2 = new DashboardWidget();
newWidget2.setTitle("New widget 2");
section.add(newWidget2);
section.addWidgetAtIndex(0, newWidget1);
});
addSectionWithMultipleWidgets
.setId("add-section-with-multiple-widgets");

NativeButton removeFirstSection = new NativeButton(
"Remove first section");
removeFirstSection.addClickListener(click -> getFirstSection(dashboard)
.ifPresent(dashboard::remove));
removeFirstSection.setId("remove-first-section");

NativeButton addWidgetToFirstSection = new NativeButton(
"Add widget to first section");
addWidgetToFirstSection.addClickListener(
click -> getFirstSection(dashboard).ifPresent(section -> {
DashboardWidget newWidget = new DashboardWidget();
newWidget.setTitle("New widget");
section.add(newWidget);
}));
addWidgetToFirstSection.setId("add-widget-to-first-section");

NativeButton removeFirstWidgetFromFirstSection = new NativeButton(
"Remove first widget from first section");
removeFirstWidgetFromFirstSection.addClickListener(
click -> getFirstSection(dashboard).ifPresent(section -> {
List<DashboardWidget> currentWidgets = section.getWidgets();
if (currentWidgets.isEmpty()) {
return;
}
section.remove(currentWidgets.get(0));
}));
removeFirstWidgetFromFirstSection
.setId("remove-first-widget-from-first-section");

NativeButton removeAllFromFirstSection = new NativeButton(
"Remove all from first section");
removeAllFromFirstSection
.addClickListener(click -> getFirstSection(dashboard)
.ifPresent(DashboardSection::removeAll));
removeAllFromFirstSection.setId("remove-all-from-first-section");

NativeButton setMaximumColumnCount1 = new NativeButton(
"Set maximum column count 1");
Expand All @@ -93,8 +170,18 @@ public DashboardPage() {
.forEach(widget -> widget.setColspan(widget.getColspan() - 1)));
decreaseAllColspansBy1.setId("decrease-all-colspans-by-1");

add(addWidgetAtIndex1, removeFirstAndLastWidgets, removeAllWidgets,
setMaximumColumnCount1, setMaximumColumnCountNull,
increaseAllColspansBy1, decreaseAllColspansBy1, dashboard);
add(addMultipleWidgets, removeFirstAndLastWidgets, removeAll,
addSectionWithMultipleWidgets, removeFirstSection,
addWidgetToFirstSection, removeFirstWidgetFromFirstSection,
removeAllFromFirstSection, setMaximumColumnCount1,
setMaximumColumnCountNull, increaseAllColspansBy1,
decreaseAllColspansBy1, dashboard);
}

private static Optional<DashboardSection> getFirstSection(
Dashboard dashboard) {
return dashboard.getChildren()
.filter(DashboardSection.class::isInstance)
.map(DashboardSection.class::cast).findFirst();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import org.junit.Test;

import com.vaadin.flow.component.dashboard.testbench.DashboardElement;
import com.vaadin.flow.component.dashboard.testbench.DashboardSectionElement;
import com.vaadin.flow.component.dashboard.testbench.DashboardWidgetElement;
import com.vaadin.flow.testutil.TestPath;
import com.vaadin.tests.AbstractComponentIT;
Expand All @@ -35,27 +36,96 @@ public void init() {
}

@Test
public void addWidgets_widgetsAreCorrectlyAdded() {
assertWidgetsByTitle("Widget 1", "Widget 2", "Widget 3");
public void addInitialWidgetsToDashboard_widgetsAreCorrectlyAdded() {
assertDashboardWidgetsByTitle("Widget 1", "Widget 2", "Widget 3",
"Widget 1 in Section 1", "Widget 2 in Section 1",
"Widget 1 in Section 2");
}

@Test
public void addWidgetsAtIndex1_widgetIsAddedIntoTheCorrectPlace() {
clickElementWithJs("add-widget-at-index-1");
assertWidgetsByTitle("Widget 1", "Widget at index 1", "Widget 2",
"Widget 3");
public void addWidgetsToDashboard_widgetsAreCorrectlyAdded() {
clickElementWithJs("add-multiple-widgets");
assertDashboardWidgetsByTitle("Widget 1", "Widget 2", "Widget 3",
"Widget 1 in Section 1", "Widget 2 in Section 1",
"Widget 1 in Section 2", "New widget 1", "New widget 2");
}

@Test
public void removeFirstAndLastWidgets_widgetsAreCorrectlyRemoved() {
public void removeFirstAndLastWidgetsFromDashboard_widgetsAreCorrectlyRemoved() {
clickElementWithJs("remove-first-and-last-widgets");
assertWidgetsByTitle("Widget 2");
assertDashboardWidgetsByTitle("Widget 2", "Widget 3",
"Widget 1 in Section 1", "Widget 2 in Section 1");
}

@Test
public void removeAllWidgets_widgetsAreCorrectlyRemoved() {
clickElementWithJs("remove-all-widgets");
assertWidgetsByTitle();
public void removeAllFromDashboard_widgetsAnsSectionsAreCorrectlyRemoved() {
clickElementWithJs("remove-all");
assertDashboardWidgetsByTitle();
Assert.assertTrue(dashboardElement.getSections().isEmpty());
}

@Test
public void addInitialSectionsWithWidgetsToDashboard_widgetsAreCorrectlyAdded() {
List<DashboardSectionElement> sections = dashboardElement.getSections();
Assert.assertEquals(2, sections.size());

DashboardSectionElement section1 = sections.get(0);
Assert.assertEquals("Section 1", section1.getTitle());
assertSectionWidgetsByTitle(section1, "Widget 1 in Section 1",
"Widget 2 in Section 1");

DashboardSectionElement section2 = sections.get(1);
Assert.assertEquals("Section 2", section2.getTitle());
assertSectionWidgetsByTitle(section2, "Widget 1 in Section 2");
}

@Test
public void addSectionWithWidgets_sectionAndWidgetsAreCorrectlyAdded() {
clickElementWithJs("add-section-with-multiple-widgets");
List<DashboardSectionElement> sections = dashboardElement.getSections();
Assert.assertEquals(3, sections.size());
DashboardSectionElement newSection = sections.get(2);
Assert.assertEquals("New section with multiple widgets",
newSection.getTitle());
assertSectionWidgetsByTitle(newSection, "New widget 1", "New widget 2");
}

@Test
public void removeFirstSection_sectionIsRemoved() {
clickElementWithJs("remove-first-section");
List<DashboardSectionElement> sections = dashboardElement.getSections();
Assert.assertEquals(1, sections.size());
DashboardSectionElement firstSection = sections.get(0);
Assert.assertEquals("Section 2", firstSection.getTitle());
assertSectionWidgetsByTitle(firstSection, "Widget 1 in Section 2");
}

@Test
public void addWidgetToFirstSection_widgetsAreAdded() {
clickElementWithJs("add-widget-to-first-section");
List<DashboardSectionElement> sections = dashboardElement.getSections();
DashboardSectionElement firstSection = sections.get(0);
Assert.assertEquals("Section 1", firstSection.getTitle());
assertSectionWidgetsByTitle(firstSection, "Widget 1 in Section 1",
"Widget 2 in Section 1", "New widget");
}

@Test
public void removeFirstWidgetFromFirstSection_widgetIsRemoved() {
clickElementWithJs("remove-first-widget-from-first-section");
List<DashboardSectionElement> sections = dashboardElement.getSections();
DashboardSectionElement firstSection = sections.get(0);
Assert.assertEquals("Section 1", firstSection.getTitle());
assertSectionWidgetsByTitle(firstSection, "Widget 2 in Section 1");
}

@Test
public void removeAllFromFirstSection_widgetsAreRemoved() {
clickElementWithJs("remove-all-from-first-section");
List<DashboardSectionElement> sections = dashboardElement.getSections();
DashboardSectionElement firstSection = sections.get(0);
Assert.assertEquals("Section 1", firstSection.getTitle());
assertSectionWidgetsByTitle(firstSection);
}

@Test
Expand Down Expand Up @@ -103,9 +173,20 @@ public void updateColspans_colspansForAllWidgetsUpdated() {
widget.getColspan()));
}

private void assertWidgetsByTitle(String... expectedWidgetTitles) {
List<DashboardWidgetElement> widgets = dashboardElement.getWidgets();
List<String> widgetTitles = widgets.stream()
private void assertDashboardWidgetsByTitle(String... expectedWidgetTitles) {
assertWidgetsByTitle(dashboardElement.getWidgets(),
expectedWidgetTitles);
}

private static void assertSectionWidgetsByTitle(
DashboardSectionElement section, String... expectedWidgetTitles) {
assertWidgetsByTitle(section.getWidgets(), expectedWidgetTitles);
}

private static void assertWidgetsByTitle(
List<DashboardWidgetElement> actualWidgets,
String... expectedWidgetTitles) {
List<String> widgetTitles = actualWidgets.stream()
.map(DashboardWidgetElement::getTitle).toList();
Assert.assertEquals(Arrays.asList(expectedWidgetTitles), widgetTitles);
}
Expand Down
Loading

0 comments on commit 621ec81

Please sign in to comment.