Просмотр исходного кода

Merge pull request #6786 from netbox-community/nav-menu-plugins

Refactor navigation menu to support plugin items
Jeremy Stretch 4 лет назад
Родитель
Сommit
407f05629a

+ 227 - 179
netbox/netbox/navigation_menu.py

@@ -1,23 +1,35 @@
 from dataclasses import dataclass
 from typing import Sequence, Optional
 
+from extras.registry import registry
+from utilities.choices import ButtonColorChoices
+
+
+#
+# Nav menu data classes
+#
+
+@dataclass
+class MenuItemButton:
+
+    link: str
+    title: str
+    icon_class: str
+    permissions: Optional[list] = None
+    color: Optional[str] = None
+
 
 @dataclass
 class MenuItem:
-    """A navigation menu item link. Example: Sites, Platforms, RIRs, etc."""
 
-    label: str
-    url: str
-    disabled: bool = True
-    add_url: Optional[str] = None
-    import_url: Optional[str] = None
-    has_add: bool = False
-    has_import: bool = False
+    link: str
+    link_text: str
+    permissions: Optional[list] = None
+    buttons: Optional[Sequence[MenuItemButton]] = None
 
 
 @dataclass
 class MenuGroup:
-    """A group of menu items within a menu."""
 
     label: str
     items: Sequence[MenuItem]
@@ -25,302 +37,338 @@ class MenuGroup:
 
 @dataclass
 class Menu:
-    """A top level menu group. Example: Organization, Devices, IPAM."""
 
     label: str
-    icon: str
+    icon_class: str
     groups: Sequence[MenuGroup]
 
 
+#
+# Utility functions
+#
+
+def get_model_item(app_label, model_name, label, actions=('add', 'import')):
+    return MenuItem(
+        link=f'{app_label}:{model_name}_list',
+        link_text=label,
+        permissions=[f'{app_label}.view_{model_name}'],
+        buttons=get_model_buttons(app_label, model_name, actions)
+    )
+
+
+def get_model_buttons(app_label, model_name, actions=('add', 'import')):
+    buttons = []
+
+    if 'add' in actions:
+        buttons.append(
+            MenuItemButton(
+                link=f'{app_label}:{model_name}_add',
+                title='Add',
+                icon_class='mdi mdi-plus-thick',
+                permissions=[f'{app_label}.add_{model_name}'],
+                color=ButtonColorChoices.GREEN
+            )
+        )
+    if 'import' in actions:
+        buttons.append(
+            MenuItemButton(
+                link=f'{app_label}:{model_name}_import',
+                title='Import',
+                icon_class='mdi mdi-upload',
+                permissions=[f'{app_label}.add_{model_name}'],
+                color=ButtonColorChoices.CYAN
+            )
+        )
+
+    return buttons
+
+
+#
+# Nav menus
+#
+
 ORGANIZATION_MENU = Menu(
-    label="Organization",
-    icon="domain",
+    label='Organization',
+    icon_class='mdi mdi-domain',
     groups=(
         MenuGroup(
-            label="Sites",
+            label='Sites',
             items=(
-                MenuItem(label="Sites", url="dcim:site_list",
-                         add_url="dcim:site_add", import_url="dcim:site_import"),
-                MenuItem(label="Site Groups", url="dcim:sitegroup_list",
-                         add_url="dcim:sitegroup_add", import_url="dcim:sitegroup_import"),
-                MenuItem(label="Regions", url="dcim:region_list",
-                         add_url="dcim:region_add", import_url="dcim:region_import"),
-                MenuItem(label="Locations", url="dcim:location_list",
-                         add_url="dcim:location_add", import_url="dcim:location_import"),
+                get_model_item('dcim', 'site', 'Sites'),
+                get_model_item('dcim', 'region', 'Regions'),
+                get_model_item('dcim', 'sitegroup', 'Site Groups'),
+                get_model_item('dcim', 'location', 'Locations'),
             ),
         ),
         MenuGroup(
-            label="Racks",
+            label='Racks',
             items=(
-                MenuItem(label="Racks", url="dcim:rack_list",
-                         add_url="dcim:rack_add", import_url="dcim:rack_import"),
-                MenuItem(label="Rack Roles", url="dcim:rackrole_list",
-                         add_url="dcim:rackrole_add", import_url="dcim:rackrole_import"),
-                MenuItem(label="Reservations", url="dcim:rackreservation_list",
-                         add_url="dcim:rackreservation_add", import_url=None),
-                MenuItem(label="Elevations", url="dcim:rack_elevation_list",
-                         add_url=None, import_url=None),
+                get_model_item('dcim', 'rack', 'Racks'),
+                get_model_item('dcim', 'rackrole', 'Rack Roles'),
+                get_model_item('dcim', 'rackreservation', 'Reservations'),
+                MenuItem(
+                    link='dcim:rack_elevation_list',
+                    link_text='Elevations',
+                    permissions=['dcim.view_rack']
+                ),
             ),
         ),
         MenuGroup(
-            label="Tenancy",
+            label='Tenancy',
             items=(
-                MenuItem(label="Tenants", url="tenancy:tenant_list",
-                         add_url="tenancy:tenant_add", import_url="tenancy:tenant_import"),
-                MenuItem(label="Tenant Groups",
-                         url="tenancy:tenantgroup_list", add_url="tenancy:tenantgroup_add",
-                         import_url="tenancy:tenantgroup_import"),
+                get_model_item('tenancy', 'tenant', 'Tenants'),
+                get_model_item('tenancy', 'tenantgroup', 'Tenant Groups'),
             ),
         ),
-        MenuGroup(
-            label="Tags",
-            items=(MenuItem(label="Tags", url="extras:tag_list",
-                   add_url="extras:tag_add", import_url="extras:tag_import"),),
-        ),
     ),
 )
 
 DEVICES_MENU = Menu(
-    label="Devices",
-    icon="server",
+    label='Devices',
+    icon_class='mdi mdi-server',
     groups=(
         MenuGroup(
-            label="Devices",
+            label='Devices',
             items=(
-                MenuItem(label="Devices", url="dcim:device_list",
-                         add_url="dcim:device_add", import_url="dcim:device_import"),
-                MenuItem(label="Device Roles", url="dcim:devicerole_list",
-                         add_url="dcim:devicerole_add", import_url="dcim:devicerole_import"),
-                MenuItem(label="Platforms", url="dcim:platform_list",
-                         add_url="dcim:platform_add", import_url="dcim:platform_import"),
-                MenuItem(label="Virtual Chassis",
-                         url="dcim:virtualchassis_list", add_url="dcim:virtualchassis_add",
-                         import_url="dcim:virtualchassis_import"),
+                get_model_item('dcim', 'device', 'Devices'),
+                get_model_item('dcim', 'devicerole', 'Device Roles'),
+                get_model_item('dcim', 'platform', 'Platforms'),
+                get_model_item('dcim', 'virtualchassis', 'Virtual Chassis'),
             ),
         ),
         MenuGroup(
-            label="Device Types",
+            label='Device Types',
             items=(
-                MenuItem(label="Device Types", url="dcim:devicetype_list",
-                         add_url="dcim:devicetype_add", import_url="dcim:devicetype_import"),
-                MenuItem(label="Manufacturers", url="dcim:manufacturer_list",
-                         add_url="dcim:manufacturer_add", import_url="dcim:manufacturer_import"),
+                get_model_item('dcim', 'devicetype', 'Device Types'),
+                get_model_item('dcim', 'manufacturer', 'Manufacturers'),
             ),
         ),
         MenuGroup(
-            label="Connections",
+            label='Device Components',
             items=(
-                MenuItem(label="Cables", url="dcim:cable_list",
-                         add_url=None, import_url="dcim:cable_import"),
-                MenuItem(
-                    label="Console Connections", url="dcim:console_connections_list", add_url=None, import_url=None,
-                ),
-                MenuItem(
-                    label="Interface Connections", url="dcim:interface_connections_list", add_url=None, import_url=None,
-                ),
-                MenuItem(label="Power Connections",
-                         url="dcim:power_connections_list", add_url=None, import_url=None,),
+                get_model_item('dcim', 'interface', 'Interfaces', actions=['import']),
+                get_model_item('dcim', 'frontport', 'Front Ports', actions=['import']),
+                get_model_item('dcim', 'rearport', 'Rear Ports', actions=['import']),
+                get_model_item('dcim', 'consoleport', 'Console Ports', actions=['import']),
+                get_model_item('dcim', 'consoleserverport', 'Console Server Ports', actions=['import']),
+                get_model_item('dcim', 'powerport', 'Power Ports', actions=['import']),
+                get_model_item('dcim', 'poweroutlet', 'Power Outlets', actions=['import']),
+                get_model_item('dcim', 'devicebay', 'Device Bays', actions=['import']),
+                get_model_item('dcim', 'inventoryitem', 'Inventory Items', actions=['import']),
             ),
         ),
+    ),
+)
+
+CONNECTIONS_MENU = Menu(
+    label='Connections',
+    icon_class='mdi mdi-ethernet',
+    groups=(
         MenuGroup(
-            label="Device Components",
+            label='Connections',
             items=(
-                MenuItem(label="Interfaces", url="dcim:interface_list",
-                         add_url=None, import_url="dcim:interface_import"),
-                MenuItem(label="Front Ports", url="dcim:frontport_list",
-                         add_url=None, import_url="dcim:frontport_import"),
-                MenuItem(label="Rear Ports", url="dcim:rearport_list",
-                         add_url=None, import_url="dcim:rearport_import"),
-                MenuItem(label="Console Ports", url="dcim:consoleport_list",
-                         add_url=None, import_url="dcim:consoleport_import"),
-                MenuItem(label="Console Server Ports", url="dcim:consoleserverport_list",
-                         add_url=None, import_url="dcim:consoleserverport_import"),
-                MenuItem(label="Power Ports", url="dcim:powerport_list",
-                         add_url=None, import_url="dcim:powerport_import"),
-                MenuItem(label="Power Outlets", url="dcim:poweroutlet_list",
-                         add_url=None, import_url="dcim:poweroutlet_import"),
-                MenuItem(label="Device Bays", url="dcim:devicebay_list",
-                         add_url=None, import_url="dcim:devicebay_import"),
-                MenuItem(label="Inventory Items",
-                         url="dcim:inventoryitem_list", add_url=None, import_url="dcim:inventoryitem_import"),
+                get_model_item('dcim', 'cable', 'Cables', actions=['import']),
+                MenuItem(
+                    link='dcim:interface_connections_list',
+                    link_text='Interface Connections',
+                    permissions=['dcim.view_interface']
+                ),
+                MenuItem(
+                    link='dcim:console_connections_list',
+                    link_text='Console Connections',
+                    permissions=['dcim.view_consoleport']
+                ),
+                MenuItem(
+                    link='dcim:power_connections_list',
+                    link_text='Power Connections',
+                    permissions=['dcim.view_powerport']
+                ),
             ),
         ),
     ),
 )
 
 IPAM_MENU = Menu(
-    label="IPAM",
-    icon="counter",
+    label='IPAM',
+    icon_class='mdi mdi-counter',
     groups=(
         MenuGroup(
-            label="IP Addresses",
+            label='IP Addresses',
             items=(
-                MenuItem(label="IP Ranges", url="ipam:iprange_list",
-                         add_url="ipam:iprange_add", import_url="ipam:iprange_import"),
-                MenuItem(label="IP Addresses", url="ipam:ipaddress_list",
-                         add_url="ipam:ipaddress_add", import_url="ipam:ipaddress_import"),
+                get_model_item('ipam', 'ipaddress', 'IP Addresses'),
+                get_model_item('ipam', 'iprange', 'IP Ranges'),
             ),
         ),
         MenuGroup(
-            label="Prefixes",
+            label='Prefixes',
             items=(
-                MenuItem(label="Prefixes", url="ipam:prefix_list",
-                         add_url="ipam:prefix_add", import_url="ipam:prefix_import"),
-                MenuItem(label="Prefix & VLAN Roles", url="ipam:role_list",
-                         add_url="ipam:role_add", import_url="ipam:role_import"),
+                get_model_item('ipam', 'prefix', 'Prefixes'),
+                get_model_item('ipam', 'role', 'Prefix & VLAN Roles'),
             ),
         ),
         MenuGroup(
-            label="Aggregates",
+            label='Aggregates',
             items=(
-                MenuItem(label="Aggregates", url="ipam:aggregate_list",
-                         add_url="ipam:aggregate_add", import_url="ipam:aggregate_import"),
-                MenuItem(label="RIRs", url="ipam:rir_list",
-                         add_url="ipam:rir_add", import_url="ipam:rir_import"),
+                get_model_item('ipam', 'aggregate', 'Aggregates'),
+                get_model_item('ipam', 'rir', 'RIRs'),
             ),
         ),
         MenuGroup(
-            label="VRFs",
+            label='VRFs',
             items=(
-                MenuItem(label="VRFs", url="ipam:vrf_list",
-                         add_url="ipam:vrf_add", import_url="ipam:vrf_import"),
-                MenuItem(label="Route Targets", url="ipam:routetarget_list",
-                         add_url="ipam:routetarget_add", import_url="ipam:routetarget_import"),
+                get_model_item('ipam', 'vrf', 'VRFs'),
+                get_model_item('ipam', 'routetarget', 'Route Targets'),
             ),
         ),
         MenuGroup(
-            label="VLANs",
+            label='VLANs',
             items=(
-                MenuItem(label="VLANs", url="ipam:vlan_list",
-                         add_url="ipam:vlan_add", import_url="ipam:vlan_import"),
-                MenuItem(label="VLAN Groups", url="ipam:vlangroup_list",
-                         add_url="ipam:vlangroup_add", import_url="ipam:vlangroup_import"),
+                get_model_item('ipam', 'vlan', 'VLANs'),
+                get_model_item('ipam', 'vlangroup', 'VLAN Groups'),
             ),
         ),
         MenuGroup(
-            label="Services",
-            items=(MenuItem(label="Services", url="ipam:service_list",
-                   add_url=None, import_url="ipam:service_import"),),
+            label='Services',
+            items=(
+                get_model_item('ipam', 'service', 'Services', actions=['import']),
+            ),
         ),
     ),
 )
 
 VIRTUALIZATION_MENU = Menu(
-    label="Virtualization",
-    icon="monitor",
+    label='Virtualization',
+    icon_class='mdi mdi-monitor',
     groups=(
         MenuGroup(
-            label="Virtual Machines",
+            label='Virtual Machines',
             items=(
-                MenuItem(
-                    label="Virtual Machines",
-                    url="virtualization:virtualmachine_list", add_url="virtualization:virtualmachine_add", import_url="virtualization:virtualmachine_import"),
-                MenuItem(label="Interfaces",
-                         url="virtualization:vminterface_list", add_url="virtualization:vminterface_add", import_url="virtualization:vminterface_import"),
+                get_model_item('virtualization', 'virtualmachine', 'Virtual Machines'),
+                get_model_item('virtualization', 'vminterface', 'Interfaces', actions=['import']),
             ),
         ),
         MenuGroup(
-            label="Clusters",
+            label='Clusters',
             items=(
-                MenuItem(label="Clusters", url="virtualization:cluster_list",
-                         add_url="virtualization:cluster_add", import_url="virtualization:cluster_import"),
-                MenuItem(label="Cluster Types",
-                         url="virtualization:clustertype_list", add_url="virtualization:clustertype_add", import_url="virtualization:clustertype_import"),
-                MenuItem(
-                    label="Cluster Groups", url="virtualization:clustergroup_list", add_url="virtualization:clustergroup_add", import_url="virtualization:clustergroup_import"),
+                get_model_item('virtualization', 'cluster', 'Clusters'),
+                get_model_item('virtualization', 'clustertype', 'Cluster Types'),
+                get_model_item('virtualization', 'clustergroup', 'Cluster Groups'),
             ),
         ),
     ),
 )
 
 CIRCUITS_MENU = Menu(
-    label="Circuits",
-    icon="transit-connection-variant",
+    label='Circuits',
+    icon_class='mdi mdi-transit-connection-variant',
     groups=(
         MenuGroup(
-            label="Circuits",
+            label='Circuits',
             items=(
-                MenuItem(label="Circuits", url="circuits:circuit_list",
-                         add_url="circuits:circuit_add", import_url="circuits:circuit_import"),
-                MenuItem(label="Circuit Types",
-                         url="circuits:circuittype_list", add_url="circuits:circuittype_add", import_url="circuits:circuittype_import"),
+                get_model_item('circuits', 'circuit', 'Circuits'),
+                get_model_item('circuits', 'circuittype', 'Circuit Types'),
             ),
         ),
         MenuGroup(
-            label="Providers",
+            label='Providers',
             items=(
-                MenuItem(label="Providers", url="circuits:provider_list",
-                         add_url="circuits:provider_add", import_url="circuits:provider_import"),
-                MenuItem(
-                    label="Provider Networks", url="circuits:providernetwork_list", add_url="circuits:providernetwork_add", import_url="circuits:providernetwork_import"
-                ),
+                get_model_item('circuits', 'provider', 'Providers'),
+                get_model_item('circuits', 'providernetwork', 'Provider Networks'),
             ),
         ),
     ),
 )
 
 POWER_MENU = Menu(
-    label="Power",
-    icon="flash",
+    label='Power',
+    icon_class='mdi mdi-flash',
     groups=(
         MenuGroup(
-            label="Power",
+            label='Power',
             items=(
-                MenuItem(label="Power Feeds", url="dcim:powerfeed_list",
-                         add_url="dcim:powerfeed_add", import_url="dcim:powerfeed_import"),
-                MenuItem(label="Power Panels", url="dcim:powerpanel_list",
-                         add_url="dcim:powerpanel_add", import_url="dcim:powerpanel_import"),
+                get_model_item('dcim', 'powerfeed', 'Power Feeds'),
+                get_model_item('dcim', 'powerpanel', 'Power Panels'),
             ),
         ),
     ),
 )
 
 OTHER_MENU = Menu(
-    label="Other",
-    icon="notification-clear-all",
+    label='Other',
+    icon_class='mdi mdi-notification-clear-all',
     groups=(
         MenuGroup(
-            label="Logging",
+            label='Logging',
             items=(
-                MenuItem(label="Change Log", url="extras:objectchange_list",
-                         add_url=None, import_url=None),
-                MenuItem(label="Journal Entries",
-                         url="extras:journalentry_list", add_url=None, import_url=None),
-                MenuItem(label="Webhooks", url="extras:webhook_list",
-                         add_url="extras:webhook_add", import_url="extras:webhook_import"),
+                get_model_item('extras', 'journalentry', 'Journal Entries', actions=[]),
+                get_model_item('extras', 'objectchange', 'Change Log', actions=[]),
             ),
         ),
         MenuGroup(
-            label="Customization",
+            label='Customization',
             items=(
-                MenuItem(label="Custom Fields", url="extras:customfield_list",
-                         add_url="extras:customfield_add", import_url="extras:customfield_import"),
-                MenuItem(label="Custom Links", url="extras:customlink_list",
-                         add_url="extras:customlink_add", import_url="extras:customlink_import"),
-                MenuItem(label="Export Templates", url="extras:exporttemplate_list",
-                         add_url="extras:exporttemplate_add", import_url="extras:exporttemplate_import"),
+                get_model_item('extras', 'customfield', 'Custom Fields'),
+                get_model_item('extras', 'customlink', 'Custom Links'),
+                get_model_item('extras', 'exporttemplate', 'Export Templates'),
             ),
         ),
         MenuGroup(
-            label="Miscellaneous",
+            label='Integrations',
             items=(
-                MenuItem(label="Config Contexts", url="extras:configcontext_list",
-                         add_url="extras:configcontext_add", import_url=None),
-                MenuItem(label="Reports", url="extras:report_list",
-                         add_url=None, import_url=None),
-                MenuItem(label="Scripts", url="extras:script_list",
-                         add_url=None, import_url=None),
+                get_model_item('extras', 'webhook', 'Webhooks'),
+                MenuItem(
+                    link='extras:report_list',
+                    link_text='Reports',
+                    permissions=['extras.view_report']
+                ),
+                MenuItem(
+                    link='extras:script_list',
+                    link_text='Scripts',
+                    permissions=['extras.view_script']
+                ),
+            ),
+        ),
+        MenuGroup(
+            label='Other',
+            items=(
+                get_model_item('extras', 'tag', 'Tags'),
+                get_model_item('extras', 'configcontext', 'Config Contexts', actions=['add']),
             ),
         ),
     ),
 )
 
-MENUS = (
+
+MENUS = [
     ORGANIZATION_MENU,
     DEVICES_MENU,
+    CONNECTIONS_MENU,
     IPAM_MENU,
     VIRTUALIZATION_MENU,
     CIRCUITS_MENU,
     POWER_MENU,
     OTHER_MENU,
-)
+]
+
+#
+# Add plugin menus
+#
+
+if registry['plugin_menu_items']:
+    plugin_menu_groups = []
+
+    for plugin_name, items in registry['plugin_menu_items'].items():
+        plugin_menu_groups.append(
+            MenuGroup(
+                label=plugin_name,
+                items=items
+            )
+        )
+
+    PLUGIN_MENU = Menu(
+        label="Plugins",
+        icon_class="mdi mdi-puzzle",
+        groups=plugin_menu_groups
+    )
+
+    MENUS.append(PLUGIN_MENU)

+ 30 - 22
netbox/utilities/templates/navigation/nav_items.html

@@ -1,3 +1,5 @@
+{% load helpers %}
+
 <div id="sidenav-accordion" class="accordion accordion-flush nav-item">
   {% for menu in nav_items %}
 
@@ -11,7 +13,7 @@
         data-bs-target="#{{ menu.label|lower }}"
         class="d-flex justify-content-between align-items-center accordion-button nav-link collapsed">
           <span class="fw-bold sidebar-nav-link">
-            <i class="mdi mdi-{{ menu.icon }} me-1 opacity-50"></i>
+            <i class="{{ menu.icon_class }} me-1 opacity-50"></i>
             {{ menu.label }}
           </span>
         </a>
@@ -23,33 +25,39 @@
             {# Within each main menu, there are groups of menu items #}
             <div class="flex-column nav">
               
-              {% if menu.groups|length > 1 %}
-                <h6 class="accordion-item-title">{{ group.label }}</h6>
-              {% endif %}
+              <h6 class="accordion-item-title">{{ group.label }}</h6>
               
               {% for item in group.items %}
                 {# Each Menu Item #}
                 <div class="nav-item d-flex justify-content-between align-items-center">
                   
                   {# Menu Link with Text #}
-                  <a class="nav-link flex-grow-1" href="{% url item.url %}">
-                    {{ item.label }}
-                  </a>
-                  
-                  {# Add & Import Buttons #}
-                  {% if item.has_add or item.has_import %}
-                    <div class="btn-group ps-1">
-                      {% if item.has_add %}
-                          <a class="btn btn-sm btn-success lh-1" href="{% url item.add_url %}" title="Add {{ item.label }}">
-                            <i class="mdi mdi-plus-thick"></i>
-                          </a>
-                      {% endif %}
-                      {% if item.has_import %}
-                          <a class="btn btn-sm btn-outline-success lh-1" href="{% url item.import_url %}" title="Import {{ item.label }}">
-                            <i class="mdi mdi-upload"></i>
-                          </a>
-                      {% endif %}
-                    </div>
+                  {% if request.user|has_perms:item.permissions %}
+
+                    <a class="nav-link flex-grow-1" href="{% url item.link %}">
+                      {{ item.link_text }}
+                    </a>
+
+                    {# Menu item buttons (if any) #}
+                    {% if item.buttons %}
+                      <div class="btn-group ps-1">
+                        {% for button in item.buttons %}
+                          {% if request.user|has_perms:button.permissions %}
+                            <a class="btn btn-sm btn-{{ button.color }} lh-1" href="{% url button.link %}" title="{{ button.title }}">
+                              <i class="{{ button.icon_class }}"></i>
+                            </a>
+                          {% endif %}
+                        {% endfor %}
+                      </div>
+                    {% endif %}
+
+                  {% else %}
+
+                    {# Display a disabled link (no permission) #}
+                    <a class="nav-link flex-grow-1 disabled">
+                      {{ item.link_text }}
+                    </a>
+
                   {% endif %}
 
                 </div>

+ 8 - 32
netbox/utilities/templatetags/nav.py

@@ -1,43 +1,19 @@
 from typing import Dict
 from django import template
 from django.template import Context
-from django.contrib.auth.context_processors import PermWrapper
 
-from netbox.navigation_menu import Menu, MenuGroup, MENUS
+from netbox.navigation_menu import MENUS
 
 
 register = template.Library()
 
 
-def process_menu(menu: Menu, perms: PermWrapper) -> MenuGroup:
-    """Enable a menu item if view permissions exist for the user."""
-    for group in menu.groups:
-        for item in group.items:
-            # Parse the URL template tag to a permission string.
-            app, scope = item.url.split(":")
-            object_name = scope.replace("_list", "")
-
-            view_perm = f"{app}.view_{scope}"
-            add_perm = f"{app}.add_object_name"
-
-            if view_perm in perms:
-                # If the view permission for each item exists, toggle
-                # the `disabled` field, which will be used in the UI.
-                item.disabled = False
-
-            if add_perm in perms:
-                if item.add_url is not None:
-                    item.has_add = True
-                if item.import_url is not None:
-                    item.has_import = True
-
-    return menu
-
-
 @register.inclusion_tag("navigation/nav_items.html", takes_context=True)
 def nav(context: Context) -> Dict:
-    """Provide navigation items to template."""
-    perms: PermWrapper = context["perms"]
-    groups = [process_menu(g, perms) for g in MENUS]
-
-    return {"nav_items": groups, "request": context["request"]}
+    """
+    Render the navigation menu.
+    """
+    return {
+        "nav_items": MENUS,
+        "request": context["request"]
+    }