Merge pull request #6124 from backstage/rugvip/noroutes

plugins,dev-utils: remove usage of deprecated route registrations
This commit is contained in:
Patrik Oldsberg
2021-06-21 23:39:33 +02:00
committed by GitHub
14 changed files with 89 additions and 134 deletions
+5
View File
@@ -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.
+10
View File
@@ -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.
+13 -80
View File
@@ -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<JSX.Element>();
private readonly sidebarItems = new Array<JSX.Element>();
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(
<SidebarItem
@@ -169,9 +175,6 @@ class DevAppBuilder {
const AppProvider = app.getProvider();
const AppRouter = app.getRouter();
const deprecatedAppRoutes = app.getRoutes();
const sidebar = this.setupSidebar(this.plugins);
const DevApp = () => {
return (
@@ -181,10 +184,12 @@ class DevAppBuilder {
{this.rootChildren}
<AppRouter>
<SidebarPage>
{sidebar}
<Sidebar>
<SidebarSpacer />
{this.sidebarItems}
</Sidebar>
<FlatRoutes>
{this.routes}
{deprecatedAppRoutes}
<Route path="/_external_route" element={<DummyPage />} />
</FlatRoutes>
</SidebarPage>
@@ -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(<DevApp />, document.getElementById('root'));
}
// Create a sidebar that exposes the touchpoints of a plugin
private setupSidebar(plugins: BackstagePlugin[]): JSX.Element {
const sidebarItems = new Array<JSX.Element>();
for (const plugin of plugins) {
for (const output of plugin.output()) {
switch (output.type) {
case 'legacy-route': {
const { path } = output;
sidebarItems.push(
<SidebarItem
key={path}
to={path}
text={path}
icon={BookmarkIcon}
/>,
);
break;
}
case 'route': {
const { target } = output;
sidebarItems.push(
<SidebarItem
key={target.path}
to={target.path}
text={target.title}
icon={target.icon ?? SentimentDissatisfiedIcon}
/>,
);
break;
}
default:
break;
}
}
}
return (
<Sidebar>
<SidebarSpacer />
{this.sidebarItems}
{sidebarItems}
</Sidebar>
);
}
private findPluginPaths(plugins: BackstagePlugin[]) {
const paths = new Array<string>();
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
+11 -6
View File
@@ -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({
-4
View File
@@ -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(
+20 -1
View File
@@ -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: <CostInsightsPage />,
})
.addPage({
title: 'Growth',
element: <CostInsightsProjectGrowthInstructionsPage />,
})
.addPage({
title: 'Labelling',
element: <CostInsightsLabelDataflowInstructionsPage />,
})
.render();
+1 -13
View File
@@ -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: {
+9 -2
View File
@@ -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: <GcpProjectsPage />,
})
.render();
+1 -9
View File
@@ -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(
-8
View File
@@ -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,
+9 -2
View File
@@ -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: <NewRelicPage />,
})
.render();
-4
View File
@@ -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,
},
+9 -2
View File
@@ -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: <WelcomePage />,
})
.render();
+1 -3
View File
@@ -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');
},
});