Use an optional external route ref to link to the create component page from the api explorer

This commit is contained in:
Dominik Henneke
2021-02-26 12:34:47 +01:00
parent 5ffb6c57f6
commit f715898006
7 changed files with 113 additions and 44 deletions
+23
View File
@@ -0,0 +1,23 @@
---
'@backstage/create-app': patch
---
The api-docs plugin has been migrated to use an [external route reference](https://backstage.io/docs/plugins/composability#binding-external-routes-in-the-app) to dynamically link to the create component page.
If you want to have a button that links to the scaffolder plugin from the API explorer, apply the following changes to `packages/app/src/App.tsx`:
```diff
+ import { apiDocsPlugin } from '@backstage/plugin-api-docs';
import { scaffolderPlugin } from '@backstage/plugin-scaffolder';
const app = createApp({
// ...
bindRoutes({ bind }) {
+ bind(apiDocsPlugin.externalRoutes, {
+ createComponent: scaffolderPlugin.routes.root,
+ });
},
});
```
If you choose to not bind the routes, the button to create new APIs is not displayed.
+23
View File
@@ -0,0 +1,23 @@
---
'@backstage/plugin-api-docs': patch
---
The api-docs plugin has been migrated to use an [external route reference](https://backstage.io/docs/plugins/composability#binding-external-routes-in-the-app) to dynamically link to the create component page. This means you need to migrate the api docs plugin to use the new extension components, as well as bind the external route.
To bind the external route from the api docs plugin to the scaffolder template index page, make sure you have the appropriate imports and add the following to the `createApp` call:
```ts
import { apiDocsPlugin } from '@backstage/plugin-api-docs';
import { scaffolderPlugin } from '@backstage/plugin-scaffolder';
const app = createApp({
// ...
bindRoutes({ bind }) {
bind(apiDocsPlugin.externalRoutes, {
createComponent: scaffolderPlugin.routes.root,
});
},
});
```
If you choose to not bind the routes, the button to create new APIs is not displayed.
+15 -12
View File
@@ -21,19 +21,29 @@ import {
OAuthRequestDialog,
SignInPage,
} from '@backstage/core';
import { apiDocsPlugin, ApiExplorerPage } from '@backstage/plugin-api-docs';
import {
catalogPlugin,
CatalogIndexPage,
CatalogEntityPage,
CatalogIndexPage,
catalogPlugin,
} from '@backstage/plugin-catalog';
import { CatalogImportPage } from '@backstage/plugin-catalog-import';
import {
CostInsightsLabelDataflowInstructionsPage,
CostInsightsPage,
CostInsightsProjectGrowthInstructionsPage,
} from '@backstage/plugin-cost-insights';
import { ExplorePage } from '@backstage/plugin-explore';
import { GcpProjectsPage } from '@backstage/plugin-gcp-projects';
import { GraphiQLPage } from '@backstage/plugin-graphiql';
import { LighthousePage } from '@backstage/plugin-lighthouse';
import { NewRelicPage } from '@backstage/plugin-newrelic';
import { ScaffolderPage, scaffolderPlugin } from '@backstage/plugin-scaffolder';
import { SearchPage } from '@backstage/plugin-search';
import { TechRadarPage } from '@backstage/plugin-tech-radar';
import { TechdocsPage } from '@backstage/plugin-techdocs';
import { UserSettingsPage } from '@backstage/plugin-user-settings';
import AlarmIcon from '@material-ui/icons/Alarm';
import React from 'react';
import { hot } from 'react-hot-loader/root';
import { Navigate, Route } from 'react-router';
@@ -42,16 +52,6 @@ import { EntityPage } from './components/catalog/EntityPage';
import Root from './components/Root';
import { providers } from './identityProviders';
import * as plugins from './plugins';
import AlarmIcon from '@material-ui/icons/Alarm';
import { ApiExplorerPage } from '@backstage/plugin-api-docs';
import { GcpProjectsPage } from '@backstage/plugin-gcp-projects';
import { NewRelicPage } from '@backstage/plugin-newrelic';
import { SearchPage } from '@backstage/plugin-search';
import {
CostInsightsLabelDataflowInstructionsPage,
CostInsightsPage,
CostInsightsProjectGrowthInstructionsPage,
} from '@backstage/plugin-cost-insights';
const app = createApp({
apis,
@@ -76,6 +76,9 @@ const app = createApp({
bind(catalogPlugin.externalRoutes, {
createComponent: scaffolderPlugin.routes.root,
});
bind(apiDocsPlugin.externalRoutes, {
createComponent: scaffolderPlugin.routes.root,
});
},
});
@@ -1,29 +1,28 @@
import React from 'react';
import {
createApp,
AlertDisplay,
createApp,
FlatRoutes,
OAuthRequestDialog,
SidebarPage,
FlatRoutes,
} from '@backstage/core';
import { apiDocsPlugin, ApiExplorerPage } from '@backstage/plugin-api-docs';
import {
CatalogEntityPage,
CatalogIndexPage,
catalogPlugin,
} from '@backstage/plugin-catalog';
import { CatalogImportPage } from '@backstage/plugin-catalog-import';
import { ScaffolderPage, scaffolderPlugin } from '@backstage/plugin-scaffolder';
import { SearchPage } from '@backstage/plugin-search';
import { TechRadarPage } from '@backstage/plugin-tech-radar';
import { TechdocsPage } from '@backstage/plugin-techdocs';
import { UserSettingsPage } from '@backstage/plugin-user-settings';
import React from 'react';
import { Navigate, Route } from 'react-router';
import { apis } from './apis';
import { EntityPage } from './components/catalog/EntityPage';
import * as plugins from './plugins';
import { AppSidebar } from './sidebar';
import { Route, Navigate } from 'react-router';
import {
catalogPlugin,
CatalogIndexPage,
CatalogEntityPage,
} from '@backstage/plugin-catalog';
import { TechdocsPage } from '@backstage/plugin-techdocs';
import { CatalogImportPage } from '@backstage/plugin-catalog-import';
import { TechRadarPage } from '@backstage/plugin-tech-radar';
import { SearchPage } from '@backstage/plugin-search';
import { UserSettingsPage } from '@backstage/plugin-user-settings';
import { ApiExplorerPage } from '@backstage/plugin-api-docs';
import { EntityPage } from './components/catalog/EntityPage';
import { scaffolderPlugin, ScaffolderPage } from '@backstage/plugin-scaffolder';
const app = createApp({
apis,
@@ -32,7 +31,10 @@ const app = createApp({
bind(catalogPlugin.externalRoutes, {
createComponent: scaffolderPlugin.routes.root,
});
}
bind(apiDocsPlugin.externalRoutes, {
createComponent: scaffolderPlugin.routes.root,
});
},
});
const AppProvider = app.getProvider();
@@ -14,16 +14,24 @@
* limitations under the License.
*/
import { Content, ContentHeader, SupportButton, useApi } from '@backstage/core';
import {
Content,
ContentHeader,
SupportButton,
useApi,
useRouteRef,
} from '@backstage/core';
import { catalogApiRef } from '@backstage/plugin-catalog-react';
import { Button } from '@material-ui/core';
import React from 'react';
import { Link as RouterLink } from 'react-router-dom';
import { useAsync } from 'react-use';
import { createComponentRouteRef } from '../../routes';
import { ApiExplorerTable } from '../ApiExplorerTable';
import { ApiExplorerLayout } from './ApiExplorerLayout';
export const ApiExplorerPage = () => {
const createComponentLink = useRouteRef(createComponentRouteRef);
const catalogApi = useApi(catalogApiRef);
const { loading, error, value: catalogResponse } = useAsync(() => {
return catalogApi.getEntities({ filter: { kind: 'API' } });
@@ -33,14 +41,16 @@ export const ApiExplorerPage = () => {
<ApiExplorerLayout>
<Content>
<ContentHeader title="">
<Button
variant="contained"
color="primary"
component={RouterLink}
to="/catalog-import"
>
Register Existing API
</Button>
{createComponentLink && (
<Button
variant="contained"
color="primary"
component={RouterLink}
to={createComponentLink()}
>
Register Existing API
</Button>
)}
<SupportButton>All your APIs</SupportButton>
</ContentHeader>
<ApiExplorerTable
+6 -3
View File
@@ -17,14 +17,14 @@
import { ApiEntity } from '@backstage/catalog-model';
import {
createApiFactory,
createComponentExtension,
createPlugin,
createRoutableExtension,
createComponentExtension,
} from '@backstage/core';
import { ApiExplorerPage as Page } from './components/ApiExplorerPage/ApiExplorerPage';
import { defaultDefinitionWidgets } from './components/ApiDefinitionCard';
import { rootRoute } from './routes';
import { ApiExplorerPage as Page } from './components/ApiExplorerPage/ApiExplorerPage';
import { apiDocsConfigRef } from './config';
import { createComponentRouteRef, rootRoute } from './routes';
export const apiDocsPlugin = createPlugin({
id: 'api-docs',
@@ -45,6 +45,9 @@ export const apiDocsPlugin = createPlugin({
},
}),
],
externalRoutes: {
createComponent: createComponentRouteRef,
},
register({ router }) {
router.addRoute(rootRoute, Page);
},
+6 -1
View File
@@ -14,7 +14,7 @@
* limitations under the License.
*/
import { createRouteRef } from '@backstage/core';
import { createExternalRouteRef, createRouteRef } from '@backstage/core';
const NoIcon = () => null;
@@ -23,3 +23,8 @@ export const rootRoute = createRouteRef({
path: '/api-docs',
title: 'APIs',
});
export const createComponentRouteRef = createExternalRouteRef({
id: 'create-component',
optional: true,
});