core-compat-api: collect into legacy plugin instead of extension + test refactor

Co-authored-by: Camila Belo <camilaibs@gmail.com>
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2023-10-17 15:44:31 +02:00
parent 4830d0df02
commit c5e8be56c3
3 changed files with 94 additions and 67 deletions
+2 -2
View File
@@ -106,7 +106,7 @@ const scmIntegrationApi = createApiExtension({
}),
});
const collectedLegacyRoutes = collectLegacyRoutes(
const collectedLegacyPlugin = collectLegacyRoutes(
<FlatRoutes>
<Route path="/catalog-import" element={<CatalogImportPage />} />
</FlatRoutes>,
@@ -120,13 +120,13 @@ const app = createApp({
techdocsPlugin,
userSettingsPlugin,
homePlugin,
...collectedLegacyPlugin,
createExtensionOverrides({
extensions: [
entityPageExtension,
homePageExtension,
scmAuthExtension,
scmIntegrationApi,
...collectedLegacyRoutes,
],
}),
],
@@ -14,22 +14,15 @@
* 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 React from 'react';
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(
@@ -40,26 +33,65 @@ describe('collectLegacyRoutes', () => {
</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),
}),
// ??????????????
expect(
collected.map(p => ({
id: p.id,
extensions: p.extensions.map(e => ({
id: e.id,
attachTo: e.attachTo,
disabled: e.disabled,
defaultConfig: e.configSchema?.parse({}),
})),
})),
).toEqual([
{
id: 'score-card',
extensions: [
{
id: 'plugin.score-card.page',
attachTo: { id: 'core.routes', input: 'routes' },
disabled: false,
defaultConfig: { path: 'score-board' },
},
{
id: 'apis.plugin.scoringdata.service',
attachTo: { id: 'core', input: 'apis' },
disabled: false,
},
],
},
{
id: 'stackstorm',
extensions: [
{
id: 'plugin.stackstorm.page',
attachTo: { id: 'core.routes', input: 'routes' },
disabled: false,
defaultConfig: { path: 'stackstorm' },
},
{
id: 'apis.plugin.stackstorm.service',
attachTo: { id: 'core', input: 'apis' },
disabled: false,
},
],
},
{
id: 'puppetDb',
extensions: [
{
id: 'plugin.puppetDb.page',
attachTo: { id: 'core.routes', input: 'routes' },
disabled: false,
defaultConfig: { path: 'puppetdb' },
},
{
id: 'apis.plugin.puppetdb.service',
attachTo: { id: 'core', input: 'apis' },
disabled: false,
},
],
},
]);
});
});
@@ -19,10 +19,12 @@ import {
Extension,
createApiExtension,
createPageExtension,
createPlugin,
BackstagePlugin,
} from '@backstage/frontend-plugin-api';
import { Route, Routes } from 'react-router-dom';
import {
BackstagePlugin,
BackstagePlugin as LegacyBackstagePlugin,
RouteRef,
getComponentData,
} from '@backstage/core-plugin-api';
@@ -30,23 +32,8 @@ import { convertLegacyRouteRef } from '@backstage/core-plugin-api/alpha';
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>>();
): BackstagePlugin[] {
const results = new Array<BackstagePlugin>();
React.Children.forEach(
flatRoutesElement.props.children,
@@ -63,7 +50,7 @@ export function collectLegacyRoutes(
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>(
const plugin = getComponentData<LegacyBackstagePlugin>(
routeElement,
'core.plugin',
);
@@ -79,24 +66,28 @@ export function collectLegacyRoutes(
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: routeRef ? convertLegacyRouteRef(routeRef) : undefined,
const detectedExtensions = new Array<Extension<unknown>>();
loader: async () =>
route.props.children ? (
<Routes>
<Route path="*" element={routeElement}>
<Route path="*" element={route.props.children} />
</Route>
</Routes>
) : (
routeElement
),
});
detectedExtensions.push(
createPageExtension({
id: `plugin.${pluginId}.page`,
defaultPath: path[0] === '/' ? path.slice(1) : path,
routeRef: routeRef ? convertLegacyRouteRef(routeRef) : undefined,
results.push(
loader: async () =>
route.props.children ? (
<Routes>
<Route path="*" element={routeElement}>
<Route path="*" element={route.props.children} />
</Route>
</Routes>
) : (
routeElement
),
}),
);
detectedExtensions.push(
...Array.from(plugin.getApis()).map(factory =>
createApiExtension({
factory,
@@ -104,8 +95,12 @@ export function collectLegacyRoutes(
),
);
// TODO: Create converted plugin instance instead. We need to move over APIs etc.
results.push(detectedExtension);
results.push(
createPlugin({
id: plugin.getId(),
extensions: detectedExtensions,
}),
);
},
);