@@ -20,7 +20,6 @@ import { pagesPlugin } from './examples/pagesPlugin';
|
||||
import notFoundErrorPage from './examples/notFoundErrorPageExtension';
|
||||
import userSettingsPlugin from '@backstage/plugin-user-settings/alpha';
|
||||
import homePlugin, {
|
||||
extensions,
|
||||
titleExtensionDataRef,
|
||||
} from '@backstage/plugin-home/alpha';
|
||||
|
||||
@@ -75,48 +74,15 @@ TODO:
|
||||
|
||||
/* app.tsx */
|
||||
|
||||
// const homePageExtension = createExtension({
|
||||
// name: 'myhomepage',
|
||||
// attachTo: { id: 'page:home', input: 'props' },
|
||||
// output: {
|
||||
// children: coreExtensionData.reactElement,
|
||||
// title: titleExtensionDataRef,
|
||||
// },
|
||||
// factory() {
|
||||
// return { children: homePage, title: 'just a title' };
|
||||
// },
|
||||
// });
|
||||
|
||||
// const homePage = createPageExtension({
|
||||
// defaultPath: '/home',
|
||||
// routeRef: rootRouteRef,
|
||||
// inputs: {
|
||||
// props: createExtensionInput(
|
||||
// {
|
||||
// children: coreExtensionData.reactElement.optional(),
|
||||
// title: titleExtensionDataRef.optional(),
|
||||
// },
|
||||
|
||||
// {
|
||||
// singleton: true,
|
||||
// optional: true,
|
||||
// },
|
||||
// ),
|
||||
// },
|
||||
// loader: ({ inputs }) =>
|
||||
// import('./components/').then(m =>
|
||||
// compatWrapper(
|
||||
// <m.HomepageCompositionRoot
|
||||
// children={inputs.props?.output.children}
|
||||
// title={inputs.props?.output.title}
|
||||
// />,
|
||||
// ),
|
||||
// ),
|
||||
// });
|
||||
|
||||
const homePageExtension = extensions.homePage.override({
|
||||
factory(origi) {
|
||||
return origi();
|
||||
const homePageExtension = createExtension({
|
||||
name: 'myhomepage',
|
||||
attachTo: { id: 'page:home', input: 'props' },
|
||||
output: {
|
||||
children: coreExtensionData.reactElement,
|
||||
title: titleExtensionDataRef,
|
||||
},
|
||||
factory() {
|
||||
return { children: homePage, title: 'just a title' };
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -23,8 +23,6 @@ import {
|
||||
ResolvedExtensionInputs,
|
||||
AnyExtensionInputMap,
|
||||
createExtensionBlueprint,
|
||||
ExtensionInput,
|
||||
AnyExtensionDataRef,
|
||||
} from '../wiring';
|
||||
import { RouteRef } from '../routing';
|
||||
import { Expand } from '../types';
|
||||
@@ -99,79 +97,6 @@ export function createPageExtension<
|
||||
});
|
||||
}
|
||||
|
||||
export function createNewPageExtension<
|
||||
TConfig extends { path: string },
|
||||
TInputs extends {
|
||||
[inputName in string]: ExtensionInput<
|
||||
AnyExtensionDataRef,
|
||||
{ optional: boolean; singleton: boolean }
|
||||
>;
|
||||
},
|
||||
>(
|
||||
options: (
|
||||
| {
|
||||
defaultPath: string;
|
||||
}
|
||||
| {
|
||||
configSchema: PortableSchema<TConfig>;
|
||||
}
|
||||
) & {
|
||||
namespace?: string;
|
||||
name?: string;
|
||||
attachTo?: { id: string; input: string };
|
||||
disabled?: boolean;
|
||||
inputs?: TInputs;
|
||||
routeRef?: RouteRef;
|
||||
loader: (options: {
|
||||
config: TConfig;
|
||||
inputs: Expand<ResolvedExtensionInputs<TInputs>>;
|
||||
}) => Promise<JSX.Element>;
|
||||
},
|
||||
) {
|
||||
const configSchema =
|
||||
'configSchema' in options
|
||||
? options.configSchema
|
||||
: (createSchemaFromZod(z =>
|
||||
z.object({ path: z.string().default(options.defaultPath) }),
|
||||
) as PortableSchema<TConfig>);
|
||||
|
||||
return createExtension({
|
||||
kind: 'page',
|
||||
namespace: options.namespace,
|
||||
name: options.name,
|
||||
attachTo: options.attachTo ?? { id: 'app/routes', input: 'routes' },
|
||||
configSchema,
|
||||
inputs: options.inputs,
|
||||
disabled: options.disabled,
|
||||
output: [
|
||||
coreExtensionData.routePath,
|
||||
coreExtensionData.reactElement,
|
||||
coreExtensionData.routeRef.optional(),
|
||||
],
|
||||
factory({ config, inputs, node }) {
|
||||
const ExtensionComponent = lazy(() =>
|
||||
options
|
||||
.loader({ config, inputs })
|
||||
.then(element => ({ default: () => element })),
|
||||
);
|
||||
|
||||
const outputs = [
|
||||
coreExtensionData.routePath(config.path),
|
||||
coreExtensionData.reactElement(
|
||||
<ExtensionBoundary node={node}>
|
||||
<ExtensionComponent />
|
||||
</ExtensionBoundary>,
|
||||
),
|
||||
];
|
||||
|
||||
if (options.routeRef) {
|
||||
return [...outputs, coreExtensionData.routeRef(options.routeRef)];
|
||||
}
|
||||
|
||||
return outputs;
|
||||
},
|
||||
});
|
||||
}
|
||||
/**
|
||||
* A blueprint for creating extensions for routable React page components.
|
||||
* @public
|
||||
@@ -208,7 +133,8 @@ export const PageExtensionBlueprint = createExtensionBlueprint({
|
||||
loader({ config, inputs }).then(element => ({ default: () => element })),
|
||||
);
|
||||
|
||||
// TODO(blam): this is a little awkward for optional returns. I wonder if we should be using generators or yield instead
|
||||
// TODO(blam): this is a little awkward for optional returns.
|
||||
// I wonder if we should be using generators or yield instead
|
||||
// for a better API here.
|
||||
const outputs = [
|
||||
coreExtensionData.routePath(config.path ?? defaultPath!),
|
||||
|
||||
@@ -25,10 +25,6 @@ import {
|
||||
createRouteRef,
|
||||
} from '@backstage/frontend-plugin-api';
|
||||
import { compatWrapper } from '@backstage/core-compat-api';
|
||||
import {
|
||||
PageExtensionBlueprint,
|
||||
createNewPageExtension,
|
||||
} from '@backstage/frontend-plugin-api/src/extensions/createPageExtension';
|
||||
|
||||
const rootRouteRef = createRouteRef();
|
||||
|
||||
@@ -39,15 +35,15 @@ export const titleExtensionDataRef = createExtensionDataRef<string>().with({
|
||||
id: 'title',
|
||||
});
|
||||
|
||||
const homePage = createNewPageExtension({
|
||||
const homePage = createPageExtension({
|
||||
defaultPath: '/home',
|
||||
routeRef: rootRouteRef,
|
||||
inputs: {
|
||||
props: createExtensionInput(
|
||||
[
|
||||
coreExtensionData.reactElement.optional(),
|
||||
titleExtensionDataRef.optional(),
|
||||
],
|
||||
{
|
||||
children: coreExtensionData.reactElement.optional(),
|
||||
title: titleExtensionDataRef.optional(),
|
||||
},
|
||||
|
||||
{
|
||||
singleton: true,
|
||||
@@ -59,49 +55,13 @@ const homePage = createNewPageExtension({
|
||||
import('./components/').then(m =>
|
||||
compatWrapper(
|
||||
<m.HomepageCompositionRoot
|
||||
children={inputs.props?.get(coreExtensionData.reactElement)}
|
||||
title={inputs.props?.get(titleExtensionDataRef)}
|
||||
children={inputs.props?.output.children}
|
||||
title={inputs.props?.output.title}
|
||||
/>,
|
||||
),
|
||||
),
|
||||
});
|
||||
|
||||
// const homePage2 = PageExtensionBlueprint.make({
|
||||
// inputs: {
|
||||
// props: createExtensionInput(
|
||||
// [
|
||||
// coreExtensionData.reactElement.optional(),
|
||||
// titleExtensionDataRef.optional(),
|
||||
// ],
|
||||
// {
|
||||
// singleton: true,
|
||||
// optional: true,
|
||||
// },
|
||||
// ),
|
||||
// },
|
||||
// factory(origFactory, { config, inputs, node }) {
|
||||
// return origFactory({
|
||||
// defaultPath: '/home',
|
||||
// routeRef: rootRouteRef,
|
||||
// loader: () =>
|
||||
// import('./components/').then(m =>
|
||||
// compatWrapper(
|
||||
// <m.HomepageCompositionRoot
|
||||
// children={inputs.props?.[0].get(coreExtensionData.reactElement)}
|
||||
// title={inputs.props?.[0].get(coreExtensionData.reactElement}
|
||||
// />,
|
||||
// ),
|
||||
// },
|
||||
// });
|
||||
|
||||
/**
|
||||
* @alpha
|
||||
* This will not be the way to export extensions eventually,
|
||||
* will be something like `homePlugin.extensions.homePage` or `homePlugin.extensions.get('page')`
|
||||
* Just haven't worked out a nice way to fix the types yet
|
||||
*/
|
||||
export const extensions = { homePage };
|
||||
|
||||
/**
|
||||
* @alpha
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user