Hi all,
is it possibile to add multiple main views (under different routes) containing its own menu?
The base idea is to split big menus for a single application. For now i was able to create multiple main views, but reusing the same main menu
Hi all,
is it possibile to add multiple main views (under different routes) containing its own menu?
The base idea is to split big menus for a single application. For now i was able to create multiple main views, but reusing the same main menu
I’m going to try to reformulate the question: is it possible to use listmenu component referencing to a particolar subset of main menu, for example a menu including only some specific items from main menu
Thanks for helping!
Hi Michele,
Yes it’s possible.
First, turn off the default loading of listMenu:
<listMenu id="menu" loadMenuConfig="false"/>
Then create your own MenuItemProvider
and use it in listMenu
component:
package com.company.demo.view.main;
import com.vaadin.flow.router.Route;
import io.jmix.flowui.app.main.StandardMainView;
import io.jmix.flowui.component.main.JmixListMenu;
import io.jmix.flowui.kit.component.main.ListMenu;
import io.jmix.flowui.menu.ListMenuBuilder;
import io.jmix.flowui.menu.MenuConfig;
import io.jmix.flowui.menu.MenuItem;
import io.jmix.flowui.menu.provider.MenuConfigMenuItemProvider;
import io.jmix.flowui.view.Subscribe;
import io.jmix.flowui.view.ViewComponent;
import io.jmix.flowui.view.ViewController;
import io.jmix.flowui.view.ViewDescriptor;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
@Route("")
@ViewController("MainView")
@ViewDescriptor("main-view.xml")
public class MainView extends StandardMainView {
@ViewComponent
private JmixListMenu menu;
@Autowired
private MenuConfig menuConfig;
@Autowired
private ListMenuBuilder listMenuBuilder;
@Subscribe
public void onInit(final InitEvent event) {
// Create custom MenuItemProvider and set it to ListMenu component
SampleMenuItemProvider menuItemProvider = new SampleMenuItemProvider(menuConfig, listMenuBuilder);
menu.setMenuItemProvider(menuItemProvider);
// Load ListMenu from the MenuItemProvider
menuItemProvider.load();
}
private static class SampleMenuItemProvider extends MenuConfigMenuItemProvider<ListMenu.MenuItem> {
protected ListMenuBuilder listMenuBuilder;
public SampleMenuItemProvider(MenuConfig menuConfig, ListMenuBuilder listMenuBuilder) {
super(menuConfig);
this.listMenuBuilder = listMenuBuilder;
}
@Override
protected List<ListMenu.MenuItem> convertToMenuItems(Collection<MenuItem> menuConfigItems) {
// Create a desired copy of the menu structure
Collection<MenuItem> sampleMenuItems = new ArrayList<>();
createSampleMenuItems(menuConfigItems, sampleMenuItems);
// Convert the created menu structure to ListMenu items structure
return sampleMenuItems.stream()
.flatMap(menuItem -> listMenuBuilder.createListMenu(menuItem).stream())
.collect(Collectors.toCollection(ArrayList::new));
}
private void createSampleMenuItems(Collection<MenuItem> srcItems, Collection<MenuItem> dstItems) {
for (MenuItem srcItem : srcItems) {
if (satisfiesSampleCondition(srcItem)) {
MenuItem dstItem = new MenuItem(srcItem.getId());
dstItems.add(dstItem);
dstItem.setMenu(srcItem.isMenu());
dstItem.setView(srcItem.getView());
dstItem.setTitle(srcItem.getTitle());
// copy all MenuItem properties here
// ...
if (!srcItem.getChildren().isEmpty()) {
createSampleMenuItems(srcItem.getChildren(), dstItem.getChildren());
}
}
}
}
private boolean satisfiesSampleCondition(MenuItem srcItem) {
return srcItem.isMenu() || srcItem.getView().startsWith("User");
}
}
}
Regards,
Konstantin
Thanks!
Ok, good, but if i’d want to write my custom xml menu config and rely on this building a custon MenuConfig bean?
Consider turning off the default loading of listMenu and just building it using the JmixListMenu.addMenuItem()
methods.
I think my last question is not clear…
Actually, if i understood how the mechanism works, listMenu rely on menu.xml by default; but i’d want to know if is it posssible creating a custom-menu.xml and passing it, in some way, to a listMenu instance programmatically or through xml definition in main view
Thank’s again!
In my example above, I implemented SampleMenuItemProvider
by extending MenuConfigMenuItemProvider
class which loads items from the standard menu.xml
.
You could create a menu item provider by implementing the MenuItemProvider
interface from scratch and load items from a different source.