Coverage for src/lexigram/admin/actions/header_manager/types.py: 100%
78 statements
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-21 14:56 +0800
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-21 14:56 +0800
1"""
2Types and data structures for header action management.
4Provides enums, dataclasses, and protocols for header actions.
5"""
7from __future__ import annotations
9from collections.abc import Callable
10from dataclasses import dataclass, field
11from enum import StrEnum
12from typing import Any, Protocol, TypeVar
14T = TypeVar("T")
17class HeaderActionStyle(StrEnum):
18 """Visual style for header actions."""
20 PRIMARY = "primary"
21 SECONDARY = "secondary"
22 SUCCESS = "success"
23 DANGER = "danger"
24 WARNING = "warning"
25 INFO = "info"
28class TableDensity(StrEnum):
29 """Table row density options."""
31 COMPACT = "compact"
32 NORMAL = "normal"
33 COMFORTABLE = "comfortable"
36@dataclass(slots=True)
37class HeaderAction:
38 """Configuration for a header action."""
40 name: str
41 """Action identifier."""
43 label: str
44 """Display label."""
46 handler: Callable[[], Any] | None = None
47 """Async function to execute the action."""
49 icon: str | None = None
50 """Icon name."""
52 style: HeaderActionStyle = HeaderActionStyle.SECONDARY
53 """Visual style."""
55 url: str | None = None
56 """URL for link-based actions."""
58 method: str = "GET"
59 """HTTP method for URL-based actions."""
61 open_in_modal: bool = False
62 """Whether to open URL in a modal."""
64 keyboard_shortcut: str | None = None
65 """Keyboard shortcut."""
67 visible: Callable[[], bool] = lambda: True
68 """Function to determine if action is visible."""
70 disabled: Callable[[], bool] = lambda: False
71 """Function to determine if action is disabled."""
73 tooltip: str | None = None
74 """Tooltip text."""
76 badge: str | None = None
77 """Badge text."""
79 position: str = "end"
80 """Position in header (start/end)."""
82 metadata: dict[str, Any] = field(default_factory=dict)
83 """Additional metadata."""
86@dataclass(slots=True)
87class ColumnVisibilityConfig:
88 """Configuration for column visibility toggle."""
90 enabled: bool = True
91 """Whether column visibility is enabled."""
93 default_visible: list[str] = field(default_factory=list)
94 """Columns visible by default."""
96 always_visible: list[str] = field(default_factory=list)
97 """Columns that cannot be hidden."""
99 save_preference: bool = True
100 """Whether to save user preferences."""
102 storage_key: str = "table_column_visibility"
103 """Storage key for saving preferences."""
106@dataclass(slots=True)
107class DensityConfig:
108 """Configuration for table density toggle."""
110 enabled: bool = True
111 """Whether density toggle is enabled."""
113 default: TableDensity = TableDensity.NORMAL
114 """Default density."""
116 options: list[TableDensity] = field(
117 default_factory=lambda: [
118 TableDensity.COMPACT,
119 TableDensity.NORMAL,
120 TableDensity.COMFORTABLE,
121 ]
122 )
123 """Available density options."""
125 save_preference: bool = True
126 """Whether to save user preferences."""
128 storage_key: str = "table_density"
129 """Storage key for saving preferences."""
132class IHeaderDataSource(Protocol[T]):
133 """Protocol for data sources that support header operations."""
135 async def create(self, data: dict[str, Any]) -> T:
136 """Create a new record."""
137 ...
139 async def import_data(self, file_path: str, file_format: str = "csv") -> int:
140 """Import data from file."""
141 ...
143 async def export_all(self, file_format: str = "csv") -> str:
144 """Export all data to file."""
145 ...
147 async def refresh(self) -> list[T]:
148 """Refresh table data."""
149 ...