feat: govern effective appearance defaults
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, Literal, Mapping
|
||||
|
||||
|
||||
AppearancePalette = Literal["default", "civic_blue", "forest", "plum"]
|
||||
AppearanceSource = Literal["user", "tenant", "system", "tenant_lock", "system_lock"]
|
||||
|
||||
APPEARANCE_PALETTES: tuple[AppearancePalette, ...] = ("default", "civic_blue", "forest", "plum")
|
||||
APPEARANCE_SETTINGS_KEY = "appearance"
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class EffectiveAppearance:
|
||||
palette: AppearancePalette
|
||||
source: AppearanceSource
|
||||
locked: bool
|
||||
system_default_palette: AppearancePalette
|
||||
tenant_default_palette: AppearancePalette | None
|
||||
inherited_palette: AppearancePalette
|
||||
|
||||
def as_dict(self) -> dict[str, object]:
|
||||
return {
|
||||
"palette": self.palette,
|
||||
"source": self.source,
|
||||
"locked": self.locked,
|
||||
"system_default_palette": self.system_default_palette,
|
||||
"tenant_default_palette": self.tenant_default_palette,
|
||||
"inherited_palette": self.inherited_palette,
|
||||
}
|
||||
|
||||
|
||||
def normalize_appearance_palette(value: object, *, fallback: AppearancePalette | None = None) -> AppearancePalette | None:
|
||||
normalized = str(value or "").strip().lower()
|
||||
return normalized if normalized in APPEARANCE_PALETTES else fallback # type: ignore[return-value]
|
||||
|
||||
|
||||
def appearance_settings(settings: Mapping[str, Any] | None) -> tuple[AppearancePalette | None, bool]:
|
||||
raw = settings.get(APPEARANCE_SETTINGS_KEY) if isinstance(settings, Mapping) else None
|
||||
if not isinstance(raw, Mapping):
|
||||
return None, False
|
||||
return normalize_appearance_palette(raw.get("default_palette")), raw.get("palette_locked") is True
|
||||
|
||||
|
||||
def update_appearance_settings(
|
||||
settings: Mapping[str, Any] | None,
|
||||
*,
|
||||
default_palette: AppearancePalette | None,
|
||||
palette_locked: bool,
|
||||
) -> dict[str, Any]:
|
||||
updated = dict(settings or {})
|
||||
appearance = dict(updated.get(APPEARANCE_SETTINGS_KEY) or {}) if isinstance(updated.get(APPEARANCE_SETTINGS_KEY), Mapping) else {}
|
||||
if default_palette is None:
|
||||
appearance.pop("default_palette", None)
|
||||
else:
|
||||
normalized = normalize_appearance_palette(default_palette)
|
||||
if normalized is None:
|
||||
raise ValueError("Unsupported appearance palette.")
|
||||
appearance["default_palette"] = normalized
|
||||
if palette_locked:
|
||||
appearance["palette_locked"] = True
|
||||
else:
|
||||
appearance.pop("palette_locked", None)
|
||||
if appearance:
|
||||
updated[APPEARANCE_SETTINGS_KEY] = appearance
|
||||
else:
|
||||
updated.pop(APPEARANCE_SETTINGS_KEY, None)
|
||||
return updated
|
||||
|
||||
|
||||
def resolve_effective_appearance(
|
||||
*,
|
||||
system_settings: Mapping[str, Any] | None,
|
||||
tenant_settings: Mapping[str, Any] | None,
|
||||
user_settings: Mapping[str, Any] | None,
|
||||
) -> EffectiveAppearance:
|
||||
system_palette, system_locked = appearance_settings(system_settings)
|
||||
system_palette = system_palette or "default"
|
||||
tenant_palette, tenant_locked = appearance_settings(tenant_settings)
|
||||
inherited_palette = tenant_palette or system_palette
|
||||
raw_ui = user_settings.get("ui") if isinstance(user_settings, Mapping) else None
|
||||
user_palette = normalize_appearance_palette(raw_ui.get("palette")) if isinstance(raw_ui, Mapping) else None
|
||||
|
||||
if system_locked:
|
||||
return EffectiveAppearance(system_palette, "system_lock", True, system_palette, tenant_palette, system_palette)
|
||||
if tenant_locked:
|
||||
return EffectiveAppearance(inherited_palette, "tenant_lock", True, system_palette, tenant_palette, inherited_palette)
|
||||
return EffectiveAppearance(
|
||||
user_palette or inherited_palette,
|
||||
"user" if user_palette else "tenant" if tenant_palette else "system",
|
||||
False,
|
||||
system_palette,
|
||||
tenant_palette,
|
||||
inherited_palette,
|
||||
)
|
||||
|
||||
|
||||
__all__ = [
|
||||
"APPEARANCE_PALETTES",
|
||||
"APPEARANCE_SETTINGS_KEY",
|
||||
"AppearancePalette",
|
||||
"AppearanceSource",
|
||||
"EffectiveAppearance",
|
||||
"appearance_settings",
|
||||
"normalize_appearance_palette",
|
||||
"resolve_effective_appearance",
|
||||
"update_appearance_settings",
|
||||
]
|
||||
Reference in New Issue
Block a user