Metabase 嵌入式分析 SDK 自定义 Dashboard 卡片菜单项:CustomDashboardCardMenuItem 类型深入解析
【免费下载链接】metabaseThe easy-to-use open source Business Intelligence and Embedded Analytics tool that lets everyone work with data :bar_chart:项目地址: https://gitcode.com/GitHub_Trending/me/metabase
本篇技术指南聚焦 Metabase 嵌入式分析 SDK(Embedding SDK)中用于扩展InteractiveDashboard卡片菜单(Dashboard Card Menu)的CustomDashboardCardMenuItem类型。该类型允许开发者以函数形式动态生成菜单项,并在运行时拿到当前卡片对应的MetabaseQuestion对象。读完本文,你将掌握该类型的完整签名、参数与返回值语义、它与普通菜单项DashCardMenuItem的区别,以及如何通过MetabasePluginsConfig插件配置将其接入实际嵌入场景。
类型定义速览
CustomDashboardCardMenuItem是一个返回型函数类型:接收包含可选question参数的对象,返回一个DashCardMenuItem。其定义位于 dashcard-menu.ts,与 API 文档 CustomDashboardCardMenuItem.md 完全对应:
type CustomDashboardCardMenuItem = ({ question, }: { question?: MetabaseQuestion; }) => DashCardMenuItem;关键语义:
- 它本身不是菜单项,而是"菜单项工厂"——每次渲染时被调用一次,产出一个具体的
DashCardMenuItem; question是可选的(?后缀),但实际运行时 SDK 总会传入当前卡片对应的MetabaseQuestion,见下文源码验证;- 返回的
DashCardMenuItem必须是完整、合法的菜单项对象(label与onClick为必填)。
参数解析:question?与MetabaseQuestion
按 API 文档的参数表,该函数类型只有一组参数:
| 参数 | 类型 | 说明 |
|---|---|---|
{ question, } | { question?: MetabaseQuestion } | 解构自函数的入参对象 |
{ question, }.question? | MetabaseQuestion | 当前卡片所对应的问题(可选) |
MetabaseQuestion是该 SDK 对外暴露的、只读摘要版问题对象,属性如下(见 MetabaseQuestion.md):
| 属性 | 类型 | 含义 |
|---|---|---|
description | string \| null | 问题描述 |
entityId | string | 实体唯一标识 |
id | number | 问题 ID |
isSavedQuestion | boolean | 是否为已保存问题 |
name | string | 问题名称 |
在自定义菜单回调里最常用的就是question.name(用于展示)与question.id(用于跳转或埋点)。
返回值:DashCardMenuItem属性全解
函数必须返回一个DashCardMenuItem,其完整属性如下:
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
label | string | ✅ | 菜单项显示文本 |
iconName | IconName | ✅ | 图标名称 |
onClick | () => void | ✅ | 点击处理函数 |
children? | ReactNode | ❌ | 子节点内容 |
closeMenuOnClick? | boolean | ❌ | 点击后是否关闭菜单,覆盖Menu组件的closeOnItemClick |
color? | MantineColor | ❌ | theme.colors的键或任意合法 CSS 颜色 |
disabled? | boolean | ❌ | 禁用该菜单项 |
leftSection? | ReactNode | ❌ | 标签左侧区域 |
rightSection? | ReactNode | ❌ | 标签右侧区域 |
label、iconName、onClick为必填项,其余均可选。若需要在点击时保持菜单展开(例如触发下载中状态),可设置closeMenuOnClick: false。
源码验证:函数式菜单项如何被调用
在 SDK 运行时,自定义菜单项在 DashCardMenuItems.tsx 中被渲染:
if (customItems) { items.push( ...customItems.map((item) => { const customItem = typeof item === "function" ? item({ question: transformSdkQuestion(question) }) : item; return { ...customItem, key: `MB_CUSTOM_${customItem.label}`, }; }), ); }从源码结构可以看到两个重要实现事实:
- 类型判别:
customItems数组里的元素既可以是普通对象DashCardMenuItem,也可以是函数CustomDashboardCardMenuItem。SDK 通过typeof item === "function"判断——是函数则调用它并传入{ question },否则原样使用; - question 的来源:传入函数的是
transformSdkQuestion(question)的结果,即内部Question对象经过 SDK 转换后得到的MetabaseQuestion只读视图。因此回调中question.name、question.id等字段始终可用,question?的可选标记仅为类型层面的保守声明。
每个自定义项还会被注入唯一key(MB_CUSTOM_${label}),并在 DashCardMenu.tsx 中随"下载结果"“编辑问题”等内置项一同渲染为 MantineMenu.Item(左侧自动渲染iconName图标)。
接入方式:通过插件配置启用
CustomDashboardCardMenuItem不是单独使用的,它作为DashboardCardCustomMenuItem.customItems数组的元素之一,挂在InteractiveDashboard的plugins.dashboard.dashboardCardMenu上。类型装配关系定义在 dashcard-menu.ts 与 plugins.ts:
type DashboardCardCustomMenuItem = { withDownloads?: boolean; withEditLink?: boolean; customItems?: (DashCardMenuItem | CustomDashboardCardMenuItem)[]; }; type DashboardCardMenu = | DashboardCardMenuCustomElement // 整个菜单替换为自定义元素 | DashboardCardCustomMenuItem; // 保留默认菜单并在其中追加/配置自定义项相关配置字段:
| 字段 | 类型 | 说明 |
|---|---|---|
withDownloads | boolean | 是否保留"下载结果"内置菜单项(默认true) |
withEditLink | boolean | 是否保留"编辑"内置菜单项(默认true) |
customItems | (DashCardMenuItem \| CustomDashboardCardMenuItem)[] | 追加的自定义菜单项,支持静态对象或函数两种形态 |
完整实战示例
以下示例来自官方文档代码片段 plugins.tsx,演示如何同时使用静态对象与函数式菜单项:
import { InteractiveDashboard, type MetabasePluginsConfig, } from "@metabase/embedding-sdk-react"; const plugins: MetabasePluginsConfig = { dashboard: { dashboardCardMenu: { customItems: [ // 静态菜单项:无需感知具体问题 { iconName: "chevronright", label: "Custom action", onClick: () => { alert(`Custom action clicked`); }, }, // 函数式菜单项:动态读取当前卡片对应的问题 ({ question }) => { return { iconName: "chevronright", label: "Custom action", onClick: () => { alert(`Custom action clicked ${question?.name}`); }, }; }, ], }, }, }; export const MyDashboard = () => ( <InteractiveDashboard dashboardId={1} plugins={plugins} /> );典型应用场景包括:
- 按问题类型动态生成菜单:根据
question.isSavedQuestion决定展示"查看详情"还是"保存为收藏"; - 携带问题元数据跳转:在
onClick中使用question.id触发自有业务逻辑(如打开外部报表系统); - 与默认菜单共存:保持
withDownloads/withEditLink为true,只在末尾追加自定义动作。
若需完全替换菜单,可改用DashboardCardMenuCustomElement(即dashboardCardMenu直接传函数返回自定义ReactNode),参见 plugins.tsx 中的dashboardCardMenu: ({ question }) => <button>...形态。
小结
CustomDashboardCardMenuItem是 Metabase 嵌入式分析 SDK 扩展 Dashboard 卡片菜单的"动态工厂"类型:它把当前卡片的MetabaseQuestion注入到菜单生成回调中,让开发者可以在不触碰内置菜单的前提下,按需产出上下文相关的自定义操作项。使用时牢记三点:返回对象必须包含label、iconName、onClick;question在运行时总是可用;customItems中静态对象与函数可以混用。
【免费下载链接】metabaseThe easy-to-use open source Business Intelligence and Embedded Analytics tool that lets everyone work with data :bar_chart:项目地址: https://gitcode.com/GitHub_Trending/me/metabase
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考