Merge pull request #18481 from backstage/orkohunter/catalog-import-fixes
catalog-import: Add a View Component button after registering a new component
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-import': patch
|
||||
---
|
||||
|
||||
Add a "View Component" button as the primary CTA after registering a new component using a link to catalog-info.yaml
|
||||
@@ -14,6 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { LinkButton } from '@backstage/core-components';
|
||||
import { Button, CircularProgress } from '@material-ui/core';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import React, { ComponentProps } from 'react';
|
||||
@@ -68,3 +69,20 @@ export const BackButton = (props: ComponentProps<typeof Button>) => {
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
|
||||
export const ViewComponentButton = (
|
||||
props: ComponentProps<typeof LinkButton>,
|
||||
) => {
|
||||
const classes = useStyles();
|
||||
|
||||
return (
|
||||
<LinkButton
|
||||
color="primary"
|
||||
variant="contained"
|
||||
className={classes.button}
|
||||
{...props}
|
||||
>
|
||||
{props.children}
|
||||
</LinkButton>
|
||||
);
|
||||
};
|
||||
|
||||
+41
-11
@@ -17,23 +17,45 @@
|
||||
import { Grid, Typography } from '@material-ui/core';
|
||||
import LocationOnIcon from '@material-ui/icons/LocationOn';
|
||||
import React from 'react';
|
||||
import { BackButton } from '../Buttons';
|
||||
import { BackButton, ViewComponentButton } from '../Buttons';
|
||||
import { EntityListComponent } from '../EntityListComponent';
|
||||
import { PrepareResult } from '../useImportState';
|
||||
import { Link } from '@backstage/core-components';
|
||||
import partition from 'lodash/partition';
|
||||
import { CompoundEntityRef } from '@backstage/catalog-model';
|
||||
import { entityRouteRef } from '@backstage/plugin-catalog-react';
|
||||
import { useRouteRef } from '@backstage/core-plugin-api';
|
||||
|
||||
type Props = {
|
||||
prepareResult: PrepareResult;
|
||||
onReset: () => void;
|
||||
};
|
||||
|
||||
// Among the newly registered entities, return a software entity (e.g. Component, API, Resource)
|
||||
const filterComponentEntity = (
|
||||
newLocations: Array<{
|
||||
exists?: boolean;
|
||||
target: string;
|
||||
entities: CompoundEntityRef[];
|
||||
}>,
|
||||
): CompoundEntityRef | null => {
|
||||
for (const location of newLocations) {
|
||||
for (const entity of location.entities) {
|
||||
if (
|
||||
['component', 'api', 'resource'].includes(
|
||||
entity.kind.toLocaleLowerCase('en-US'),
|
||||
)
|
||||
) {
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
export const StepFinishImportLocation = ({ prepareResult, onReset }: Props) => {
|
||||
const continueButton = (
|
||||
<Grid container spacing={0}>
|
||||
<BackButton onClick={onReset}>Register another</BackButton>
|
||||
</Grid>
|
||||
);
|
||||
const entityRoute = useRouteRef(entityRouteRef);
|
||||
|
||||
if (prepareResult.type === 'repository') {
|
||||
return (
|
||||
@@ -48,12 +70,13 @@ export const StepFinishImportLocation = ({ prepareResult, onReset }: Props) => {
|
||||
{prepareResult.pullRequest.url}
|
||||
</Link>
|
||||
</Typography>
|
||||
|
||||
<Typography paragraph>
|
||||
Your entities will be imported as soon as the Pull Request is merged.
|
||||
</Typography>
|
||||
|
||||
{continueButton}
|
||||
<Grid container spacing={0}>
|
||||
<BackButton onClick={onReset}>Register another</BackButton>
|
||||
</Grid>
|
||||
;
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -62,7 +85,7 @@ export const StepFinishImportLocation = ({ prepareResult, onReset }: Props) => {
|
||||
prepareResult.locations,
|
||||
l => l.exists,
|
||||
);
|
||||
|
||||
const newComponentEntity = filterComponentEntity(newLocations);
|
||||
return (
|
||||
<>
|
||||
{newLocations.length > 0 && (
|
||||
@@ -91,7 +114,14 @@ export const StepFinishImportLocation = ({ prepareResult, onReset }: Props) => {
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{continueButton}
|
||||
<Grid container spacing={0}>
|
||||
{newComponentEntity && (
|
||||
<ViewComponentButton to={entityRoute(newComponentEntity)}>
|
||||
View Component
|
||||
</ViewComponentButton>
|
||||
)}
|
||||
<BackButton onClick={onReset}>Register another</BackButton>
|
||||
</Grid>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
+12
-18
@@ -64,12 +64,8 @@ describe('<StepInitAnalyzeUrl />', () => {
|
||||
wrapper: Wrapper,
|
||||
});
|
||||
|
||||
expect(
|
||||
screen.getByRole('textbox', { name: /Repository/i }),
|
||||
).toBeInTheDocument();
|
||||
expect(screen.getByRole('textbox', { name: /Repository/i })).toHaveValue(
|
||||
'',
|
||||
);
|
||||
expect(screen.getByRole('textbox', { name: /URL/i })).toBeInTheDocument();
|
||||
expect(screen.getByRole('textbox', { name: /URL/i })).toHaveValue('');
|
||||
});
|
||||
|
||||
it('should use default analysis url', async () => {
|
||||
@@ -83,10 +79,8 @@ describe('<StepInitAnalyzeUrl />', () => {
|
||||
},
|
||||
);
|
||||
|
||||
expect(
|
||||
screen.getByRole('textbox', { name: /Repository/i }),
|
||||
).toBeInTheDocument();
|
||||
expect(screen.getByRole('textbox', { name: /Repository/i })).toHaveValue(
|
||||
expect(screen.getByRole('textbox', { name: /URL/i })).toBeInTheDocument();
|
||||
expect(screen.getByRole('textbox', { name: /URL/i })).toHaveValue(
|
||||
'https://default',
|
||||
);
|
||||
});
|
||||
@@ -120,7 +114,7 @@ describe('<StepInitAnalyzeUrl />', () => {
|
||||
|
||||
await act(async () => {
|
||||
await userEvent.type(
|
||||
screen.getByRole('textbox', { name: /Repository/i }),
|
||||
screen.getByRole('textbox', { name: /URL/i }),
|
||||
'http:/',
|
||||
);
|
||||
await userEvent.click(screen.getByRole('button', { name: /Analyze/i }));
|
||||
@@ -152,7 +146,7 @@ describe('<StepInitAnalyzeUrl />', () => {
|
||||
|
||||
await act(async () => {
|
||||
await userEvent.type(
|
||||
screen.getByRole('textbox', { name: /Repository/i }),
|
||||
screen.getByRole('textbox', { name: /URL/i }),
|
||||
'https://my-repository',
|
||||
);
|
||||
await userEvent.click(screen.getByRole('button', { name: /Analyze/i }));
|
||||
@@ -186,7 +180,7 @@ describe('<StepInitAnalyzeUrl />', () => {
|
||||
|
||||
await act(async () => {
|
||||
await userEvent.type(
|
||||
screen.getByRole('textbox', { name: /Repository/i }),
|
||||
screen.getByRole('textbox', { name: /URL/i }),
|
||||
'https://my-repository-1',
|
||||
);
|
||||
await userEvent.click(screen.getByRole('button', { name: /Analyze/i }));
|
||||
@@ -219,7 +213,7 @@ describe('<StepInitAnalyzeUrl />', () => {
|
||||
|
||||
await act(async () => {
|
||||
await userEvent.type(
|
||||
screen.getByRole('textbox', { name: /Repository/i }),
|
||||
screen.getByRole('textbox', { name: /URL/i }),
|
||||
'https://my-repository-1',
|
||||
);
|
||||
await userEvent.click(screen.getByRole('button', { name: /Analyze/i }));
|
||||
@@ -260,7 +254,7 @@ describe('<StepInitAnalyzeUrl />', () => {
|
||||
|
||||
await act(async () => {
|
||||
await userEvent.type(
|
||||
screen.getByRole('textbox', { name: /Repository/i }),
|
||||
screen.getByRole('textbox', { name: /URL/i }),
|
||||
'https://my-repository-2',
|
||||
);
|
||||
await userEvent.click(screen.getByRole('button', { name: /Analyze/i }));
|
||||
@@ -295,7 +289,7 @@ describe('<StepInitAnalyzeUrl />', () => {
|
||||
|
||||
await act(async () => {
|
||||
await userEvent.type(
|
||||
screen.getByRole('textbox', { name: /Repository/i }),
|
||||
screen.getByRole('textbox', { name: /URL/i }),
|
||||
'https://my-repository-2',
|
||||
);
|
||||
await userEvent.click(screen.getByRole('button', { name: /Analyze/i }));
|
||||
@@ -339,7 +333,7 @@ describe('<StepInitAnalyzeUrl />', () => {
|
||||
|
||||
await act(async () => {
|
||||
await userEvent.type(
|
||||
screen.getByRole('textbox', { name: /Repository/i }),
|
||||
screen.getByRole('textbox', { name: /URL/i }),
|
||||
'https://my-repository-2',
|
||||
);
|
||||
await userEvent.click(screen.getByRole('button', { name: /Analyze/i }));
|
||||
@@ -365,7 +359,7 @@ describe('<StepInitAnalyzeUrl />', () => {
|
||||
|
||||
await act(async () => {
|
||||
await userEvent.type(
|
||||
screen.getByRole('textbox', { name: /Repository/i }),
|
||||
screen.getByRole('textbox', { name: /URL/i }),
|
||||
'https://my-repository-2',
|
||||
);
|
||||
await userEvent.click(screen.getByRole('button', { name: /Analyze/i }));
|
||||
|
||||
@@ -147,7 +147,7 @@ export const StepInitAnalyzeUrl = (props: StepInitAnalyzeUrlProps) => {
|
||||
)}
|
||||
fullWidth
|
||||
id="url"
|
||||
label="Repository URL"
|
||||
label="URL"
|
||||
placeholder={exampleLocationUrl}
|
||||
helperText="Enter the full path to your entity file to start tracking your component"
|
||||
margin="normal"
|
||||
|
||||
Reference in New Issue
Block a user