Files
orion/app/config/menu_registry.py
Samir Boulahtit 9a828999fe feat: add admin menu configuration and sidebar improvements
- Add AdminMenuConfig model for per-platform menu customization
- Add menu registry for centralized menu configuration
- Add my-menu-config and platform-menu-config admin pages
- Update sidebar with improved layout and Alpine.js interactions
- Add FrontendType enum for admin/vendor menu separation
- Document self-contained module patterns in session note

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 20:34:58 +01:00

547 lines
17 KiB
Python

# app/config/menu_registry.py
"""
Menu registry for Admin and Vendor frontends.
This module defines the complete menu structure for both frontends.
Menu items are identified by unique IDs that are used for:
- Storing visibility configuration in AdminMenuConfig
- Checking access in require_menu_access() dependency
- Rendering the sidebar dynamically
The registry is the single source of truth for menu structure.
Database only stores visibility overrides (is_visible=False).
"""
from enum import Enum
from models.database.admin_menu_config import FrontendType
class AdminMenuItem(str, Enum):
"""Admin frontend menu item identifiers."""
# Dashboard (always visible section)
DASHBOARD = "dashboard"
# Super Admin section
ADMIN_USERS = "admin-users"
# Platform Administration section
COMPANIES = "companies"
VENDORS = "vendors"
MESSAGES = "messages"
# Vendor Operations section
VENDOR_PRODUCTS = "vendor-products"
CUSTOMERS = "customers"
INVENTORY = "inventory"
ORDERS = "orders"
# Marketplace section
MARKETPLACE_LETZSHOP = "marketplace-letzshop"
# Billing & Subscriptions section
SUBSCRIPTION_TIERS = "subscription-tiers"
SUBSCRIPTIONS = "subscriptions"
BILLING_HISTORY = "billing-history"
# Content Management section
PLATFORMS = "platforms"
CONTENT_PAGES = "content-pages"
VENDOR_THEMES = "vendor-themes"
# Developer Tools section
COMPONENTS = "components"
ICONS = "icons"
# Platform Health section
PLATFORM_HEALTH = "platform-health"
TESTING = "testing"
CODE_QUALITY = "code-quality"
# Platform Monitoring section
IMPORTS = "imports"
BACKGROUND_TASKS = "background-tasks"
LOGS = "logs"
NOTIFICATIONS = "notifications"
# Platform Settings section
SETTINGS = "settings"
EMAIL_TEMPLATES = "email-templates"
MY_MENU = "my-menu" # Super admin only - personal menu configuration
class VendorMenuItem(str, Enum):
"""Vendor frontend menu item identifiers."""
# Main section (always visible)
DASHBOARD = "dashboard"
ANALYTICS = "analytics"
# Products & Inventory section
PRODUCTS = "products"
INVENTORY = "inventory"
MARKETPLACE = "marketplace"
# Sales & Orders section
ORDERS = "orders"
LETZSHOP = "letzshop"
INVOICES = "invoices"
# Customers section
CUSTOMERS = "customers"
MESSAGES = "messages"
NOTIFICATIONS = "notifications"
# Shop & Content section
CONTENT_PAGES = "content-pages"
MEDIA = "media"
# Account & Settings section
TEAM = "team"
PROFILE = "profile"
BILLING = "billing"
EMAIL_TEMPLATES = "email-templates"
SETTINGS = "settings"
# =============================================================================
# Admin Menu Registry
# =============================================================================
ADMIN_MENU_REGISTRY = {
"frontend_type": FrontendType.ADMIN,
"sections": [
{
"id": "main",
"label": None, # No header, always at top
"items": [
{
"id": AdminMenuItem.DASHBOARD.value,
"label": "Dashboard",
"icon": "home",
"url": "/admin/dashboard",
},
],
},
{
"id": "superAdmin",
"label": "Super Admin",
"super_admin_only": True,
"items": [
{
"id": AdminMenuItem.ADMIN_USERS.value,
"label": "Admin Users",
"icon": "shield",
"url": "/admin/admin-users",
},
],
},
{
"id": "platformAdmin",
"label": "Platform Administration",
"items": [
{
"id": AdminMenuItem.COMPANIES.value,
"label": "Companies",
"icon": "office-building",
"url": "/admin/companies",
},
{
"id": AdminMenuItem.VENDORS.value,
"label": "Vendors",
"icon": "shopping-bag",
"url": "/admin/vendors",
},
{
"id": AdminMenuItem.MESSAGES.value,
"label": "Messages",
"icon": "chat-bubble-left-right",
"url": "/admin/messages",
},
],
},
{
"id": "vendorOps",
"label": "Vendor Operations",
"items": [
{
"id": AdminMenuItem.VENDOR_PRODUCTS.value,
"label": "Products",
"icon": "cube",
"url": "/admin/vendor-products",
},
{
"id": AdminMenuItem.CUSTOMERS.value,
"label": "Customers",
"icon": "user-group",
"url": "/admin/customers",
},
{
"id": AdminMenuItem.INVENTORY.value,
"label": "Inventory",
"icon": "archive",
"url": "/admin/inventory",
},
{
"id": AdminMenuItem.ORDERS.value,
"label": "Orders",
"icon": "clipboard-list",
"url": "/admin/orders",
},
],
},
{
"id": "marketplace",
"label": "Marketplace",
"items": [
{
"id": AdminMenuItem.MARKETPLACE_LETZSHOP.value,
"label": "Letzshop",
"icon": "shopping-cart",
"url": "/admin/marketplace/letzshop",
},
],
},
{
"id": "billing",
"label": "Billing & Subscriptions",
"items": [
{
"id": AdminMenuItem.SUBSCRIPTION_TIERS.value,
"label": "Subscription Tiers",
"icon": "tag",
"url": "/admin/subscription-tiers",
},
{
"id": AdminMenuItem.SUBSCRIPTIONS.value,
"label": "Vendor Subscriptions",
"icon": "credit-card",
"url": "/admin/subscriptions",
},
{
"id": AdminMenuItem.BILLING_HISTORY.value,
"label": "Billing History",
"icon": "document-text",
"url": "/admin/billing-history",
},
],
},
{
"id": "contentMgmt",
"label": "Content Management",
"items": [
{
"id": AdminMenuItem.PLATFORMS.value,
"label": "Platforms",
"icon": "globe-alt",
"url": "/admin/platforms",
},
{
"id": AdminMenuItem.CONTENT_PAGES.value,
"label": "Content Pages",
"icon": "document-text",
"url": "/admin/content-pages",
},
{
"id": AdminMenuItem.VENDOR_THEMES.value,
"label": "Vendor Themes",
"icon": "color-swatch",
"url": "/admin/vendor-themes",
},
],
},
{
"id": "devTools",
"label": "Developer Tools",
"items": [
{
"id": AdminMenuItem.COMPONENTS.value,
"label": "Components",
"icon": "view-grid",
"url": "/admin/components",
},
{
"id": AdminMenuItem.ICONS.value,
"label": "Icons",
"icon": "photograph",
"url": "/admin/icons",
},
],
},
{
"id": "platformHealth",
"label": "Platform Health",
"items": [
{
"id": AdminMenuItem.PLATFORM_HEALTH.value,
"label": "Capacity Monitor",
"icon": "chart-bar",
"url": "/admin/platform-health",
},
{
"id": AdminMenuItem.TESTING.value,
"label": "Testing Hub",
"icon": "beaker",
"url": "/admin/testing",
},
{
"id": AdminMenuItem.CODE_QUALITY.value,
"label": "Code Quality",
"icon": "shield-check",
"url": "/admin/code-quality",
},
],
},
{
"id": "monitoring",
"label": "Platform Monitoring",
"items": [
{
"id": AdminMenuItem.IMPORTS.value,
"label": "Import Jobs",
"icon": "cube",
"url": "/admin/imports",
},
{
"id": AdminMenuItem.BACKGROUND_TASKS.value,
"label": "Background Tasks",
"icon": "collection",
"url": "/admin/background-tasks",
},
{
"id": AdminMenuItem.LOGS.value,
"label": "Application Logs",
"icon": "document-text",
"url": "/admin/logs",
},
{
"id": AdminMenuItem.NOTIFICATIONS.value,
"label": "Notifications",
"icon": "bell",
"url": "/admin/notifications",
},
],
},
{
"id": "settingsSection",
"label": "Platform Settings",
"items": [
{
"id": AdminMenuItem.SETTINGS.value,
"label": "General",
"icon": "cog",
"url": "/admin/settings",
},
{
"id": AdminMenuItem.EMAIL_TEMPLATES.value,
"label": "Email Templates",
"icon": "mail",
"url": "/admin/email-templates",
},
{
"id": AdminMenuItem.MY_MENU.value,
"label": "My Menu",
"icon": "view-grid",
"url": "/admin/my-menu",
"super_admin_only": True, # Only super admins can customize their menu
},
],
},
],
}
# =============================================================================
# Vendor Menu Registry
# =============================================================================
VENDOR_MENU_REGISTRY = {
"frontend_type": FrontendType.VENDOR,
"sections": [
{
"id": "main",
"label": None, # No header, always at top
"items": [
{
"id": VendorMenuItem.DASHBOARD.value,
"label": "Dashboard",
"icon": "home",
"url": "/dashboard", # Relative to /vendor/{code}/
},
{
"id": VendorMenuItem.ANALYTICS.value,
"label": "Analytics",
"icon": "chart-bar",
"url": "/analytics",
},
],
},
{
"id": "products",
"label": "Products & Inventory",
"items": [
{
"id": VendorMenuItem.PRODUCTS.value,
"label": "All Products",
"icon": "shopping-bag",
"url": "/products",
},
{
"id": VendorMenuItem.INVENTORY.value,
"label": "Inventory",
"icon": "clipboard-list",
"url": "/inventory",
},
{
"id": VendorMenuItem.MARKETPLACE.value,
"label": "Marketplace Import",
"icon": "download",
"url": "/marketplace",
},
],
},
{
"id": "sales",
"label": "Sales & Orders",
"items": [
{
"id": VendorMenuItem.ORDERS.value,
"label": "Orders",
"icon": "document-text",
"url": "/orders",
},
{
"id": VendorMenuItem.LETZSHOP.value,
"label": "Letzshop Orders",
"icon": "external-link",
"url": "/letzshop",
},
{
"id": VendorMenuItem.INVOICES.value,
"label": "Invoices",
"icon": "currency-euro",
"url": "/invoices",
},
],
},
{
"id": "customers",
"label": "Customers",
"items": [
{
"id": VendorMenuItem.CUSTOMERS.value,
"label": "All Customers",
"icon": "user-group",
"url": "/customers",
},
{
"id": VendorMenuItem.MESSAGES.value,
"label": "Messages",
"icon": "chat-bubble-left-right",
"url": "/messages",
},
{
"id": VendorMenuItem.NOTIFICATIONS.value,
"label": "Notifications",
"icon": "bell",
"url": "/notifications",
},
],
},
{
"id": "shop",
"label": "Shop & Content",
"items": [
{
"id": VendorMenuItem.CONTENT_PAGES.value,
"label": "Content Pages",
"icon": "document-text",
"url": "/content-pages",
},
{
"id": VendorMenuItem.MEDIA.value,
"label": "Media Library",
"icon": "photograph",
"url": "/media",
},
],
},
{
"id": "account",
"label": "Account & Settings",
"items": [
{
"id": VendorMenuItem.TEAM.value,
"label": "Team",
"icon": "user-group",
"url": "/team",
},
{
"id": VendorMenuItem.PROFILE.value,
"label": "Profile",
"icon": "user",
"url": "/profile",
},
{
"id": VendorMenuItem.BILLING.value,
"label": "Billing",
"icon": "credit-card",
"url": "/billing",
},
{
"id": VendorMenuItem.EMAIL_TEMPLATES.value,
"label": "Email Templates",
"icon": "mail",
"url": "/email-templates",
},
{
"id": VendorMenuItem.SETTINGS.value,
"label": "Settings",
"icon": "adjustments",
"url": "/settings",
},
],
},
],
}
# =============================================================================
# Helper Functions
# =============================================================================
def get_all_menu_item_ids(frontend_type: FrontendType) -> set[str]:
"""Get all menu item IDs for a frontend type."""
registry = (
ADMIN_MENU_REGISTRY if frontend_type == FrontendType.ADMIN else VENDOR_MENU_REGISTRY
)
items = set()
for section in registry["sections"]:
for item in section["items"]:
items.add(item["id"])
return items
def get_menu_item(frontend_type: FrontendType, menu_item_id: str) -> dict | None:
"""Get a menu item definition by ID."""
registry = (
ADMIN_MENU_REGISTRY if frontend_type == FrontendType.ADMIN else VENDOR_MENU_REGISTRY
)
for section in registry["sections"]:
for item in section["items"]:
if item["id"] == menu_item_id:
return {**item, "section_id": section["id"], "section_label": section.get("label")}
return None
def is_super_admin_only_item(menu_item_id: str) -> bool:
"""Check if a menu item is in a super_admin_only section."""
for section in ADMIN_MENU_REGISTRY["sections"]:
if section.get("super_admin_only"):
for item in section["items"]:
if item["id"] == menu_item_id:
return True
return False