Coverage for src / lexigram / admin / navigation / types.py: 85%
52 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-08-13 22:14 +0800
« prev ^ index » next coverage.py v7.13.5, created at 2026-08-13 22:14 +0800
1"""Navigation type definitions for admin sidebar construction."""
3from __future__ import annotations
5from dataclasses import dataclass, field
8@dataclass
9class NavItem:
10 """Navigation item."""
12 name: str
13 label: str
14 url: str
15 icon: str | None = None
16 badge: str | None = None
17 badge_variant: str = "primary"
18 active: bool = False
19 external: bool = False
21 children: list[NavItem] | None = None
23 resource_name: str | None = None
24 permission: str | None = None
27@dataclass
28class NavGroup:
29 """Navigation group containing multiple items."""
31 name: str
32 label: str
33 icon: str | None = None
34 order: int = 0
35 collapsible: bool = True
36 collapsed: bool = False
38 items: list[NavItem] = field(default_factory=list)
40 permission: str | None = None
41 feature_flag: str | None = None
44@dataclass
45class SidebarNavItem:
46 """Normalized sidebar navigation item.
48 Converts ``NavigationContribution`` and resource nav entries into one
49 shell-ready shape consumed by ``AdminShell._prepare_navigation()``.
50 """
52 label: str
53 href: str
54 icon: str | None = None
55 badge: str | None = None
56 active: bool = False
57 is_group: bool = False
58 permission: str | None = None
59 feature: str | None = None
61 def to_dict(self) -> dict[str, str | bool | None]:
62 """Convert to dict for backward-compatible shell consumption."""
63 d: dict[str, str | bool | None] = {
64 "label": self.label,
65 "href": self.href,
66 "icon": self.icon,
67 "badge": self.badge,
68 "active": self.active,
69 }
70 if self.is_group:
71 d["is_group"] = True
72 if self.permission:
73 d["permission"] = self.permission
74 if self.feature:
75 d["feature"] = self.feature
76 return d
79@dataclass
80class NavigationConfig:
81 """Configuration for navigation assembly."""
83 prefix: str = "/admin"
85 groups: dict[str, NavGroup] = field(default_factory=dict)
87 default_icons: dict[str, str] = field(
88 default_factory=lambda: {
89 "users": "users",
90 "products": "cube",
91 "orders": "shopping-cart",
92 "settings": "cog",
93 "reports": "chart-bar",
94 "logs": "document-text",
95 },
96 )
98 show_counts: bool = False
101__all__ = ["NavGroup", "NavItem", "NavigationConfig", "SidebarNavItem"]