ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Metabase 嵌入 SDK 全局插件配置:MetabaseGlobalPluginsConfig 类型详解与实战

Metabase 嵌入 SDK 全局插件配置:MetabaseGlobalPluginsConfig 类型详解与实战 Metabase 嵌入 SDK 全局插件配置MetabaseGlobalPluginsConfig 类型详解与实战【免费下载链接】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导读MetabaseGlobalPluginsConfig是 Metabase 模块化嵌入 SDKEmbedded Analytics SDK中定义全局插件配置的 TypeScript 类型它决定了嵌入应用在「链接点击处理」「无数据/无对象占位插图」两个维度上如何被宿主应用定制。本篇以该类型为骨架结合仓库内的类型定义、运行时实现与官方示例讲解pluginsConfig的挂载位置、三个可配置函数签名与返回约定、作用域限制并给出可直接复制运行的 React 代码。读完本文你将能独立完成嵌入应用中链接拦截与空状态品牌化定制。一、类型定义总览从源码到文档在文档 MetabaseGlobalPluginsConfig.md 中该类型的完整声明为type MetabaseGlobalPluginsConfig MetabasePluginsConfig { getNoDataIllustration?: () string | null | undefined; getNoObjectIllustration?: () string | null | undefined; handleLink?: (url: string) { handled: boolean; }; };其底层源码位于 frontend/src/embedding-sdk-bundle/types/plugins.ts与文档完全一致并补充了两条关键 JSDoc 注释getNoDataIllustration与getNoObjectIllustration的返回值是base64 编码的图片字符串返回null则回退到默认插图handleLink接收 URL 字符串返回{ handled: boolean }。继承的基类型 MetabasePluginsConfig全局插件类型通过继承了组件级插件的基类型MetabasePluginsConfig见 MetabasePluginsConfig.md 与 plugins.tstype MetabasePluginsConfig { dashboard?: MetabaseDashboardPluginsConfig; mapQuestionClickActions?: MetabaseClickActionPluginsConfig; };属性类型用途dashboard?MetabaseDashboardPluginsConfig自定义仪表盘卡片菜单dashboardCardMenumapQuestionClickActions?MetabaseClickActionPluginsConfig定制图表/仪表盘数据点点击行为因此MetabaseGlobalPluginsConfig实际可配置五个字段上述两个继承字段加上本文重点的三个全局字段。两者的作用域差异见下文「插件作用域」一节。二、挂载位置pluginsConfig 与 MetabaseProvider全局插件必须挂载在MetabaseProvider的pluginsConfigprop 上。该 prop 的类型即MetabaseGlobalPluginsConfig这可以从 SDK API 文档 MetabaseProviderProps.md 中确认pluginsConfig?:MetabaseGlobalPluginsConfig— See Plugins.一个最小挂载示例源码示例见 global-plugins.tsximport type { PropsWithChildren } from react; import { type MetabaseAuthConfig, MetabaseProvider, type MetabaseTheme, } from metabase/embedding-sdk-react; const authConfig {} as MetabaseAuthConfig; const theme {} as MetabaseTheme; const Example ({ children }: PropsWithChildren) ( MetabaseProvider authConfig{authConfig} theme{theme} pluginsConfig{{ mapQuestionClickActions: () [], // 在此添加自定义点击行为 }} {children} /MetabaseProvider );运行时如何读取全局插件从源码结构看MetabaseProvider与 SDK 的大部分代码分属不同的 bundlenpm 包与 SDK bundle无法直接共享一个导出对象作为单例。因此仓库在 sdk-global-plugins.ts 中通过ensureMetabaseProviderPropsStore建立了一个挂在window上的单例 storekey 为METABASE_PROVIDER_PROPS_STORE见 ensure-metabase-provider-props-store.tsexport const getSdkGlobalPlugins (): SdkGlobalPlugins { return ( ensureMetabaseProviderPropsStoreSdkGlobalPluginsProps().getState().props ?.pluginsConfig || {} ); };即MetabaseProvider收到的pluginsConfig会被写入全局单例 storeSDK 各组件通过getSdkGlobalPlugins()跨 bundle 读取。值得注意的是SDK 对外要求同步函数而内部实际处理链路是异步的类型定义同时兼容两种签名见 sdk-global-plugins.ts 中的HandleLinkFn。三、handleLink拦截嵌入内容中的链接点击签名与返回值约定handleLink?: (url: string) { handled: boolean; };入参url用户点击的链接字符串返回值{ handled: true }宿主应用接管了该链接阻止 SDK 默认导航行为返回值{ handled: false }不接管恢复 SDK 默认行为默认在新标签页打开链接。完整示例内部链接交给路由外部链接保持默认仓库官方示例 handlelink.tsx 展示了最典型的使用场景——把内部链接交给宿主应用自己的路由器处理import { InteractiveDashboard, type MetabaseAuthConfig, MetabaseProvider, } from metabase/embedding-sdk-react; const authConfig {} as MetabaseAuthConfig; export default function App() { const plugins { handleLink: (urlString: string) { const url new URL(urlString, window.location.origin); const isInternal url.origin window.location.origin; if (isInternal) { // 处理内部导航例如交给你的 router console.log(Navigate to:, url.pathname url.search url.hash); return { handled: true }; // 阻止默认导航 } return { handled: false }; // 让 SDK 执行默认行为 }, }; return ( MetabaseProvider authConfig{authConfig} pluginsConfig{plugins} InteractiveDashboard dashboardId{1} / /MetabaseProvider ); }该示例的实践意义嵌入场景中点击内部链接默认会在新标签页打开体验割裂通过handleLink结合window.location.origin判断同源可将内部链接改走宿主应用的客户端路由例如 React Router同时放行外部链接走默认新标签页。底层调用链openUrl 如何遵守插件约定handleLink并非孤立 API它被接入了 Metabase 全局的 URL 打开工具链。在 frontend/src/metabase/urls/open-url.ts 中/** * Opens a URL using the most appropriate strategy: in the current window, * a new tab, or via client-side navigation when its an in-app Metabase URL. * Honours the embedding SDKs handleLink plugin if installed. */ export async function openUrl(url: string, {...}): Promisevoid { url ignoreSiteUrl ? url : getWithSiteUrl(url); // In the sdk, allow the host app to override how to open links if (isEmbeddingSdk()) { const result await handleLinkSdkPlugin(url); if (result.handled) { // Plugin handled the link, dont continue with default behavior return; } } // ...否则按默认策略打开新窗口 / 同源客户端导航 / 当前窗口 }调用链可概括为openUrl→handleLinkSdkPlugin见 sdk-global-plugins.ts内部调用默认的MODULAR_EMBEDDING_HANDLE_LINK_PLUGIN其默认实现为(_url) Promise.resolve({ handled: false })→ 读取宿主传入的handleLink。因此默认情况下链接行为不受影响只有宿主显式配置了插件才会被拦截。handleLinkSdkPlugin也是该插件模块的核心导出在 SDK 的链接渲染组件如表单中的链接渲染中被复用。作用域限制与 Modular Embedding 的等价 API根据 plugins.mdhandleLink只能全局使用provider 级别不能在单个组件上通过pluginsprop 使用在 Modular Embedding无 React 的模块化嵌入中handleLink同样可用通过defineMetabaseConfig的pluginsConfig传入API 完全一致可参考 MetabaseProvider.ts 的 API 文档若想在表格列中产生可点击链接需将列的格式设置为「以链接形式显示」display as link。四、getNoDataIllustration 与 getNoObjectIllustration定制空状态插图签名与返回值约定getNoDataIllustration?: () string | null | undefined; getNoObjectIllustration?: () string | null | undefined;返回base64 编码的图片字符串作为空状态占位插图返回null或undefined时回退到默认插图。两者语义区别根据 loading-and-errors.md 的官方说明getNoDataIllustration覆盖「查询返回零行」的场景即图表/表格无数据时的提示图getNoObjectIllustration覆盖「搜索无结果」的场景例如搜索页面、实体选择器entity picker中找不到任何匹配项或没有仪表盘、没有集合等对象为空的情况。默认情况下Metabase 在这两种场景展示一张帆船sailboat插图。完整示例官方示例 custom-images.tsximport { InteractiveDashboard, type MetabaseAuthConfig, MetabaseProvider, } from metabase/embedding-sdk-react; const authConfig {} as MetabaseAuthConfig; export default function App() { const img_base64 ...; // base64-encoded image const plugins { getNoDataIllustration: () img_base64, getNoObjectIllustration: () img_base64, }; return ( MetabaseProvider authConfig{authConfig} pluginsConfig{plugins} InteractiveDashboard dashboardId{1} / /MetabaseProvider ); }与loaderComponent、errorComponent这类「组件 prop」不同这两个配置项属于插件plugins必须放进pluginsConfig且返回的是 base64 图片字符串而不是 React 组件。两者都只能全局设置provider 级别。渲染链路从插件到 UI从源码看这两个插件的消费链路是「选择器 → 错误组件 → 渲染」选择器定义于 frontend/src/metabase/selectors/whitelabel/index.tsexport function getNoDataIllustration(state: State) { return PLUGIN_SELECTORS.getNoDataIllustration(state); } export function getNoObjectIllustration(state: State) { return PLUGIN_SELECTORS.getNoObjectIllustration(state); }默认实现位于 frontend/src/metabase/plugins/oss/core.ts两者默认都返回noResultsSource即默认的帆船插图资源getNoDataIllustration: (_state: State): string | null { return noResultsSource; }, getNoObjectIllustration: (_state: State): string | null { return noResultsSource; },消费组件分别是 NoDataError.tsx 与 NoObjectError.tsx。两者结构一致通过useSelector(getNoDataIllustration / getNoObjectIllustration)读取插件返回值非空时渲染为 120×120 的Imagealt 文本为「No results」为空则渲染null。export function NoDataError(props: ImageProps) { const noDataIllustration useSelector(getNoDataIllustration); return noDataIllustration ? ( Image alt{tNo results} w{120} h{120} src{noDataIllustration} {...props} / ) : null; }在嵌入 SDK 侧InteractiveDashboard 的 props 校验 schema 也显式允许这两个字段见 InteractiveDashboard.schema.tsplugins: Yup.object({ mapQuestionClickActions: Yup.mixed().optional(), dashboard: Yup.mixed().optional(), getNoDataIllustration: Yup.mixed().optional(), getNoObjectIllustration: Yup.mixed().optional(), }) .optional() .noUnknown(),这也验证了这两个插图插件在 SDK 中被视为与mapQuestionClickActions、dashboard同级的全局插件配置项。五、插件作用域总结全局 vs 组件级根据 plugins.mdMetabase SDK 插件分两种挂载方式插件全局providerpluginsConfig组件级组件pluginsprophandleLink✅ 仅限全局❌getNoDataIllustration✅ 仅限全局❌getNoObjectIllustration✅ 仅限全局❌mapQuestionClickActions✅✅dashboard卡片菜单✅✅按组件组件级插件的挂载示例见 component-plugins.tsximport { InteractiveQuestion } from metabase/embedding-sdk-react; const Example () ( InteractiveQuestion questionId{1} plugins{{ mapQuestionClickActions: () [], }} / );因此本文三个核心字段的共同特征是「全局生效、provider 挂载」——这正是MetabaseGlobalPluginsConfig中「Global」一词的含义它们影响的是整个嵌入应用的行为与观感而不是单个组件。六、小结与进一步阅读MetabaseGlobalPluginsConfig是嵌入 SDK 全局定制的类型入口handleLink让宿主应用接管嵌入内容中的链接导航实现同源路由跳转、弹窗打开等自定义策略底层由openUrl调用链统一遵守open-url.tsgetNoDataIllustration/getNoObjectIllustration用 base64 图片替换默认帆船插图覆盖「查询无数据」与「搜索无对象」两种空状态渲染链路经过白标选择器whitelabel/index.ts与错误组件NoDataError.tsx、NoObjectError.tsx。若需继续深入可阅读仓库内以下文档插件总览与作用域docs/embedding/sdk/plugins.md空状态与加载、错误定制docs/embedding/sdk/loading-and-errors.md基类型MetabasePluginsConfigdocs/embedding/sdk/api/snippets/MetabasePluginsConfig.md图表点击行为定制mapQuestionClickActionsdocs/embedding/sdk/chart.md仪表盘卡片菜单定制dashboard.dashboardCardMenudocs/embedding/sdk/dashboard.md【免费下载链接】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),仅供参考
返回列表