fix: merge GridStackView into DashboardView (#19)
CI / build-and-test (pull_request) Successful in 2m22s
CI / build-and-test (pull_request) Successful in 2m22s
DashboardView and GridStackView rendered the same three charts from the
same hardcoded data, so every chart factory method existed twice. The
dashboard is now the GridStackLayout variant at @Route(""):
- GridStackView deleted, its grid/toolbar/chart factories moved into
DashboardView, which keeps the point-click notifications the old
dashboard had.
- Charts size to their widget (100%/100%) instead of a fixed 400px.
- MainLayout has one dashboard entry; nav.gridstack/page.gridstack keys
dropped from all three bundles.
- Storage key is "dashboard" (was "gridstack-demo"), so a saved layout
from the old route is not reused.
- GridStackViewTest renamed to DashboardViewTest, plus a test asserting
the three charts render.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0124BiJikbhbiEsNfJxdWM69
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
package com.example.views;
|
||||
|
||||
import com.example.Application;
|
||||
import com.example.components.BarChart;
|
||||
import com.example.components.GridStackItem;
|
||||
import com.example.components.GridStackLayout;
|
||||
import com.example.components.LineChart;
|
||||
import com.example.components.PieChart;
|
||||
import com.vaadin.browserless.SpringBrowserlessTest;
|
||||
import com.vaadin.browserless.ViewPackages;
|
||||
import com.vaadin.browserless.internal.ElementUtilsKt;
|
||||
import com.vaadin.flow.component.button.Button;
|
||||
import com.vaadin.flow.component.html.Div;
|
||||
import com.vaadin.flow.dom.DomEvent;
|
||||
import com.vaadin.flow.internal.JacksonUtils;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
@SpringBootTest(classes = Application.class)
|
||||
@ViewPackages(classes = DashboardView.class)
|
||||
class DashboardViewTest extends SpringBrowserlessTest {
|
||||
|
||||
@Test
|
||||
void view_rendersGridWithDefaultWidgets() {
|
||||
navigate(DashboardView.class);
|
||||
|
||||
GridStackLayout grid = $view(GridStackLayout.class).first();
|
||||
assertNotNull(grid);
|
||||
|
||||
List<GridStackItem.Position> layout = grid.getLayout();
|
||||
assertEquals(4, layout.size(), "expected the four default widgets");
|
||||
assertTrue(layout.stream().allMatch(p -> p.w() > 0 && p.h() > 0));
|
||||
}
|
||||
|
||||
@Test
|
||||
void view_rendersTheThreeCharts() {
|
||||
navigate(DashboardView.class);
|
||||
|
||||
assertNotNull($view(LineChart.class).first());
|
||||
assertNotNull($view(BarChart.class).first());
|
||||
assertNotNull($view(PieChart.class).first());
|
||||
}
|
||||
|
||||
@Test
|
||||
void addAndCloseWidget_changesItemCount() {
|
||||
navigate(DashboardView.class);
|
||||
|
||||
GridStackLayout grid = $view(GridStackLayout.class).first();
|
||||
int initial = grid.getLayout().size();
|
||||
|
||||
button("gridstack.addWidget").click();
|
||||
assertEquals(initial + 1, grid.getLayout().size());
|
||||
|
||||
clickCloseButton($view(GridStackItem.class).last());
|
||||
assertEquals(initial, grid.getLayout().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
void closeButton_removesTheClickedWidgetOnly() {
|
||||
navigate(DashboardView.class);
|
||||
|
||||
GridStackLayout grid = $view(GridStackLayout.class).first();
|
||||
GridStackItem first = $view(GridStackItem.class).first();
|
||||
String closedId = first.getItemId();
|
||||
|
||||
clickCloseButton(first);
|
||||
|
||||
List<GridStackItem.Position> layout = grid.getLayout();
|
||||
assertEquals(3, layout.size());
|
||||
assertFalse(layout.stream().anyMatch(p -> closedId.equals(p.id())),
|
||||
"the closed widget must be gone from the layout");
|
||||
}
|
||||
|
||||
@Test
|
||||
void closeListener_firesOnceItemIsDetached() {
|
||||
navigate(DashboardView.class);
|
||||
|
||||
GridStackLayout grid = $view(GridStackLayout.class).first();
|
||||
GridStackItem item = $view(GridStackItem.class).first();
|
||||
int[] fired = {0};
|
||||
item.addCloseListener(e -> fired[0]++);
|
||||
|
||||
item.close();
|
||||
|
||||
assertEquals(1, fired[0]);
|
||||
assertEquals(3, grid.getLayout().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
void nonClosableItem_hasNoCloseButton() {
|
||||
navigate(DashboardView.class);
|
||||
|
||||
GridStackItem item = $view(GridStackItem.class).first();
|
||||
assertTrue(item.isClosable(), "items are closable by default");
|
||||
|
||||
item.setClosable(false);
|
||||
assertFalse(item.isClosable());
|
||||
assertFalse(item.getChildren().anyMatch(child -> child == item.getCloseButton()));
|
||||
}
|
||||
|
||||
/** Fires the DOM click the close button listens for, rather than calling
|
||||
* {@code close()} directly, so the button's own wiring is covered too. */
|
||||
private void clickCloseButton(GridStackItem item) {
|
||||
Div closeButton = item.getCloseButton();
|
||||
ElementUtilsKt._fireDomEvent(closeButton.getElement(),
|
||||
new DomEvent(closeButton.getElement(), "click", JacksonUtils.createObjectNode()));
|
||||
}
|
||||
|
||||
private Button button(String translationKey) {
|
||||
String caption = getCurrentView().getElement().getComponent()
|
||||
.orElseThrow().getTranslation(translationKey);
|
||||
return $view(Button.class).withText(caption).first();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user