Coverage for src/backend/InvenTree/plugin/base/integration/NavigationMixin.py: 42%

32 statements  

« prev     ^ index     » next       coverage.py v7.15.2, created at 2026-10-07 17:47 +0000

1"""Plugin mixin classes.""" 

2 

3import structlog 

4 

5from plugin import PluginMixinEnum 

6from plugin.helpers import MixinNotImplementedError 

7 

8logger = structlog.get_logger('inventree') 

9 

10 

11class NavigationMixin: 

12 """Mixin that enables custom navigation links with the plugin.""" 

13 

14 NAVIGATION_TAB_NAME = None 

15 NAVIGATION_TAB_ICON = 'fas fa-question' 

16 

17 class MixinMeta: 

18 """Meta options for this mixin.""" 

19 

20 MIXIN_NAME = 'Navigation Links' 

21 

22 def __init__(self): 

23 """Register mixin.""" 

24 super().__init__() 

25 self.add_mixin(PluginMixinEnum.NAVIGATION, 'has_navigation', __class__) 

26 self.navigation = self.setup_navigation() 

27 

28 def setup_navigation(self): 

29 """Setup navigation links for this plugin.""" 

30 nav_links = getattr(self, 'NAVIGATION', None) 

31 if nav_links: 

32 # check if needed values are configured 

33 for link in nav_links: 

34 if False in [a in link for a in ('link', 'name')]: 

35 raise MixinNotImplementedError('Wrong Link definition', link) 

36 return nav_links 

37 

38 @property 

39 def has_navigation(self): 

40 """Does this plugin define navigation elements.""" 

41 return bool(self.navigation) 

42 

43 @property 

44 def navigation_name(self): 

45 """Name for navigation tab.""" 

46 name = getattr(self, 'NAVIGATION_TAB_NAME', None) 

47 if not name: 

48 name = self.human_name 

49 return name 

50 

51 @property 

52 def navigation_icon(self): 

53 """Icon-name for navigation tab.""" 

54 return getattr(self, 'NAVIGATION_TAB_ICON', 'fas fa-question')