Coverage for src / lexigram / admin / ui / organisms / data_table / states.py: 38%
24 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-08-13 22:14 +0800
« prev ^ index » next coverage.py v7.13.5, created at 2026-08-13 22:14 +0800
1"""State rendering for data table component (skeleton, error states)."""
3from __future__ import annotations
5from typing import Any
7from lexigram.admin.config import TableConfiguration
8from lexigram.ui import ActionButton, EmptyState, ErrorState, Skeleton, TableState, el
11class StateRenderer:
12 """Renders different states for data table (loading, error, empty)."""
14 def __init__(self, config: TableConfiguration, state: TableState):
15 self.config = config
16 self.state = state
18 def render_skeleton(self) -> Any:
19 """Render loading skeleton."""
20 skeleton_rows = []
21 for _i in range(min(5, self.state.per_page)):
22 cells = []
23 if self.config.resource_prefix:
24 cells.append(
25 el(
26 "td",
27 Skeleton(variant="rectangular", width="16px", height="16px"),
28 class_="px-3 sm:px-6 py-4",
29 ),
30 )
31 for _ in self.config.columns:
32 cells.append(
33 el(
34 "td",
35 Skeleton(variant="text", width="80%"),
36 class_="px-3 sm:px-6 py-4",
37 ),
38 )
39 if self.config.resource_prefix:
40 cells.append(
41 el(
42 "td",
43 Skeleton(variant="text", width="60px"),
44 class_="px-3 sm:px-6 py-4",
45 ),
46 )
47 skeleton_rows.append(
48 el(
49 "tr",
50 *cells,
51 class_="border-b border-border",
52 ),
53 )
54 return el(
55 "div",
56 el(
57 "table",
58 el("tbody", *skeleton_rows, class_="bg-card"),
59 class_="w-full",
60 aria_label="Loading data",
61 ),
62 aria_busy="true",
63 class_="overflow-x-auto",
64 )
66 def render_error(self, error: Any) -> Any:
67 """Render error state."""
68 return ErrorState(
69 title="Failed to load data",
70 message=str(error),
71 action=ActionButton(
72 label="Retry",
73 color="primary",
74 onclick="window.location.reload()",
75 ).render(),
76 )
78 def render_empty(self) -> Any:
79 """Render empty state."""
80 return EmptyState(
81 title="No results found",
82 message="Try adjusting your filters or search terms.",
83 icon="🔍",
84 )