- ABP Framework version: v4.2.2
- UI type: Blazor
- DB provider: EF Core
- Tiered (MVC) or Identity Server Separated (Angular): yes / no
- Exception message and stack trace:
- Steps to reproduce the issue:
Hi, I have added two menus that should be visible only in the Tenant Side. I don't want then on the Host side. How can I do that?
I tried to inject CurrentTenant and check the property IsAvailable, but, the class is instanced manually and dependency injection doesn't work. See my code below:
public class AvalancheOCPMenuContributor : IMenuContributor
    {
        private readonly IConfiguration _configuration;
        public AvalancheOCPMenuContributor(IConfiguration configuration)
        {
            _configuration = configuration;
        }
        public async Task ConfigureMenuAsync(MenuConfigurationContext context)
        {
            if (context.Menu.Name == StandardMenus.Main)
            {
                await ConfigureMainMenuAsync(context);
            }
            else if (context.Menu.Name == StandardMenus.User)
            {
                await ConfigureUserMenuAsync(context);
            }
        }
        //This method was intentionally "async" because ABP Suite will generate asnyc method calls here.
        private static async Task ConfigureMainMenuAsync(MenuConfigurationContext context)
        {
            var l = context.GetLocalizer<AvalancheOCPResource>();
            context.Menu.AddItem(new ApplicationMenuItem(
                AvalancheOCPMenus.Home,
                l["Menu:Home"],
                "/",
                icon: "fas fa-home",
                order: 1
            ));
            // Tenant Side
            **//if (_currentTenant.IsAvailable) // How to do it? Or what is the best way to do that?**
            { 
                var settings = new ApplicationMenuItem(
                    "Settings",
                    l["Menu:AvalancheOCPSettings"],
                    icon: "fa fa-sliders",
                    order: 2
                );
                context.Menu.AddItem(settings);
                if (await context.IsGrantedAsync(AvalancheOCPPermissions.Causes.Default))
                {
                    settings.AddItem(new ApplicationMenuItem(
                        "Settings.Causes",
                        l["Menu:Causes"],
                        url: "/causes"
                    ));
                }
                if (await context.IsGrantedAsync(AvalancheOCPPermissions.SupplyNetworks.Default))
                {
                    settings.AddItem(new ApplicationMenuItem(
                        "Settings.SupplyNetworks",
                        l["Menu:SupplyNetworks"],
                        url: "/supplynetworks"
                    ));
                }
            }
6 Answer(s)
- 
    0Hi, I've found in the class PermissionDefinitionProvider a parameter for each permission that defines the multiTenancySide. Does that mean to define the menu as well? public class AvalancheOCPPermissionDefinitionProvider : PermissionDefinitionProvider { public override void Define(IPermissionDefinitionContext context) { var myGroup = context.AddGroup(AvalancheOCPPermissions.GroupName); myGroup.AddPermission(AvalancheOCPPermissions.Dashboard.Host, L("Permission:Dashboard"), MultiTenancySides.Host); myGroup.AddPermission(AvalancheOCPPermissions.Dashboard.Tenant, L("Permission:Dashboard"), MultiTenancySides.Tenant); var settings = context.AddGroup(AvalancheOCPPermissions.AvalancheOCPSettings, L("Menu:AvalancheOCPSettings"), MultiTenancySides.Tenant); var causes = settings.AddPermission(AvalancheOCPPermissions.Causes.Default, L("Menu:Causes"), MultiTenancySides.Tenant); causes.AddChild(AvalancheOCPPermissions.Causes.Create, L("Permission:Causes.Create"), MultiTenancySides.Tenant); causes.AddChild(AvalancheOCPPermissions.Causes.Edit, L("Permission:Causes.Edit"), MultiTenancySides.Tenant); causes.AddChild(AvalancheOCPPermissions.Causes.Delete, L("Permission:Causes.Delete"), MultiTenancySides.Tenant); var supplyNetworks = settings.AddPermission(AvalancheOCPPermissions.SupplyNetworks.Default, L("Menu:SupplyNetworks"), MultiTenancySides.Tenant); supplyNetworks.AddChild(AvalancheOCPPermissions.SupplyNetworks.Create, L("Permission:SupplyNetworks.Create"), MultiTenancySides.Tenant); supplyNetworks.AddChild(AvalancheOCPPermissions.SupplyNetworks.Edit, L("Permission:SupplyNetworks.Edit"), MultiTenancySides.Tenant); supplyNetworks.AddChild(AvalancheOCPPermissions.SupplyNetworks.Delete, L("Permission:SupplyNetworks.Delete"), MultiTenancySides.Tenant); myGroup.AddPermission(AvalancheOCPPermissions.OutageReportsGrid.Default, L("Permission:OutageReportGrid"), MultiTenancySides.Tenant); //Define your own permissions here. Example: //myGroup.AddPermission(AvalancheOCPPermissions.MyPermission1, L("Permission:MyPermission1")); } private static LocalizableString L(string name) { return LocalizableString.Create<AvalancheOCPResource>(name); } }
- 
    0hi Leonardo, sorry for my late response, this menu item will be shown on host myGroup.AddPermission(AvalancheOCPPermissions.Dashboard.Host, L("Permission:Dashboard"), MultiTenancySides.Host);this menu item will be shown on tenant myGroup.AddPermission(AvalancheOCPPermissions.Dashboard.Tenant, L("Permission:Dashboard"), MultiTenancySides.Tenant);
- 
    0Hi Alper, So, I need to set the menu scope (Tenant / Host) in the PermissionDefinitionProvider and then it will reflect the menu as well, is that right? 
- 
    0yes correct 
- 
    0Hi @Leonardo.Willrich As I understand, You don't want to change entire menu for tenant or host, just show/hide some menu items for host/tenant. At this line I can show you a workaround: //if (_currentTenant.IsAvailable) // How to do it? Or what is the best way to do that?** if(_currentTenant.Id != null) { // tenant side } else { // host side }Host doesn't have Id and it'll be null for host. Honestly, It's not best way or recommended to check host tenant but might help for you. 
- 
    0Hi Enisn, I appreciated your answer, but, I could not create an instance for CurrentTenant in the MenuContributor class. Dependency Injection doesn't work on that class and I have no idea how I could create a new instance to check the current TenantId. Anyway, it seems to be answered by @alper, the right thing is defining the scope in the PermissionDefinitionClass. 
 
                                