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

1"""Navigation type definitions for admin sidebar construction.""" 

2 

3from __future__ import annotations 

4 

5from dataclasses import dataclass, field 

6 

7 

8@dataclass 

9class NavItem: 

10 """Navigation item.""" 

11 

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 

20 

21 children: list[NavItem] | None = None 

22 

23 resource_name: str | None = None 

24 permission: str | None = None 

25 

26 

27@dataclass 

28class NavGroup: 

29 """Navigation group containing multiple items.""" 

30 

31 name: str 

32 label: str 

33 icon: str | None = None 

34 order: int = 0 

35 collapsible: bool = True 

36 collapsed: bool = False 

37 

38 items: list[NavItem] = field(default_factory=list) 

39 

40 permission: str | None = None 

41 feature_flag: str | None = None 

42 

43 

44@dataclass 

45class SidebarNavItem: 

46 """Normalized sidebar navigation item. 

47 

48 Converts ``NavigationContribution`` and resource nav entries into one 

49 shell-ready shape consumed by ``AdminShell._prepare_navigation()``. 

50 """ 

51 

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 

60 

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 

77 

78 

79@dataclass 

80class NavigationConfig: 

81 """Configuration for navigation assembly.""" 

82 

83 prefix: str = "/admin" 

84 

85 groups: dict[str, NavGroup] = field(default_factory=dict) 

86 

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 ) 

97 

98 show_counts: bool = False 

99 

100 

101__all__ = ["NavGroup", "NavItem", "NavigationConfig", "SidebarNavItem"]