Coverage for src / lexigram / admin / di / sub_providers / ui.py: 90%
29 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"""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.admin.ui.organisms.form_registry import FormFieldRegistry
39 from lexigram.ui import MetricsCollector
41 container.singleton(ComponentRegistry, ComponentRegistry())
42 container.singleton(FormFieldRegistry, FormFieldRegistry())
44 # Register navigation assembler (container will instantiate via DI)
45 container.singleton(NavigationAssembler, NavigationAssembler)
47 # Pre-construct LayoutManager to avoid the container trying to resolve
48 # LayoutType (an enum, not a registered service) as a dependency.
49 container.singleton(LayoutManager, LayoutManager())
51 container.singleton(MetricsCollector, MetricsCollector)
53 async def boot(self, container: ContainerResolverProtocol) -> None:
54 """Boot UI services: initialize component registry and navigation."""
55 self._initialized = True
57 async def shutdown(self) -> None:
58 """Shut down UI services."""
59 self._initialized = False
61 async def health_check(self, timeout: float = 5.0) -> HealthCheckResult:
62 """Return UI infrastructure health status."""
63 return HealthCheckResult(
64 component="admin_ui",
65 status=HealthStatus.HEALTHY if self._initialized else HealthStatus.UNKNOWN,
66 message="Admin UI operational"
67 if self._initialized
68 else "Not yet initialized",
69 )
72__all__ = ["AdminUISubProvider"]