feat: create core component factories
Signed-off-by: Camila Belo <camilaibs@gmail.com>
This commit is contained in:
@@ -29,6 +29,7 @@ import {
|
||||
createExtension,
|
||||
createApiExtension,
|
||||
createExtensionOverrides,
|
||||
createNotFoundErrorPageExtension,
|
||||
} from '@backstage/frontend-plugin-api';
|
||||
import techdocsPlugin from '@backstage/plugin-techdocs/alpha';
|
||||
import { homePage } from './HomePage';
|
||||
@@ -48,6 +49,8 @@ import {
|
||||
} from '@backstage/integration-react';
|
||||
import { createSignInPageExtension } from '@backstage/frontend-plugin-api';
|
||||
import { SignInPage } from '@backstage/core-components';
|
||||
import { Box, Typography } from '@material-ui/core';
|
||||
import { Button } from '@backstage/core-components';
|
||||
|
||||
/*
|
||||
|
||||
@@ -108,6 +111,40 @@ const scmIntegrationApi = createApiExtension({
|
||||
}),
|
||||
});
|
||||
|
||||
const customNotFoundErrorPage = createNotFoundErrorPageExtension({
|
||||
component: () => (
|
||||
<Box
|
||||
component="article"
|
||||
width="100%"
|
||||
height="100vh"
|
||||
display="grid"
|
||||
textAlign="center"
|
||||
alignContent="center"
|
||||
justifyContent="center"
|
||||
justifyItems="center"
|
||||
>
|
||||
<Typography variant="h1">404</Typography>
|
||||
<Typography color="textSecondary" paragraph style={{ width: 300 }}>
|
||||
Bowie was unable to locate this page. Please contact your support team
|
||||
if this page used to exist.
|
||||
</Typography>
|
||||
<img
|
||||
alt="Backstage bowie"
|
||||
src="https://info.backstage.spotify.com/hs-fs/hubfs/Call%20Bowie%202.png"
|
||||
width="200"
|
||||
style={{ filter: 'grayscale(50%)' }}
|
||||
/>
|
||||
<Button
|
||||
variant="contained"
|
||||
to="/"
|
||||
style={{ marginTop: '1rem', width: 200 }}
|
||||
>
|
||||
Go home
|
||||
</Button>
|
||||
</Box>
|
||||
),
|
||||
});
|
||||
|
||||
const collectedLegacyPlugins = collectLegacyRoutes(
|
||||
<FlatRoutes>
|
||||
<Route path="/catalog-import" element={<CatalogImportPage />} />
|
||||
@@ -129,6 +166,7 @@ const app = createApp({
|
||||
scmAuthExtension,
|
||||
scmIntegrationApi,
|
||||
signInPage,
|
||||
customNotFoundErrorPage,
|
||||
],
|
||||
}),
|
||||
],
|
||||
|
||||
@@ -19,12 +19,36 @@ import {
|
||||
createExtension,
|
||||
coreExtensionData,
|
||||
createExtensionInput,
|
||||
createProgressExtension,
|
||||
createBootErrorPageExtension,
|
||||
createNotFoundErrorPageExtension,
|
||||
createErrorBoundaryFallbackExtension,
|
||||
} from '@backstage/frontend-plugin-api';
|
||||
// eslint-disable-next-line @backstage/no-relative-monorepo-imports
|
||||
import { components as defaultComponents } from '../../../app-defaults/src/defaults';
|
||||
// eslint-disable-next-line @backstage/no-relative-monorepo-imports
|
||||
import { AppContextProvider } from '../../../core-app-api/src/app/AppContext';
|
||||
// eslint-disable-next-line @backstage/no-relative-monorepo-imports
|
||||
import { useApp } from '../../../core-plugin-api/src/app/useApp';
|
||||
|
||||
export const DefaultProgressComponent = createProgressExtension({
|
||||
component: defaultComponents.Progress,
|
||||
});
|
||||
|
||||
export const DefaultBootErrorPageComponent = createBootErrorPageExtension({
|
||||
component: defaultComponents.BootErrorPage,
|
||||
});
|
||||
|
||||
export const DefaultNotFoundErrorPageComponent =
|
||||
createNotFoundErrorPageExtension({
|
||||
component: defaultComponents.NotFoundErrorPage,
|
||||
});
|
||||
|
||||
export const DefaultErrorBoundaryComponent =
|
||||
createErrorBoundaryFallbackExtension({
|
||||
component: defaultComponents.ErrorBoundaryFallback,
|
||||
});
|
||||
|
||||
export const CoreComponents = createExtension({
|
||||
id: 'core.components',
|
||||
attachTo: { id: 'core', input: 'components' },
|
||||
|
||||
@@ -21,6 +21,8 @@ import {
|
||||
createExtensionInput,
|
||||
} from '@backstage/frontend-plugin-api';
|
||||
import { useRoutes } from 'react-router-dom';
|
||||
// eslint-disable-next-line @backstage/no-relative-monorepo-imports
|
||||
import { useApp } from '../../../core-plugin-api/src/app/useApp';
|
||||
|
||||
export const CoreRoutes = createExtension({
|
||||
id: 'core.routes',
|
||||
@@ -37,12 +39,18 @@ export const CoreRoutes = createExtension({
|
||||
},
|
||||
factory({ inputs }) {
|
||||
const Routes = () => {
|
||||
const element = useRoutes(
|
||||
inputs.routes.map(route => ({
|
||||
const app = useApp();
|
||||
const { NotFoundErrorPage } = app.getComponents();
|
||||
const element = useRoutes([
|
||||
...inputs.routes.map(route => ({
|
||||
path: `${route.path}/*`,
|
||||
element: route.element,
|
||||
})),
|
||||
);
|
||||
{
|
||||
path: '*',
|
||||
element: <NotFoundErrorPage />,
|
||||
},
|
||||
]);
|
||||
|
||||
return element;
|
||||
};
|
||||
|
||||
@@ -89,7 +89,13 @@ import { RoutingProvider } from '../routing/RoutingProvider';
|
||||
import { resolveRouteBindings } from '../routing/resolveRouteBindings';
|
||||
import { collectRouteIds } from '../routing/collectRouteIds';
|
||||
import { createAppTree } from '../tree';
|
||||
import { CoreComponents } from '../extensions/CoreComponents';
|
||||
import {
|
||||
CoreComponents,
|
||||
DefaultProgressComponent,
|
||||
DefaultErrorBoundaryComponent,
|
||||
DefaultBootErrorPageComponent,
|
||||
DefaultNotFoundErrorPageComponent,
|
||||
} from '../extensions/CoreComponents';
|
||||
import { AppNode } from '@backstage/frontend-plugin-api';
|
||||
import { toLegacyPlugin } from '../routing/toLegacyPlugin';
|
||||
import { InternalAppContext } from './InternalAppContext';
|
||||
@@ -106,6 +112,10 @@ const builtinExtensions = [
|
||||
CoreNav,
|
||||
CoreLayout,
|
||||
CoreComponents,
|
||||
DefaultProgressComponent,
|
||||
DefaultErrorBoundaryComponent,
|
||||
DefaultBootErrorPageComponent,
|
||||
DefaultNotFoundErrorPageComponent,
|
||||
LightTheme,
|
||||
DarkTheme,
|
||||
];
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 2023 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.
|
||||
*/
|
||||
|
||||
// eslint-disable-next-line @backstage/no-relative-monorepo-imports
|
||||
import { AppComponents } from '../../../core-app-api/src/app/types';
|
||||
import { coreExtensionData, createExtension } from '../wiring';
|
||||
|
||||
/** @public */
|
||||
export function createBootErrorPageExtension(options: {
|
||||
component: AppComponents['BootErrorPage'];
|
||||
}) {
|
||||
return createExtension({
|
||||
id: `core.components.bootErrorPage`,
|
||||
attachTo: { id: 'core.components', input: 'bootErrorPage' },
|
||||
inputs: {},
|
||||
output: {
|
||||
component: coreExtensionData.components.bootErrorPage,
|
||||
},
|
||||
factory({ bind }) {
|
||||
bind({
|
||||
component: options.component,
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export function createNotFoundErrorPageExtension(options: {
|
||||
component: AppComponents['NotFoundErrorPage'];
|
||||
}) {
|
||||
return createExtension({
|
||||
id: `core.components.notFoundErrorPage`,
|
||||
attachTo: { id: 'core.components', input: 'notFoundErrorPage' },
|
||||
inputs: {},
|
||||
output: {
|
||||
component: coreExtensionData.components.notFoundErrorPage,
|
||||
},
|
||||
factory({ bind }) {
|
||||
bind({
|
||||
component: options.component,
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export function createErrorBoundaryFallbackExtension(options: {
|
||||
component: AppComponents['ErrorBoundaryFallback'];
|
||||
}) {
|
||||
return createExtension({
|
||||
id: `core.components.errorBoundaryFallback`,
|
||||
attachTo: { id: 'core.components', input: 'errorBoundaryFallback' },
|
||||
inputs: {},
|
||||
output: {
|
||||
component: coreExtensionData.components.errorBoundaryFallback,
|
||||
},
|
||||
factory({ bind }) {
|
||||
bind({
|
||||
component: options.component,
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export function createProgressExtension(options: {
|
||||
component: AppComponents['Progress'];
|
||||
}) {
|
||||
return createExtension({
|
||||
id: `core.components.progress`,
|
||||
attachTo: { id: 'core.components', input: 'progress' },
|
||||
inputs: {},
|
||||
output: {
|
||||
component: coreExtensionData.components.progress,
|
||||
},
|
||||
factory({ bind }) {
|
||||
bind({
|
||||
component: options.component,
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -19,3 +19,9 @@ export { createPageExtension } from './createPageExtension';
|
||||
export { createNavItemExtension } from './createNavItemExtension';
|
||||
export { createSignInPageExtension } from './createSignInPageExtension';
|
||||
export { createThemeExtension } from './createThemeExtension';
|
||||
export {
|
||||
createProgressExtension,
|
||||
createBootErrorPageExtension,
|
||||
createNotFoundErrorPageExtension,
|
||||
createErrorBoundaryFallbackExtension,
|
||||
} from './createComponentExtension';
|
||||
|
||||
Reference in New Issue
Block a user