注册扩展
扩展 是由插件定义的链接或 React 组件,可以在 Grafana 核心 UI 或另一个应用插件中渲染。
与 公开组件 相比,它们是针对一个或多个扩展点 ID 显式注册的。当您想要扩展 Grafana 的核心 UI,或者需要更多控制哪些内容可以使用您的插件扩展时,这可能更为合适。
在 关键概念 下阅读有关扩展的更多信息。
类型 | 描述 |
---|---|
链接 | 链接具有 path 或 onClick() 属性。何时使用? 如果您想为插件提供定义自定义用户操作的方式,可以使用链接,例如,为 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
的参考。
故障排除
我的链接没有出现
- 检查控制台日志 - 很有可能是因为某些验证错误导致您的链接没有出现。在这种情况下,您应该在浏览器控制台中看到一些相关的日志。
- 检查 targets - 确保您使用的是正确的扩展点 ID(始终使用 Grafana 扩展点的
PluginExtensionPoints
枚举) - 检查 links
configure()
函数 - 如果您的链接有一个configure()
函数,那么在某些条件下它可能返回undefined
,这会隐藏链接。 - 检查是否注册了太多的链接 - 某些扩展点限制每个插件允许的链接数量,如果您的插件为同一扩展点注册了多个链接,那么有些链接可能会被过滤掉。
- 检查 Grafana 版本 - 链接和组件扩展仅在 Grafana 版本
>=10.1.0
后支持,而addLink()
仅在版本 >=11.1.0
中支持。
我的组件没有出现
- 检查控制台日志 - 很有可能是因为某些验证错误导致您的组件没有出现。在这种情况下,您应该在浏览器控制台中看到一些相关的日志。
- 检查 targets - 确保您使用的是正确的扩展点 ID(始终使用 Grafana 扩展点的
PluginExtensionPoints
枚举) - 检查组件实现 - 如果您的组件在特定条件下返回
null
,那么它将不会被渲染在扩展点。 - 检查是否注册了太多的组件 - 某些扩展点限制每个插件允许的组件数量,如果您的插件为同一扩展点注册了多个组件,那么有些组件可能会被过滤掉。
- 检查 Grafana 版本 - 链接和组件扩展仅在 Grafana 版本
>=10.1.0
后支持,而addComponent()
仅在版本 >=11.1.0
中支持。