diff --git a/docs/developer-guide/plugin/extension-points/ui/dashboard-widgets.md b/docs/developer-guide/plugin/extension-points/ui/dashboard-widgets.md new file mode 100644 index 0000000..e2c9613 --- /dev/null +++ b/docs/developer-guide/plugin/extension-points/ui/dashboard-widgets.md @@ -0,0 +1,284 @@ +--- +title: 仪表盘扩展点 +description: 扩展仪表盘小部件 - console:dashboard:widgets:create +--- + +仪表盘扩展点允许插件为 Halo 的控制台仪表盘添加自定义小部件和快速操作项。通过这些扩展点,插件可以: + +- 创建自定义的仪表盘小部件来展示特定数据或功能 +- 为快速操作小部件添加自定义操作项 + +![仪表盘扩展点](/img/developer-guide/plugin/extension-points/ui/dashboard-widgets.png) + +## console:dashboard:widgets:create + +此扩展点用于创建自定义的仪表盘小部件。 + +### 定义方式 + +```ts +import { definePlugin } from "@halo-dev/console-shared"; +import { markRaw } from "vue"; +import MyCustomWidget from "./components/MyCustomWidget.vue"; + +export default definePlugin({ + extensionPoints: { + "console:dashboard:widgets:create": () => { + return [ + { + id: "my-custom-widget", + component: markRaw(MyCustomWidget), + group: "my-plugin", + configFormKitSchema: [ + { + $formkit: "text", + name: "title", + label: "标题", + value: "默认标题", + }, + { + $formkit: "number", + name: "refresh_interval", + label: "刷新间隔(秒)", + value: 30, + min: 10, + }, + ], + defaultConfig: { + title: "我的自定义小部件", + refresh_interval: 30, + }, + defaultSize: { + w: 6, + h: 8, + minW: 3, + minH: 4, + maxW: 12, + maxH: 16, + }, + permissions: ["plugin:my-plugin:view"], + }, + ]; + }, + }, +}); +``` + +### DashboardWidgetDefinition 类型 + +```ts +export interface DashboardWidgetDefinition { + id: string; // 小部件唯一标识符 + component: Raw; // 小部件 Vue 组件 + group: string; // 小部件分组,用于在小部件库中分类显示 + configFormKitSchema?: Record[]; // 配置表单 FormKit 定义 + defaultConfig?: Record; // 默认配置 + defaultSize: { // 默认尺寸 + w: number; // 宽度(网格单位),根据不同屏幕尺寸,网格单位不同,可参考:{ lg: 12, md: 12, sm: 6, xs: 4 } + h: number; // 高度(网格单位) + minW?: number; // 最小宽度 + minH?: number; // 最小高度 + maxW?: number; // 最大宽度 + maxH?: number; // 最大高度 + }; + permissions?: string[]; // 访问权限 +} +``` + +### 小部件组件开发 + +```html + + + +``` + +**小部件组件的属性与事件:** + +| 属性 | 类型 | 说明 | +|---------------|-------------------------|--------------| +| `editMode` | boolean | 是否为编辑模式 | +| `previewMode` | boolean | 是否为预览模式 | +| `config` | Record\ | 小部件配置 | + +| 事件 | 说明 | +|-----------------|------------------| +| `update:config` | 小部件配置更新事件 | + +**WidgetCard 组件的属性与插槽:** + +| 属性 | 类型 | 说明 | +|---------------|-------------------------|--------------| +| `title` | string | 小部件标题 | +| `bodyClass` | string[] | 小部件内容区域样式 | + +| 插槽 | 说明 | +|-----------|------------| +| `title` | 小部件标题 | +| `default` | 小部件内容 | +| `actions` | 小部件操作项 | + +**重要说明:** + +- 小部件组件必须使用 `WidgetCard` 作为根组件,此组件已经在全局注册,不需要导入 +- 支持 `editMode` 和 `previewMode` 两种模式,当仪表盘处于编辑页面时,`editMode` 为 `true`,在小组件选择列表时,`previewMode` 为 `true`。可以根据这两个属性来控制小部件的显示内容 +- `update:config` 事件通常不需要实现,已经在内部实现了打开配置表单的功能,此事件用于自行实现配置表单 +- 使用 `markRaw()` 包装组件以避免响应式转换 + +## console:dashboard:widgets:internal:quick-action:item:create + +此扩展点用于为快速操作小部件添加自定义操作项。 + +### 定义方式 + +```ts +import { definePlugin } from "@halo-dev/console-shared"; +import { markRaw } from "vue"; +import { IconPlug } from "@halo-dev/components"; +import { useRouter } from "vue-router"; + +export default definePlugin({ + extensionPoints: { + "console:dashboard:widgets:internal:quick-action:item:create": () => { + return [ + { + id: "my-plugin-action", + icon: markRaw(IconPlug), + title: "我的插件操作", + action: () => { + // do something + }, + permissions: ["plugin:my-plugin:manage"], + }, + ]; + }, + }, +}); +``` + +### 自定义组件操作项 + +你也可以提供自定义组件而不是标准的操作项: + +```ts +import CustomActionItem from "./components/CustomActionItem.vue"; + +export default definePlugin({ + extensionPoints: { + "console:dashboard:widgets:internal:quick-action:item:create": () => { + return [ + { + id: "custom-action", + component: markRaw(CustomActionItem), + permissions: ["plugin:my-plugin:view"], + }, + ]; + }, + }, +}); +``` + +自定义组件: + +```html + + + +``` + +### DashboardWidgetQuickActionItem 类型 + +```ts +interface DashboardWidgetQuickActionBaseItem { + id: string; // 操作项唯一标识符 + permissions?: string[]; // 访问权限 +} + +interface DashboardWidgetQuickActionComponentItem + extends DashboardWidgetQuickActionBaseItem { + component: Raw; // 自定义组件 + icon?: Raw; // 图标(可选) + title?: string; // 标题(可选) + action?: () => void; // 点击操作(可选) +} + +interface DashboardWidgetQuickActionStandardItem + extends DashboardWidgetQuickActionBaseItem { + component?: never; // 不使用自定义组件 + icon: Raw; // 图标(必需) + title: string; // 标题(必需) + action: () => void; // 点击操作(必需) +} + +export type DashboardWidgetQuickActionItem = + | DashboardWidgetQuickActionComponentItem + | DashboardWidgetQuickActionStandardItem; +``` + +## 权限控制 + +两个扩展点都支持权限控制: + +- **小部件权限**:通过 `permissions` 字段控制小部件的显示 +- **操作项权限**:通过 `permissions` 字段控制快速操作项的显示 + +权限检查会自动进行,用户只能看到有权限访问的小部件和操作项。 diff --git a/sidebars.js b/sidebars.js index 7da5381..c3e0895 100644 --- a/sidebars.js +++ b/sidebars.js @@ -297,6 +297,7 @@ module.exports = { "developer-guide/plugin/extension-points/ui/post-list-item-field-create", "developer-guide/plugin/extension-points/ui/user-detail-tabs-create", "developer-guide/plugin/extension-points/ui/uc-user-profile-tabs-create", + "developer-guide/plugin/extension-points/ui/dashboard-widgets", ], }, ], diff --git a/static/img/developer-guide/plugin/extension-points/ui/dashboard-widgets.png b/static/img/developer-guide/plugin/extension-points/ui/dashboard-widgets.png new file mode 100644 index 0000000..fc28a92 Binary files /dev/null and b/static/img/developer-guide/plugin/extension-points/ui/dashboard-widgets.png differ