frontend-app-api: updates to use new routing API
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
@@ -20,8 +20,8 @@ import {
|
||||
coreExtensionData,
|
||||
createExtensionInput,
|
||||
NavTarget,
|
||||
useRouteRef,
|
||||
} from '@backstage/frontend-plugin-api';
|
||||
import { useRouteRef } from '@backstage/core-plugin-api';
|
||||
import { makeStyles } from '@material-ui/core';
|
||||
import {
|
||||
Sidebar,
|
||||
@@ -66,7 +66,7 @@ const SidebarLogo = () => {
|
||||
|
||||
const SidebarNavItem = (props: NavTarget) => {
|
||||
const { icon: Icon, title, routeRef } = props;
|
||||
const to = useRouteRef(routeRef)({});
|
||||
const to = useRouteRef(routeRef)();
|
||||
// TODO: Support opening modal, for example, the search one
|
||||
return <SidebarItem to={to} icon={Icon} text={title} />;
|
||||
};
|
||||
|
||||
@@ -15,28 +15,27 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import {
|
||||
BackstagePlugin,
|
||||
RouteRef,
|
||||
createRouteRef,
|
||||
} from '@backstage/core-plugin-api';
|
||||
import { BackstagePlugin } from '@backstage/core-plugin-api';
|
||||
import { extractRouteInfoFromInstanceTree } from './extractRouteInfoFromInstanceTree';
|
||||
import {
|
||||
AnyRouteParams,
|
||||
Extension,
|
||||
RouteRef,
|
||||
coreExtensionData,
|
||||
createExtension,
|
||||
createExtensionInput,
|
||||
createPlugin,
|
||||
createRouteRef,
|
||||
} from '@backstage/frontend-plugin-api';
|
||||
import { createInstances } from '../wiring/createApp';
|
||||
import { MockConfigApi } from '@backstage/test-utils';
|
||||
|
||||
const ref1 = createRouteRef({ id: 'page1' });
|
||||
const ref2 = createRouteRef({ id: 'page2' });
|
||||
const ref3 = createRouteRef({ id: 'page3' });
|
||||
const ref4 = createRouteRef({ id: 'page4' });
|
||||
const ref5 = createRouteRef({ id: 'page5' });
|
||||
const refOrder = [ref1, ref2, ref3, ref4, ref5];
|
||||
const ref1 = createRouteRef();
|
||||
const ref2 = createRouteRef();
|
||||
const ref3 = createRouteRef();
|
||||
const ref4 = createRouteRef();
|
||||
const ref5 = createRouteRef();
|
||||
const refOrder: RouteRef<AnyRouteParams>[] = [ref1, ref2, ref3, ref4, ref5];
|
||||
|
||||
function createTestExtension(options: {
|
||||
id: string;
|
||||
|
||||
@@ -14,12 +14,24 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { RouteRef } from '@backstage/core-plugin-api';
|
||||
import { coreExtensionData } from '@backstage/frontend-plugin-api';
|
||||
import { RouteRef, coreExtensionData } from '@backstage/frontend-plugin-api';
|
||||
import { ExtensionInstance } from '../wiring/createExtensionInstance';
|
||||
// eslint-disable-next-line @backstage/no-relative-monorepo-imports
|
||||
import { BackstageRouteObject } from '../../../core-app-api/src/routing/types';
|
||||
import { toLegacyPlugin } from '../wiring/createApp';
|
||||
import { BackstagePlugin as LegacyBackstagePlugin } from '@backstage/core-plugin-api';
|
||||
|
||||
/**
|
||||
* A duplicate of the react-router RouteObject, but with routeRef added
|
||||
* @internal
|
||||
*/
|
||||
export interface BackstageRouteObject {
|
||||
caseSensitive: boolean;
|
||||
children?: BackstageRouteObject[];
|
||||
element: React.ReactNode;
|
||||
path: string;
|
||||
routeRefs: Set<RouteRef>;
|
||||
plugins: Set<LegacyBackstagePlugin>;
|
||||
}
|
||||
|
||||
// We always add a child that matches all subroutes but without any route refs. This makes
|
||||
// sure that we're always able to match each route no matter how deep the navigation goes.
|
||||
|
||||
@@ -19,13 +19,13 @@ import {
|
||||
createExtensionOverrides,
|
||||
createPageExtension,
|
||||
createPlugin,
|
||||
createRouteRef,
|
||||
createThemeExtension,
|
||||
} from '@backstage/frontend-plugin-api';
|
||||
import { createApp, createInstances } from './createApp';
|
||||
import { screen } from '@testing-library/react';
|
||||
import { MockConfigApi, renderWithEffects } from '@backstage/test-utils';
|
||||
import React from 'react';
|
||||
import { createRouteRef } from '@backstage/core-plugin-api';
|
||||
|
||||
const extBaseConfig = {
|
||||
id: 'test',
|
||||
@@ -83,14 +83,14 @@ describe('createInstances', () => {
|
||||
const ExtensionA = createPageExtension({
|
||||
id: 'A',
|
||||
defaultPath: '/',
|
||||
routeRef: createRouteRef({ id: 'A.route' }),
|
||||
routeRef: createRouteRef(),
|
||||
loader: async () => <div>Extension A</div>,
|
||||
});
|
||||
|
||||
const ExtensionB = createPageExtension({
|
||||
id: 'B',
|
||||
defaultPath: '/',
|
||||
routeRef: createRouteRef({ id: 'B.route' }),
|
||||
routeRef: createRouteRef(),
|
||||
loader: async () => <div>Extension B</div>,
|
||||
});
|
||||
|
||||
|
||||
@@ -21,6 +21,10 @@ import {
|
||||
coreExtensionData,
|
||||
ExtensionDataRef,
|
||||
ExtensionOverrides,
|
||||
ExternalRouteRef,
|
||||
RouteRef,
|
||||
SubRouteRef,
|
||||
useRouteRef,
|
||||
} from '@backstage/frontend-plugin-api';
|
||||
import { Core } from '../extensions/Core';
|
||||
import { CoreRoutes } from '../extensions/CoreRoutes';
|
||||
@@ -44,11 +48,9 @@ import {
|
||||
ConfigApi,
|
||||
configApiRef,
|
||||
IconComponent,
|
||||
RouteRef,
|
||||
BackstagePlugin as LegacyBackstagePlugin,
|
||||
featureFlagsApiRef,
|
||||
attachComponentData,
|
||||
useRouteRef,
|
||||
identityApiRef,
|
||||
AppTheme,
|
||||
} from '@backstage/core-plugin-api';
|
||||
@@ -57,7 +59,6 @@ import {
|
||||
ApiFactoryRegistry,
|
||||
ApiProvider,
|
||||
ApiResolver,
|
||||
AppRouteBinder,
|
||||
AppThemeSelector,
|
||||
} from '@backstage/core-app-api';
|
||||
|
||||
@@ -98,6 +99,57 @@ import {
|
||||
translationApiRef,
|
||||
} from '@backstage/core-plugin-api/alpha';
|
||||
|
||||
/**
|
||||
* Extracts a union of the keys in a map whose value extends the given type
|
||||
*
|
||||
* @ignore
|
||||
*/
|
||||
type KeysWithType<Obj extends { [key in string]: any }, Type> = {
|
||||
[key in keyof Obj]: Obj[key] extends Type ? key : never;
|
||||
}[keyof Obj];
|
||||
|
||||
/**
|
||||
* Takes a map Map required values and makes all keys matching Keys optional
|
||||
*
|
||||
* @ignore
|
||||
*/
|
||||
type PartialKeys<
|
||||
Map extends { [name in string]: any },
|
||||
Keys extends keyof Map,
|
||||
> = Partial<Pick<Map, Keys>> & Required<Omit<Map, Keys>>;
|
||||
|
||||
/**
|
||||
* Creates a map of target routes with matching parameters based on a map of external routes.
|
||||
*
|
||||
* @ignore
|
||||
*/
|
||||
type TargetRouteMap<
|
||||
ExternalRoutes extends { [name: string]: ExternalRouteRef },
|
||||
> = {
|
||||
[name in keyof ExternalRoutes]: ExternalRoutes[name] extends ExternalRouteRef<
|
||||
infer Params,
|
||||
any
|
||||
>
|
||||
? RouteRef<Params> | SubRouteRef<Params>
|
||||
: never;
|
||||
};
|
||||
|
||||
/**
|
||||
* A function that can bind from external routes of a given plugin, to concrete
|
||||
* routes of other plugins. See {@link createApp}.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type AppRouteBinder = <
|
||||
TExternalRoutes extends { [name: string]: ExternalRouteRef },
|
||||
>(
|
||||
externalRoutes: TExternalRoutes,
|
||||
targetRoutes: PartialKeys<
|
||||
TargetRouteMap<TExternalRoutes>,
|
||||
KeysWithType<TExternalRoutes, ExternalRouteRef<any, true>>
|
||||
>,
|
||||
) => void;
|
||||
|
||||
/** @public */
|
||||
export interface ExtensionTreeNode {
|
||||
id: string;
|
||||
@@ -312,8 +364,9 @@ export function createApp(options: {
|
||||
<AppContextProvider appContext={appContext}>
|
||||
<AppThemeProvider>
|
||||
<RoutingProvider
|
||||
{...extractRouteInfoFromInstanceTree(coreInstance)}
|
||||
routeBindings={resolveRouteBindings(options.bindRoutes)}
|
||||
// TODO(Rugvip): Move over routing app API to new system to avoid these casts
|
||||
{...(extractRouteInfoFromInstanceTree(coreInstance) as any)}
|
||||
routeBindings={resolveRouteBindings(options.bindRoutes as any)}
|
||||
>
|
||||
{/* TODO: set base path using the logic from AppRouter */}
|
||||
<BrowserRouter>
|
||||
|
||||
Reference in New Issue
Block a user