Merge pull request #6124 from backstage/rugvip/noroutes
plugins,dev-utils: remove usage of deprecated route registrations
This commit is contained in:
@@ -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.
|
||||
@@ -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.
|
||||
@@ -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
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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');
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user