plugin-catalog-import: add NFS page layout and plugin metadata

- Register title and icon on the new-frontend createFrontendPlugin export.
- Add NfsDefaultImportPage using @backstage/ui Header with shared grid body.
- Point the alpha PageBlueprint loader at the NFS variant.
- Depend on @backstage/ui and @remixicon/react.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
This commit is contained in:
Patrik Oldsberg
2026-03-25 16:52:32 +01:00
parent 0e147e8e45
commit fa0593e6e5
6 changed files with 61 additions and 15 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog-import': patch
---
Updated the catalog import plugin for the new frontend system with plugin title and icon metadata, and a page layout that uses Backstage UI header instead of legacy page chrome.
+2
View File
@@ -66,10 +66,12 @@
"@backstage/plugin-catalog-common": "workspace:^",
"@backstage/plugin-catalog-react": "workspace:^",
"@backstage/plugin-permission-react": "workspace:^",
"@backstage/ui": "workspace:^",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.61",
"@octokit/rest": "^19.0.3",
"@remixicon/react": "^4.6.0",
"git-url-parse": "^15.0.0",
"js-base64": "^3.6.0",
"lodash": "^4.17.21",
+6 -2
View File
@@ -14,6 +14,8 @@
* limitations under the License.
*/
import { RiAddCircleLine } from '@remixicon/react';
import {
configApiRef,
discoveryApiRef,
@@ -49,9 +51,9 @@ const catalogImportPage = PageBlueprint.make({
path: '/catalog-import',
routeRef: rootRouteRef,
loader: () =>
import('./components/ImportPage').then(m => (
import('./components/DefaultImportPage').then(m => (
<RequirePermission permission={catalogEntityCreatePermission}>
<m.ImportPage />
<m.NfsDefaultImportPage />
</RequirePermission>
)),
},
@@ -91,6 +93,8 @@ const catalogImportApi = ApiBlueprint.make({
/** @alpha */
export default createFrontendPlugin({
pluginId: 'catalog-import',
title: 'Register Existing Component',
icon: <RiAddCircleLine />,
info: { packageJson: () => import('../package.json') },
extensions: [catalogImportApi, catalogImportPage],
routes: {
@@ -23,6 +23,7 @@ import {
} from '@backstage/core-components';
import { configApiRef, useApi } from '@backstage/core-plugin-api';
import { useTranslationRef } from '@backstage/frontend-plugin-api';
import { Header as BuiHeader } from '@backstage/ui';
import Grid from '@material-ui/core/Grid';
import { useTheme } from '@material-ui/core/styles';
import useMediaQuery from '@material-ui/core/useMediaQuery';
@@ -31,17 +32,9 @@ import { catalogImportTranslationRef } from '../../translation';
import { ImportInfoCard } from '../ImportInfoCard';
import { ImportStepper } from '../ImportStepper';
/**
* The default catalog import page.
*
* @public
*/
export const DefaultImportPage = () => {
const { t } = useTranslationRef(catalogImportTranslationRef);
const DefaultImportPageGrid = () => {
const theme = useTheme();
const configApi = useApi(configApiRef);
const isMobile = useMediaQuery(theme.breakpoints.down('sm'));
const appTitle = configApi.getOptionalString('app.title') || 'Backstage';
const contentItems = [
<Grid key={0} item xs={12} md={4} lg={6} xl={8}>
@@ -53,6 +46,23 @@ export const DefaultImportPage = () => {
</Grid>,
];
return (
<Grid container spacing={2}>
{isMobile ? contentItems : [...contentItems].reverse()}
</Grid>
);
};
/**
* The default catalog import page.
*
* @public
*/
export const DefaultImportPage = () => {
const { t } = useTranslationRef(catalogImportTranslationRef);
const configApi = useApi(configApiRef);
const appTitle = configApi.getOptionalString('app.title') || 'Backstage';
return (
<Page themeId="home">
<Header title={t('defaultImportPage.headerTitle')} />
@@ -65,10 +75,33 @@ export const DefaultImportPage = () => {
</SupportButton>
</ContentHeader>
<Grid container spacing={2}>
{isMobile ? contentItems : contentItems.reverse()}
</Grid>
<DefaultImportPageGrid />
</Content>
</Page>
);
};
/**
* @public
*/
export const NfsDefaultImportPage = () => {
const { t } = useTranslationRef(catalogImportTranslationRef);
const configApi = useApi(configApiRef);
const appTitle = configApi.getOptionalString('app.title') || 'Backstage';
return (
<>
<BuiHeader
title={t('defaultImportPage.contentHeaderTitle', { appTitle })}
customActions={
<SupportButton>
{t('defaultImportPage.supportTitle', { appTitle })}
</SupportButton>
}
/>
<Content>
<DefaultImportPageGrid />
</Content>
</>
);
};
@@ -14,4 +14,4 @@
* limitations under the License.
*/
export { DefaultImportPage } from './DefaultImportPage';
export { DefaultImportPage, NfsDefaultImportPage } from './DefaultImportPage';
+2
View File
@@ -5245,10 +5245,12 @@ __metadata:
"@backstage/plugin-catalog-react": "workspace:^"
"@backstage/plugin-permission-react": "workspace:^"
"@backstage/test-utils": "workspace:^"
"@backstage/ui": "workspace:^"
"@material-ui/core": "npm:^4.12.2"
"@material-ui/icons": "npm:^4.9.1"
"@material-ui/lab": "npm:4.0.0-alpha.61"
"@octokit/rest": "npm:^19.0.3"
"@remixicon/react": "npm:^4.6.0"
"@testing-library/dom": "npm:^10.0.0"
"@testing-library/jest-dom": "npm:^6.0.0"
"@testing-library/react": "npm:^16.0.0"