83 lines
2.9 KiB
Python
83 lines
2.9 KiB
Python
"""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)
|