frontend-plugin-api: simplify deprecation of AppRootWrapperBlueprint
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
@@ -1,138 +0,0 @@
|
||||
/*
|
||||
* Copyright 2024 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { Fragment } from 'react';
|
||||
import { AppRootWrapperBlueprint } from './AppRootWrapperBlueprint';
|
||||
import { screen, waitFor } from '@testing-library/react';
|
||||
import {
|
||||
coreExtensionData,
|
||||
createExtension,
|
||||
createExtensionInput,
|
||||
createFrontendModule,
|
||||
} from '@backstage/frontend-plugin-api';
|
||||
import { renderTestApp } from '@backstage/frontend-test-utils';
|
||||
|
||||
describe('AppRootWrapperBlueprint', () => {
|
||||
it('should return an extension with sensible defaults', () => {
|
||||
const extension = AppRootWrapperBlueprint.make({
|
||||
params: {
|
||||
component: () => <div>Hello</div>,
|
||||
},
|
||||
});
|
||||
|
||||
expect(extension).toMatchInlineSnapshot(`
|
||||
{
|
||||
"$$type": "@backstage/ExtensionDefinition",
|
||||
"T": undefined,
|
||||
"attachTo": {
|
||||
"id": "app/root",
|
||||
"input": "wrappers",
|
||||
},
|
||||
"configSchema": undefined,
|
||||
"disabled": false,
|
||||
"factory": [Function],
|
||||
"inputs": {},
|
||||
"kind": "app-root-wrapper",
|
||||
"name": undefined,
|
||||
"output": [
|
||||
[Function],
|
||||
],
|
||||
"override": [Function],
|
||||
"toString": [Function],
|
||||
"version": "v2",
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
it('should render a simple component wrapper', async () => {
|
||||
const extension = AppRootWrapperBlueprint.make({
|
||||
name: 'test',
|
||||
params: {
|
||||
component: () => <div>Hello</div>,
|
||||
},
|
||||
});
|
||||
|
||||
renderTestApp({
|
||||
features: [
|
||||
createFrontendModule({
|
||||
pluginId: 'app',
|
||||
extensions: [extension],
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
await waitFor(() => expect(screen.getByText('Hello')).toBeInTheDocument());
|
||||
});
|
||||
|
||||
it('should render a complex component wrapper', async () => {
|
||||
const extension = AppRootWrapperBlueprint.makeWithOverrides({
|
||||
config: {
|
||||
schema: {
|
||||
name: z => z.string(),
|
||||
},
|
||||
},
|
||||
inputs: {
|
||||
children: createExtensionInput([coreExtensionData.reactElement]),
|
||||
},
|
||||
*factory(originalFactory, { inputs, config }) {
|
||||
yield* originalFactory({
|
||||
component: ({ children }) => (
|
||||
<div data-testid={`${config.name}-${inputs.children.length}`}>
|
||||
{inputs.children.flatMap((c, index) => (
|
||||
<Fragment key={index}>
|
||||
{c.get(coreExtensionData.reactElement)}
|
||||
</Fragment>
|
||||
))}
|
||||
{children}
|
||||
</div>
|
||||
),
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
renderTestApp({
|
||||
features: [
|
||||
createFrontendModule({
|
||||
pluginId: 'app',
|
||||
extensions: [
|
||||
extension,
|
||||
createExtension({
|
||||
name: 'test-child',
|
||||
attachTo: extension.inputs.children,
|
||||
output: [coreExtensionData.reactElement],
|
||||
factory: () => [
|
||||
coreExtensionData.reactElement(<div>Its Me</div>),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
config: {
|
||||
app: {
|
||||
extensions: [
|
||||
{
|
||||
'app-root-wrapper:app': { config: { name: 'Robin' } },
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId('Robin-1')).toBeInTheDocument();
|
||||
expect(screen.getByText('Its Me')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright 2024 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ComponentType, ReactNode } from 'react';
|
||||
import {
|
||||
createExtensionBlueprint,
|
||||
createExtensionDataRef,
|
||||
} from '@backstage/frontend-plugin-api';
|
||||
|
||||
const componentDataRef = createExtensionDataRef<
|
||||
ComponentType<{ children: ReactNode }>
|
||||
>().with({ id: 'app.root-wrapper-component' });
|
||||
|
||||
/**
|
||||
* Creates an extension that renders a React wrapper at the app root, enclosing
|
||||
* the app layout.
|
||||
*
|
||||
* @remarks
|
||||
*
|
||||
* This is useful for example for adding global React contexts and similar. This
|
||||
* extension is only available for use by app modules, plugins should use the
|
||||
* {@link @backstage/frontend-plugin-api#PluginWrapperBlueprint} instead.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const AppRootWrapperBlueprint = createExtensionBlueprint({
|
||||
kind: 'app-root-wrapper',
|
||||
attachTo: { id: 'app/root', input: 'wrappers' },
|
||||
output: [componentDataRef],
|
||||
dataRefs: {
|
||||
component: componentDataRef,
|
||||
},
|
||||
*factory(params: {
|
||||
component: (props: { children: ReactNode }) => JSX.Element | null;
|
||||
}) {
|
||||
yield componentDataRef(params.component);
|
||||
},
|
||||
});
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
import {
|
||||
AppRootWrapperBlueprint as _AppRootWrapperBlueprint,
|
||||
IconBundleBlueprint as _IconBundleBlueprint,
|
||||
NavContentBlueprint as _NavContentBlueprint,
|
||||
type NavContentComponent,
|
||||
@@ -27,7 +28,13 @@ import {
|
||||
TranslationBlueprint as _TranslationBlueprint,
|
||||
} from '@backstage/frontend-plugin-api';
|
||||
|
||||
export { AppRootWrapperBlueprint } from './AppRootWrapperBlueprint';
|
||||
/**
|
||||
* Creates an extension that renders a React wrapper at the app root, enclosing
|
||||
* the app layout. This blueprint is limited to use by the app plugin.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const AppRootWrapperBlueprint = _AppRootWrapperBlueprint;
|
||||
|
||||
/**
|
||||
* Creates an extension that adds/replaces an app theme. This blueprint is limited to use by the app plugin.
|
||||
|
||||
Reference in New Issue
Block a user