Serenity: Hide menu items

Created on 11 Sep 2018  路  6Comments  路  Source: serenity-is/Serenity

Hi

How is it possible to manipulate (hide) certain menu items?

I saw in demo how to generate them, but I would just need to hide bunch depending on date

Most helpful comment

Okay, I have no idea if this is the correct way to do this. So, use at your own risk.

First I created a set of permissions called PagePermission in my TestLabPermissionKeys.cs:

public class PagePermission
{
     public const string TestInfo = "Pages:TestInfo";
     public const string TestRequest = "Pages:TestRequest";
}

Then I created RowPermission in the same file:

public class RowPermission
{
     public const string TestRequestRead = "TestRequest:Read";
     public const string TestRequestModify = "TestRequest:Modify";
     public const string TestRequestInsert = "TestRequest:Insert";
     public const string TestRequestUpdate = "TestRequest:Update";
     public const string TestRequestDelete = "TestRequest:Delete";

     public const string TestInfoRead = "TestInfo:Read";
     public const string TestInfoModify = "TestInfo:Modify";
     public const string TestInfoInsert = "TestInfo:Insert";
     public const string TestInfoUpdate = "TestInfo:Update";
     public const string TestInfoDelete = "TestInfo:Delete";
}

Then in my roles I would define the PagePermissions for a role. So, Sales person can only see TestRequest and Testinfo.
TestRequestPage.cs (which also happens to be my default landing page)

namespace TestLabSuite.TestLab.Pages
{
    using Serenity.Web;
    using System.Web.Mvc;
    using TestLabSuite.Modules.TestLab;

    [RoutePrefix("TestLab/TestRequest"), Route("{action=index}")]
    //[PageAuthorize(typeof(Entities.TestRequestRow))]
    [PageAuthorize(PermissionKeys.PagePermission.TestRequest)]
    public class TestRequestController : Controller
    {
        [Authorize, HttpGet, Route("~/")]
        public ActionResult Index()
        {
            return View("~/Modules/TestLab/TestRequest/TestRequestIndex.cshtml");
        }
    }
}

This means that only a role or user with the PagePermission.TestRequest will see the menu item for it.

I then added more granular control on the row level.
TestRequestRow.cs

namespace TestLabSuite.TestLab.Entities
{
    using Serenity.ComponentModel;
    using Serenity.Data;
    using Serenity.Data.Mapping;
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using TestLabSuite.Modules.TestLab;

    [ConnectionKey("Default"), Module("TestLab"), TableName("[tl].[TestRequest]")]
    [DisplayName("Test Request"), InstanceName("Test Request"), TwoLevelCached]
    [ReadPermission(PermissionKeys.RowPermission.TestRequestRead)]
    [ModifyPermission(PermissionKeys.RowPermission.TestRequestModify)]
    [InsertPermission(PermissionKeys.RowPermission.TestRequestInsert)]
    [UpdatePermission(PermissionKeys.RowPermission.TestRequestUpdate)]
    [DeletePermission(PermissionKeys.RowPermission.TestRequestDelete)]
    public sealed class TestRequestRow : Row, IIdRow, INameRow
    {

        [DisplayName("Test Request Id"), Identity]
        public Int32? TestRequestId
        {
            get { return Fields.TestRequestId[this]; }
            set { Fields.TestRequestId[this] = value; }
        }
}

Again, I have no idea if this is right. But so far it seems to be working.

All 6 comments

Hi @ga5tan

have a look at the free serene (demo) example, how the dynamic Navigation is done.

Or at this Wiki article: https://github.com/volkanceylan/Serenity/wiki/Dynamic-navigation-items

And then you have to display the desired menu items dynamically.

yeah, I found example, but it is only dealing with adding of items.
I don't want to add, I want to remove/hide some existing...

I am currently trying to figure this out as well. I have built a bunch of modules that users don't actually need to see. I thought I would hide them via permissions but then the module they have permissions to calls the modules I am trying to hide.

If I come across anything I think can help I will post it here.

rite now I am just filtering it out in Model

Okay, I have no idea if this is the correct way to do this. So, use at your own risk.

First I created a set of permissions called PagePermission in my TestLabPermissionKeys.cs:

public class PagePermission
{
     public const string TestInfo = "Pages:TestInfo";
     public const string TestRequest = "Pages:TestRequest";
}

Then I created RowPermission in the same file:

public class RowPermission
{
     public const string TestRequestRead = "TestRequest:Read";
     public const string TestRequestModify = "TestRequest:Modify";
     public const string TestRequestInsert = "TestRequest:Insert";
     public const string TestRequestUpdate = "TestRequest:Update";
     public const string TestRequestDelete = "TestRequest:Delete";

     public const string TestInfoRead = "TestInfo:Read";
     public const string TestInfoModify = "TestInfo:Modify";
     public const string TestInfoInsert = "TestInfo:Insert";
     public const string TestInfoUpdate = "TestInfo:Update";
     public const string TestInfoDelete = "TestInfo:Delete";
}

Then in my roles I would define the PagePermissions for a role. So, Sales person can only see TestRequest and Testinfo.
TestRequestPage.cs (which also happens to be my default landing page)

namespace TestLabSuite.TestLab.Pages
{
    using Serenity.Web;
    using System.Web.Mvc;
    using TestLabSuite.Modules.TestLab;

    [RoutePrefix("TestLab/TestRequest"), Route("{action=index}")]
    //[PageAuthorize(typeof(Entities.TestRequestRow))]
    [PageAuthorize(PermissionKeys.PagePermission.TestRequest)]
    public class TestRequestController : Controller
    {
        [Authorize, HttpGet, Route("~/")]
        public ActionResult Index()
        {
            return View("~/Modules/TestLab/TestRequest/TestRequestIndex.cshtml");
        }
    }
}

This means that only a role or user with the PagePermission.TestRequest will see the menu item for it.

I then added more granular control on the row level.
TestRequestRow.cs

namespace TestLabSuite.TestLab.Entities
{
    using Serenity.ComponentModel;
    using Serenity.Data;
    using Serenity.Data.Mapping;
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using TestLabSuite.Modules.TestLab;

    [ConnectionKey("Default"), Module("TestLab"), TableName("[tl].[TestRequest]")]
    [DisplayName("Test Request"), InstanceName("Test Request"), TwoLevelCached]
    [ReadPermission(PermissionKeys.RowPermission.TestRequestRead)]
    [ModifyPermission(PermissionKeys.RowPermission.TestRequestModify)]
    [InsertPermission(PermissionKeys.RowPermission.TestRequestInsert)]
    [UpdatePermission(PermissionKeys.RowPermission.TestRequestUpdate)]
    [DeletePermission(PermissionKeys.RowPermission.TestRequestDelete)]
    public sealed class TestRequestRow : Row, IIdRow, INameRow
    {

        [DisplayName("Test Request Id"), Identity]
        public Int32? TestRequestId
        {
            get { return Fields.TestRequestId[this]; }
            set { Fields.TestRequestId[this] = value; }
        }
}

Again, I have no idea if this is right. But so far it seems to be working.

@ga5tan ,
you can completely hide an entry (for everybody) by removing the following line(s) from your xyzPage.cs /NavigationItems.cs:

[assembly: NavigationLink(2100, "TACMasterLayouts/TacMasterLayouts", typeof(RALayoutManager2.TACMasterLayouts.Pages.TacMasterLayoutsController))]

and then use the approach in above linked Wiki article to show them dynamically to people who should see it.

But... i like the approach above from @chadburnett better because it also really protects the access to these pages - while my approach just hides the pages but if somebody knows the link he/she still can access the hidden page.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

stixoffire picture stixoffire  路  3Comments

stepankurdylo picture stepankurdylo  路  3Comments

moostafaa picture moostafaa  路  3Comments

StefanTheiner picture StefanTheiner  路  3Comments

GitHubOrim picture GitHubOrim  路  3Comments