64 lines
2.1 KiB
Python
64 lines
2.1 KiB
Python
"""Dashboard routes — list available widgets from active plugins (Task 5.25)."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import uuid
|
|
|
|
from fastapi import APIRouter, Depends
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from app.core.db import get_db
|
|
from app.deps import require_permission
|
|
from app.plugins.builtins.contracts import get_contract
|
|
from app.plugins.registry import get_registry
|
|
|
|
router = APIRouter(prefix="/api/v1/dashboard", tags=["dashboard"])
|
|
|
|
|
|
@router.get("/widgets")
|
|
async def list_dashboard_widgets(
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user: dict = Depends(require_permission("dashboard:read")),
|
|
):
|
|
"""List all available dashboard widgets from active plugins.
|
|
|
|
Returns a flat list of widget definitions contributed by active plugins,
|
|
sorted by their order field. Each widget includes the contributing plugin name.
|
|
"""
|
|
registry = get_registry()
|
|
manifests = await registry.get_active_manifests(db)
|
|
|
|
widgets: list[dict] = []
|
|
for manifest in manifests:
|
|
for widget in manifest.get("dashboard_widgets", []):
|
|
widget_copy = dict(widget)
|
|
widget_copy["plugin_name"] = manifest["name"]
|
|
widgets.append(widget_copy)
|
|
|
|
# Sort by order field
|
|
widgets.sort(key=lambda w: w.get("order", 100))
|
|
|
|
return {"items": widgets, "total": len(widgets)}
|
|
|
|
|
|
@router.get("/counts")
|
|
async def get_dashboard_counts(
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user: dict = Depends(require_permission("dashboard:read")),
|
|
):
|
|
"""Get dashboard count statistics filtered by user visibility.
|
|
|
|
Counts come from the contacts plugin contract (Block C7) — the core
|
|
dashboard route has no direct dependency on the Contact model.
|
|
"""
|
|
contacts_contract = get_contract("contacts")
|
|
if contacts_contract is None or not hasattr(contacts_contract, "get_counts"):
|
|
return {"contacts": 0, "companies": 0, "persons": 0, "total": 0}
|
|
|
|
return await contacts_contract.get_counts(
|
|
db=db,
|
|
tenant_id=uuid.UUID(current_user["tenant_id"]),
|
|
user_id=uuid.UUID(current_user["user_id"]),
|
|
is_system_admin=current_user.get("is_system_admin", False),
|
|
)
|