Coverage for src / lexigram / ui / organisms / activity_feed.py: 27%

22 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-08-10 04:11 +0800

1from __future__ import annotations 

2 

3from typing import Any 

4 

5from lexigram.ui.core.base import Component, el 

6 

7 

8class ActivityFeed(Component): 

9 def __init__( 

10 self, 

11 title: str = "Recent Activity", 

12 items: list[dict[str, Any]] | None = None, 

13 max_items: int = 5, 

14 **props, 

15 ) -> None: 

16 super().__init__(title=title, items=items or [], max_items=max_items, **props) 

17 self.title = title 

18 self.items = items or [] 

19 self.max_items = max_items 

20 

21 def render(self) -> Any: 

22 activity_items: list[Any] = [] 

23 

24 for item in self.items[: self.max_items]: 

25 user = item.get("user", "System") 

26 action = item.get("action", "performed action") 

27 resource = item.get("resource", "") 

28 timestamp = item.get("timestamp", "just now") 

29 icon = item.get("icon", "•") 

30 

31 activity_item = el( 

32 "li", 

33 el( 

34 "div", 

35 el("span", icon, class_="text-primary mr-2"), 

36 el( 

37 "span", 

38 el( 

39 "strong", 

40 user, 

41 class_="font-medium text-foreground", 

42 ), 

43 f" {action} ", 

44 el("span", resource, class_="text-primary font-medium") 

45 if resource 

46 else "", 

47 class_="text-sm text-muted-foreground", 

48 ), 

49 class_="flex items-start", 

50 ), 

51 el( 

52 "span", 

53 timestamp, 

54 class_="text-xs text-muted-foreground ml-6", 

55 ), 

56 class_="py-3 border-b border-border last:border-0", 

57 ) 

58 activity_items.append(activity_item) 

59 

60 if not activity_items: 

61 activity_items.append( 

62 el( 

63 "li", 

64 el( 

65 "p", 

66 "No recent activity", 

67 class_="text-sm text-muted-foreground text-center", 

68 ), 

69 class_="py-8", 

70 ) 

71 ) 

72 

73 return el( 

74 "div", 

75 el( 

76 "h3", 

77 self.title, 

78 class_="text-lg font-semibold text-foreground mb-4 px-6 pt-6", 

79 ), 

80 el("ul", *activity_items, class_="px-6 pb-6"), 

81 class_="bg-card rounded-xl shadow-sm border border-border transition-colors duration-300", 

82 )