feat: dynamic merchant sidebar with module-driven menus
Replace the hardcoded merchant sidebar with a dynamic menu system driven by module definitions, matching the existing admin frontend pattern. Modules declare FrontendType.MERCHANT menus in their definition.py, and a new API endpoint unions enabled modules across all platforms the merchant is subscribed to — so loyalty only appears when enabled. - Add MERCHANT menu definitions to core, billing, tenancy, loyalty modules - Extend MenuDiscoveryService with enabled_module_codes parameter - Create GET /merchants/core/menu/render/merchant endpoint - Update merchant Alpine.js with loadMenuConfig() and dynamic section state - Replace hardcoded sidebar.html with x-for rendering + loading skeleton + fallback - Add 36 unit and integration tests for menu discovery, service, and endpoint Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -74,6 +74,9 @@ core_module = ModuleDefinition(
|
||||
"settings",
|
||||
"email-templates",
|
||||
],
|
||||
FrontendType.MERCHANT: [
|
||||
"dashboard",
|
||||
],
|
||||
},
|
||||
# New module-driven menu definitions
|
||||
menus={
|
||||
@@ -121,6 +124,25 @@ core_module = ModuleDefinition(
|
||||
],
|
||||
),
|
||||
],
|
||||
FrontendType.MERCHANT: [
|
||||
MenuSectionDefinition(
|
||||
id="main",
|
||||
label_key=None,
|
||||
icon=None,
|
||||
order=0,
|
||||
is_collapsible=False,
|
||||
items=[
|
||||
MenuItemDefinition(
|
||||
id="dashboard",
|
||||
label_key="core.menu.dashboard",
|
||||
icon="home",
|
||||
route="/merchants/dashboard",
|
||||
order=10,
|
||||
is_mandatory=True,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
FrontendType.STORE: [
|
||||
MenuSectionDefinition(
|
||||
id="main",
|
||||
|
||||
Reference in New Issue
Block a user