Files

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