Want to set badge text to MenuItem in FlowUI

Hi there,
I want to set badge text to left side menu. It was easy in classicUI with SideMenu. But can’t set in FlowUI.
Is there any way to show badge text in FlowUI?

image

Thanks,
Nurmuhammad

1 Like

Hello!

For now, ListMenu component does not support setting badges to menu items. I’ve created a GitHub issue: jmix-framework/jmix#1287.

As a workaround you can override JmixListMenu component to provide your menu item type.

Extended JmixListMenu
public class AppListMenu extends JmixListMenu {

    @Override
    protected RouterLink createMenuItemComponent(MenuItem menuItem) {
        RouterLink item = super.createMenuItemComponent(menuItem);

        if (menuItem instanceof BadgeMenuItem) {
            Div badge = new Div();
            badge.setText(((BadgeMenuItem) menuItem).getBadge());
            badge.addClassName("menu-item-badge");
            item.add(badge);
        }
        return item;
    }

    public static class BadgeMenuItem extends ViewMenuItem {

        protected String badge;

        public BadgeMenuItem(String id) {
            super(id);
        }

        public String getBadge() {
            return badge;
        }

        public BadgeMenuItem withBadge(String badge) {
            this.badge = badge;
            return this;
        }
    }
}

Then register your component in the Spring Configuration:

@Bean
public ComponentRegistration appListMenu() {
    return ComponentRegistrationBuilder.create(AppListMenu.class)
            .replaceComponent(JmixListMenu.class)
            .build();
}

And add CSS for the badge:

.menu-item-badge {
    color: var(--lumo-primary-text-color);
    font-size: var(--lumo-font-size-s);
    font-weight: 500;
    line-height: var(--lumo-line-height-s);
}

The usage will be the following:

@ViewComponent
private JmixListMenu menu;

@Subscribe
public void onInit(InitEvent event) {
    menu.addMenuItem(new AppListMenu.BadgeMenuItem("badgeExample")
            .withBadge("6")
            .withTitle("User view")
            .withControllerClass(UserListView.class));
}
1 Like

Thank you @pinyazhin
how would you go about creating a menu entry to a details class? I always get an error, because the RouterLink is missing the :id paramter.

@pinyazhin Thank you, it works.

It seems that ViewMenuItem does not support navigation to detail views neither from the descriptor nor from the code. You can create simple MenuItem and perform navigation manually, like:

@ViewComponent
private JmixListMenu menu;
@Autowired
private ViewNavigators viewNavigators;

@Subscribe
public void onInit(InitEvent event) {
    menu.addMenuItem(ListMenu.MenuItem.create("DateEntityDetail")
            .withTitle("Test detail")
            .withClickHandler(menuItem -> {
                viewNavigators.detailView(DateEntity.class)
                        .withViewClass(DateEntityDetailView.class)
                        .newEntity()
                        .navigate();
            }));
}

I created an issue to support detail view navigation: Support navigation to Detail views from Menu · Issue #1308 · jmix-framework/jmix · GitHub

1 Like

@pinyazhin @klaus @nurmuhammad.abdurash

Hello Everyone

For your information, it is possible to open a DetailView (Editor) from the main Menu using a menu item bean. It is documented here MenuConfig :: Jmix Documentation under the Item Attributes section.

I have implemented this myself (below) and it works for both dialogWindows.detail() (commented out in my code below) and viewNavigators.detailView() methods. I have added a check at the beginning of each method, so that the DetailView cannot be opened multiple times on top of itself. I retrieve the user’s “Member” entity with a memberService bean that I previously built; each user has only one Member instance, so they can open it directly from their main Menu.

I hope that this information is helpful.

Best regards
Chris

menu.xml

    <menu id="personal-nf" title="msg://menu-config.personal-nf" opened="true">
        <item bean="nf_MainViewMenuService" beanMethod="showMemberView" title="msg://com.company.nf.view.member/memberDetailView.title"/>
        <item bean="nf_MainViewMenuService" beanMethod="showProfileDefaultsView" title="msg://menu-config.nf_ProfileDefaults.edit"/>
    </menu>

MainViewMenuService.java (Bean)

@Component("nf_MainViewMenuService")
public class MainViewMenuService {
    private static final Logger log = LoggerFactory.getLogger(MainViewMenuService.class);

    //############# Data Components ###############
    //############# Components ####################
    //############# Actions #######################
    //############# View API ######################
    private final DialogWindows dialogWindows;
    private final ViewNavigators viewNavigators;
    private final Notifications notifications;
    //############# Infrastructure ################
    private final Messages messages;
    //############# Project Beans #################
    private final CurrentUserService currentUserService;
    private final ProfileDefaultsService profileDefaultsService;
    private final MemberService memberService;
    private final MembershipService membershipService;
    //############# Project Properties ############
    //############# Other Beans ###################
    //############# Other Properties ##############
    //#############################################

    public MainViewMenuService(
            CurrentUserService currentUserService,
            MemberService memberService,
            MembershipService membershipService,
            ProfileDefaultsService profileDefaultsService,
            DialogWindows dialogWindows,
            ViewNavigators viewNavigators,
            Notifications notifications,
            Messages messages) {
        this.currentUserService = currentUserService;
        this.memberService = memberService;
        this.membershipService = membershipService;
        this.profileDefaultsService = profileDefaultsService;
        this.dialogWindows = dialogWindows;
        this.viewNavigators = viewNavigators;
        this.notifications = notifications;
        this.messages = messages;
    }

    public void showMemberView() {

        if (UI.getCurrent().getCurrentView() instanceof MemberDetailView) {
            notifications.create("Member view is already open") // TODO create new message
                    .withType(Notifications.Type.WARNING)
                    .withPosition(Notification.Position.MIDDLE)
                    .withThemeVariant(NotificationVariant.LUMO_WARNING)
                    .withCloseable(false)
                    .withDuration(3000)
                    .show();
            return;
        }

/*
        dialogWindows.detail((View<?>) UI.getCurrent().getCurrentView(), Member.class)
                .withViewClass(MemberDetailView.class)
                .editEntity(memberService.getMember(currentUserService.getCurrentUser().getUsername()))
                .open();
*/

        viewNavigators.detailView(Member.class)
                .withViewClass(MemberDetailView.class)
                .editEntity(memberService.getMember(currentUserService.getCurrentUser().getUsername()))
                .navigate();
    }

    more menu item bean methods......... e.g. showProfileDefaultsView()
}```