52 lines
1.9 KiB
Python
52 lines
1.9 KiB
Python
"""Abstract sidebar-menu override persistence API.
|
|
|
|
The original ``menu_overrides`` document remains the administrator's default
|
|
layout. User layouts are stored as a separate, complete snapshot so that a
|
|
user can customise the menu without changing the default for anybody else.
|
|
The router overlays a user's snapshot on top of the default and lets default
|
|
rows for node ids not present in that snapshot flow through (new administrator
|
|
menus therefore appear for existing users).
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from abc import ABC, abstractmethod
|
|
from typing import Any
|
|
|
|
|
|
class MenuOverrideStore(ABC):
|
|
@abstractmethod
|
|
async def list_overrides(self) -> list[dict[str, Any]]:
|
|
"""Return every stored override row (order unspecified)."""
|
|
raise NotImplementedError
|
|
|
|
@abstractmethod
|
|
async def replace_all(self, rows: list[dict[str, Any]], *, updated_by: str | None = None) -> list[dict[str, Any]]:
|
|
"""Atomically replace the entire override set with ``rows``.
|
|
|
|
Each row is ``{node_id, parent_id, sort_order, label, disabled}``.
|
|
Returns the persisted rows.
|
|
"""
|
|
raise NotImplementedError
|
|
|
|
@abstractmethod
|
|
async def list_user_overrides(self, user_id: str) -> list[dict[str, Any]] | None:
|
|
"""Return one user's snapshot, or ``None`` when no snapshot exists."""
|
|
raise NotImplementedError
|
|
|
|
@abstractmethod
|
|
async def replace_user_overrides(
|
|
self,
|
|
user_id: str,
|
|
rows: list[dict[str, Any]],
|
|
*,
|
|
updated_by: str | None = None,
|
|
) -> list[dict[str, Any]] | None:
|
|
"""Replace one user's snapshot.
|
|
|
|
An empty list removes the snapshot and returns ``None``. This is the
|
|
reset-to-default operation and intentionally differs from the admin
|
|
``replace_all`` document, where an empty list means an empty default.
|
|
"""
|
|
raise NotImplementedError
|