Skip to content

Commit

Permalink
feat: add header support to dashboard widget (#6617)
Browse files Browse the repository at this point in the history
* feat: add content related api to dashboard widget

* feat: add header support to dashboard widget

* test: fix merge problems

* test: add missing buttons to test page
  • Loading branch information
ugur-vaadin committed Oct 15, 2024
1 parent 0e2ec79 commit bb49967
Show file tree
Hide file tree
Showing 5 changed files with 167 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public DashboardWidgetPage() {
DashboardWidget widget1 = new DashboardWidget();
widget1.setTitle("Widget 1");
widget1.setContent(new Div("Some content"));
widget1.setHeader(new Span("Some header"));
widget1.setId("widget-1");

DashboardWidget widget2 = new DashboardWidget();
Expand Down Expand Up @@ -83,7 +84,28 @@ public DashboardWidgetPage() {
removeContentOfTheFirstWidget
.setId("remove-content-of-the-first-widget");

NativeButton updateHeaderOfTheFirstWidget = new NativeButton(
"Update header of the first widget");
updateHeaderOfTheFirstWidget.addClickListener(click -> {
List<DashboardWidget> widgets = dashboard.getWidgets();
if (!widgets.isEmpty()) {
widgets.get(0).setHeader(new Span("Updated header"));
}
});
updateHeaderOfTheFirstWidget.setId("update-header-of-the-first-widget");

NativeButton removeHeaderOfTheFirstWidget = new NativeButton(
"Remove header of the first widget");
removeHeaderOfTheFirstWidget.addClickListener(click -> {
List<DashboardWidget> widgets = dashboard.getWidgets();
if (!widgets.isEmpty()) {
widgets.get(0).setHeader(null);
}
});
removeHeaderOfTheFirstWidget.setId("remove-header-of-the-first-widget");

add(updateContentOfTheFirstWidget, removeContentOfTheFirstWidget,
updateHeaderOfTheFirstWidget, removeHeaderOfTheFirstWidget,
increaseAllColspansBy1, decreaseAllColspansBy1,
increaseAllRowspansBy1, decreaseAllRowspansBy1, dashboard);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,4 +104,34 @@ public void removeWidgetContent_contentIsCorrectlyRemoved() {
Assert.assertFalse(firstWidget.getText().contains("Some content"));
Assert.assertNull(firstWidget.getContent());
}

@Test
public void widgetWithInitialHeader_headerIsCorrectlySet() {
DashboardWidgetElement firstWidget = dashboardElement.getWidgets()
.get(0);
Assert.assertNotNull(firstWidget.getHeader());
Assert.assertTrue(
firstWidget.getHeader().getText().contains("Some header"));
}

@Test
public void updateWidgetHeader_headerIsCorrectlyUpdated() {
clickElementWithJs("update-header-of-the-first-widget");
DashboardWidgetElement firstWidget = dashboardElement.getWidgets()
.get(0);
Assert.assertNotNull(firstWidget.getHeader());
Assert.assertFalse(
firstWidget.getHeader().getText().contains("Some header"));
Assert.assertTrue(
firstWidget.getHeader().getText().contains("Updated header"));
}

@Test
public void removeWidgetHeader_headerIsCorrectlyRemoved() {
clickElementWithJs("remove-header-of-the-first-widget");
DashboardWidgetElement firstWidget = dashboardElement.getWidgets()
.get(0);
Assert.assertFalse(firstWidget.getText().contains("Some header"));
Assert.assertNull(firstWidget.getHeader());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import com.vaadin.flow.component.Tag;
import com.vaadin.flow.component.dependency.JsModule;
import com.vaadin.flow.component.dependency.NpmPackage;
import com.vaadin.flow.component.shared.SlotUtils;

/**
* @author Vaadin Ltd
Expand Down Expand Up @@ -132,6 +133,28 @@ public void setContent(Component content) {
}
}

/**
* Gets the component in the header slot of this widget.
*
* @return the header component of this widget, or {@code null} if no header
* component has been set
*/
public Component getHeader() {
return SlotUtils.getChildInSlot(this, "header");
}

/**
* Sets the component in the header slot of this widget, replacing any
* existing header component.
*
* @param header
* the component to set, can be {@code null} to remove existing
* header component
*/
public void setHeader(Component header) {
SlotUtils.setSlot(this, "header", header);
}

private void notifyParentDashboardOrSection() {
getParent().ifPresent(parent -> {
if (parent instanceof Dashboard dashboard) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,86 @@ public void setNullContentToNonEmptyWidget_contentIsRemoved() {
Assert.assertNull(widget.getContent());
}

@Test
public void defaultHeaderIsNull() {
DashboardWidget widget = new DashboardWidget();
Assert.assertNull(widget.getHeader());
}

@Test
public void setHeaderToEmptyWidget_correctHeaderIsSet() {
Div header = new Div();
DashboardWidget widget = new DashboardWidget();
widget.setHeader(header);
Assert.assertEquals(header, widget.getHeader());
}

@Test
public void setAnotherHeaderToNonEmptyWidget_correctHeaderIsSet() {
DashboardWidget widget = new DashboardWidget();
widget.setHeader(new Div());
Span newHeader = new Span();
widget.setHeader(newHeader);
Assert.assertEquals(newHeader, widget.getHeader());
}

@Test
public void setTheSameHeaderToNonEmptyWidget_correctHeaderIsSet() {
Div header = new Div();
DashboardWidget widget = new DashboardWidget();
widget.setHeader(header);
widget.setHeader(header);
Assert.assertEquals(header, widget.getHeader());
}

@Test
public void setNullHeaderToNonEmptyWidget_headerIsRemoved() {
DashboardWidget widget = new DashboardWidget();
widget.setHeader(new Div());
widget.setHeader(null);
Assert.assertNull(widget.getHeader());
}

@Test
public void setNullHeaderToWidgetWithContent_contentIsNotRemoved() {
Div content = new Div();
DashboardWidget widget = new DashboardWidget();
widget.setContent(content);
widget.setHeader(null);
Assert.assertEquals(content, widget.getContent());
}

@Test
public void setNullContentToWidgetWithHeader_headerIsNotRemoved() {
Div header = new Div();
DashboardWidget widget = new DashboardWidget();
widget.setHeader(header);
widget.setContent(null);
Assert.assertEquals(header, widget.getHeader());
}

@Test
public void setHeaderToWidgetWithContent_contentAndHeaderCorrectlyRetrieved() {
Div content = new Div();
Span header = new Span();
DashboardWidget widget = new DashboardWidget();
widget.setContent(content);
widget.setHeader(header);
Assert.assertEquals(content, widget.getContent());
Assert.assertEquals(header, widget.getHeader());
}

@Test
public void setContentToWidgetWithHeader_contentAndHeaderCorrectlyRetrieved() {
Div content = new Div();
Span header = new Span();
DashboardWidget widget = new DashboardWidget();
widget.setHeader(header);
widget.setContent(content);
Assert.assertEquals(content, widget.getContent());
Assert.assertEquals(header, widget.getHeader());
}

private void fakeClientCommunication() {
ui.getInternals().getStateTree().runExecutionsBeforeClientResponse();
ui.getInternals().getStateTree().collectChanges(ignore -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,18 @@ public TestBenchElement getContent() {
return content == null ? null : (TestBenchElement) content;
}

/**
* Returns the header of the widget.
*
* @return the header element set to the widget
*/
public TestBenchElement getHeader() {
Object header = executeScript(
"return Array.from(arguments[0].children).filter(child => child.slot === 'header')[0]",
this);
return header == null ? null : (TestBenchElement) header;
}

private String getComputedCssValue(String propertyName) {
return (String) executeScript(
"return getComputedStyle(arguments[0]).getPropertyValue(arguments[1]);",
Expand Down

0 comments on commit bb49967

Please sign in to comment.