Coverage for src/lexigram/admin/actions/header_manager/visibility.py: 0%
59 statements
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-24 23:18 +0800
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-24 23:18 +0800
1"""
2Column visibility management for header actions.
4Handles showing/hiding table columns and saving user preferences.
5"""
7from __future__ import annotations
9from collections.abc import Callable
11from lexigram import serialization as json
12from lexigram.admin.actions.header_manager.types import ColumnVisibilityConfig
15class ColumnVisibilityManager:
16 """Manages column visibility state and preferences."""
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.
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()
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)
45 # Initialize with defaults if no saved preferences
46 if not self._visible_columns:
47 self._visible_columns = set(config.default_visible)
49 @property
50 def visible_columns(self) -> set[str]:
51 """Get currently visible columns."""
52 return self._visible_columns.copy()
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
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()
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()
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)
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()
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()
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()
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]
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)]
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)]