跳到主要内容

注册扩展

扩展 是插件定义的链接或 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>
),
}),
});

组件

添加组件的最佳实践

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

注册组件

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(始终使用 PluginExtensionPoints 枚举用于 Grafana 扩展点)
  3. 检查链接的 configure() 函数 - 如果您的链接有 configure() 函数,则在某些情况下它可能会返回 undefined,这会隐藏该链接。
  4. 检查是否注册了太多链接 - 某些扩展点限制每个插件允许的链接数量,如果您的插件为同一个扩展点注册了多个链接,则可能有一些链接被过滤掉了。
  5. 检查 Grafana 版本 - 链接和组件扩展仅在 Grafana 版本 >=10.1.0 后受支持,而 addLink() 仅在版本 >=11.1.0 中受支持。

我的组件没有出现

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