feat(L1): modular widget dashboard — 15 configurable widgets

Replaces monolithic AdminDashboard/ClientDashboard with a per-user
configurable widget grid. 15 widget types: ProductionStats, QueueStatus,
RecentRenders, CostOverview, WorkerStatus, KPISummary, OrderThroughput,
Revenue, ItemStatus, ProcessingTimes, RenderTimeByOutputType,
OutputTypeUsage, TopProducts, OrdersByUser, RenderBackendStats.

DashboardTimeframeContext provides shared timeframe state. Dashboard
config persisted in DB via GET/PUT /api/dashboard/config.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-06 23:11:13 +01:00
parent a70cb55d01
commit f15b035b88
19 changed files with 939 additions and 798 deletions
+18 -6
View File
@@ -24,15 +24,27 @@ WIDGET_TYPES = (
"RecentRenders",
"CostOverview",
"WorkerStatus",
"KPISummary",
"OrderThroughput",
"RevenueChart",
"ItemStatus",
"ProcessingTimes",
"RenderTimeByOutputType",
"OutputTypeUsage",
"TopProducts",
"OrdersByUser",
"RenderBackendStats",
)
# Default layouts per role
_DEFAULT_ADMIN_WIDGETS: list[dict] = [
{"widget_type": "ProductionStats", "position": {"col": 0, "row": 0, "w": 1, "h": 1}},
{"widget_type": "QueueStatus", "position": {"col": 1, "row": 0, "w": 1, "h": 1}},
{"widget_type": "WorkerStatus", "position": {"col": 2, "row": 0, "w": 1, "h": 1}},
{"widget_type": "RecentRenders", "position": {"col": 0, "row": 1, "w": 2, "h": 1}},
{"widget_type": "CostOverview", "position": {"col": 2, "row": 1, "w": 1, "h": 1}},
{"widget_type": "KPISummary", "position": {"col": 0, "row": 0, "w": 1, "h": 1}},
{"widget_type": "QueueStatus", "position": {"col": 1, "row": 0, "w": 1, "h": 1}},
{"widget_type": "WorkerStatus", "position": {"col": 2, "row": 0, "w": 1, "h": 1}},
{"widget_type": "OrderThroughput","position": {"col": 0, "row": 1, "w": 2, "h": 1}},
{"widget_type": "ItemStatus", "position": {"col": 2, "row": 1, "w": 1, "h": 1}},
{"widget_type": "RevenueChart", "position": {"col": 0, "row": 2, "w": 2, "h": 1}},
{"widget_type": "ProcessingTimes","position": {"col": 2, "row": 2, "w": 1, "h": 1}},
]
_DEFAULT_CLIENT_WIDGETS: list[dict] = [
@@ -44,7 +56,7 @@ _DEFAULT_CLIENT_WIDGETS: list[dict] = [
def get_default_widgets_for_role(role: str) -> list[dict]:
"""Return systemwide default widget layout for a given role.
admin / project_manager: all 5 widget types.
admin / project_manager: KPI + analytics defaults.
client: RecentRenders + ProductionStats only.
"""
if role in ("admin", "project_manager"):