From 76db86c45704898ca72eff4a44507e27b6507e93 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sat, 19 Jun 2021 14:05:00 +0200 Subject: [PATCH 1/3] dev-utils: remove support for registered routes Signed-off-by: Patrik Oldsberg --- .changeset/five-baboons-explain.md | 5 ++ packages/dev-utils/src/devApp/render.tsx | 93 ++++-------------------- 2 files changed, 18 insertions(+), 80 deletions(-) create mode 100644 .changeset/five-baboons-explain.md diff --git a/.changeset/five-baboons-explain.md b/.changeset/five-baboons-explain.md new file mode 100644 index 0000000000..b30c1a6237 --- /dev/null +++ b/.changeset/five-baboons-explain.md @@ -0,0 +1,5 @@ +--- +'@backstage/dev-utils': minor +--- + +Removed support for deprecated registered plugin routes. All routes now need to be added using `addPage` instead. diff --git a/packages/dev-utils/src/devApp/render.tsx b/packages/dev-utils/src/devApp/render.tsx index 06975df20f..271c8d70cf 100644 --- a/packages/dev-utils/src/devApp/render.tsx +++ b/packages/dev-utils/src/devApp/render.tsx @@ -39,7 +39,6 @@ import { } from '@backstage/integration-react'; import { Box } from '@material-ui/core'; import BookmarkIcon from '@material-ui/icons/Bookmark'; -import SentimentDissatisfiedIcon from '@material-ui/icons/SentimentDissatisfied'; import React, { ComponentType, ReactNode } from 'react'; import ReactDOM from 'react-dom'; import { hot } from 'react-hot-loader'; @@ -75,6 +74,8 @@ class DevAppBuilder { private readonly routes = new Array(); private readonly sidebarItems = new Array(); + private defaultPage?: string; + /** * Register one or more plugins to render in the dev app */ @@ -113,6 +114,11 @@ class DevAppBuilder { */ addPage(opts: RegisterPageOptions): DevAppBuilder { const path = opts.path ?? `/page-${this.routes.length + 1}`; + + if (!this.defaultPage || path === '/') { + this.defaultPage = path; + } + if (opts.title) { this.sidebarItems.push( { return ( @@ -181,10 +184,12 @@ class DevAppBuilder { {this.rootChildren} - {sidebar} + + + {this.sidebarItems} + {this.routes} - {deprecatedAppRoutes} } /> @@ -207,84 +212,12 @@ class DevAppBuilder { const DevApp = hot(hotModule)(this.build()); - const paths = this.findPluginPaths(this.plugins); - - if (window.location.pathname === '/') { - if (!paths.includes('/') && paths.length > 0) { - window.location.pathname = paths[0]; - } + if (window.location.pathname === '/' && this.defaultPage) { + window.location.pathname = this.defaultPage; } ReactDOM.render(, document.getElementById('root')); } - - // Create a sidebar that exposes the touchpoints of a plugin - private setupSidebar(plugins: BackstagePlugin[]): JSX.Element { - const sidebarItems = new Array(); - for (const plugin of plugins) { - for (const output of plugin.output()) { - switch (output.type) { - case 'legacy-route': { - const { path } = output; - sidebarItems.push( - , - ); - break; - } - case 'route': { - const { target } = output; - sidebarItems.push( - , - ); - break; - } - default: - break; - } - } - } - - return ( - - - {this.sidebarItems} - {sidebarItems} - - ); - } - - private findPluginPaths(plugins: BackstagePlugin[]) { - const paths = new Array(); - - for (const plugin of plugins) { - for (const output of plugin.output()) { - switch (output.type) { - case 'legacy-route': { - paths.push(output.path); - break; - } - case 'route': { - paths.push(output.target.path); - break; - } - default: - break; - } - } - } - - return paths; - } } // TODO(rugvip): Figure out patterns for how to allow in-house apps to build upon From d719926d25582350e9c6f6d8c1e773c76de517da Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sat, 19 Jun 2021 14:36:11 +0200 Subject: [PATCH 2/3] plugins: remove deprecated route registrations Signed-off-by: Patrik Oldsberg --- .changeset/heavy-numbers-refuse.md | 10 ++++++++++ plugins/api-docs/src/plugin.ts | 4 ---- plugins/cost-insights/src/plugin.ts | 14 +------------- plugins/gcp-projects/src/plugin.ts | 10 +--------- plugins/gitops-profiles/src/plugin.ts | 8 -------- plugins/newrelic/src/plugin.ts | 4 ---- plugins/welcome/src/plugin.ts | 4 +--- 7 files changed, 13 insertions(+), 41 deletions(-) create mode 100644 .changeset/heavy-numbers-refuse.md diff --git a/.changeset/heavy-numbers-refuse.md b/.changeset/heavy-numbers-refuse.md new file mode 100644 index 0000000000..c5d9dc6deb --- /dev/null +++ b/.changeset/heavy-numbers-refuse.md @@ -0,0 +1,10 @@ +--- +'@backstage/plugin-api-docs': minor +'@backstage/plugin-cost-insights': minor +'@backstage/plugin-gcp-projects': minor +'@backstage/plugin-gitops-profiles': minor +'@backstage/plugin-newrelic': minor +'@backstage/plugin-welcome': minor +--- + +**BREAKING CHANGE** Remove deprecated route registrations, meaning that it is no longer enough to only import the plugin in the app and the exported page extension must be used instead. diff --git a/plugins/api-docs/src/plugin.ts b/plugins/api-docs/src/plugin.ts index 4956a48f18..bb8395081f 100644 --- a/plugins/api-docs/src/plugin.ts +++ b/plugins/api-docs/src/plugin.ts @@ -22,7 +22,6 @@ import { createRoutableExtension, } from '@backstage/core'; import { defaultDefinitionWidgets } from './components/ApiDefinitionCard'; -import { ApiExplorerPage as Page } from './components/ApiExplorerPage/ApiExplorerPage'; import { apiDocsConfigRef } from './config'; import { createComponentRouteRef, rootRoute } from './routes'; @@ -48,9 +47,6 @@ export const apiDocsPlugin = createPlugin({ externalRoutes: { createComponent: createComponentRouteRef, }, - register({ router }) { - router.addRoute(rootRoute, Page); - }, }); export const ApiExplorerPage = apiDocsPlugin.provide( diff --git a/plugins/cost-insights/src/plugin.ts b/plugins/cost-insights/src/plugin.ts index 29e345532d..aabafade9a 100644 --- a/plugins/cost-insights/src/plugin.ts +++ b/plugins/cost-insights/src/plugin.ts @@ -19,9 +19,6 @@ import { createRouteRef, createRoutableExtension, } from '@backstage/core'; -import { CostInsightsPage as CostInsightsPageComponent } from './components/CostInsightsPage'; -import { ProjectGrowthInstructionsPage as ProjectGrowthInstructionsPageComponent } from './components/ProjectGrowthInstructionsPage'; -import { LabelDataflowInstructionsPage as LabelDataflowInstructionsPageComponent } from './components/LabelDataflowInstructionsPage'; export const rootRouteRef = createRouteRef({ path: '/cost-insights', @@ -40,16 +37,7 @@ export const unlabeledDataflowAlertRef = createRouteRef({ export const costInsightsPlugin = createPlugin({ id: 'cost-insights', - register({ router, featureFlags }) { - router.addRoute(rootRouteRef, CostInsightsPageComponent); - router.addRoute( - projectGrowthAlertRef, - ProjectGrowthInstructionsPageComponent, - ); - router.addRoute( - unlabeledDataflowAlertRef, - LabelDataflowInstructionsPageComponent, - ); + register({ featureFlags }) { featureFlags.register('cost-insights-currencies'); }, routes: { diff --git a/plugins/gcp-projects/src/plugin.ts b/plugins/gcp-projects/src/plugin.ts index 9126716d55..5280ff8e35 100644 --- a/plugins/gcp-projects/src/plugin.ts +++ b/plugins/gcp-projects/src/plugin.ts @@ -21,10 +21,7 @@ import { googleAuthApiRef, } from '@backstage/core'; import { gcpApiRef, GcpClient } from './api'; -import { NewProjectPage } from './components/NewProjectPage'; -import { ProjectDetailsPage } from './components/ProjectDetailsPage'; -import { ProjectListPage } from './components/ProjectListPage'; -import { rootRouteRef, projectRouteRef, newProjectRouteRef } from './routes'; +import { rootRouteRef } from './routes'; export const gcpProjectsPlugin = createPlugin({ id: 'gcp-projects', @@ -40,11 +37,6 @@ export const gcpProjectsPlugin = createPlugin({ }, }), ], - register({ router }) { - router.addRoute(rootRouteRef, ProjectListPage); - router.addRoute(projectRouteRef, ProjectDetailsPage); - router.addRoute(newProjectRouteRef, NewProjectPage); - }, }); export const GcpProjectsPage = gcpProjectsPlugin.provide( diff --git a/plugins/gitops-profiles/src/plugin.ts b/plugins/gitops-profiles/src/plugin.ts index 98a0067969..df19087199 100644 --- a/plugins/gitops-profiles/src/plugin.ts +++ b/plugins/gitops-profiles/src/plugin.ts @@ -19,9 +19,6 @@ import { createApiFactory, createRoutableExtension, } from '@backstage/core'; -import ProfileCatalog from './components/ProfileCatalog'; -import ClusterPage from './components/ClusterPage'; -import ClusterList from './components/ClusterList'; import { gitOpsClusterListRoute, gitOpsClusterDetailsRoute, @@ -34,11 +31,6 @@ export const gitopsProfilesPlugin = createPlugin({ apis: [ createApiFactory(gitOpsApiRef, new GitOpsRestApi('http://localhost:3008')), ], - register({ router }) { - router.addRoute(gitOpsClusterListRoute, ClusterList); - router.addRoute(gitOpsClusterDetailsRoute, ClusterPage); - router.addRoute(gitOpsClusterCreateRoute, ProfileCatalog); - }, routes: { listPage: gitOpsClusterListRoute, detailsPage: gitOpsClusterDetailsRoute, diff --git a/plugins/newrelic/src/plugin.ts b/plugins/newrelic/src/plugin.ts index d89aa813e9..a92c051b27 100644 --- a/plugins/newrelic/src/plugin.ts +++ b/plugins/newrelic/src/plugin.ts @@ -22,7 +22,6 @@ import { createRoutableExtension, } from '@backstage/core'; import { NewRelicClient, newRelicApiRef } from './api'; -import NewRelicComponent from './components/NewRelicComponent'; export const rootRouteRef = createRouteRef({ path: '/newrelic', @@ -38,9 +37,6 @@ export const newRelicPlugin = createPlugin({ factory: ({ discoveryApi }) => new NewRelicClient({ discoveryApi }), }), ], - register({ router }) { - router.addRoute(rootRouteRef, NewRelicComponent); - }, routes: { root: rootRouteRef, }, diff --git a/plugins/welcome/src/plugin.ts b/plugins/welcome/src/plugin.ts index f950b93874..54a7cd93d1 100644 --- a/plugins/welcome/src/plugin.ts +++ b/plugins/welcome/src/plugin.ts @@ -19,7 +19,6 @@ import { createRoutableExtension, createRouteRef, } from '@backstage/core'; -import WelcomePageComponent from './components/WelcomePage'; export const rootRouteRef = createRouteRef({ title: 'Welcome', @@ -27,8 +26,7 @@ export const rootRouteRef = createRouteRef({ export const welcomePlugin = createPlugin({ id: 'welcome', - register({ router, featureFlags }) { - router.addRoute(rootRouteRef, WelcomePageComponent); + register({ featureFlags }) { featureFlags.register('enable-welcome-box'); }, }); From 9b9a8f3925c0f37097155c75bc723f45e7e49428 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sat, 19 Jun 2021 15:01:32 +0200 Subject: [PATCH 3/3] plugins: restore dev setups Signed-off-by: Patrik Oldsberg --- plugins/api-docs/dev/index.tsx | 17 +++++++++++------ plugins/cost-insights/dev/index.tsx | 21 ++++++++++++++++++++- plugins/gcp-projects/dev/index.tsx | 11 +++++++++-- plugins/newrelic/dev/index.tsx | 11 +++++++++-- plugins/welcome/dev/index.tsx | 11 +++++++++-- 5 files changed, 58 insertions(+), 13 deletions(-) diff --git a/plugins/api-docs/dev/index.tsx b/plugins/api-docs/dev/index.tsx index fbfab37f5b..6d4b0c199e 100644 --- a/plugins/api-docs/dev/index.tsx +++ b/plugins/api-docs/dev/index.tsx @@ -30,6 +30,13 @@ import graphqlApiEntity from './graphql-example-api.yaml'; import openapiApiEntity from './openapi-example-api.yaml'; import otherApiEntity from './other-example-api.yaml'; +const mockEntities = ([ + openapiApiEntity, + asyncapiApiEntity, + graphqlApiEntity, + otherApiEntity, +] as unknown) as Entity[]; + createDevApp() .registerApi({ api: catalogApiRef, @@ -38,14 +45,12 @@ createDevApp() (({ async getEntities() { return { - items: [ - openapiApiEntity, - asyncapiApiEntity, - graphqlApiEntity, - otherApiEntity, - ], + items: mockEntities.slice(), }; }, + async getEntityByName(name: string) { + return mockEntities.find(e => e.metadata.name === name); + }, } as unknown) as typeof catalogApiRef.T), }) .registerApi({ diff --git a/plugins/cost-insights/dev/index.tsx b/plugins/cost-insights/dev/index.tsx index 8cfa12fc18..009fca55dd 100644 --- a/plugins/cost-insights/dev/index.tsx +++ b/plugins/cost-insights/dev/index.tsx @@ -13,10 +13,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +import React from 'react'; import { createDevApp } from '@backstage/dev-utils'; import { ExampleCostInsightsClient } from '../src/example'; import { costInsightsApiRef } from '../src/api'; -import { costInsightsPlugin } from '../src/plugin'; +import { + costInsightsPlugin, + CostInsightsPage, + CostInsightsProjectGrowthInstructionsPage, + CostInsightsLabelDataflowInstructionsPage, +} from '../src/plugin'; createDevApp() .registerPlugin(costInsightsPlugin) @@ -25,4 +32,16 @@ createDevApp() deps: {}, factory: () => new ExampleCostInsightsClient(), }) + .addPage({ + title: 'Cost Insights', + element: , + }) + .addPage({ + title: 'Growth', + element: , + }) + .addPage({ + title: 'Labelling', + element: , + }) .render(); diff --git a/plugins/gcp-projects/dev/index.tsx b/plugins/gcp-projects/dev/index.tsx index b87d4b7d47..5b01456ec8 100644 --- a/plugins/gcp-projects/dev/index.tsx +++ b/plugins/gcp-projects/dev/index.tsx @@ -14,7 +14,14 @@ * limitations under the License. */ +import React from 'react'; import { createDevApp } from '@backstage/dev-utils'; -import { gcpProjectsPlugin } from '../src/plugin'; +import { gcpProjectsPlugin, GcpProjectsPage } from '../src/plugin'; -createDevApp().registerPlugin(gcpProjectsPlugin).render(); +createDevApp() + .registerPlugin(gcpProjectsPlugin) + .addPage({ + title: 'GCP Projects', + element: , + }) + .render(); diff --git a/plugins/newrelic/dev/index.tsx b/plugins/newrelic/dev/index.tsx index 9ca421f94a..59e1157d17 100644 --- a/plugins/newrelic/dev/index.tsx +++ b/plugins/newrelic/dev/index.tsx @@ -14,7 +14,14 @@ * limitations under the License. */ +import React from 'react'; import { createDevApp } from '@backstage/dev-utils'; -import { newRelicPlugin } from '../src/plugin'; +import { newRelicPlugin, NewRelicPage } from '../src/plugin'; -createDevApp().registerPlugin(newRelicPlugin).render(); +createDevApp() + .registerPlugin(newRelicPlugin) + .addPage({ + title: 'New Relic', + element: , + }) + .render(); diff --git a/plugins/welcome/dev/index.tsx b/plugins/welcome/dev/index.tsx index b237812f97..399c157fad 100644 --- a/plugins/welcome/dev/index.tsx +++ b/plugins/welcome/dev/index.tsx @@ -14,7 +14,14 @@ * limitations under the License. */ +import React from 'react'; import { createDevApp } from '@backstage/dev-utils'; -import { welcomePlugin } from '../src/plugin'; +import { welcomePlugin, WelcomePage } from '../src/plugin'; -createDevApp().registerPlugin(welcomePlugin).render(); +createDevApp() + .registerPlugin(welcomePlugin) + .addPage({ + title: 'Welcome', + element: , + }) + .render();