Coverage for src / lexigram / admin / dashboard / settings_assembler.py: 58%
19 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
1from __future__ import annotations
3from collections.abc import Sequence
5from lexigram.admin.dashboard.naming_policy import NamingPolicy
6from lexigram.admin.dashboard.permission_filter import PermissionFilter
7from lexigram.admin.types import AdminUser
8from lexigram.contracts.admin import (
9 BaseAdminContributor,
10 SettingsPanelDefinition,
11)
14class SettingsPanelAssembler:
15 """Collects and validates ``SettingsPanelDefinition`` from contributors."""
17 def __init__(
18 self,
19 *,
20 naming_policy: NamingPolicy,
21 permission_filter: PermissionFilter,
22 ) -> None:
23 self._naming = naming_policy
24 self._perms = permission_filter
26 def assemble(
27 self,
28 contributors: Sequence[BaseAdminContributor],
29 user: AdminUser | None = None,
30 ) -> list[SettingsPanelDefinition]:
31 """Collect settings panels from all *contributors*."""
32 collected: list[SettingsPanelDefinition] = []
33 for c in contributors:
34 for panel in c.get_settings_panels():
35 ns_name = self._naming.namespaced(c.package_source, panel.name)
36 self._naming.register("settings", ns_name)
37 p = SettingsPanelDefinition(
38 name=ns_name,
39 title=panel.title,
40 contributor=c.package_source,
41 route_path=panel.route_path,
42 handler=panel.handler,
43 icon=panel.icon,
44 category=panel.category,
45 permission=panel.permission,
46 )
47 collected.append(p)
48 return self._perms.filter(
49 collected,
50 user,
51 get_required_permissions=lambda p: (
52 frozenset({p.permission}) if p.permission else frozenset()
53 ),
54 )