Skip to content

Menu System

MedUX uses Conjunto's menu system to build navigation elements. Menus are defined as Python classes implementing IMenuItem and are automatically discovered by GDAPS.

Available Menus

menu value Location
"views" Left sidebar navigation
"main_menu" Top main navigation bar
"top_navbar" Top-right icon area
"user" User dropdown (top-right)
"administration" Admin settings sidebar
"profile" User profile page tabs

Defining a Menu Item

from django.urls import reverse_lazy
from django.utils.translation import gettext_lazy as _
from conjunto.menu import IMenuItem


class PatientsMenu(IMenuItem):
    title = _("Patients")
    slug = "patients"
    menu = "views"           # appears in the sidebar
    url = reverse_lazy("core:patient:list")
    icon = "users"           # Tabler icon name
    weight = 10              # lower = higher in the menu
    permission_required = "core.view_patient"

Nested Items

Create hierarchical menus by setting parent instead of menu:

class EmployeesSubMenu(IMenuItem):
    title = _("Employees")
    slug = "tenant__employees"
    parent = "tenant"        # nested under the "tenant" item
    url = reverse_lazy("adm:tenant:employee-list")
    icon = "users"
    weight = 20

Warning

menu and parent are mutually exclusive. Conjunto raises ValueError if both are set. A child's menu is determined by walking up the parent chain.

The double-underscore in slug (e.g., tenant__employees) is a cosmetic convention — it is not how nesting is resolved. Always set parent explicitly.

Visibility and Permissions

Menu items support several visibility controls:

  • permission_required — Django permission string; the item is hidden if the user lacks this permission
  • visible — a boolean or callable for dynamic visibility
  • disabled — renders the item but grays it out
  • view_name — highlights the item when the current view matches

Use MenuSeparator to add visual dividers:

from conjunto.menu import MenuSeparator

class AdminSeparator(MenuSeparator):
    menu = "administration"
    weight = 40