跳转到主要内容

注册扩展

扩展 是由插件定义的链接或 React 组件,可以在 Grafana 核心 UI 或另一个应用插件中渲染。

公开组件 相比,它们是针对一个或多个扩展点 ID 显式注册的。当您想要扩展 Grafana 的核心 UI,或者需要更多控制哪些内容可以使用您的插件扩展时,这可能更为合适。

关键概念 下阅读有关扩展的更多信息。

类型描述
链接链接具有 pathonClick() 属性。

何时使用?
如果您想为插件提供定义自定义用户操作的方式,可以使用链接,例如,为 UI 的一部分实现跨链接,或者使用 onClick() 方法实现更互动的页面体验。

API 参考
- addLink() - 从插件注册链接
- usePluginLinks() - 获取已注册扩展点的链接
组件组件是可以用于渲染自定义用户体验的 React 组件。

何时使用?
如果您想给插件提供更多自由来扩展您的 UI,例如使用自定义部分扩展配置表单,可以使用组件。

API 参考
- addComponent() - 从插件注册组件
- usePluginComponents() - 获取已注册扩展点的组件
警告

您必须更新plugin.json元数据以列出任何已注册的扩展。

您可以为链接添加扩展。例如

import { PluginExtensionPoints } from '@grafana/data';
import pluginJson from './plugin.json';

export const plugin = new AppPlugin().addLink({
title: '...', // This appears as the label for the link
description: '...',
targets: [PluginExtensionPoints.DashboardPanelMenu], // Show it in the panel menu
path: `/a/${pluginJson.id}/foo`, // Path can only point somewhere under the plugin
});

您可以在扩展点处隐藏链接。例如

import { PluginExtensionPoints } from '@grafana/data';

export const plugin = new AppPlugin().addLink({
title: '...',
description: '...',
targets: [PluginExtensionPoints.DashboardPanelMenu],
path: `/a/${pluginJson.id}/foo`,
// The `context` is coming from the extension point.
// (Passed in to the `usePluginLinks({ context })` hook.)
configure: (context) => {
// Returning `undefined` will hide the link at the extension point.
// (In this example we are NOT showing the link for "timeseries" panels.)
if (context?.pluginId === 'timeseries') {
return undefined;
}

// Returning an empty object meanst that we don't update the link properties.
return {};
},
});

根据上下文更新路径

import { PluginExtensionPoints } from '@grafana/data';

export const plugin = new AppPlugin().addLink({
title: '...',
description: '...',
targets: [PluginExtensionPoints.DashboardPanelMenu],
path: `/a/${pluginJson.id}/foo`,
configure: (context) => {
if (context?.pluginId === 'timeseries') {
// We render a different link for "timeseries" panels.
//
// Heads up! Only the following properties can be updated from the `configure()` function:
// - title
// - description
// - path
// - icon
// - category
return {
path: `/a/${pluginJson.id}/foo/timeseries`,
};
}

// Returning an empty object means no updates to any of the properties.
return {};
},
});

onClick()打开模态

import { PluginExtensionPoints } from '@grafana/data';
import { Button, Modal } from '@grafana/ui';

export const plugin = new AppPlugin().addLink({
title: '...',
description: '...',
targets: [PluginExtensionPoints.DashboardPanelMenu],
// `event` - the `React.MouseEvent` from the click event
// `context` - the `context` object shared with the extensions
onClick: (event, { openModal, context }) =>
openModal({
title: 'My modal',
width: 500, // (Optional) - width of the modal in pixels
height: 500, // (Optional) - height of the modal in pixels

// Calling `onDismiss()` closes the modal
body: ({ onDismiss }) => (
<div>
<div>This is our modal.</div>

<Modal.ButtonRow>
<Button variant="secondary" fill="outline" onClick={onDismiss}>
Cancel
</Button>
<Button onClick={onDismiss}>Ok</Button>
</Modal.ButtonRow>
</div>
),
}),
});

组件

添加组件的最佳实践

  • 使用props - 检查扩展点传递给组件的props,并使用它们来实现更定制化的体验。
  • 将组件包裹在提供者中 - 如果您想在组件中访问任何特定于插件的状态,请确保使用必要的React上下文提供者(例如,对于Redux)将其包裹。
  • 使用Grafana扩展点ID的枚举 - 如果您要将组件注册到可用的Grafana扩展点之一,请确保使用由@grafana/data包公开的PluginExtensionPoints枚举。

注册组件

import { PluginExtensionPoints } from '@grafana/data';

export const plugin = new AppPlugin().addComponent({
title: 'User profile tab',
description: '...',
targets: [PluginExtensionPoints.UserProfileTab],
component: () => <div>This is a new tab on the user profile page.</div>,
});

在组件中访问插件元数据

您可以使用usePluginContext()钩子来访问组件内部的任何特定于插件元信息。该钩子返回一个PluginMeta对象。这很有用,因为您从插件注册的组件不会在您的插件React树下渲染,而是在UI的其他位置。

import { usePluginContext, PluginExtensionPoints } from '@grafana/data';

export const plugin = new AppPlugin().addComponent({
title: 'User profile tab',
description: '...',
targets: [PluginExtensionPoints.UserProfileTab],
component: () => {
const { meta } = usePluginContext();

// The `jsonData` property is an object that your plugin can manage
// using the Grafana Rest APIs
return <div>Plugin specific setting: {meta.jsonData.foo}</div>;
},
});

在组件中访问插件状态

import { PluginExtensionPoints } from '@grafana/data';
import { MyCustomDataProvider } from './MyCustomDataProvider';

export const plugin = new AppPlugin().addComponent({
title: 'User profile tab',
description: '...',
targets: [PluginExtensionPoints.UserProfileTab],
component: () => (
<MyCustomDataProvider>
<div>Plugin specific setting: {meta.jsonData.foo}</div>
</MyCustomDataProvider>
),
});

在特定条件下隐藏组件

只需从您的组件返回null,以不渲染任何内容并因此隐藏组件。

import { usePluginContext, PluginExtensionPoints } from '@grafana/data';

export const plugin = new AppPlugin().addComponent({
title: 'User profile tab',
description: '...',
targets: [PluginExtensionPoints.UserProfileTab],
component: () => {
const { meta } = usePluginContext();

// For the sake of the example this condition is relying on a `jsonData` property
// that is managed by your plugin
if (!meta.jsonData.isExtensionEnabled) {
return null;
}

return <div>Plugin specific setting: {meta.jsonData.foo}</div>;
},
});

更新plugin.json元数据

一旦您已定义了要针对扩展点注册的链接或组件扩展,您必须更新您的plugin.json元数据。

例如

"extensions": [
{
"extensionPointId": "grafana/dashboard/panel/menu/v1",
"type": "link"
"title": "My app",
"description": "Link to my app"
}
]

有关更多信息,请参阅plugin.json参考

故障排除

  1. 检查控制台日志 - 很有可能是因为某些验证错误导致您的链接没有出现。在这种情况下,您应该在浏览器控制台中看到一些相关的日志。
  2. 检查 targets - 确保您使用的是正确的扩展点 ID(始终使用 Grafana 扩展点的 PluginExtensionPoints 枚举)
  3. 检查 links configure() 函数 - 如果您的链接有一个 configure() 函数,那么在某些条件下它可能返回 undefined,这会隐藏链接。
  4. 检查是否注册了太多的链接 - 某些扩展点限制每个插件允许的链接数量,如果您的插件为同一扩展点注册了多个链接,那么有些链接可能会被过滤掉。
  5. 检查 Grafana 版本 - 链接和组件扩展仅在 Grafana 版本 >=10.1.0 后支持,而 addLink() 仅在版本 >=11.1.0 中支持。

我的组件没有出现

  1. 检查控制台日志 - 很有可能是因为某些验证错误导致您的组件没有出现。在这种情况下,您应该在浏览器控制台中看到一些相关的日志。
  2. 检查 targets - 确保您使用的是正确的扩展点 ID(始终使用 Grafana 扩展点的 PluginExtensionPoints 枚举)
  3. 检查组件实现 - 如果您的组件在特定条件下返回 null,那么它将不会被渲染在扩展点。
  4. 检查是否注册了太多的组件 - 某些扩展点限制每个插件允许的组件数量,如果您的插件为同一扩展点注册了多个组件,那么有些组件可能会被过滤掉。
  5. 检查 Grafana 版本 - 链接和组件扩展仅在 Grafana 版本 >=10.1.0 后支持,而 addComponent() 仅在版本 >=11.1.0 中支持。