Settings: a section per plugin, and call the folder Spam
Plugin settings pages were stacked at the bottom of Settings -> Accounts, which put antispam's thresholds and lists under a heading about mail accounts. Each `settings.page` now gets its own entry in the Settings nav: "Antispam filtering" and "Mail filters". Slot gains an optional `title` for this — the host needs a label when it gives a slot an area of its own, and falls back to the plugin name. PluginSlot gains an optional `plugin` filter so a host can render one plugin's bundle rather than every binding for a slot name. Wording: the app calls that folder Spam (i18n `nav.spam`), so the plugin's copy now does too — "filed into Spam", "Move to Spam", "marked as spam". The IMAP special-use stays `junk`, which is what the protocol calls it; only what the user reads changed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018SqJYt7jD7oUEkoY68sBZo
This commit is contained in:
@@ -96,7 +96,10 @@ def mount_routers(app: FastAPI) -> None:
|
||||
|
||||
|
||||
def _slot_dict(slot: Slot) -> dict[str, str]:
|
||||
return {"name": slot.name, "bundle": slot.bundle}
|
||||
d = {"name": slot.name, "bundle": slot.bundle}
|
||||
if slot.title:
|
||||
d["title"] = slot.title
|
||||
return d
|
||||
|
||||
|
||||
def _page_dict(page: Page) -> dict[str, Any]:
|
||||
@@ -120,9 +123,7 @@ def _manifest_dict(plugin: Plugin, manifest: UiManifest) -> dict[str, Any]:
|
||||
|
||||
def build_ui_manifest() -> dict[str, Any]:
|
||||
"""Aggregate every plugin's UI manifest for the frontend loader (SPEC §11.3)."""
|
||||
plugins = [
|
||||
_manifest_dict(p, p.ui_manifest) for p in get_plugins() if p.ui_manifest is not None
|
||||
]
|
||||
plugins = [_manifest_dict(p, p.ui_manifest) for p in get_plugins() if p.ui_manifest is not None]
|
||||
return {"plugins": plugins}
|
||||
|
||||
|
||||
|
||||
@@ -38,6 +38,10 @@ class Slot:
|
||||
|
||||
name: str
|
||||
bundle: str # path served by the plugin router, resolved by the frontend loader
|
||||
# Human label for slots the host renders as a named area of its own — today
|
||||
# `settings.page`, which becomes a section in Settings rather than being
|
||||
# stacked under someone else's. Falls back to the plugin's name.
|
||||
title: str | None = None
|
||||
|
||||
def __post_init__(self) -> None:
|
||||
if self.name not in SLOT_NAMES:
|
||||
|
||||
Reference in New Issue
Block a user