From 70d0b7a0d24a1225b4ee37407d7ae55575d09b23 Mon Sep 17 00:00:00 2001 From: "Grot (@grafanabot)" <43478413+grafanabot@users.noreply.github.com> Date: Tue, 23 May 2023 20:23:38 +0100 Subject: [PATCH] [v9.4.x] Docs: Plugins doc review chunk 3 (#68919) Docs: Plugins doc review chunk 3 (#68159) * Initial commit Signed-off-by: Joe Perez * Minor fix Signed-off-by: Joe Perez * Review changes Signed-off-by: Joe Perez * Doc fixes Signed-off-by: Joe Perez * Minor fix Signed-off-by: Joe Perez * Update docs/sources/developers/plugins/cross-plugin-linking.md Co-authored-by: Matt Dodson <47385188+MattDodsonEnglish@users.noreply.github.com> * Update docs/sources/developers/plugins/development-with-local-grafana.md Co-authored-by: Matt Dodson <47385188+MattDodsonEnglish@users.noreply.github.com> * Update docs/sources/developers/plugins/cross-plugin-linking.md Co-authored-by: Matt Dodson <47385188+MattDodsonEnglish@users.noreply.github.com> * Update docs/sources/developers/plugins/cross-plugin-linking.md Co-authored-by: Matt Dodson <47385188+MattDodsonEnglish@users.noreply.github.com> * Update docs/sources/developers/plugins/development-with-local-grafana.md Co-authored-by: Matt Dodson <47385188+MattDodsonEnglish@users.noreply.github.com> * Incorporating review feedback Signed-off-by: Joe Perez * Update docs/sources/developers/plugins/development-with-local-grafana.md Co-authored-by: Matt Dodson <47385188+MattDodsonEnglish@users.noreply.github.com> * Test commit Signed-off-by: Joe Perez --------- Signed-off-by: Joe Perez Co-authored-by: Matt Dodson <47385188+MattDodsonEnglish@users.noreply.github.com> (cherry picked from commit d68079e92757d741941a6b50dc6237b41dd2056e) Co-authored-by: Joseph Perez <45749060+josmperez@users.noreply.github.com> --- .../plugins/cross-plugin-linking.md | 74 +++++++++++++++++++ .../plugins/custom-panel-option-editors.md | 27 +++---- .../plugins/development-with-local-grafana.md | 68 +++++++++-------- 3 files changed, 126 insertions(+), 43 deletions(-) create mode 100644 docs/sources/developers/plugins/cross-plugin-linking.md diff --git a/docs/sources/developers/plugins/cross-plugin-linking.md b/docs/sources/developers/plugins/cross-plugin-linking.md new file mode 100644 index 00000000000..1772e2816e6 --- /dev/null +++ b/docs/sources/developers/plugins/cross-plugin-linking.md @@ -0,0 +1,74 @@ +--- +title: Work with cross-plugin links +description: Learn how to add plugin links to a Grafana app plugin +--- + +# Work with cross-plugin links + +With the Plugins extension API, app plugins can register extension points of their own to display other plugins links. This is called _cross-plugin linking_, and you can use it to create more immersive user experiences with installed plugins. + +## Available extension points within plugins + +An extension point is a location in another plugin's UI where your plugin can insert links. All extension point IDs within plugins should follow the naming convention `plugins//`. + +## How to create an extension point within a plugin + +Use the `getPluginExtensions` method in `@grafana/runtime` to create an extension point within your plugin. An extension point is a way to specify where in the plugin UI other plugins links are rendered. + +{{% admonition type="note" %}} +Creating an extension point in a plugin creates a public interface for other plugins to interact with. Changes to the extension point ID or its context could break any plugin that attempts to register a link inside your plugin. +{{% /admonition %}} + +The `getPluginExtensions` method takes an object consisting of the `extensionPointId`, which must begin `plugin/`, and any contextual information that you want to provide. The `getPluginExtensions` method returns a list of `extensionLinks` that your program can loop over: + +```typescript +import { getPluginExtensions } from '@grafana/runtime'; +import { isPluginExtensionLink } from '@grafana/data'; +import { LinkButton } from '@grafana/ui'; + +function AppExtensionPointExample() { + const { extensions } = getPluginExtensions({ + extensionPointId: 'plugin/another-app-plugin/menu', + context: { + pluginId: 'another-app-plugin', + }, + }); + + if (extensions.length === 0) { + return null; + } + + return ( +
+ {extensions.map((extension) => { + if (isPluginExtensionLink(extension)) { + return ( + + {extension.title} + + ); + } + + return null; + })} +
+ ); +} +``` + +The preceding example shows a component that renders `` components for all link extensions that other plugins registered for the `plugin/another-app-plugin/menu` extension point ID. The context is passed as the second parameter to `getPluginExtensions`, which uses `Object.freeze` to make the context immutable before passing it to other plugins. + +## Insert links into another plugin + +Create links for other plugins in the same way you [extend the Grafana application UI]({{< relref "./extend-the-grafana-ui-with-links" >}}) with a link. Don't specify a `grafana/...` extension point. Instead, specify the plugin extension point `plugin//`. + +Given the preceding example, use a plugin link such as the following: + +```typescript +new AppPlugin().configureExtensionLink({ + title: 'Go to basic app', + description: 'Will navigate the user to the basic app', + extensionPointId: 'plugin/another-app-plugin/menu', + path: '/a/myorg-basic-app/one', +}); +``` diff --git a/docs/sources/developers/plugins/custom-panel-option-editors.md b/docs/sources/developers/plugins/custom-panel-option-editors.md index d943c6deb70..344ced91328 100644 --- a/docs/sources/developers/plugins/custom-panel-option-editors.md +++ b/docs/sources/developers/plugins/custom-panel-option-editors.md @@ -1,12 +1,17 @@ --- -title: Custom panel option editors +title: Build a custom panel option editor --- -# Custom panel option editors +# Build a custom panel option editor -The Grafana plugin platform comes with a range of editors that allow your users to customize a panel. The standard editors cover the most common types of options, such as text input and boolean switches. If you don't find the editor you're looking for, you can build your own. In this guide, you'll learn how to build your own panel option editor. +The Grafana plugin platform comes with a range of editors that allow your users to customize a panel. The standard editors cover the most common types of options, such as text input and boolean switches. If you don't find the editor you're looking for, you can build your own. -The simplest editor is a React component that accepts two props: `value` and `onChange`. `value` contains the current value of the option, and `onChange` updates it. +## Panel option editor basics + +The simplest editor is a React component that accepts two props: + +- **`value`**: the current value of the option +- **`onChange`**: updates the option's value The editor in the example below lets the user toggle a boolean value by clicking a button: @@ -22,7 +27,7 @@ export const SimpleEditor: React.FC> = ({ value, on }; ``` -To use a custom panel option editor, use the `addCustomEditor` on the `OptionsUIBuilder` object in your `module.ts` file. Configure the editor to use by setting the `editor` property to the `SimpleEditor` component. +To use a custom panel option editor, use the `addCustomEditor` on the `OptionsUIBuilder` object in your `module.ts` file and set the `editor` property to the name of your custom editor component. **module.ts** @@ -39,9 +44,9 @@ export const plugin = new PanelPlugin(SimplePanel).setPanelOption ## Add settings to your panel option editor -If you're using your custom editor to configure multiple options, you might want to be able to customize it. Add settings to your editor by setting the second template variable of `StandardEditorProps` to an interface that contains the settings you want to be able to configure. +You can use your custom editor to customize multiple possible settings. To add settings to your editor, set the second template variable of `StandardEditorProps` to an interface that contains the settings you want to configure. Access the editor settings through the `item` prop. -You can access the editor settings through the `item` prop. Here's an example of an editor that populates a drop-down with a range of numbers. The range is defined by the `from` and `to` properties in the `Settings` interface. +Here's an example of an editor that populates a drop-down with a range of numbers. The `Settings` interface defines the range of the `from` and `to` properties. **SimpleEditor.tsx** @@ -69,7 +74,7 @@ export const SimpleEditor: React.FC> = ({ }; ``` -You can now configure the editor for each option, by configuring the `settings` property in the call to `addCustomEditor`. +You can now configure the editor for each option by configuring the `settings` property to call `addCustomEditor`: ```ts export const plugin = new PanelPlugin(SimplePanel).setPanelOptions((builder) => { @@ -88,9 +93,7 @@ export const plugin = new PanelPlugin(SimplePanel).setPanelOption ## Use query results in your panel option editor -Option editors can access the results from the last query. This lets you update your editor dynamically, based on the data returned by the data source. - -> **Note:** This feature was introduced in 7.0.3. Anyone using an older version of Grafana will see an error when using your plugin. +Option editors can access the results from the last query. This lets you update your editor dynamically based on the data returned by the data source. The editor context is available through the `context` prop. The data frames returned by the data source are available under `context.data`. @@ -114,5 +117,3 @@ export const SimpleEditor: React.FC> = ({ item, valu return