Implement customization with an API instead of context
Signed-off-by: Oliver Sand <oliver.sand@sda-se.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-import': patch
|
||||
'@backstage/plugin-catalog-import': minor
|
||||
---
|
||||
|
||||
Add initial support for customizing the catalog import page.
|
||||
@@ -33,3 +33,13 @@ is used.
|
||||
</Page>
|
||||
</Route>
|
||||
```
|
||||
|
||||
Previously it was possible to disable and customize the automatic pull request
|
||||
feature by passing options to `<CatalogImportPage>` (`pullRequest.disable` and
|
||||
`pullRequest.preparePullRequest`). This functionality is moved to the
|
||||
`CatalogImportApi` which now provides an optional `preparePullRequest()`
|
||||
function. The function can either be overridden to generate a different content
|
||||
for the pull request, or removed to disable this feature.
|
||||
|
||||
The export of the long term deprecated legacy `<Router>` is removed, migrate to
|
||||
`<CatalogImportPage>` instead.
|
||||
|
||||
@@ -9,7 +9,6 @@ import { ApiRef } from '@backstage/core-plugin-api';
|
||||
import { BackstagePlugin } from '@backstage/core-plugin-api';
|
||||
import { CatalogApi } from '@backstage/catalog-client';
|
||||
import { ConfigApi } from '@backstage/core-plugin-api';
|
||||
import { Context } from 'react';
|
||||
import { Controller } from 'react-hook-form';
|
||||
import { DiscoveryApi } from '@backstage/core-plugin-api';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
@@ -69,6 +68,11 @@ export interface CatalogImportApi {
|
||||
// (undocumented)
|
||||
analyzeUrl(url: string): Promise<AnalyzeResult>;
|
||||
// (undocumented)
|
||||
preparePullRequest?(): {
|
||||
title: string;
|
||||
body: string;
|
||||
};
|
||||
// (undocumented)
|
||||
submitPullRequest(options: {
|
||||
repositoryUrl: string;
|
||||
fileContent: string;
|
||||
@@ -95,10 +99,16 @@ export class CatalogImportClient implements CatalogImportApi {
|
||||
identityApi: IdentityApi;
|
||||
scmIntegrationsApi: ScmIntegrationRegistry;
|
||||
catalogApi: CatalogApi;
|
||||
configApi: ConfigApi;
|
||||
});
|
||||
// (undocumented)
|
||||
analyzeUrl(url: string): Promise<AnalyzeResult>;
|
||||
// (undocumented)
|
||||
preparePullRequest(): {
|
||||
title: string;
|
||||
body: string;
|
||||
};
|
||||
// (undocumented)
|
||||
submitPullRequest({
|
||||
repositoryUrl,
|
||||
fileContent,
|
||||
@@ -115,11 +125,10 @@ export class CatalogImportClient implements CatalogImportApi {
|
||||
}>;
|
||||
}
|
||||
|
||||
// Warning: (ae-forgotten-export) The symbol "ImportOptions" needs to be exported by the entry point index.d.ts
|
||||
// Warning: (ae-missing-release-tag) "CatalogImportPage" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
// @public (undocumented)
|
||||
export const CatalogImportPage: (opts: ImportOptions) => JSX.Element;
|
||||
export const CatalogImportPage: () => JSX.Element;
|
||||
|
||||
// Warning: (ae-missing-release-tag) "catalogImportPlugin" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
@@ -168,11 +177,6 @@ export const EntityListComponent: ({
|
||||
// @public (undocumented)
|
||||
export const ImportInfoCard: () => JSX.Element;
|
||||
|
||||
// Warning: (ae-missing-release-tag) "ImportOptionsContext" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
// @public (undocumented)
|
||||
export const ImportOptionsContext: Context<ImportOptions>;
|
||||
|
||||
// Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts
|
||||
// Warning: (ae-missing-release-tag) "ImportStepper" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
@@ -218,11 +222,6 @@ export const PreviewPullRequestComponent: ({
|
||||
classes,
|
||||
}: Props_7) => JSX.Element;
|
||||
|
||||
// Warning: (ae-missing-release-tag) "Router" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
// @public (undocumented)
|
||||
export const Router: (opts: ImportOptions) => JSX.Element;
|
||||
|
||||
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
|
||||
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
|
||||
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
|
||||
@@ -249,11 +248,6 @@ export const StepPrepareCreatePullRequest: ({
|
||||
defaultBody,
|
||||
}: Props_8) => JSX.Element;
|
||||
|
||||
// Warning: (ae-missing-release-tag) "useImportOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
// @public (undocumented)
|
||||
export const useImportOptions: () => ImportOptions;
|
||||
|
||||
// Warnings were encountered during analysis:
|
||||
//
|
||||
// src/api/CatalogImportApi.d.ts:14:5 - (ae-forgotten-export) The symbol "PartialEntity" needs to be exported by the entry point index.d.ts
|
||||
|
||||
@@ -42,6 +42,10 @@ export type AnalyzeResult =
|
||||
export interface CatalogImportApi {
|
||||
analyzeUrl(url: string): Promise<AnalyzeResult>;
|
||||
|
||||
preparePullRequest?(): {
|
||||
title: string;
|
||||
body: string;
|
||||
};
|
||||
submitPullRequest(options: {
|
||||
repositoryUrl: string;
|
||||
fileContent: string;
|
||||
|
||||
@@ -115,6 +115,7 @@ describe('CatalogImportClient', () => {
|
||||
scmIntegrationsApi,
|
||||
identityApi,
|
||||
catalogApi,
|
||||
configApi: new ConfigReader({}),
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
import { CatalogApi } from '@backstage/catalog-client';
|
||||
import { EntityName } from '@backstage/catalog-model';
|
||||
import {
|
||||
ConfigApi,
|
||||
DiscoveryApi,
|
||||
IdentityApi,
|
||||
OAuthApi,
|
||||
@@ -37,6 +38,7 @@ export class CatalogImportClient implements CatalogImportApi {
|
||||
private readonly githubAuthApi: OAuthApi;
|
||||
private readonly scmIntegrationsApi: ScmIntegrationRegistry;
|
||||
private readonly catalogApi: CatalogApi;
|
||||
private readonly configApi: ConfigApi;
|
||||
|
||||
constructor(options: {
|
||||
discoveryApi: DiscoveryApi;
|
||||
@@ -44,12 +46,14 @@ export class CatalogImportClient implements CatalogImportApi {
|
||||
identityApi: IdentityApi;
|
||||
scmIntegrationsApi: ScmIntegrationRegistry;
|
||||
catalogApi: CatalogApi;
|
||||
configApi: ConfigApi;
|
||||
}) {
|
||||
this.discoveryApi = options.discoveryApi;
|
||||
this.githubAuthApi = options.githubAuthApi;
|
||||
this.identityApi = options.identityApi;
|
||||
this.scmIntegrationsApi = options.scmIntegrationsApi;
|
||||
this.catalogApi = options.catalogApi;
|
||||
this.configApi = options.configApi;
|
||||
}
|
||||
|
||||
async analyzeUrl(url: string): Promise<AnalyzeResult> {
|
||||
@@ -114,6 +118,24 @@ export class CatalogImportClient implements CatalogImportApi {
|
||||
};
|
||||
}
|
||||
|
||||
preparePullRequest(): {
|
||||
title: string;
|
||||
body: string;
|
||||
} {
|
||||
const appTitle =
|
||||
this.configApi.getOptionalString('app.title') ?? 'Backstage';
|
||||
const appBaseUrl = this.configApi.getString('app.baseUrl');
|
||||
|
||||
return {
|
||||
title: 'Add catalog-info.yaml config file',
|
||||
body: `This pull request adds a **Backstage entity metadata file** \
|
||||
to this repository so that the component can be added to the \
|
||||
[${appTitle} software catalog](${appBaseUrl}).\n\nAfter this pull request is merged, \
|
||||
the component will become available.\n\nFor more information, read an \
|
||||
[overview of the Backstage software catalog](https://backstage.io/docs/features/software-catalog/software-catalog-overview).`,
|
||||
};
|
||||
}
|
||||
|
||||
async submitPullRequest({
|
||||
repositoryUrl,
|
||||
fileContent,
|
||||
|
||||
@@ -62,6 +62,7 @@ describe('<DefaultImportPage />', () => {
|
||||
identityApi,
|
||||
scmIntegrationsApi: {} as any,
|
||||
catalogApi: {} as any,
|
||||
configApi: {} as any,
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
@@ -23,19 +23,35 @@ import { configApiRef } from '@backstage/core-plugin-api';
|
||||
import { wrapInTestApp } from '@backstage/test-utils';
|
||||
import { act, render } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { CatalogImportApi, catalogImportApiRef } from '../../api';
|
||||
import { ImportInfoCard } from './ImportInfoCard';
|
||||
|
||||
describe('<ImportInfoCard />', () => {
|
||||
let apis: ApiRegistry;
|
||||
let catalogImportApi: jest.Mocked<CatalogImportApi>;
|
||||
|
||||
beforeEach(() => {
|
||||
catalogImportApi = {
|
||||
analyzeUrl: jest.fn(),
|
||||
submitPullRequest: jest.fn(),
|
||||
};
|
||||
|
||||
apis = ApiRegistry.with(
|
||||
configApiRef,
|
||||
new ConfigReader({ integrations: {} }),
|
||||
);
|
||||
new ConfigReader({
|
||||
integrations: {
|
||||
github: [{ token: 'my-token' }],
|
||||
},
|
||||
}),
|
||||
).with(catalogImportApiRef, catalogImportApi);
|
||||
});
|
||||
|
||||
it('renders without exploding', async () => {
|
||||
apis = ApiRegistry.with(
|
||||
configApiRef,
|
||||
new ConfigReader({ integrations: {} }),
|
||||
).with(catalogImportApiRef, catalogImportApi);
|
||||
|
||||
await act(async () => {
|
||||
const { getByText } = render(
|
||||
wrapInTestApp(
|
||||
@@ -48,4 +64,38 @@ describe('<ImportInfoCard />', () => {
|
||||
expect(getByText('Register an existing component')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
it('renders section on GitHub discovery if supported', async () => {
|
||||
catalogImportApi.preparePullRequest = () => ({ title: '', body: '' });
|
||||
|
||||
await act(async () => {
|
||||
const { getByText } = render(
|
||||
wrapInTestApp(
|
||||
<ApiProvider apis={apis}>
|
||||
<ImportInfoCard />
|
||||
</ApiProvider>,
|
||||
),
|
||||
);
|
||||
|
||||
expect(getByText(/The wizard discovers all/)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
it('renders section on pull requests if supported', async () => {
|
||||
catalogImportApi.preparePullRequest = () => ({ title: '', body: '' });
|
||||
|
||||
await act(async () => {
|
||||
const { getByText } = render(
|
||||
wrapInTestApp(
|
||||
<ApiProvider apis={apis}>
|
||||
<ImportInfoCard />
|
||||
</ApiProvider>,
|
||||
),
|
||||
);
|
||||
|
||||
expect(
|
||||
getByText(/the wizard will prepare a Pull Request/),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -18,12 +18,12 @@ import { InfoCard } from '@backstage/core-components';
|
||||
import { configApiRef, useApi } from '@backstage/core-plugin-api';
|
||||
import { Chip, Typography } from '@material-ui/core';
|
||||
import React from 'react';
|
||||
import { useImportOptions } from '../ImportOptionsContext';
|
||||
import { catalogImportApiRef } from '../../api';
|
||||
|
||||
export const ImportInfoCard = () => {
|
||||
const configApi = useApi(configApiRef);
|
||||
const appTitle = configApi.getOptional('app.title') || 'Backstage';
|
||||
const opts = useImportOptions();
|
||||
const catalogImportApi = useApi(catalogImportApiRef);
|
||||
|
||||
const integrations = configApi.getConfig('integrations');
|
||||
const hasGithubIntegration = integrations.has('github');
|
||||
@@ -33,8 +33,7 @@ export const ImportInfoCard = () => {
|
||||
title="Register an existing component"
|
||||
deepLink={{
|
||||
title: 'Learn more about the Software Catalog',
|
||||
link:
|
||||
'https://backstage.io/docs/features/software-catalog/software-catalog-overview',
|
||||
link: 'https://backstage.io/docs/features/software-catalog/software-catalog-overview',
|
||||
}}
|
||||
>
|
||||
<Typography variant="body2" paragraph>
|
||||
@@ -65,7 +64,7 @@ export const ImportInfoCard = () => {
|
||||
repository, previews the entities, and adds them to the {appTitle}{' '}
|
||||
catalog.
|
||||
</Typography>
|
||||
{!opts?.pullRequest?.disable && (
|
||||
{catalogImportApi.preparePullRequest && (
|
||||
<Typography variant="body2" paragraph>
|
||||
If no entities are found, the wizard will prepare a Pull Request
|
||||
that adds an example <code>catalog-info.yaml</code> and prepares
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
* Copyright 2021 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 { createContext, useContext } from 'react';
|
||||
import { ImportOptions } from '../types';
|
||||
|
||||
export const ImportOptionsContext = createContext<ImportOptions>({});
|
||||
|
||||
export const useImportOptions = (): ImportOptions => {
|
||||
return useContext(ImportOptionsContext);
|
||||
};
|
||||
@@ -1,17 +0,0 @@
|
||||
/*
|
||||
* Copyright 2021 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.
|
||||
*/
|
||||
|
||||
export { ImportOptionsContext, useImportOptions } from './ImportOptionsContext';
|
||||
@@ -25,9 +25,15 @@ import { catalogApiRef } from '@backstage/plugin-catalog-react';
|
||||
import { wrapInTestApp } from '@backstage/test-utils';
|
||||
import { act, render } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { useOutlet } from 'react-router';
|
||||
import { catalogImportApiRef, CatalogImportClient } from '../../api';
|
||||
import { ImportPage } from './ImportPage';
|
||||
|
||||
jest.mock('react-router', () => ({
|
||||
...jest.requireActual('react-router'),
|
||||
useOutlet: jest.fn(),
|
||||
}));
|
||||
|
||||
describe('<ImportPage />', () => {
|
||||
const identityApi = {
|
||||
getUserId: () => {
|
||||
@@ -62,10 +68,13 @@ describe('<ImportPage />', () => {
|
||||
identityApi,
|
||||
scmIntegrationsApi: {} as any,
|
||||
catalogApi: {} as any,
|
||||
configApi: new ConfigReader({}),
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
afterEach(() => jest.resetAllMocks());
|
||||
|
||||
it('renders without exploding', async () => {
|
||||
await act(async () => {
|
||||
const { getByText } = render(
|
||||
@@ -81,4 +90,20 @@ describe('<ImportPage />', () => {
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
it('renders with custom children', async () => {
|
||||
(useOutlet as jest.Mock).mockReturnValue(<div>Hello World</div>);
|
||||
|
||||
await act(async () => {
|
||||
const { getByText } = render(
|
||||
wrapInTestApp(
|
||||
<ApiProvider apis={apis}>
|
||||
<ImportPage />
|
||||
</ApiProvider>,
|
||||
),
|
||||
);
|
||||
|
||||
expect(getByText('Hello World')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -17,15 +17,9 @@
|
||||
import React from 'react';
|
||||
import { useOutlet } from 'react-router';
|
||||
import { DefaultImportPage } from '../DefaultImportPage';
|
||||
import { ImportOptionsContext } from '../ImportOptionsContext';
|
||||
import { ImportOptions } from '../types';
|
||||
|
||||
export const ImportPage = (opts: ImportOptions) => {
|
||||
export const ImportPage = () => {
|
||||
const outlet = useOutlet();
|
||||
|
||||
return (
|
||||
<ImportOptionsContext.Provider value={opts}>
|
||||
{outlet || <DefaultImportPage />}
|
||||
</ImportOptionsContext.Provider>
|
||||
);
|
||||
return outlet || <DefaultImportPage />;
|
||||
};
|
||||
|
||||
@@ -14,11 +14,12 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { InfoCard, InfoCardVariants } from '@backstage/core-components';
|
||||
import { useApi } from '@backstage/core-plugin-api';
|
||||
import { Step, StepContent, Stepper } from '@material-ui/core';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import React, { useMemo } from 'react';
|
||||
import { useImportOptions } from '../ImportOptionsContext';
|
||||
import { ImportOptions } from '../types';
|
||||
import { catalogImportApiRef } from '../../api';
|
||||
import { ImportFlows, ImportState, useImportState } from '../useImportState';
|
||||
import {
|
||||
defaultGenerateStepper,
|
||||
@@ -27,9 +28,6 @@ import {
|
||||
StepperProvider,
|
||||
} from './defaults';
|
||||
|
||||
import { configApiRef, useApi } from '@backstage/core-plugin-api';
|
||||
import { InfoCard, InfoCardVariants } from '@backstage/core-components';
|
||||
|
||||
const useStyles = makeStyles(() => ({
|
||||
stepperRoot: {
|
||||
padding: 0,
|
||||
@@ -43,8 +41,6 @@ type Props = {
|
||||
defaults: StepperProvider,
|
||||
) => StepperProvider;
|
||||
variant?: InfoCardVariants;
|
||||
/// @deprecated Pass import options via ImportOptionsContext instead.
|
||||
opts?: ImportOptions;
|
||||
};
|
||||
|
||||
export const ImportStepper = ({
|
||||
@@ -52,10 +48,9 @@ export const ImportStepper = ({
|
||||
generateStepper = defaultGenerateStepper,
|
||||
variant,
|
||||
}: Props) => {
|
||||
const configApi = useApi(configApiRef);
|
||||
const catalogImportApi = useApi(catalogImportApiRef);
|
||||
const classes = useStyles();
|
||||
const state = useImportState({ initialUrl });
|
||||
const opts = useImportOptions();
|
||||
|
||||
const states = useMemo<StepperProvider>(
|
||||
() => generateStepper(state.activeFlow, defaultStepper),
|
||||
@@ -81,25 +76,25 @@ export const ImportStepper = ({
|
||||
{render(
|
||||
states.analyze(
|
||||
state as Extract<ImportState, { activeState: 'analyze' }>,
|
||||
{ apis: { configApi }, opts },
|
||||
{ apis: { catalogImportApi } },
|
||||
),
|
||||
)}
|
||||
{render(
|
||||
states.prepare(
|
||||
state as Extract<ImportState, { activeState: 'prepare' }>,
|
||||
{ apis: { configApi }, opts },
|
||||
{ apis: { catalogImportApi } },
|
||||
),
|
||||
)}
|
||||
{render(
|
||||
states.review(
|
||||
state as Extract<ImportState, { activeState: 'review' }>,
|
||||
{ apis: { configApi }, opts },
|
||||
{ apis: { catalogImportApi } },
|
||||
),
|
||||
)}
|
||||
{render(
|
||||
states.finish(
|
||||
state as Extract<ImportState, { activeState: 'finish' }>,
|
||||
{ apis: { configApi }, opts },
|
||||
{ apis: { catalogImportApi } },
|
||||
),
|
||||
)}
|
||||
</Stepper>
|
||||
|
||||
@@ -34,7 +34,7 @@ import {
|
||||
} from '../StepPrepareCreatePullRequest';
|
||||
import { StepPrepareSelectLocations } from '../StepPrepareSelectLocations';
|
||||
import { StepReviewLocation } from '../StepReviewLocation';
|
||||
import { ImportOptions, StepperApis } from '../types';
|
||||
import { StepperApis } from '../types';
|
||||
import { ImportFlows, ImportState } from '../useImportState';
|
||||
|
||||
export type StepConfiguration = {
|
||||
@@ -45,41 +45,22 @@ export type StepConfiguration = {
|
||||
export type StepperProvider = {
|
||||
analyze: (
|
||||
s: Extract<ImportState, { activeState: 'analyze' }>,
|
||||
opts: { apis: StepperApis; opts?: ImportOptions },
|
||||
opts: { apis: StepperApis },
|
||||
) => StepConfiguration;
|
||||
prepare: (
|
||||
s: Extract<ImportState, { activeState: 'prepare' }>,
|
||||
opts: { apis: StepperApis; opts?: ImportOptions },
|
||||
opts: { apis: StepperApis },
|
||||
) => StepConfiguration;
|
||||
review: (
|
||||
s: Extract<ImportState, { activeState: 'review' }>,
|
||||
opts: { apis: StepperApis; opts?: ImportOptions },
|
||||
opts: { apis: StepperApis },
|
||||
) => StepConfiguration;
|
||||
finish: (
|
||||
s: Extract<ImportState, { activeState: 'finish' }>,
|
||||
opts: { apis: StepperApis; opts?: ImportOptions },
|
||||
opts: { apis: StepperApis },
|
||||
) => StepConfiguration;
|
||||
};
|
||||
|
||||
function defaultPreparePullRequest(
|
||||
apis: StepperApis,
|
||||
{ title, body }: { title?: string; body?: string } = {},
|
||||
) {
|
||||
const appTitle = apis.configApi.getOptionalString('app.title') ?? 'Backstage';
|
||||
const appBaseUrl = apis.configApi.getString('app.baseUrl');
|
||||
|
||||
return {
|
||||
title: title ?? 'Add catalog-info.yaml config file',
|
||||
body:
|
||||
body ??
|
||||
`This pull request adds a **Backstage entity metadata file** \
|
||||
to this repository so that the component can be added to the \
|
||||
[${appTitle} software catalog](${appBaseUrl}).\n\nAfter this pull request is merged, \
|
||||
the component will become available.\n\nFor more information, read an \
|
||||
[overview of the Backstage software catalog](https://backstage.io/docs/features/software-catalog/software-catalog-overview).`,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* The default stepper generation function.
|
||||
*
|
||||
@@ -155,12 +136,8 @@ export function defaultGenerateStepper(
|
||||
return defaults.prepare(state, opts);
|
||||
}
|
||||
|
||||
const preparePullRequest =
|
||||
opts?.opts?.pullRequest?.preparePullRequest;
|
||||
const { title, body } = defaultPreparePullRequest(
|
||||
opts.apis,
|
||||
preparePullRequest ? preparePullRequest(opts.apis) : {},
|
||||
);
|
||||
const { title, body } =
|
||||
opts.apis.catalogImportApi.preparePullRequest!();
|
||||
|
||||
return {
|
||||
stepLabel: <StepLabel>Create Pull Request</StepLabel>,
|
||||
@@ -285,14 +262,14 @@ export function defaultGenerateStepper(
|
||||
}
|
||||
|
||||
export const defaultStepper: StepperProvider = {
|
||||
analyze: (state, { opts }) => ({
|
||||
analyze: (state, { apis }) => ({
|
||||
stepLabel: <StepLabel>Select URL</StepLabel>,
|
||||
content: (
|
||||
<StepInitAnalyzeUrl
|
||||
key="analyze"
|
||||
analysisUrl={state.analysisUrl}
|
||||
onAnalysis={state.onAnalysis}
|
||||
disablePullRequest={opts?.pullRequest?.disable}
|
||||
disablePullRequest={!apis.catalogImportApi.preparePullRequest}
|
||||
/>
|
||||
),
|
||||
}),
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 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 React from 'react';
|
||||
import { Route, Routes } from 'react-router-dom';
|
||||
import { ImportPage } from './ImportPage';
|
||||
import { ImportOptions } from './types';
|
||||
|
||||
/// @deprecated, use ImportPage instead.
|
||||
export const Router = (opts: ImportOptions) => (
|
||||
<Routes>
|
||||
<Route element={<ImportPage {...opts} />} />
|
||||
</Routes>
|
||||
);
|
||||
@@ -17,7 +17,6 @@
|
||||
export * from './DefaultImportPage';
|
||||
export * from './EntityListComponent';
|
||||
export * from './ImportInfoCard';
|
||||
export * from './ImportOptionsContext';
|
||||
export * from './ImportStepper';
|
||||
export * from './StepInitAnalyzeUrl';
|
||||
export * from './StepPrepareCreatePullRequest';
|
||||
|
||||
@@ -14,17 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ConfigApi } from '@backstage/core-plugin-api';
|
||||
|
||||
export type ImportOptions = {
|
||||
pullRequest?: {
|
||||
disable?: boolean;
|
||||
preparePullRequest?: (
|
||||
apis: StepperApis,
|
||||
) => { title?: string; body?: string };
|
||||
};
|
||||
};
|
||||
import { CatalogImportApi } from '../api';
|
||||
|
||||
export type StepperApis = {
|
||||
configApi: ConfigApi;
|
||||
catalogImportApi: CatalogImportApi;
|
||||
};
|
||||
|
||||
@@ -25,6 +25,5 @@ export {
|
||||
catalogImportPlugin as plugin,
|
||||
CatalogImportPage,
|
||||
} from './plugin';
|
||||
export { Router } from './components/Router';
|
||||
export * from './components';
|
||||
export * from './api';
|
||||
|
||||
@@ -14,10 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { scmIntegrationsApiRef } from '@backstage/integration-react';
|
||||
import { catalogApiRef } from '@backstage/plugin-catalog-react';
|
||||
import { catalogImportApiRef, CatalogImportClient } from './api';
|
||||
import {
|
||||
configApiRef,
|
||||
createApiFactory,
|
||||
createPlugin,
|
||||
createRoutableExtension,
|
||||
@@ -26,6 +24,9 @@ import {
|
||||
githubAuthApiRef,
|
||||
identityApiRef,
|
||||
} from '@backstage/core-plugin-api';
|
||||
import { scmIntegrationsApiRef } from '@backstage/integration-react';
|
||||
import { catalogApiRef } from '@backstage/plugin-catalog-react';
|
||||
import { catalogImportApiRef, CatalogImportClient } from './api';
|
||||
|
||||
export const rootRouteRef = createRouteRef({
|
||||
path: '',
|
||||
@@ -43,6 +44,7 @@ export const catalogImportPlugin = createPlugin({
|
||||
identityApi: identityApiRef,
|
||||
scmIntegrationsApi: scmIntegrationsApiRef,
|
||||
catalogApi: catalogApiRef,
|
||||
configApi: configApiRef,
|
||||
},
|
||||
factory: ({
|
||||
discoveryApi,
|
||||
@@ -50,6 +52,7 @@ export const catalogImportPlugin = createPlugin({
|
||||
identityApi,
|
||||
scmIntegrationsApi,
|
||||
catalogApi,
|
||||
configApi,
|
||||
}) =>
|
||||
new CatalogImportClient({
|
||||
discoveryApi,
|
||||
@@ -57,6 +60,7 @@ export const catalogImportPlugin = createPlugin({
|
||||
scmIntegrationsApi,
|
||||
identityApi,
|
||||
catalogApi,
|
||||
configApi,
|
||||
}),
|
||||
}),
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user