docs: plugin integration into catalog

This commit is contained in:
Ivan Shmidt
2020-08-31 23:18:06 +02:00
parent e57798cd88
commit 713060d1f3
8 changed files with 154 additions and 27 deletions
+7
View File
@@ -26,3 +26,10 @@ This helps the community know what plugins are in development.
You can also use this process if you have an idea for a good plugin but you hope
that someone else will pick up the work.
## Integrate into the catalog service
If your plugin isn't supposed to live as a standalone page, but rather needs to
be presented as a part of a catalog service (e.g. a separate tab or a card on an
"Overview" tab), then check out
[the instruction](integrating-plugin-into-service-catalog.md). on how to do it.
@@ -0,0 +1,125 @@
---
id: integrating-plugin-into-service-catalog
title: Integrate into the catalog service
---
> This is an advanced use case and currently is an experimental feature. Expect
> API to change over time
## Steps
1. [Create a plugin](#create-a-plugin)
1. [Export a router with relative routes](#export-a-router)
1. [Import and use router in the APP](#import-and-use-router-in-the-app)
### Create a plugin
Follow the [same process](create-a-plugin.md) as for standalone plugin. You
should have a separate package in a folder, which represents your plugin.
Example:
```
$ yarn create-plugin
> ? Enter an ID for the plugin [required] my-plugin
> ? Enter the owner(s) of the plugin. If specified, this will be added to CODEOWNERS for the plugin path. [optional]
Creating the plugin...
```
### Export a router
Now in the plugin you have a `Router.tsx` file in the `src` folder. By default
it contains only one example route. Create a routing structure needed for your
plugin, keeping in mind that the whole set of routes defined here are going to
be mounted under some different route in the App.
Example:
`my-plugin` consists of 2 different views - `/me` and `/about`. I envision
people integrating it into plugin catalog as a tab named "MyPlugin". Then, my
`Routes.tsx` for the plugin is going to look like:
```tsx
<Routes>
<Route path="/me" element={<MePage />} />
<Route path="/about" element={<AboutPage />} />
</Routes>
```
(where MePage and AboutPage are 2 components defined in your plugin and imported
accordingly inside `Router.tsx`)
> Pay attention, if your `MePage` references the `AboutPage` it needs to do it
> through link to `about`, not `/about`. This allows react-router v6 to enable
> its relative routing mechanism. Read more -
> https://reacttraining.com/blog/react-router-v6-pre/#relative-route-path-and-link-to
### Import and use router in the APP
In the `app/src/components/catalog/EntityPage.tsx` (app === your folder,
containing backstage app) import your created Router:
```tsx
import { Router as MyPluginRouter } from '@backstage/plugin-my-plugin;
```
Now, you need to mount `MyPluginRouter` onto some route, for example if you had:
```tsx
const DefaultEntityPage = ({ entity }: { entity: Entity }) => (
<EntityPageLayout>
<EntityPageLayout.Content
path="/"
title="Overview"
element={<OverviewPage entity={entity} />}
/>
</EntityPageLayout>
);
```
after you add your code it becomes:
```tsx
const DefaultEntityPage = ({ entity }: { entity: Entity }) => (
<EntityPageLayout>
<EntityPageLayout.Content
path="/"
title="Overview"
element={<OverviewPage entity={entity} />}
/>
<EntityPageLayout.Content
path="/my-plugin"
title="My Plugin"
element={<MyPluginRouter entity={entity} />}
/>
</EntityPageLayout>
);
```
All of magic happens thanks to the `EntityPageLayout` component, which comes as
an export from `@backstage/plugin-catalog` package.
```tsx
type EntityPageLayoutContentProps = {
/**
* Going to be transformed into react-router v6
* path under the hood. Read more at https://reacttraining.com/blog/react-router-v6-pre
*/
path: string;
/**
* Gets transformed into the title for the tab
*/
title: string;
/**
* Element that is rendered when the location
* matches the path provided
*/
element: JSX.Element;
};
```
> The recommended pattern is to get the `entity` in the App and then pass it to
> the plugin's Router component as a prop. However if it inconvenient for you,
> use `useEntity` hook from `@backstage/plugin-catalog` directly inside your
> plugin.