feat: master-user impersonation route + app-top-banner plugin slot

This commit is contained in:
Linus Rath
2026-05-16 17:59:07 +02:00
parent 0ff88f36ed
commit ca1108f455
8 changed files with 515 additions and 2 deletions
+14
View File
@@ -185,6 +185,15 @@ export interface PluginAPI {
i18n: PluginI18n;
ui: {
registerToolbarAction: (action: ToolbarAction) => Disposable;
/**
* Register a banner that renders at the very top of the authenticated app
* shell — above the navigation rail, sidebar and content panes. Used for
* persistent global notices (impersonation, maintenance, etc.). The
* component receives `{ username, serverUrl }` as props.
*
* Requires the `ui:app-top-banner` permission.
*/
registerAppTopBanner: (component: React.ComponentType<Record<string, unknown>>) => Disposable;
registerEmailBanner: (factory: BannerFactory) => Disposable;
registerEmailFooter: (component: React.ComponentType) => Disposable;
registerSettingsSection: (section: SettingsSection) => Disposable;
@@ -710,6 +719,11 @@ export function createPluginAPI(plugin: InstalledPlugin): PluginAPI {
return registerSlot(plugin.id, 'email-banner', factory.render as unknown as React.ComponentType<Record<string, unknown>>, 100);
},
registerAppTopBanner: (component: React.ComponentType<Record<string, unknown>>) => {
requirePermission(plugin, 'ui:app-top-banner');
return registerSlot(plugin.id, 'app-top-banner', component, 100);
},
registerEmailFooter: (component: React.ComponentType) => {
requirePermission(plugin, 'ui:email-footer');
return registerSlot(plugin.id, 'email-footer', component as React.ComponentType<Record<string, unknown>>, 100);