Coverage for src/lexigram/admin/di/sub_providers/ui.py: 96%
27 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"""Admin UI sub-provider — rendering, component registry, forms, navigation."""
3from __future__ import annotations
5from typing import TYPE_CHECKING
7from lexigram.contracts.core.health import HealthCheckResult, HealthStatus
9if TYPE_CHECKING:
10 from lexigram.admin.config import AdminConfig
11 from lexigram.contracts.core.di import (
12 ContainerRegistrarProtocol,
13 ContainerResolverProtocol,
14 )
17class AdminUISubProvider:
18 """Manages admin UI infrastructure: rendering, components, forms, navigation.
20 Registers UI services: renderer, component registry, form renderer, navigation.
21 """
23 def __init__(self, config: AdminConfig, **kwargs: object) -> None:
24 self._config = config
25 self._kwargs = kwargs
26 self._initialized = False
28 @property
29 def config(self) -> AdminConfig:
30 """Return current admin config."""
31 return self._config
33 async def register(self, container: ContainerRegistrarProtocol) -> None:
34 """Register UI services: component registry, form renderer, navigation, layout."""
35 from lexigram.admin.layout.layout_manager import LayoutManager
36 from lexigram.admin.navigation.assembler import NavigationAssembler
37 from lexigram.admin.services.component_registry import ComponentRegistry
38 from lexigram.ui import MetricsCollector
40 container.singleton(ComponentRegistry, ComponentRegistry())
42 # Register navigation assembler (container will instantiate via DI)
43 container.singleton(NavigationAssembler, NavigationAssembler)
45 # Pre-construct LayoutManager to avoid the container trying to resolve
46 # LayoutType (an enum, not a registered service) as a dependency.
47 container.singleton(LayoutManager, LayoutManager())
49 container.singleton(MetricsCollector, MetricsCollector)
51 async def boot(self, container: ContainerResolverProtocol) -> None:
52 """Boot UI services: initialize component registry and navigation."""
53 self._initialized = True
55 async def shutdown(self) -> None:
56 """Shut down UI services."""
57 self._initialized = False
59 async def health_check(self, timeout: float = 5.0) -> HealthCheckResult:
60 """Return UI infrastructure health status."""
61 return HealthCheckResult(
62 component="admin_ui",
63 status=HealthStatus.HEALTHY if self._initialized else HealthStatus.UNKNOWN,
64 message="Admin UI operational"
65 if self._initialized
66 else "Not yet initialized",
67 )
70__all__ = ["AdminUISubProvider"]