Coverage for src/lexigram/admin/config/ui.py: 11%
37 statements
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-24 23:31 +0800
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-24 23:31 +0800
1"""UI, dashboard layout, cluster, and data configurations."""
3from __future__ import annotations
5from dataclasses import dataclass
6from typing import Literal
8from lexigram.domain import DomainModel
9from lexigram.validation import Field
12@dataclass(init=False)
13class AdminUIConfig(DomainModel):
14 """UI/Theme configuration."""
16 theme: Literal["light", "dark", "system"] = Field(default="system")
17 primary_color: str = Field(default="#6B7280")
18 sidebar_width: int = Field(default=256, ge=200, le=400)
19 sidebar_collapsed_width: int = Field(default=64, ge=48, le=100)
20 content_max_width: int | None = Field(default=None, ge=800)
21 logo_url: str | None = None
22 favicon_url: str | None = None
24 model_config = {"extra": "allow"}
27@dataclass(init=False)
28class DashboardLayoutConfig(DomainModel):
29 """Dashboard layout configuration."""
31 widget_refresh_default: int = Field(default=30)
32 max_widgets: int = Field(default=20)
33 layout: Literal["grid", "masonry"] = Field(default="grid")
36@dataclass(init=False)
37class ClusterSpec(DomainModel):
38 """Declarative description of an extra cluster.
40 Registered clusters get a routable center at ``/admin/{slug}`` with
41 its own landing page, namespaced child URLs, secondary sidebar, and
42 primary-sidebar collapse — no per-cluster code required.
43 """
45 name: str = Field(description="Cluster key (used to derive slug/group when unset)")
46 label: str = Field(description="Display label")
47 icon: str | None = Field(default=None, description="Icon name")
48 order: int = Field(default=0, description="Sort order in the registry")
49 collapsible: bool = Field(default=True)
50 collapsed_by_default: bool = Field(default=False)
51 slug: str = Field(default="", description="URL segment (defaults to name)")
52 group: str = Field(default="", description="Navigation group (defaults to name)")
53 description: str | None = Field(default=None)
56@dataclass(init=False)
57class AdminClustersConfig(DomainModel):
58 """Aggregate configuration for cluster centers."""
60 extra: list[ClusterSpec] = Field(
61 default_factory=list,
62 description="Extra clusters beyond the built-in infrastructure cluster",
63 )
66@dataclass(init=False)
67class AdminDataConfig(DomainModel):
68 query_timeout_seconds: int = Field(default=5, ge=1, le=120)