Coverage for src/lexigram/admin/dashboard/page_assembler.py: 0%
19 statements
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-24 23:18 +0800
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-24 23:18 +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 ManagementPageDefinition,
11)
14class PageAssembler:
15 """Collects and validates ``ManagementPageDefinition`` 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[ManagementPageDefinition]:
31 """Collect pages from all *contributors*, namespacing and filtering."""
32 collected: list[ManagementPageDefinition] = []
33 for c in contributors:
34 for page in c.get_management_pages():
35 ns_name = self._naming.namespaced(c.package_source, page.name)
36 self._naming.register("page", ns_name)
37 p = ManagementPageDefinition(
38 name=ns_name,
39 title=page.title,
40 contributor=c.package_source,
41 route_path=page.route_path,
42 handler=page.handler,
43 category=page.category,
44 permission=page.permission,
45 filters=page.filters,
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 )