feat: add configurable view-aware dashboards

This commit is contained in:
2026-07-29 14:32:54 +02:00
parent b28229c003
commit f0732bead2
24 changed files with 3169 additions and 146 deletions
+56 -2
View File
@@ -1,8 +1,39 @@
from __future__ import annotations
from pathlib import Path
from govoplan_core.core.access import CAPABILITY_AUTH_PERMISSION_EVALUATOR, CAPABILITY_AUTH_PRINCIPAL_RESOLVER
from govoplan_core.core.modules import DocumentationTopic, FrontendModule, FrontendRoute, ModuleManifest, NavItem
from govoplan_core.core.module_guards import (
drop_table_retirement_provider,
persistent_table_uninstall_guard,
)
from govoplan_core.core.modules import (
DocumentationTopic,
FrontendModule,
FrontendRoute,
MigrationSpec,
ModuleManifest,
NavItem,
)
from govoplan_core.core.views import ViewSurface
from govoplan_core.db.base import Base
from govoplan_dashboard.backend.db.models import DashboardLayout
def _dashboard_router(_context):
from govoplan_dashboard.backend.router import router
return router
def _tenant_summary(session, tenant_id: str) -> dict[str, int]:
return {
"dashboard_layouts": (
session.query(DashboardLayout)
.filter(DashboardLayout.tenant_id == tenant_id)
.count()
)
}
manifest = ModuleManifest(
@@ -11,6 +42,28 @@ manifest = ModuleManifest(
version="0.1.8",
required_capabilities=(CAPABILITY_AUTH_PRINCIPAL_RESOLVER, CAPABILITY_AUTH_PERMISSION_EVALUATOR),
optional_dependencies=("ops", "campaigns", "files", "mail", "tasks", "notifications", "reporting"),
route_factory=_dashboard_router,
tenant_summary_providers=(_tenant_summary,),
migration_spec=MigrationSpec(
module_id="dashboard",
metadata=Base.metadata,
script_location=str(Path(__file__).with_name("migrations") / "versions"),
retirement_supported=True,
retirement_provider=drop_table_retirement_provider(
DashboardLayout,
label="Dashboard",
),
retirement_notes=(
"Destructive retirement removes personal Dashboard layouts after "
"the installer captures a database snapshot."
),
),
uninstall_guard_providers=(
persistent_table_uninstall_guard(
DashboardLayout,
label="Dashboard",
),
),
nav_items=(NavItem(path="/dashboard", label="Dashboard", icon="dashboard", order=10),),
frontend=FrontendModule(
module_id="dashboard",
@@ -34,7 +87,8 @@ manifest = ModuleManifest(
summary="The dashboard module owns the configurable home surface. Feature modules expose widgets through a narrow dashboard.widgets capability.",
body=(
"Core only provides a minimal fallback home when the dashboard module is absent. "
"Dashboard widgets must be contributed through core contracts, not by importing sibling module components directly."
"Dashboard widgets must be contributed through core contracts, not by importing sibling module components directly. "
"Personal layouts are stored per tenant, account, and active View."
),
layer="configured",
documentation_types=("admin", "user"),