registry.py 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940
  1. from __future__ import annotations
  2. from typing import Any
  3. from app.core.system.permissions import READ_GOVERNANCE
  4. WIDGET_REGISTRY = {
  5. "pending_reviews": {"title": "待审核数量", "min_w": 2, "max_w": 6, "min_h": 2, "max_h": 4, "permission": READ_GOVERNANCE},
  6. "order_status": {"title": "数据订单状态", "min_w": 3, "max_w": 8, "min_h": 2, "max_h": 6, "permission": READ_GOVERNANCE},
  7. "product_stats": {"title": "数据产品统计", "min_w": 2, "max_w": 6, "min_h": 2, "max_h": 4, "permission": READ_GOVERNANCE},
  8. "datasource_health": {"title": "数据源健康", "min_w": 3, "max_w": 8, "min_h": 2, "max_h": 6, "permission": READ_GOVERNANCE},
  9. "n8n_executions": {"title": "n8n 执行概览", "min_w": 3, "max_w": 8, "min_h": 2, "max_h": 6, "permission": READ_GOVERNANCE},
  10. }
  11. DEFAULT_LAYOUT = [
  12. {"id": "pending_reviews", "x": 0, "y": 0, "w": 3, "h": 2},
  13. {"id": "order_status", "x": 3, "y": 0, "w": 5, "h": 3},
  14. {"id": "product_stats", "x": 8, "y": 0, "w": 3, "h": 2},
  15. {"id": "datasource_health", "x": 0, "y": 3, "w": 5, "h": 3},
  16. {"id": "n8n_executions", "x": 5, "y": 3, "w": 6, "h": 3},
  17. ]
  18. def validate_layout(widgets: list[dict[str, Any]]) -> list[dict[str, Any]]:
  19. if not isinstance(widgets, list):
  20. raise ValueError("widgets must be a list")
  21. seen = set()
  22. cleaned = []
  23. for item in widgets:
  24. widget_id = item.get("id")
  25. spec = WIDGET_REGISTRY.get(widget_id)
  26. if not spec or widget_id in seen:
  27. raise ValueError("unknown or duplicate widget")
  28. seen.add(widget_id)
  29. values = {key: int(item.get(key, 0)) for key in ("x", "y", "w", "h")}
  30. if values["x"] < 0 or values["y"] < 0 or not (spec["min_w"] <= values["w"] <= spec["max_w"]) or not (spec["min_h"] <= values["h"] <= spec["max_h"]):
  31. raise ValueError(f"invalid size or position for {widget_id}")
  32. cleaned.append({"id": widget_id, **values})
  33. return cleaned