跳到主要内容

注册扩展

扩展 是插件定义的链接或 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() hook 来访问组件内部的任何插件特定元信息。该 hook 返回一个 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. 检查链接的 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 中受支持。