Coverage for src / lexigram / admin / actions / header_manager / visibility.py: 0%

59 statements  

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

1""" 

2Column visibility management for header actions. 

3 

4Handles showing/hiding table columns and saving user preferences. 

5""" 

6 

7from __future__ import annotations 

8 

9from collections.abc import Callable 

10 

11from lexigram import serialization as json 

12from lexigram.admin.actions.header_manager.types import ColumnVisibilityConfig 

13 

14 

15class ColumnVisibilityManager: 

16 """Manages column visibility state and preferences.""" 

17 

18 def __init__( 

19 self, 

20 config: ColumnVisibilityConfig, 

21 storage: Callable[[str, str], None] | None = None, 

22 retriever: Callable[[str], str | None] | None = None, 

23 ) -> None: 

24 """Initialize the visibility manager. 

25 

26 Args: 

27 config: Visibility configuration 

28 storage: Function to store preferences (key, value) 

29 retriever: Function to retrieve preferences (key) -> value 

30 """ 

31 self.config = config 

32 self._storage = storage 

33 self._retriever = retriever 

34 self._visible_columns: set[str] = set() 

35 

36 # Load saved preferences 

37 if config.save_preference and retriever: 

38 saved = retriever(config.storage_key) 

39 if saved: 

40 try: 

41 self._visible_columns = set(json.loads(saved)) 

42 except (json.JSONDecodeError, TypeError): 

43 self._visible_columns = set(config.default_visible) 

44 

45 # Initialize with defaults if no saved preferences 

46 if not self._visible_columns: 

47 self._visible_columns = set(config.default_visible) 

48 

49 @property 

50 def visible_columns(self) -> set[str]: 

51 """Get currently visible columns.""" 

52 return self._visible_columns.copy() 

53 

54 def is_column_visible(self, column: str) -> bool: 

55 """Check if a column is visible.""" 

56 if column in self.config.always_visible: 

57 return True 

58 return column in self._visible_columns 

59 

60 def show_column(self, column: str) -> None: 

61 """Show a column.""" 

62 if column not in self.config.always_visible: 

63 self._visible_columns.add(column) 

64 self._save_preferences() 

65 

66 def hide_column(self, column: str) -> None: 

67 """Hide a column.""" 

68 if column not in self.config.always_visible: 

69 self._visible_columns.discard(column) 

70 self._save_preferences() 

71 

72 def toggle_column(self, column: str) -> None: 

73 """Toggle column visibility.""" 

74 if self.is_column_visible(column): 

75 self.hide_column(column) 

76 else: 

77 self.show_column(column) 

78 

79 def show_all_columns(self, all_columns: list[str]) -> None: 

80 """Show all columns.""" 

81 for column in all_columns: 

82 if column not in self.config.always_visible: 

83 self._visible_columns.add(column) 

84 self._save_preferences() 

85 

86 def hide_all_columns(self) -> None: 

87 """Hide all columns except always visible ones.""" 

88 self._visible_columns = set(self.config.always_visible) 

89 self._save_preferences() 

90 

91 def reset_to_defaults(self, all_columns: list[str] | None = None) -> None: 

92 """Reset to default visibility.""" 

93 self._visible_columns = set(self.config.default_visible) 

94 if all_columns: 

95 # Ensure always visible columns are included 

96 self._visible_columns.update(self.config.always_visible) 

97 self._save_preferences() 

98 

99 def _save_preferences(self) -> None: 

100 """Save current preferences.""" 

101 if self.config.save_preference and self._storage: 

102 visible_list = list(self._visible_columns) 

103 self._storage(self.config.storage_key, json.dumps(visible_list)) # type: ignore[arg-type] 

104 

105 def get_hidden_columns(self, all_columns: list[str]) -> list[str]: 

106 """Get list of hidden columns.""" 

107 return [col for col in all_columns if not self.is_column_visible(col)] 

108 

109 def get_visible_columns_list(self, all_columns: list[str]) -> list[str]: 

110 """Get list of visible columns in original order.""" 

111 return [col for col in all_columns if self.is_column_visible(col)]