core-compat-api: collection of fixes for convertLegacyApp
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
---
|
||||
'@backstage/core-compat-api': patch
|
||||
---
|
||||
|
||||
The `convertLegacyApp` has received the following changes:
|
||||
|
||||
- `null` routes will now be ignored.
|
||||
- Converted routes no longer need to belong to a plugin, falling back to a `converted-orphan-routes` plugin instead.
|
||||
- The generate layout override extension is now properly attached to the `app/root` extension.
|
||||
- Converted root elements are now automatically wrapped with `compatWrapper`.
|
||||
@@ -48,8 +48,10 @@ describe('collectLegacyRoutes', () => {
|
||||
<FlatRoutes>
|
||||
<Route path="/score-board" element={<ScoreBoardPage />} />
|
||||
<Route path="/stackstorm" element={<StackstormPage />} />
|
||||
<Route path="/other" element={<div />} />
|
||||
<Route path="/puppetdb" element={<PuppetDbPage />} />
|
||||
<Route path="/puppetdb" element={<PuppetDbPage />} />
|
||||
<Route path="/other" element={<div />} />
|
||||
</FlatRoutes>,
|
||||
);
|
||||
|
||||
@@ -96,6 +98,23 @@ describe('collectLegacyRoutes', () => {
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'converted-orphan-routes',
|
||||
extensions: [
|
||||
{
|
||||
id: 'page:converted-orphan-routes',
|
||||
attachTo: { id: 'app/routes', input: 'routes' },
|
||||
disabled: false,
|
||||
defaultConfig: {},
|
||||
},
|
||||
{
|
||||
id: 'page:converted-orphan-routes/2',
|
||||
attachTo: { id: 'app/routes', input: 'routes' },
|
||||
disabled: false,
|
||||
defaultConfig: {},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'puppetDb',
|
||||
extensions: [
|
||||
@@ -378,8 +397,6 @@ describe('collectLegacyRoutes', () => {
|
||||
<Route element={<Navigate to="/somewhere" />} />
|
||||
</FlatRoutes>,
|
||||
),
|
||||
).toThrow(
|
||||
/Route with path undefined has en element that can not be converted/,
|
||||
);
|
||||
).toThrow(/Route element inside FlatRoutes had no path prop value given/);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -18,6 +18,7 @@ import {
|
||||
AnyRouteRefParams,
|
||||
BackstagePlugin as LegacyBackstagePlugin,
|
||||
RouteRef,
|
||||
createPlugin,
|
||||
getComponentData,
|
||||
} from '@backstage/core-plugin-api';
|
||||
import {
|
||||
@@ -167,6 +168,9 @@ export function collectLegacyRoutes(
|
||||
return () => String(currentIndex++);
|
||||
})();
|
||||
|
||||
// Placeholder plugin for any routes that don't belong to a plugin
|
||||
const orphanRoutesPlugin = createPlugin({ id: 'converted-orphan-routes' });
|
||||
|
||||
const getPluginExtensions = (plugin: LegacyBackstagePlugin) => {
|
||||
let extensions = pluginExtensions.get(plugin);
|
||||
if (!extensions) {
|
||||
@@ -179,6 +183,9 @@ export function collectLegacyRoutes(
|
||||
React.Children.forEach(
|
||||
flatRoutesElement.props.children,
|
||||
(route: ReactNode) => {
|
||||
if (route === null) {
|
||||
return;
|
||||
}
|
||||
// TODO(freben): Handle feature flag and permissions framework wrapper elements
|
||||
if (!React.isValidElement(route)) {
|
||||
throw new Error(
|
||||
@@ -192,20 +199,13 @@ export function collectLegacyRoutes(
|
||||
}
|
||||
const routeElement = route.props.element;
|
||||
const path: string | undefined = route.props.path;
|
||||
const plugin = getComponentData<LegacyBackstagePlugin>(
|
||||
routeElement,
|
||||
'core.plugin',
|
||||
);
|
||||
const plugin =
|
||||
getComponentData<LegacyBackstagePlugin>(routeElement, 'core.plugin') ??
|
||||
orphanRoutesPlugin;
|
||||
const routeRef = getComponentData<RouteRef>(
|
||||
routeElement,
|
||||
'core.mountPoint',
|
||||
);
|
||||
if (!plugin) {
|
||||
throw new Error(
|
||||
// TODO(vinzscam): add See <link-to-app-migration-docs> for more info
|
||||
`Route with path ${path} has en element that can not be converted as it does not belong to a plugin. Make sure that the top-level React element of the element prop is an extension from a Backstage plugin, or remove the Route completely.`,
|
||||
);
|
||||
}
|
||||
if (path === undefined) {
|
||||
throw new Error(
|
||||
`Route element inside FlatRoutes had no path prop value given`,
|
||||
|
||||
@@ -114,7 +114,7 @@ describe('convertLegacyApp', () => {
|
||||
extensions: [
|
||||
{
|
||||
id: 'app/layout',
|
||||
attachTo: { id: 'app', input: 'root' },
|
||||
attachTo: { id: 'app/root', input: 'children' },
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
|
||||
@@ -32,6 +32,7 @@ import {
|
||||
} from '@backstage/frontend-plugin-api';
|
||||
import { getComponentData } from '@backstage/core-plugin-api';
|
||||
import { collectLegacyRoutes } from './collectLegacyRoutes';
|
||||
import { compatWrapper } from './compatWrapper';
|
||||
|
||||
function selectChildren(
|
||||
rootNode: ReactNode,
|
||||
@@ -106,7 +107,7 @@ export function convertLegacyApp(
|
||||
|
||||
const CoreLayoutOverride = createExtension({
|
||||
name: 'layout',
|
||||
attachTo: { id: 'app', input: 'root' },
|
||||
attachTo: { id: 'app/root', input: 'children' },
|
||||
inputs: {
|
||||
content: createExtensionInput([coreExtensionData.reactElement], {
|
||||
singleton: true,
|
||||
@@ -117,10 +118,12 @@ export function convertLegacyApp(
|
||||
// Clone the root element, this replaces the FlatRoutes declared in the app with out content input
|
||||
return [
|
||||
coreExtensionData.reactElement(
|
||||
React.cloneElement(
|
||||
rootEl,
|
||||
undefined,
|
||||
inputs.content.get(coreExtensionData.reactElement),
|
||||
compatWrapper(
|
||||
React.cloneElement(
|
||||
rootEl,
|
||||
undefined,
|
||||
inputs.content.get(coreExtensionData.reactElement),
|
||||
),
|
||||
),
|
||||
),
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user