I’ve just created a dashboard, following the “Dashboards add-on video tutorial”, but I don’t know to add the dashboard to the root application screen with top menu.
I don’t know how to open the main screen window descriptor, to find where to add the xmlns:dashboard namespace or where to find the main:workArea tag to put the created dashboard.
I’d bee very grateful to receive any ideas to achieve the goal.
The goal is to keep a dashboard tab always open. The dashboard itself is a normal screen.
Dashboard.java
In the method onAfterClose I open the dashboard again when it has been closed by ‘Close All’.
@UiController("ksm_Dashboard")
@UiDescriptor("dashboard.xml")
public class Dashboard extends Screen {
@Inject
private Screens screens;
@Subscribe
public void onAfterClose(AfterCloseEvent event) {
SideMenu sideMenu = findSideMenu();
if (sideMenu != null) {
final SideMenu.MenuItem dashboardMenuItem = sideMenu.getMenuItem("ksm_Dashboard");
if (dashboardMenuItem != null) {
// Aktuellen WindowStack merken
Screens.WindowStack selectedWindowStack = screens.getOpenedScreens().getWorkAreaStacks().stream()
.filter(Screens.WindowStack::isSelected)
.filter(windowStack -> windowStack.getBreadcrumbs().stream().noneMatch(screen -> screen instanceof Dashboard))
.findAny()
.orElse(null);
// wieder öffnen
dashboardMenuItem.getCommand().accept(dashboardMenuItem);
// Aktuellen WindowStack wieder aktivieren
if (selectedWindowStack != null) {
selectedWindowStack.select();
}
}
}
}
/**
* Sucht das SideMenu im Top-Level-Window oder alternativ in der Host-Screen, falls das TopLevelWindow null ist.
* Dies ist der Falls, wenn man das Fragment in die MainScreen einbindet.
*
* @return sidemenu oder null, wenn es nicht gefunden wurde
*/
private SideMenu findSideMenu() {
Window window = AppUI.getCurrent().getTopLevelWindow();
if (window == null) {
window = getWindow();
}
if (window != null) {
return window.getComponents().stream()
.filter(component -> component instanceof SideMenu)
.map(component -> (SideMenu) component)
.findAny()
.orElse(null);
} else {
return null;
}
}
}
ExtMainScreen.java
Here I overwrite the menu entry for the dashboard, so that instead of showing a new dashboard, it opens the existing one. Also for me to add a listener to the WorkArea to open the dashboard in initial state.
@UiController("extMainScreen")
@UiDescriptor("ext-main-screen.xml")
public class ExtMainScreen extends MainScreen {
...
@Subscribe
public void onInit(InitEvent event) {
// Dashboard-Tab öffnen, wenn alle anderne Tabs geschlossen sind
final SideMenu.MenuItem dashboardMenuItem = sideMenu.getMenuItem("ksm_Dashboard");
if (workArea instanceof WebAppWorkArea && dashboardMenuItem != null) {
workArea.addStateChangeListener(stateChangeEvent -> {
if (stateChangeEvent.getState() == INITIAL_LAYOUT) {
screenBuilders.screen(this)
.withScreenClass(Dashboard.class)
.show();
}
});
// Verhindern, dass das Dashbord doppelt geöffnet wird
final Consumer<SideMenu.MenuItem> dashboardMenuItemCommand = dashboardMenuItem.getCommand();
dashboardMenuItem.setCommand(menuItem -> {
screens.getOpenedScreens().getWorkAreaStacks().stream()
.filter(windowStack -> windowStack.getBreadcrumbs().stream().anyMatch(screen -> screen instanceof Dashboard))
.peek(Screens.WindowStack::select)
.flatMap(windowStack -> windowStack.getBreadcrumbs().stream())
.filter(screen -> !(screen instanceof Dashboard))
.forEach(Screen::closeWithDefaultAction);
if (screens.getOpenedScreens().getWorkAreaScreens().stream().noneMatch(screen -> screen instanceof Dashboard)) {
dashboardMenuItemCommand.accept(dashboardMenuItem);
}
});
}
}
@Subscribe
public void onAfterShow1(AfterShowEvent event) {
// Dashboard öffnen. Hinweis: die App-Property "cuba.web.defaultScreenId" kann nicht verwendet werden
// weil z.B. der Revisor keinen Zugriff auf das Dashboard hat. Daher wird das Dashboard manuell geöffnet.
final SideMenu.MenuItem dashboardMenuItem = sideMenu.getMenuItem("ksm_Dashboard");
if (dashboardMenuItem != null) {
dashboardMenuItem.getCommand().accept(dashboardMenuItem);
}
}
}
Thanks, Andreas, for your example and explanation. I’ll try to adapt your solution in my project althought my dashboard class extends from ScreenFragment instead of from Screen like in your case.