packages/core-api: split AppComponent into AppRouter and AppRoutes
This commit is contained in:
@@ -27,15 +27,18 @@ const app = createApp({
|
||||
});
|
||||
|
||||
const AppProvider = app.getProvider();
|
||||
const AppComponent = app.getRootComponent();
|
||||
const AppRouter = app.getRouter();
|
||||
const AppRoutes = app.getRoutes();
|
||||
|
||||
const App: FC<{}> = () => (
|
||||
<AppProvider>
|
||||
<AlertDisplay />
|
||||
<OAuthRequestDialog />
|
||||
<Root>
|
||||
<AppComponent />
|
||||
</Root>
|
||||
<AppRouter>
|
||||
<Root>
|
||||
<AppRoutes />
|
||||
</Root>
|
||||
</AppRouter>
|
||||
</AppProvider>
|
||||
);
|
||||
|
||||
|
||||
@@ -26,13 +26,16 @@ const app = createApp({
|
||||
});
|
||||
|
||||
const AppProvider = app.getProvider();
|
||||
const AppComponent = app.getRootComponent();
|
||||
const AppRouter = app.getRouter();
|
||||
const AppRoutes = app.getRoutes();
|
||||
|
||||
const App: FC<{}> = () => {
|
||||
useStyles();
|
||||
return (
|
||||
<AppProvider>
|
||||
<AppComponent />
|
||||
<AppRouter>
|
||||
<AppRoutes />
|
||||
</AppRouter>
|
||||
</AppProvider>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -19,7 +19,11 @@ import { AppContextProvider } from './AppContext';
|
||||
import { BackstageApp, AppComponents, AppConfigLoader, Apis } from './types';
|
||||
import { BackstagePlugin } from '../plugin';
|
||||
import { FeatureFlagsRegistryItem } from './FeatureFlags';
|
||||
import { featureFlagsApiRef } from '../apis/definitions';
|
||||
import {
|
||||
featureFlagsApiRef,
|
||||
AppThemeApi,
|
||||
ConfigApi,
|
||||
} from '../apis/definitions';
|
||||
import { AppThemeProvider } from './AppThemeProvider';
|
||||
|
||||
import { IconComponent, SystemIcons, SystemIconKey } from '../icons';
|
||||
@@ -32,6 +36,7 @@ import {
|
||||
appThemeApiRef,
|
||||
configApiRef,
|
||||
ConfigReader,
|
||||
useApi,
|
||||
} from '../apis';
|
||||
import { ApiAggregator } from '../apis/ApiAggregator';
|
||||
import { useAsync } from 'react-use';
|
||||
@@ -114,7 +119,7 @@ export class PrivateAppImpl implements BackstageApp {
|
||||
return this.icons[key];
|
||||
}
|
||||
|
||||
getRootComponent(): ComponentType<{}> {
|
||||
getRoutes(): ComponentType<{}> {
|
||||
const routes = new Array<JSX.Element>();
|
||||
const registeredFeatureFlags = new Array<FeatureFlagsRegistryItem>();
|
||||
|
||||
@@ -195,26 +200,42 @@ export class PrivateAppImpl implements BackstageApp {
|
||||
if ('node' in loadedConfig) {
|
||||
return loadedConfig.node;
|
||||
}
|
||||
const configReader = loadedConfig.api;
|
||||
const configApi = loadedConfig.api;
|
||||
|
||||
const appApis = ApiRegistry.from([
|
||||
[appThemeApiRef, AppThemeSelector.createWithStorage(this.themes)],
|
||||
[configApiRef, configReader],
|
||||
[appThemeApiRef, appThemeApi],
|
||||
[configApiRef, configApi],
|
||||
]);
|
||||
|
||||
if (!this.apis) {
|
||||
if ('get' in this.apisOrFactory) {
|
||||
this.apis = this.apisOrFactory;
|
||||
} else {
|
||||
this.apis = this.apisOrFactory(configReader);
|
||||
this.apis = this.apisOrFactory(configApi);
|
||||
}
|
||||
}
|
||||
|
||||
const apis = new ApiAggregator(this.apis, appApis);
|
||||
|
||||
const { Router } = this.components;
|
||||
return (
|
||||
<ApiProvider apis={apis}>
|
||||
<AppContextProvider app={this}>
|
||||
<AppThemeProvider>{children}</AppThemeProvider>
|
||||
</AppContextProvider>
|
||||
</ApiProvider>
|
||||
);
|
||||
};
|
||||
return Provider;
|
||||
}
|
||||
|
||||
getRouter(): ComponentType<{}> {
|
||||
const { Router: RouterComponent } = this.components;
|
||||
|
||||
const AppRouter: FC<{}> = ({ children }) => {
|
||||
const configApi = useApi(configApiRef);
|
||||
|
||||
let { pathname } = new URL(
|
||||
configReader.getString('app.baseUrl') ?? '/',
|
||||
configApi.getString('app.baseUrl') ?? '/',
|
||||
'http://dummy.dev', // baseUrl can be specified as just a path
|
||||
);
|
||||
if (pathname.endsWith('/')) {
|
||||
@@ -222,20 +243,14 @@ export class PrivateAppImpl implements BackstageApp {
|
||||
}
|
||||
|
||||
return (
|
||||
<ApiProvider apis={apis}>
|
||||
<AppContextProvider app={this}>
|
||||
<AppThemeProvider>
|
||||
<Router>
|
||||
<Routes>
|
||||
<Route path={`${pathname}/*`} element={<>{children}</>} />
|
||||
</Routes>
|
||||
</Router>
|
||||
</AppThemeProvider>
|
||||
</AppContextProvider>
|
||||
</ApiProvider>
|
||||
<RouterComponent>
|
||||
<Routes>
|
||||
<Route path={`${pathname}/*`} element={<>{children}</>} />
|
||||
</Routes>
|
||||
</RouterComponent>
|
||||
);
|
||||
};
|
||||
return Provider;
|
||||
return AppRouter;
|
||||
}
|
||||
|
||||
verify() {
|
||||
|
||||
@@ -117,14 +117,19 @@ export type BackstageApp = {
|
||||
getSystemIcon(key: SystemIconKey): IconComponent;
|
||||
|
||||
/**
|
||||
* Creates a root component for this app, including the App chrome
|
||||
* and routes to all plugins.
|
||||
*/
|
||||
getRootComponent(): ComponentType<{}>;
|
||||
|
||||
/**
|
||||
* Provider component that should wrap the App's RootComponent and
|
||||
* any other components that need to be within the app context.
|
||||
* Provider component that should wrap the Router created with getRouter()
|
||||
* and any other components that need to be within the app context.
|
||||
*/
|
||||
getProvider(): ComponentType<{}>;
|
||||
|
||||
/**
|
||||
* Router component that should wrap the App Routes create with getRoutes()
|
||||
* and any other components that should only be available while signed in.
|
||||
*/
|
||||
getRouter(): ComponentType<{}>;
|
||||
|
||||
/**
|
||||
* Routes component that contains all routes for plugin pages in the app.
|
||||
*/
|
||||
getRoutes(): ComponentType<{}>;
|
||||
};
|
||||
|
||||
@@ -82,8 +82,10 @@ class DevAppBuilder {
|
||||
apis: this.setupApiRegistry(this.factories),
|
||||
plugins: this.plugins,
|
||||
});
|
||||
|
||||
const AppProvider = app.getProvider();
|
||||
const AppComponent = app.getRootComponent();
|
||||
const AppRouter = app.getRouter();
|
||||
const AppRoutes = app.getRoutes();
|
||||
|
||||
const sidebar = this.setupSidebar(this.plugins);
|
||||
|
||||
@@ -93,10 +95,13 @@ class DevAppBuilder {
|
||||
<AlertDisplay />
|
||||
<OAuthRequestDialog />
|
||||
{this.rootChildren}
|
||||
<SidebarPage>
|
||||
{sidebar}
|
||||
<AppComponent />
|
||||
</SidebarPage>
|
||||
|
||||
<AppRouter>
|
||||
<SidebarPage>
|
||||
{sidebar}
|
||||
<AppRoutes />
|
||||
</SidebarPage>
|
||||
</AppRouter>
|
||||
</AppProvider>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -89,12 +89,15 @@ export function wrapInTestApp(
|
||||
}
|
||||
|
||||
const AppProvider = app.getProvider();
|
||||
const AppRouter = app.getRouter();
|
||||
|
||||
return (
|
||||
<AppProvider>
|
||||
{/* The path of * here is needed to be set as a catch all, so it will render the wrapper element
|
||||
* and work with nested routes if they exist too */}
|
||||
<Route path="*" element={<Wrapper />} />
|
||||
<AppRouter>
|
||||
{/* The path of * here is needed to be set as a catch all, so it will render the wrapper element
|
||||
* and work with nested routes if they exist too */}
|
||||
<Route path="*" element={<Wrapper />} />
|
||||
</AppRouter>
|
||||
</AppProvider>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user