From 6c07b5c6e5c1008919e0b10897c05eb1ab716def Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 1 Feb 2021 23:46:51 +0100 Subject: [PATCH 1/4] dev-utils: add path option to addPage, switch to render element in route, and skip sidebar item title is not set --- packages/dev-utils/src/devApp/render.tsx | 37 +++++++++++++++--------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/packages/dev-utils/src/devApp/render.tsx b/packages/dev-utils/src/devApp/render.tsx index f1a6d30b4c..5f86442b46 100644 --- a/packages/dev-utils/src/devApp/render.tsx +++ b/packages/dev-utils/src/devApp/render.tsx @@ -34,16 +34,16 @@ import { attachComponentData, } from '@backstage/core'; import SentimentDissatisfiedIcon from '@material-ui/icons/SentimentDissatisfied'; -import { Outlet } from 'react-router'; const GatheringRoute: (props: { path: string; - children: JSX.Element; -}) => JSX.Element = () => ; + element: JSX.Element; +}) => JSX.Element = ({ element }) => element; attachComponentData(GatheringRoute, 'core.gatherMountPoints', true); type RegisterPageOptions = { + path?: string; element: JSX.Element; title?: string; icon?: IconComponent; @@ -93,21 +93,30 @@ class DevAppBuilder { return this; } - addPage({ element, title, icon }: RegisterPageOptions): DevAppBuilder { - const path = `/page-${this.routes.length + 1}`; - this.sidebarItems.push( - , - ); + /** + * Adds a page component along with accompanying sidebar item. + * + * If no path is provided one will be generated. + * If no title is provider no sidebar item will be created. + */ + addPage(opts: RegisterPageOptions): DevAppBuilder { + const path = opts.path ?? `/page-${this.routes.length + 1}`; + if (opts.title) { + this.sidebarItems.push( + , + ); + } this.routes.push( - , + , ); return this; } + /** * Build a DevApp component using the resources registered so far */ From 5c300a25a72e5ca88bd9b6c598f1f18d09e2f195 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 1 Feb 2021 23:54:51 +0100 Subject: [PATCH 2/4] scaffolder: port to new composability API --- plugins/scaffolder/dev/index.tsx | 29 +++++++++++++++++++++++-- plugins/scaffolder/package.json | 1 + plugins/scaffolder/src/index.ts | 7 +++++- plugins/scaffolder/src/plugin.test.ts | 4 ++-- plugins/scaffolder/src/plugin.ts | 31 ++++++++++++++++++++++----- plugins/scaffolder/src/routes.ts | 3 +-- 6 files changed, 63 insertions(+), 12 deletions(-) diff --git a/plugins/scaffolder/dev/index.tsx b/plugins/scaffolder/dev/index.tsx index 812a5585d4..eff16ab0f5 100644 --- a/plugins/scaffolder/dev/index.tsx +++ b/plugins/scaffolder/dev/index.tsx @@ -14,7 +14,32 @@ * limitations under the License. */ +import React from 'react'; import { createDevApp } from '@backstage/dev-utils'; -import { plugin } from '../src/plugin'; +import { discoveryApiRef } from '@backstage/core'; +import { CatalogClient } from '@backstage/catalog-client'; +import { catalogApiRef } from '@backstage/plugin-catalog-react'; +import { TemplateIndexPage, TemplatePage } from '../src/plugin'; +import { ScaffolderApi, scaffolderApiRef } from '../src'; -createDevApp().registerPlugin(plugin).render(); +createDevApp() + .registerApi({ + api: catalogApiRef, + deps: { discoveryApi: discoveryApiRef }, + factory: ({ discoveryApi }) => new CatalogClient({ discoveryApi }), + }) + .registerApi({ + api: scaffolderApiRef, + deps: { discoveryApi: discoveryApiRef }, + factory: ({ discoveryApi }) => new ScaffolderApi({ discoveryApi }), + }) + .addPage({ + path: '/create', + title: 'Create', + element: , + }) + .addPage({ + path: '/create/:templateName', + element: , + }) + .render(); diff --git a/plugins/scaffolder/package.json b/plugins/scaffolder/package.json index d174991bb7..69021953a2 100644 --- a/plugins/scaffolder/package.json +++ b/plugins/scaffolder/package.json @@ -54,6 +54,7 @@ "@backstage/cli": "^0.5.0", "@backstage/dev-utils": "^0.1.8", "@backstage/test-utils": "^0.1.6", + "@backstage/catalog-client": "^0.3.5", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/user-event": "^12.0.7", diff --git a/plugins/scaffolder/src/index.ts b/plugins/scaffolder/src/index.ts index f0fdf5b429..5f102e7853 100644 --- a/plugins/scaffolder/src/index.ts +++ b/plugins/scaffolder/src/index.ts @@ -14,6 +14,11 @@ * limitations under the License. */ -export { plugin } from './plugin'; +export { + scaffolderPlugin, + scaffolderPlugin as plugin, + TemplateIndexPage, + TemplatePage, +} from './plugin'; export { ScaffolderApi, scaffolderApiRef } from './api'; export { rootRoute, templateRoute } from './routes'; diff --git a/plugins/scaffolder/src/plugin.test.ts b/plugins/scaffolder/src/plugin.test.ts index 3b4c92168d..03dd9fe465 100644 --- a/plugins/scaffolder/src/plugin.test.ts +++ b/plugins/scaffolder/src/plugin.test.ts @@ -14,10 +14,10 @@ * limitations under the License. */ -import { plugin } from './plugin'; +import { scaffolderPlugin } from './plugin'; describe('scaffolder', () => { it('should export plugin', () => { - expect(plugin).toBeDefined(); + expect(scaffolderPlugin).toBeDefined(); }); }); diff --git a/plugins/scaffolder/src/plugin.ts b/plugins/scaffolder/src/plugin.ts index 41f7a03249..ed20705185 100644 --- a/plugins/scaffolder/src/plugin.ts +++ b/plugins/scaffolder/src/plugin.ts @@ -18,13 +18,14 @@ import { createPlugin, createApiFactory, discoveryApiRef, + createRoutableExtension, } from '@backstage/core'; -import { ScaffolderPage } from './components/ScaffolderPage'; -import { TemplatePage } from './components/TemplatePage'; +import { ScaffolderPage as ScaffolderPageComponent } from './components/ScaffolderPage'; +import { TemplatePage as TemplatePageComponent } from './components/TemplatePage'; import { rootRoute, templateRoute } from './routes'; import { scaffolderApiRef, ScaffolderApi } from './api'; -export const plugin = createPlugin({ +export const scaffolderPlugin = createPlugin({ id: 'scaffolder', apis: [ createApiFactory({ @@ -34,7 +35,27 @@ export const plugin = createPlugin({ }), ], register({ router }) { - router.addRoute(rootRoute, ScaffolderPage); - router.addRoute(templateRoute, TemplatePage); + router.addRoute(rootRoute, ScaffolderPageComponent); + router.addRoute(templateRoute, TemplatePageComponent); + }, + routes: { + templateIndex: rootRoute, + template: templateRoute, }, }); + +export const TemplateIndexPage = scaffolderPlugin.provide( + createRoutableExtension({ + component: () => + import('./components/ScaffolderPage').then(m => m.ScaffolderPage), + mountPoint: rootRoute, + }), +); + +export const TemplatePage = scaffolderPlugin.provide( + createRoutableExtension({ + component: () => + import('./components/TemplatePage').then(m => m.TemplatePage), + mountPoint: templateRoute, + }), +); diff --git a/plugins/scaffolder/src/routes.ts b/plugins/scaffolder/src/routes.ts index 28c77f29a6..8efd1d3aaf 100644 --- a/plugins/scaffolder/src/routes.ts +++ b/plugins/scaffolder/src/routes.ts @@ -16,12 +16,11 @@ import { createRouteRef } from '@backstage/core'; export const rootRoute = createRouteRef({ - icon: () => null, path: '/create', title: 'Create new entity', }); + export const templateRoute = createRouteRef({ - icon: () => null, path: '/create/:templateName', title: 'Entity creation', }); From 7201498545e3dfdc41d6426ac4c03227414015d7 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 1 Feb 2021 23:57:36 +0100 Subject: [PATCH 3/4] add changesets --- .changeset/chilled-toys-raise.md | 5 +++++ .changeset/moody-apricots-warn.md | 5 +++++ 2 files changed, 10 insertions(+) create mode 100644 .changeset/chilled-toys-raise.md create mode 100644 .changeset/moody-apricots-warn.md diff --git a/.changeset/chilled-toys-raise.md b/.changeset/chilled-toys-raise.md new file mode 100644 index 0000000000..282d5492ec --- /dev/null +++ b/.changeset/chilled-toys-raise.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +Migrated to new composability API, exporting the plugin as `scaffolderPlugin`. The template list page (`/create`) is exported as the `TemplateIndexPage` extension, and the templating page itself is exported as `TemplatePage`. diff --git a/.changeset/moody-apricots-warn.md b/.changeset/moody-apricots-warn.md new file mode 100644 index 0000000000..c4d9be0ba3 --- /dev/null +++ b/.changeset/moody-apricots-warn.md @@ -0,0 +1,5 @@ +--- +'@backstage/dev-utils': patch +--- + +Added `path` option to `addPage` that can be used to set a specific path for the page rather than a generated one. Also omit sidebar item altogether if `title` option is not set. From 20ca5f179f1431cd12d3ef84a99a4df9d8b096bf Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 2 Feb 2021 11:34:48 +0100 Subject: [PATCH 4/4] Update packages/dev-utils/src/devApp/render.tsx Co-authored-by: Adam Harvey --- packages/dev-utils/src/devApp/render.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dev-utils/src/devApp/render.tsx b/packages/dev-utils/src/devApp/render.tsx index 5f86442b46..b4ec540f9c 100644 --- a/packages/dev-utils/src/devApp/render.tsx +++ b/packages/dev-utils/src/devApp/render.tsx @@ -97,7 +97,7 @@ class DevAppBuilder { * Adds a page component along with accompanying sidebar item. * * If no path is provided one will be generated. - * If no title is provider no sidebar item will be created. + * If no title is provided, no sidebar item will be created. */ addPage(opts: RegisterPageOptions): DevAppBuilder { const path = opts.path ?? `/page-${this.routes.length + 1}`;