diff --git a/.changeset/chilly-seahorses-bake.md b/.changeset/chilly-seahorses-bake.md
new file mode 100644
index 0000000000..8ab80cf93e
--- /dev/null
+++ b/.changeset/chilly-seahorses-bake.md
@@ -0,0 +1,5 @@
+---
+'@backstage/core-compat-api': patch
+---
+
+The backwards compatibility provider will now use the new `ComponentsApi` and `IconsApi` when implementing the old `AppContext`.
diff --git a/packages/core-compat-api/src/compatWrapper/BackwardsCompatProvider.tsx b/packages/core-compat-api/src/compatWrapper/BackwardsCompatProvider.tsx
index 099993a392..1dd64efb89 100644
--- a/packages/core-compat-api/src/compatWrapper/BackwardsCompatProvider.tsx
+++ b/packages/core-compat-api/src/compatWrapper/BackwardsCompatProvider.tsx
@@ -18,14 +18,13 @@ import React, { useMemo } from 'react';
import { ReactNode } from 'react';
// eslint-disable-next-line @backstage/no-relative-monorepo-imports
import { AppContextProvider } from '../../../core-app-api/src/app/AppContext';
-// eslint-disable-next-line @backstage/no-relative-monorepo-imports
-import {
- components as defaultComponents,
- icons as defaultIcons,
-} from '../../../app-defaults/src/defaults';
import {
+ createPlugin as createNewPlugin,
BackstagePlugin as NewBackstagePlugin,
appTreeApiRef,
+ componentsApiRef,
+ coreComponentRefs,
+ iconsApiRef,
useApi,
} from '@backstage/frontend-plugin-api';
import {
@@ -71,15 +70,35 @@ function toLegacyPlugin(plugin: NewBackstagePlugin): LegacyBackstagePlugin {
return legacy;
}
+// TODO: Currently a very naive implementation, may need some more work
+function toNewPlugin(plugin: LegacyBackstagePlugin): NewBackstagePlugin {
+ return createNewPlugin({
+ id: plugin.getId(),
+ });
+}
+
// Recreates the old AppContext APIs using the various new APIs that replaced it
function LegacyAppContextProvider(props: { children: ReactNode }) {
const appTreeApi = useApi(appTreeApiRef);
+ const componentsApi = useApi(componentsApiRef);
+ const iconsApi = useApi(iconsApiRef);
const appContext = useMemo(() => {
const { tree } = appTreeApi.getTree();
let gatheredPlugins: LegacyBackstagePlugin[] | undefined = undefined;
+ const ErrorBoundaryFallback = componentsApi.getComponent(
+ coreComponentRefs.errorBoundaryFallback,
+ );
+ const ErrorBoundaryFallbackWrapper: AppComponents['ErrorBoundaryFallback'] =
+ ({ plugin, ...rest }) => (
+
+ );
+
return {
getPlugins(): LegacyBackstagePlugin[] {
if (gatheredPlugins) {
@@ -98,24 +117,39 @@ function LegacyAppContextProvider(props: { children: ReactNode }) {
return gatheredPlugins;
},
- // TODO: Grab these from new API once it exists
getSystemIcon(key: string): IconComponent | undefined {
- return key in defaultIcons
- ? defaultIcons[key as keyof typeof defaultIcons]
- : undefined;
+ return iconsApi.getIcon(key);
},
- // TODO: Grab these from new API once it exists
getSystemIcons(): Record {
- return defaultIcons;
+ const { keys } = iconsApi.listIconKeys();
+
+ return Object.fromEntries(
+ Array.from(keys).map(key => [key, iconsApi.getIcon(key)!]),
+ );
},
- // TODO: Grab these from new API once it exists
getComponents(): AppComponents {
- return defaultComponents;
+ return {
+ NotFoundErrorPage: componentsApi.getComponent(
+ coreComponentRefs.notFoundErrorPage,
+ ),
+ BootErrorPage() {
+ throw new Error(
+ 'The BootErrorPage app component should not be accessed by plugins',
+ );
+ },
+ Progress: componentsApi.getComponent(coreComponentRefs.progress),
+ Router() {
+ throw new Error(
+ 'The Router app component should not be accessed by plugins',
+ );
+ },
+ ErrorBoundaryFallback: ErrorBoundaryFallbackWrapper,
+ };
},
};
- }, [appTreeApi]);
+ }, [appTreeApi, componentsApi, iconsApi]);
return (
diff --git a/packages/core-compat-api/src/compatWrapper/compatWrapper.test.tsx b/packages/core-compat-api/src/compatWrapper/compatWrapper.test.tsx
index b2ad7f3d0c..2e7dbd9d37 100644
--- a/packages/core-compat-api/src/compatWrapper/compatWrapper.test.tsx
+++ b/packages/core-compat-api/src/compatWrapper/compatWrapper.test.tsx
@@ -60,7 +60,7 @@ describe('BackwardsCompatProvider', () => {
expect(screen.getByTestId('ctx').textContent).toMatchInlineSnapshot(`
"plugins:
- components: Progress, Router, NotFoundErrorPage, BootErrorPage, ErrorBoundaryFallback
+ components: NotFoundErrorPage, BootErrorPage, Progress, Router, ErrorBoundaryFallback
icons: brokenImage, catalog, scaffolder, techdocs, search, chat, dashboard, docs, email, github, group, help, kind:api, kind:component, kind:domain, kind:group, kind:location, kind:system, kind:user, kind:resource, kind:template, user, warning"
`);
});