feat: move legacy collect routes
Signed-off-by: Camila Belo <camilaibs@gmail.com> Co-authored-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
committed by
Patrik Oldsberg
parent
9a6db6bba2
commit
8462548e8f
@@ -25,9 +25,21 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "workspace:^",
|
||||
"@backstage/core-app-api": "workspace:^",
|
||||
"@backstage/plugin-puppetdb": "workspace:^",
|
||||
"@backstage/plugin-stackstorm": "workspace:^",
|
||||
"@oriflame/backstage-plugin-score-card": "^0.7.0",
|
||||
"@testing-library/jest-dom": "^5.10.1"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
]
|
||||
],
|
||||
"peerDependencies": {
|
||||
"react": "*",
|
||||
"react-router-dom": "*"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/core-plugin-api": "workspace:^",
|
||||
"@backstage/frontend-plugin-api": "workspace:^"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2023 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { FlatRoutes } from '@backstage/core-app-api';
|
||||
import { createPageExtension } from '@backstage/frontend-plugin-api';
|
||||
import { PuppetDbPage } from '@backstage/plugin-puppetdb';
|
||||
import { StackstormPage } from '@backstage/plugin-stackstorm';
|
||||
import { ScoreBoardPage } from '@oriflame/backstage-plugin-score-card';
|
||||
import { Route } from 'react-router-dom';
|
||||
|
||||
import { getComponentData } from '@backstage/core-plugin-api';
|
||||
import { collectLegacyRoutes } from './collectLegacyRoutes';
|
||||
|
||||
jest.mock('@backstage/frontend-plugin-api', () => ({
|
||||
...jest.requireActual('@backstage/frontend-plugin-api'),
|
||||
createPageExtension: opts => opts,
|
||||
}));
|
||||
|
||||
describe('collectLegacyRoutes', () => {
|
||||
it('should collect legacy routes', () => {
|
||||
const collected = collectLegacyRoutes(
|
||||
<FlatRoutes>
|
||||
<Route path="/score-board" element={<ScoreBoardPage />} />
|
||||
<Route path="/stackstorm" element={<StackstormPage />} />
|
||||
<Route path="/puppetdb" element={<PuppetDbPage />} />
|
||||
</FlatRoutes>,
|
||||
);
|
||||
|
||||
expect(collected).toEqual([
|
||||
createPageExtension({
|
||||
id: 'plugin.score-card.page',
|
||||
defaultPath: 'score-board',
|
||||
routeRef: getComponentData(<ScoreBoardPage />, 'core.mountPoint'),
|
||||
loader: expect.any(Function),
|
||||
}),
|
||||
createPageExtension({
|
||||
id: 'plugin.stackstorm.page',
|
||||
defaultPath: 'stackstorm',
|
||||
routeRef: getComponentData(<StackstormPage />, 'core.mountPoint'),
|
||||
loader: expect.any(Function),
|
||||
}),
|
||||
createPageExtension({
|
||||
id: 'plugin.puppetDb.page',
|
||||
defaultPath: 'puppetdb',
|
||||
routeRef: getComponentData(<PuppetDbPage />, 'core.mountPoint'),
|
||||
loader: expect.any(Function),
|
||||
}),
|
||||
// ??????????????
|
||||
]);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright 2023 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { ReactNode } from 'react';
|
||||
import { Extension, createPageExtension } from '@backstage/frontend-plugin-api';
|
||||
import { Route, Routes } from 'react-router-dom';
|
||||
import {
|
||||
BackstagePlugin,
|
||||
RouteRef,
|
||||
getComponentData,
|
||||
} from '@backstage/core-plugin-api';
|
||||
|
||||
export function collectLegacyRoutes(
|
||||
flatRoutesElement: JSX.Element,
|
||||
): Extension<unknown>[] {
|
||||
// const results = traverseElementTree({
|
||||
// root,
|
||||
// discoverers: [childDiscoverer, routeElementDiscoverer],
|
||||
// collectors: {
|
||||
// foo: createCollector(
|
||||
// () => new Set<Extension>(),
|
||||
// (acc, node) => {
|
||||
// const plugin = getComponentData<BackstagePlugin>(node, 'core.plugin');
|
||||
// if (plugin) {
|
||||
// acc.add(plugin);
|
||||
// }
|
||||
// },
|
||||
// )
|
||||
// },
|
||||
// })
|
||||
const results = new Array<Extension<unknown>>();
|
||||
|
||||
React.Children.forEach(
|
||||
flatRoutesElement.props.children,
|
||||
(route: ReactNode) => {
|
||||
if (!React.isValidElement(route)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO(freben): Handle feature flag and permissions framework wrapper elements
|
||||
if (route.type !== Route) {
|
||||
return;
|
||||
}
|
||||
|
||||
const routeElement = route.props.element;
|
||||
|
||||
// TODO: to support deeper extension component, e.g. hidden within <RequirePermission>, use https://github.com/backstage/backstage/blob/518a34646b79ec2028cc0ed6bc67d4366c51c4d6/packages/core-app-api/src/routing/collectors.tsx#L69
|
||||
const plugin = getComponentData<BackstagePlugin>(
|
||||
routeElement,
|
||||
'core.plugin',
|
||||
);
|
||||
if (!plugin) {
|
||||
return;
|
||||
}
|
||||
|
||||
const routeRef = getComponentData<RouteRef>(
|
||||
routeElement,
|
||||
'core.mountPoint',
|
||||
);
|
||||
|
||||
const pluginId = plugin.getId();
|
||||
const path: string = route.props.path;
|
||||
|
||||
const detectedExtension = createPageExtension({
|
||||
id: `plugin.${pluginId}.page`,
|
||||
defaultPath: path[0] === '/' ? path.slice(1) : path,
|
||||
routeRef,
|
||||
|
||||
loader: async () =>
|
||||
route.props.children ? (
|
||||
<Routes>
|
||||
<Route path="*" element={routeElement}>
|
||||
<Route path="*" element={route.props.children} />
|
||||
</Route>
|
||||
</Routes>
|
||||
) : (
|
||||
routeElement
|
||||
),
|
||||
});
|
||||
|
||||
plugin.getApis(); // Create DI API extensions from these
|
||||
|
||||
// TODO: Create converted plugin instance instead. We need to move over APIs etc.
|
||||
results.push(detectedExtension);
|
||||
},
|
||||
);
|
||||
|
||||
// TODO: For every legacy plugin that we find, make sure any matching plugin is disabled in the new system
|
||||
return results;
|
||||
}
|
||||
@@ -3957,7 +3957,16 @@ __metadata:
|
||||
resolution: "@backstage/core-compat-api@workspace:packages/core-compat-api"
|
||||
dependencies:
|
||||
"@backstage/cli": "workspace:^"
|
||||
"@backstage/core-app-api": "workspace:^"
|
||||
"@backstage/core-plugin-api": "workspace:^"
|
||||
"@backstage/frontend-plugin-api": "workspace:^"
|
||||
"@backstage/plugin-puppetdb": "workspace:^"
|
||||
"@backstage/plugin-stackstorm": "workspace:^"
|
||||
"@oriflame/backstage-plugin-score-card": ^0.7.0
|
||||
"@testing-library/jest-dom": ^5.10.1
|
||||
peerDependencies:
|
||||
react: "*"
|
||||
react-router-dom: "*"
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
|
||||
Reference in New Issue
Block a user