Coverage for src/lexigram/admin/actions/row_manager/types.py: 0%
73 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"""
2Types and data structures for row action management.
4Provides enums, dataclasses, and protocols for row 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 ActionStyle(StrEnum):
18 """Visual style for actions."""
20 PRIMARY = "primary"
21 SECONDARY = "secondary"
22 SUCCESS = "success"
23 DANGER = "danger"
24 WARNING = "warning"
25 INFO = "info"
28class ActionPosition(StrEnum):
29 """Where to display the action."""
31 ROW_START = "row_start" # Before row content
32 ROW_END = "row_end" # After row content (default)
33 DROPDOWN = "dropdown" # In overflow menu
36@dataclass(slots=True)
37class RowAction:
38 """Configuration for a row action."""
40 name: str
41 """Action identifier."""
43 label: str
44 """Display label."""
46 handler: Callable[[Any], Any] | None = None
47 """Async function to execute the action."""
49 icon: str | None = None
50 """Icon name (e.g., 'eye', 'edit', 'trash')."""
52 style: ActionStyle = ActionStyle.SECONDARY
53 """Visual style."""
55 position: ActionPosition = ActionPosition.ROW_END
56 """Where to display the action."""
58 confirm: bool = False
59 """Whether to show confirmation dialog."""
61 confirm_message: str | None = None
62 """Custom confirmation message."""
64 url: str | None = None
65 """URL for link-based actions (alternative to handler)."""
67 method: str = "GET"
68 """HTTP method for URL-based actions."""
70 open_in_modal: bool = False
71 """Whether to open URL in a modal."""
73 keyboard_shortcut: str | None = None
74 """Keyboard shortcut (e.g., 'e', 'Ctrl+D')."""
76 visible: Callable[[Any], bool] = lambda _: True
77 """Function to determine if action is visible for a record."""
79 disabled: Callable[[Any], bool] = lambda _: False
80 """Function to determine if action is disabled for a record."""
82 tooltip: str | None = None
83 """Tooltip text."""
85 badge: str | None = None
86 """Badge text (e.g., "New", "Beta")."""
88 group: str | None = None
89 """Group name for organizing actions in dropdown."""
91 metadata: dict[str, Any] = field(default_factory=dict)
92 """Additional metadata."""
95@dataclass(slots=True)
96class ActionGroup:
97 """Group of related actions shown in a dropdown menu."""
99 name: str
100 """Group identifier."""
102 label: str
103 """Display label for the dropdown button."""
105 icon: str | None = "menu"
106 """Icon for dropdown button."""
108 actions: list[RowAction] = field(default_factory=list)
109 """Actions in this group."""
111 style: ActionStyle = ActionStyle.SECONDARY
112 """Visual style."""
114 visible: Callable[[Any], bool] = lambda _: True
115 """Function to determine if group is visible."""
118class IRowDataSource(Protocol[T]): # type: ignore[misc]
119 """Protocol for data sources that support row operations."""
121 async def get_by_id(self, record_id: Any) -> T | None:
122 """Get a single record by ID."""
123 ...
125 async def delete(self, record_id: Any) -> bool:
126 """Delete a record."""
127 ...
129 async def duplicate(self, record_id: Any) -> T:
130 """Duplicate a record."""
131 ...