Files
foodlinkk-command-center/cockpit/app/services/ui_preferences.py
T

83 lines
2.9 KiB
Python
Raw Normal View History

2026-06-09 10:41:13 +00:00
"""User UI preferences — dashboard layout and visualization modes."""
from __future__ import annotations
import json
from typing import Any
from app.db import execute, fetch_one
DEFAULT_LAYOUT = ["kpis", "executive", "briefing", "retail", "analytics", "approvals", "feed"]
DEFAULT_VIZ = "neo-bars"
VIZ_MODES = [
{"id": "neo-bars", "label": "Neo staafdiagram", "icon": "📊"},
{"id": "neo-rings", "label": "Neo ringen", "icon": "🍩"},
{"id": "neo-equalizer", "label": "Neo equalizer", "icon": "🎚️"},
{"id": "neo-cards", "label": "Neo kaarten", "icon": "🃏"},
{"id": "neo-table", "label": "Neo tabel", "icon": "📋"},
]
def get_preferences(user_key: str = "ceo") -> dict[str, Any]:
row = fetch_one("SELECT * FROM user_ui_preferences WHERE user_key = %s", (user_key,))
if not row:
return {
"user_key": user_key,
"dashboard_layout": DEFAULT_LAYOUT,
"viz_modes": {},
"global_viz_mode": DEFAULT_VIZ,
"locale": "nl",
"viz_options": VIZ_MODES,
}
layout = row.get("dashboard_layout") or DEFAULT_LAYOUT
if isinstance(layout, str):
try:
layout = json.loads(layout)
except Exception:
layout = DEFAULT_LAYOUT
viz_modes = row.get("viz_modes") or {}
if isinstance(viz_modes, str):
try:
viz_modes = json.loads(viz_modes)
except Exception:
viz_modes = {}
return {
"user_key": user_key,
"dashboard_layout": layout,
"viz_modes": viz_modes,
"global_viz_mode": row.get("global_viz_mode") or DEFAULT_VIZ,
"locale": row.get("locale") or "nl",
"viz_options": VIZ_MODES,
}
def save_preferences(
user_key: str,
dashboard_layout: list[str] | None = None,
global_viz_mode: str | None = None,
viz_modes: dict[str, str] | None = None,
locale: str | None = None,
) -> dict[str, Any]:
current = get_preferences(user_key)
layout = dashboard_layout if dashboard_layout is not None else current["dashboard_layout"]
gviz = global_viz_mode if global_viz_mode is not None else current["global_viz_mode"]
vmodes = viz_modes if viz_modes is not None else current["viz_modes"]
loc = locale if locale is not None else current.get("locale", "nl")
if loc not in ("nl", "en"):
loc = "nl"
fetch_one(
"""
INSERT INTO user_ui_preferences (user_key, dashboard_layout, global_viz_mode, viz_modes, locale, updated_at)
VALUES (%s, %s::jsonb, %s, %s::jsonb, %s, NOW())
ON CONFLICT (user_key) DO UPDATE SET
dashboard_layout = EXCLUDED.dashboard_layout,
global_viz_mode = EXCLUDED.global_viz_mode,
viz_modes = EXCLUDED.viz_modes,
locale = EXCLUDED.locale,
updated_at = NOW()
RETURNING user_key
""",
(user_key, json.dumps(layout), gviz, json.dumps(vmodes), loc),
)
return get_preferences(user_key)