/** * Layout 与 Slot 配置类型(portal-shell spec §4、§6.2) * * 对应 config-service PluginConfigResponse(三层合并后的插件配置)。 * 类型与 services/config-service 的 GraphQL schema 对齐, * 通过 apollo-router GraphQL 查询 pluginConfig(userId, role) 获取。 * * 关联:portal-shell spec §4.1 5 种 Layout 模板、§4.2 Slot 系统、§6.2 PluginConfigResponse */ import type { Role } from "./plugin.js"; /** Layout 模板信息(对应 config-service LayoutTemplateInfo) */ export interface LayoutTemplateInfo { /** Layout ID:'classic' | 'focus' | 'split' | 'triple' | 'canvas' */ layoutId: string; /** 显示名 */ displayName: string; /** 描述 */ description: string; /** 可用 slot 列表,如 ["top", "side", "main"] */ availableSlots: string[]; /** Layout schema JSON 字符串(grid 配置等) */ layoutSchemaJson: string; } /** Slot 配置(对应 config-service SlotConfig) */ export interface SlotConfig { /** Slot 名称:'top' | 'side' | 'main' | 'main-left' | 'main-right' | 'right' | 'canvas-grid' */ slotName: string; /** 导航项列表(side slot 的导航菜单项) */ navItems: string[]; } /** 插件放置(三层合并后,对应 config-service PluginPlacement) */ export interface PluginPlacement { /** 插件 ID */ pluginId: string; /** 插入的 slot 名称 */ slot: string; /** 显示顺序(升序) */ sortOrder: number; /** 尺寸 JSON 字符串({colSpan, rowSpan}) */ sizeJson: string; /** 三层合并后的最终 props JSON 字符串 */ propsJson: string; /** 是否可见 */ isVisible: boolean; } /** 插件注册项(对应 config-service PluginRegistryItem) */ export interface PluginRegistryItem { /** 插件 ID */ pluginId: string; /** 分类:'universal' | 'sidebar' | 'topbar' | 'teacher' | 'student' | 'parent' | 'admin' */ category: string; /** 版本(semver) */ version: string; /** 显示名 */ displayName: string; /** 描述 */ description: string; /** 可访问此插件的角色列表 */ requiredRoles: string[]; /** 是否内置插件 */ isBuiltin: boolean; /** 是否全局启用 */ isActive: boolean; } /** * 三层合并后的插件配置响应(对应 config-service PluginConfigResponse) * * 由 config-service 合并三层配置后返回: * Layer 1: plugin_registry(系统默认) * Layer 2: role_plugin_mapping(角色模板) * Layer 3: user_layout_override(用户覆盖) */ export interface PluginConfigResponse { /** 当前启用的 Layout 模板 */ activeLayout: LayoutTemplateInfo | null; /** Slot 配置列表 */ slots: SlotConfig[]; /** 插件放置列表(三层合并后) */ plugins: PluginPlacement[]; /** 插件注册表(所有可用插件) */ registry: PluginRegistryItem[]; } /** Layout 模板 ID 枚举(portal-shell spec §4.1) */ export const LAYOUT_TEMPLATE_IDS = [ "classic", "focus", "split", "triple", "canvas", ] as const; /** Layout 模板 ID 类型 */ export type LayoutTemplateId = (typeof LAYOUT_TEMPLATE_IDS)[number]; /** Slot 名称枚举(portal-shell spec §4.2) */ export const SLOT_NAMES = [ "top", "side", "main", "main-left", "main-right", "right", "canvas-grid", ] as const; /** Slot 名称类型 */ export type SlotName = (typeof SLOT_NAMES)[number]; /** 角色-Layout 默认配置(admin 配置角色默认模板) */ export interface RoleLayoutDefault { role: Role; layoutId: string; slotOverrides: Record; } /** 用户布局覆盖(用户自定义) */ export interface UserLayoutOverride { userId: string; activeLayout: string; slotOverrides: Record; pluginPlacements: Array<{ pluginId: string; slot: string; sortOrder: number; size: { colSpan: number; rowSpan: number }; props: Record; }>; hiddenPlugins: string[]; }