core-api: migrate app context to use a separate type and implementation

This commit is contained in:
Patrik Oldsberg
2021-02-21 22:55:25 +01:00
parent f30b16b541
commit 64f6f5255c
3 changed files with 72 additions and 10 deletions
+36 -1
View File
@@ -64,6 +64,7 @@ import { AppThemeProvider } from './AppThemeProvider';
import {
AppComponents,
AppConfigLoader,
AppContext,
AppOptions,
AppRouteBinder,
BackstageApp,
@@ -139,6 +140,38 @@ function useConfigLoader(
return { api: configReader };
}
class AppContextImpl implements AppContext {
constructor(private readonly app: PrivateAppImpl) {}
getPlugins(): BackstagePlugin<any, any>[] {
// eslint-disable-next-line no-console
console.warn('appContext.getPlugins() is deprecated and will be removed');
return this.app.getPlugins();
}
getSystemIcon(key: string): IconComponent {
return this.app.getSystemIcon(key);
}
getProvider(): React.ComponentType<{}> {
// eslint-disable-next-line no-console
console.warn('appContext.getProvider() is deprecated and will be removed');
return this.app.getProvider();
}
getRouter(): React.ComponentType<{}> {
// eslint-disable-next-line no-console
console.warn('appContext.getRouter() is deprecated and will be removed');
return this.app.getRouter();
}
getRoutes(): JSX.Element[] {
// eslint-disable-next-line no-console
console.warn('appContext.getRoutes() is deprecated and will be removed');
return this.app.getRoutes();
}
}
export class PrivateAppImpl implements BackstageApp {
private apiHolder?: ApiHolder;
private configApi?: ConfigApi;
@@ -236,6 +269,8 @@ export class PrivateAppImpl implements BackstageApp {
}
getProvider(): ComponentType<{}> {
const appContext = new AppContextImpl(this);
const Provider = ({ children }: PropsWithChildren<{}>) => {
const appThemeApi = useMemo(
() => AppThemeSelector.createWithStorage(this.themes),
@@ -273,7 +308,7 @@ export class PrivateAppImpl implements BackstageApp {
return (
<ApiProvider apis={this.getApiHolder()}>
<AppContextProvider app={this}>
<AppContextProvider appContext={appContext}>
<AppThemeProvider>
<RoutingProvider
routePaths={routePaths}
+9 -9
View File
@@ -15,25 +15,25 @@
*/
import React, { createContext, PropsWithChildren, useContext } from 'react';
import { BackstageApp } from './types';
import { AppContext } from './types';
const Context = createContext<BackstageApp | undefined>(undefined);
const Context = createContext<AppContext | undefined>(undefined);
type Props = {
app: BackstageApp;
appContext: AppContext;
};
export const AppContextProvider = ({
app,
appContext,
children,
}: PropsWithChildren<Props>) => (
<Context.Provider value={app} children={children} />
<Context.Provider value={appContext} children={children} />
);
export const useApp = (): BackstageApp => {
const app = useContext(Context);
if (!app) {
export const useApp = (): AppContext => {
const appContext = useContext(Context);
if (!appContext) {
throw new Error('No app context available');
}
return app;
return appContext;
};
+27
View File
@@ -190,3 +190,30 @@ export type BackstageApp = {
*/
getRoutes(): JSX.Element[];
};
export type AppContext = {
/**
* @deprecated Will be removed
*/
getPlugins(): BackstagePlugin<any, any>[];
/**
* Get a common or custom icon for this app.
*/
getSystemIcon(key: IconKey): IconComponent;
/**
* @deprecated Will be removed
*/
getProvider(): ComponentType<{}>;
/**
* @deprecated Will be removed
*/
getRouter(): ComponentType<{}>;
/**
* @deprecated Will be removed
*/
getRoutes(): JSX.Element[];
};