django-jet icon indicating copy to clipboard operation
django-jet copied to clipboard

Empty menu item if user has not permissions on model

Open srTinto80 opened this issue 7 years ago • 9 comments

With configuration like this:

JET_SIDE_MENU_COMPACT = True
JET_SIDE_MENU_ITEMS = [
    {
        'label': 'Test',
        'items': [
            {
                'name': 'catalog.categoria',
            },
        ]
    },
]

For staff user, with permission on catalog.categoria model, the menu appear as schermata 2018-03-09 alle 15 32 13

For staff user, WITHOUT permission on catalog.categoria model, the menu appear as: schermata 2018-03-09 alle 15 32 25

The problem is not present for JET_SIDE_MENU_COMPACT = False

I'm using django-jet 1.0.7

Regards, Roberto

srTinto80 avatar Mar 09 '18 14:03 srTinto80

hey there, I am experiencing the same behavior did you @srTinto80 ever found a solution?

orlax avatar Dec 06 '19 17:12 orlax

Hi @orlax , i finded a kind of workaround but i not use jet anymore and i dont remember with precision. I finded workaround debugging the code. The problem was in utils.py file, get_menu_items method. Try using custom JET_SIDE_MENU_ITEMS configuration, setting "permissions": [] or similar for the app. Sorry.

srTinto80 avatar Dec 06 '19 18:12 srTinto80

no worries, I will look in to it and document it if possible, thank you for pointing me on the direction.

orlax avatar Dec 06 '19 21:12 orlax

Hello there. Have you found a workaround?

Eirenne avatar Dec 16 '19 13:12 Eirenne

hello, @Eirenne for time constraints I resolved to just do a CSS override to hide those lines. I am using sass and this is what worked for me:

.sidebar-section{
    border: none;
    &> a:first-child{
        display: none; 
        
    }
    &> a:nth-child(2){
        display: none;
    }
}

but this will vary wildly depending on the project. but well, hopefully, I get some time to do this properly during this week.

orlax avatar Dec 16 '19 14:12 orlax

Hello again.

Forked the repo and tried to debug the problem. Found out that if you have app defined in custom menu and django doesn't give user permission for that app, jet makes a default object with default permissions and data from JET_SIDE_MENU_ITEMS list.

Fixed it here by setting default objects permissions to false and thus not showing it in the menu.

However this change makes side menu items only work if they all come from django. If you have custom labels and urls, you'll need to add a bit more changes there.

Eirenne avatar Dec 17 '19 15:12 Eirenne

Unfortunately, this repository is no longer maintained anymore.

SalahAdDin avatar Jan 22 '20 10:01 SalahAdDin

I have exactly the same issue, the only option that I could come up with, using jQuery to just hide the empty lines, not ideal, but solve my problem.

I override the template "admin/base.html" (not only for this purpose), and added the script:

<script>
            function fix_menu_items() {
                let $ = jQuery;
                let $sidebar_links_labels = $('.sidebar-link-label');
                let $sidebar_link = $('.sidebar-link');

                $sidebar_links_labels.each(function (i) {
                    if (!$sidebar_link.eq(i).text().trim()) {
                        $sidebar_link.eq(i).closest('.sidebar-link').hide();
                        console.debug('empty menu item removed');
                    }
                });
            }
 </script>

then, call it from body onload.

 <body class="...." onload="fix_menu_items()">

before_fixafter_fix

Update

woke up in the morning and figured out how to get around this in a more elegant way, with just one line change in template and without jQuery: in the same template "admin/base.html" find the block that itarate over the app.items ({% for model in app.items %}), and add condition and model.label to if model.has_perms if statement.

Here's what the updated code looks like:

 {% for model in app.items %}
        {% if model.has_perms and model.label %} {% comment %}<- here is the added condition (and model.label){% endcomment %}
           <div>
                <a{% if model.url %} href="{{ model.url }}"{% endif %}
                  class="sidebar-link"{% if model.url_blank %}
                                      target="_blank"{% endif %}>
                   <span class="sidebar-right">
                         <span class="sidebar-right-arrow icon-arrow-right"></span>
                   </span>
                           <span class="sidebar-link-label">{{ model.label }}</span>
                     </a>
                 </div>
          {% endif %}
 {% endfor %}

without a doubt, it’s much more correct to find the problem itself and solve it, but I don’t have the time do it, hope this will help someone also to save time .

xdma avatar Feb 06 '20 23:02 xdma

Right now you just need to use

JET_SIDE_MENU_ITEMS = [
"items": [
    {
        "label": _("Access Control"),
        "items": [{"name": "auth.user", "permissions": ['auth.view_user']}, {"name": "auth.group", "permissions": ['auth.view_group']},],
    }
]
]

Replace the items and permissions appropriately.

esirK avatar Aug 31 '20 13:08 esirK