From dc4a5a90acf661a5d36b7799aecbe6c5dde87073 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Tue, 18 May 2021 11:24:53 +0200 Subject: [PATCH 1/8] catalog: Display warning when entity is orphan Signed-off-by: Johan Haals --- .../EntityOrphanWarning.test.tsx | 104 ++++++++++++++++++ .../EntityOrphanWarning.tsx | 57 ++++++++++ .../components/EntityOrphanWarning/index.ts | 17 +++ plugins/catalog/src/index.ts | 1 + 4 files changed, 179 insertions(+) create mode 100644 plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.test.tsx create mode 100644 plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.tsx create mode 100644 plugins/catalog/src/components/EntityOrphanWarning/index.ts diff --git a/plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.test.tsx b/plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.test.tsx new file mode 100644 index 0000000000..5681a0e289 --- /dev/null +++ b/plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.test.tsx @@ -0,0 +1,104 @@ +/* + * Copyright 2020 Spotify AB + * + * 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 { ApiProvider, ApiRegistry, ConfigReader } from '@backstage/core'; +import { + ScmIntegrationsApi, + scmIntegrationsApiRef, +} from '@backstage/integration-react'; +import { EntityProvider } from '@backstage/plugin-catalog-react'; +import { renderInTestApp } from '@backstage/test-utils'; +import React from 'react'; +import { EntityOrphanWarning } from './EntityOrphanWarning'; + +describe('', () => { + it('renders EntityOrphanWarning if the entity is orphan', async () => { + const entity = { + apiVersion: 'v1', + kind: 'Component', + metadata: { + name: 'software', + description: 'This is the description', + annotations: { 'backstage.io/orphan': 'true' }, + }, + + spec: { + owner: 'guest', + type: 'service', + lifecycle: 'production', + }, + }; + const apis = ApiRegistry.with( + scmIntegrationsApiRef, + ScmIntegrationsApi.fromConfig( + new ConfigReader({ + integrations: {}, + }), + ), + ); + + const { getByText } = await renderInTestApp( + + + + + , + ); + expect( + getByText( + 'This entity is not referenced by any location and is therefore not receiving updates. Click here to unregister.', + ), + ).toBeInTheDocument(); + }); + + it('does not render EntityOrphanWarning if the entity is not orphan', async () => { + const entity = { + apiVersion: 'v1', + kind: 'Component', + metadata: { + name: 'software', + description: 'This is the description', + }, + + spec: { + owner: 'guest', + type: 'service', + lifecycle: 'production', + }, + }; + const apis = ApiRegistry.with( + scmIntegrationsApiRef, + ScmIntegrationsApi.fromConfig( + new ConfigReader({ + integrations: {}, + }), + ), + ); + + const { queryByText } = await renderInTestApp( + + + + + , + ); + expect( + queryByText( + 'This entity is not referenced by any location and is therefore not receiving updates. Click here to unregister.', + ), + ).not.toBeInTheDocument(); + }); +}); diff --git a/plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.tsx b/plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.tsx new file mode 100644 index 0000000000..1215daeed1 --- /dev/null +++ b/plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.tsx @@ -0,0 +1,57 @@ +/* + * Copyright 2021 Spotify AB + * + * 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 { useEntity } from '@backstage/plugin-catalog-react'; +import { Alert } from '@material-ui/lab'; +import React, { useState } from 'react'; +import { useNavigate } from 'react-router'; +import { UnregisterEntityDialog } from '../UnregisterEntityDialog/UnregisterEntityDialog'; + +/** + * Displays a warning alert if the entity is marked as orphan with the ability to delete said entity. + */ +export const EntityOrphanWarning = () => { + const navigate = useNavigate(); + const [confirmationDialogOpen, setConfirmationDialogOpen] = useState(false); + + const { entity } = useEntity(); + if ( + !entity.metadata?.annotations || + entity.metadata?.annotations['backstage.io/orphan'] !== 'true' + ) { + return null; + } + + const cleanUpAfterRemoval = async () => { + setConfirmationDialogOpen(false); + navigate('/'); + }; + + return ( + <> + setConfirmationDialogOpen(true)}> + This entity is not referenced by any location and is therefore not + receiving updates. Click here to unregister. + + setConfirmationDialogOpen(false)} + /> + + ); +}; diff --git a/plugins/catalog/src/components/EntityOrphanWarning/index.ts b/plugins/catalog/src/components/EntityOrphanWarning/index.ts new file mode 100644 index 0000000000..b632e6ada9 --- /dev/null +++ b/plugins/catalog/src/components/EntityOrphanWarning/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2021 Spotify AB + * + * 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 { EntityOrphanWarning } from './EntityOrphanWarning'; diff --git a/plugins/catalog/src/index.ts b/plugins/catalog/src/index.ts index 2e74219718..f7506b534a 100644 --- a/plugins/catalog/src/index.ts +++ b/plugins/catalog/src/index.ts @@ -35,3 +35,4 @@ export { EntityLinksCard, EntitySystemDiagramCard, } from './plugin'; +export * from './components/EntityOrphanWarning'; From fce24d462c33696a6135dcd04ff98f6e7e2d3d91 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Tue, 18 May 2021 11:26:11 +0200 Subject: [PATCH 2/8] catalog: Display orphanWarning, fix grid spacing Signed-off-by: Johan Haals --- packages/app/src/components/catalog/EntityPage.tsx | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/app/src/components/catalog/EntityPage.tsx b/packages/app/src/components/catalog/EntityPage.tsx index c1d892e061..c655e24122 100644 --- a/packages/app/src/components/catalog/EntityPage.tsx +++ b/packages/app/src/components/catalog/EntityPage.tsx @@ -40,6 +40,7 @@ import { isComponentType, isKind, EntityHasResourcesCard, + EntityOrphanWarning, } from '@backstage/plugin-catalog'; import { EntityCircleCIContent, @@ -214,7 +215,10 @@ const errorsContent = ( const overviewContent = ( - + + + + @@ -226,7 +230,7 @@ const overviewContent = ( - + @@ -260,7 +264,7 @@ const overviewContent = ( - + From d720a3ecf896ac2d610b2a60e2d3a10f1d9e1875 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Tue, 18 May 2021 16:38:55 +0200 Subject: [PATCH 3/8] Catalog: Add dialog to delete entity Signed-off-by: Johan Haals --- .../DeleteEntityDialog.test.tsx | 132 ++++++++++++++++++ .../DeleteEntityDialog.tsx | 73 ++++++++++ .../EntityOrphanWarning.test.tsx | 36 ++--- .../EntityOrphanWarning.tsx | 11 +- 4 files changed, 222 insertions(+), 30 deletions(-) create mode 100644 plugins/catalog/src/components/EntityOrphanWarning/DeleteEntityDialog.test.tsx create mode 100644 plugins/catalog/src/components/EntityOrphanWarning/DeleteEntityDialog.tsx diff --git a/plugins/catalog/src/components/EntityOrphanWarning/DeleteEntityDialog.test.tsx b/plugins/catalog/src/components/EntityOrphanWarning/DeleteEntityDialog.test.tsx new file mode 100644 index 0000000000..d9f266cce7 --- /dev/null +++ b/plugins/catalog/src/components/EntityOrphanWarning/DeleteEntityDialog.test.tsx @@ -0,0 +1,132 @@ +/* + * Copyright 2021 Spotify AB + * + * 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 userEvent from '@testing-library/user-event'; +import React from 'react'; +import { DeleteEntityDialog } from './DeleteEntityDialog'; +import { ORIGIN_LOCATION_ANNOTATION } from '@backstage/catalog-model'; +import { + AlertApi, + alertApiRef, + ApiProvider, + ApiRegistry, +} from '@backstage/core'; +import { CatalogApi } from '@backstage/catalog-client'; +import { catalogApiRef } from '@backstage/plugin-catalog-react'; +import { screen, waitFor } from '@testing-library/react'; +import { renderInTestApp } from '@backstage/test-utils'; + +describe('DeleteEntityDialog', () => { + const alertApi: jest.Mocked = { + post: jest.fn(), + alert$: jest.fn(), + }; + + const catalogClient: jest.Mocked = { + removeEntityByUid: jest.fn(), + } as any; + const apis = ApiRegistry.with(catalogApiRef, catalogClient).with( + alertApiRef, + alertApi, + ); + + const entity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + uid: '123', + name: 'n', + namespace: 'ns', + annotations: { + [ORIGIN_LOCATION_ANNOTATION]: 'url:http://example.com', + }, + }, + spec: {}, + }; + + const Wrapper = ({ children }: { children?: React.ReactNode }) => ( + {children} + ); + + afterEach(() => { + jest.resetAllMocks(); + }); + + it('can cancel', async () => { + const onClose = jest.fn(); + + await renderInTestApp( + + {}} + entity={entity} + /> + , + ); + + userEvent.click(screen.getByText('Cancel')); + + await waitFor(() => { + expect(onClose).toBeCalled(); + }); + }); + + it('can delete', async () => { + const onConfirm = jest.fn(); + + await renderInTestApp( + + {}} + onConfirm={onConfirm} + entity={entity} + /> + , + ); + + userEvent.click(screen.getByText('Delete')); + + await waitFor(() => { + expect(catalogClient.removeEntityByUid).toBeCalledWith('123'); + expect(onConfirm).toBeCalled(); + }); + }); + + it('handles error', async () => { + const onConfirm = jest.fn(); + + await renderInTestApp( + + {}} + onConfirm={onConfirm} + entity={entity} + /> + , + ); + + catalogClient.removeEntityByUid.mockRejectedValue(new Error('no no no')); + userEvent.click(screen.getByText('Delete')); + + await waitFor(() => { + expect(catalogClient.removeEntityByUid).toBeCalledWith('123'); + expect(alertApi.post).toBeCalledWith({ message: 'no no no' }); + }); + }); +}); diff --git a/plugins/catalog/src/components/EntityOrphanWarning/DeleteEntityDialog.tsx b/plugins/catalog/src/components/EntityOrphanWarning/DeleteEntityDialog.tsx new file mode 100644 index 0000000000..26b6b29650 --- /dev/null +++ b/plugins/catalog/src/components/EntityOrphanWarning/DeleteEntityDialog.tsx @@ -0,0 +1,73 @@ +/* + * Copyright 2021 Spotify AB + * + * 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 { Entity } from '@backstage/catalog-model'; +import { alertApiRef, useApi } from '@backstage/core'; +import { catalogApiRef } from '@backstage/plugin-catalog-react'; +import { Button, Dialog, DialogActions, DialogTitle } from '@material-ui/core'; +import React, { useState } from 'react'; + +type Props = { + open: boolean; + onClose: () => any; + onConfirm: () => any; + entity: Entity; +}; + +export const DeleteEntityDialog = ({ + open, + onClose, + onConfirm, + entity, +}: Props) => { + const [busy, setBusy] = useState(false); + const catalogApi = useApi(catalogApiRef); + const alertApi = useApi(alertApiRef); + + const onDelete = async () => { + setBusy(true); + try { + const uid = entity.metadata.uid; + await catalogApi.removeEntityByUid(uid!); + onConfirm(); + } catch (err) { + alertApi.post({ message: err.message }); + } finally { + setBusy(false); + } + }; + + return ( + + + Are you sure you want to delete this entity? + + + + + + + ); +}; diff --git a/plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.test.tsx b/plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.test.tsx index 5681a0e289..482be1dd25 100644 --- a/plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.test.tsx +++ b/plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.test.tsx @@ -14,17 +14,23 @@ * limitations under the License. */ -import { ApiProvider, ApiRegistry, ConfigReader } from '@backstage/core'; +import { ApiProvider, ApiRegistry } from '@backstage/core'; + import { - ScmIntegrationsApi, - scmIntegrationsApiRef, -} from '@backstage/integration-react'; -import { EntityProvider } from '@backstage/plugin-catalog-react'; + CatalogApi, + catalogApiRef, + EntityProvider, +} from '@backstage/plugin-catalog-react'; import { renderInTestApp } from '@backstage/test-utils'; import React from 'react'; import { EntityOrphanWarning } from './EntityOrphanWarning'; describe('', () => { + const catalogClient: jest.Mocked = { + removeEntityByUid: jest.fn(), + } as any; + const apis = ApiRegistry.with(catalogApiRef, catalogClient); + it('renders EntityOrphanWarning if the entity is orphan', async () => { const entity = { apiVersion: 'v1', @@ -41,14 +47,6 @@ describe('', () => { lifecycle: 'production', }, }; - const apis = ApiRegistry.with( - scmIntegrationsApiRef, - ScmIntegrationsApi.fromConfig( - new ConfigReader({ - integrations: {}, - }), - ), - ); const { getByText } = await renderInTestApp( @@ -59,7 +57,7 @@ describe('', () => { ); expect( getByText( - 'This entity is not referenced by any location and is therefore not receiving updates. Click here to unregister.', + 'This entity is not referenced by any location and is therefore not receiving updates. Click here to delete.', ), ).toBeInTheDocument(); }); @@ -79,14 +77,6 @@ describe('', () => { lifecycle: 'production', }, }; - const apis = ApiRegistry.with( - scmIntegrationsApiRef, - ScmIntegrationsApi.fromConfig( - new ConfigReader({ - integrations: {}, - }), - ), - ); const { queryByText } = await renderInTestApp( @@ -97,7 +87,7 @@ describe('', () => { ); expect( queryByText( - 'This entity is not referenced by any location and is therefore not receiving updates. Click here to unregister.', + 'This entity is not referenced by any location and is therefore not receiving updates. Click here to delete.', ), ).not.toBeInTheDocument(); }); diff --git a/plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.tsx b/plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.tsx index 1215daeed1..6e4780f1a0 100644 --- a/plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.tsx +++ b/plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.tsx @@ -18,7 +18,7 @@ import { useEntity } from '@backstage/plugin-catalog-react'; import { Alert } from '@material-ui/lab'; import React, { useState } from 'react'; import { useNavigate } from 'react-router'; -import { UnregisterEntityDialog } from '../UnregisterEntityDialog/UnregisterEntityDialog'; +import { DeleteEntityDialog } from './DeleteEntityDialog'; /** * Displays a warning alert if the entity is marked as orphan with the ability to delete said entity. @@ -28,10 +28,7 @@ export const EntityOrphanWarning = () => { const [confirmationDialogOpen, setConfirmationDialogOpen] = useState(false); const { entity } = useEntity(); - if ( - !entity.metadata?.annotations || - entity.metadata?.annotations['backstage.io/orphan'] !== 'true' - ) { + if (entity.metadata?.annotations?.['backstage.io/orphan'] !== 'true') { return null; } @@ -44,9 +41,9 @@ export const EntityOrphanWarning = () => { <> setConfirmationDialogOpen(true)}> This entity is not referenced by any location and is therefore not - receiving updates. Click here to unregister. + receiving updates. Click here to delete. - Date: Wed, 19 May 2021 09:36:42 +0200 Subject: [PATCH 4/8] Catalog: Wrap EntityOrphanWarning in EntitySwitch Signed-off-by: Johan Haals --- packages/app/src/components/catalog/EntityPage.tsx | 12 +++++++++--- .../EntityOrphanWarning/EntityOrphanWarning.tsx | 6 +++++- .../src/components/EntityOrphanWarning/index.ts | 2 +- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/packages/app/src/components/catalog/EntityPage.tsx b/packages/app/src/components/catalog/EntityPage.tsx index c655e24122..f646992c97 100644 --- a/packages/app/src/components/catalog/EntityPage.tsx +++ b/packages/app/src/components/catalog/EntityPage.tsx @@ -41,6 +41,7 @@ import { isKind, EntityHasResourcesCard, EntityOrphanWarning, + isOrphan, } from '@backstage/plugin-catalog'; import { EntityCircleCIContent, @@ -215,9 +216,14 @@ const errorsContent = ( const overviewContent = ( - - - + + + + + + + + diff --git a/plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.tsx b/plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.tsx index 6e4780f1a0..7f8ec8baf9 100644 --- a/plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.tsx +++ b/plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.tsx @@ -14,12 +14,16 @@ * limitations under the License. */ +import { Entity } from '@backstage/catalog-model'; import { useEntity } from '@backstage/plugin-catalog-react'; import { Alert } from '@material-ui/lab'; import React, { useState } from 'react'; import { useNavigate } from 'react-router'; import { DeleteEntityDialog } from './DeleteEntityDialog'; +export const isOrphan = (entity: Entity) => + entity?.metadata?.annotations?.['backstage.io/orphan'] === 'true'; + /** * Displays a warning alert if the entity is marked as orphan with the ability to delete said entity. */ @@ -28,7 +32,7 @@ export const EntityOrphanWarning = () => { const [confirmationDialogOpen, setConfirmationDialogOpen] = useState(false); const { entity } = useEntity(); - if (entity.metadata?.annotations?.['backstage.io/orphan'] !== 'true') { + if (entity?.metadata?.annotations?.['backstage.io/orphan'] !== 'true') { return null; } diff --git a/plugins/catalog/src/components/EntityOrphanWarning/index.ts b/plugins/catalog/src/components/EntityOrphanWarning/index.ts index b632e6ada9..b64f8c1232 100644 --- a/plugins/catalog/src/components/EntityOrphanWarning/index.ts +++ b/plugins/catalog/src/components/EntityOrphanWarning/index.ts @@ -14,4 +14,4 @@ * limitations under the License. */ -export { EntityOrphanWarning } from './EntityOrphanWarning'; +export { EntityOrphanWarning, isOrphan } from './EntityOrphanWarning'; From 0057ed31e36dedfdde16223a74af503c4fc5427e Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Wed, 19 May 2021 10:13:57 +0200 Subject: [PATCH 5/8] Catalog: Remove rendudant conditional rendering Signed-off-by: Johan Haals --- .../EntityOrphanWarning.test.tsx | 30 ------------------- .../EntityOrphanWarning.tsx | 4 --- 2 files changed, 34 deletions(-) diff --git a/plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.test.tsx b/plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.test.tsx index 482be1dd25..b33c026d4e 100644 --- a/plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.test.tsx +++ b/plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.test.tsx @@ -61,34 +61,4 @@ describe('', () => { ), ).toBeInTheDocument(); }); - - it('does not render EntityOrphanWarning if the entity is not orphan', async () => { - const entity = { - apiVersion: 'v1', - kind: 'Component', - metadata: { - name: 'software', - description: 'This is the description', - }, - - spec: { - owner: 'guest', - type: 'service', - lifecycle: 'production', - }, - }; - - const { queryByText } = await renderInTestApp( - - - - - , - ); - expect( - queryByText( - 'This entity is not referenced by any location and is therefore not receiving updates. Click here to delete.', - ), - ).not.toBeInTheDocument(); - }); }); diff --git a/plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.tsx b/plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.tsx index 7f8ec8baf9..173e9093fc 100644 --- a/plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.tsx +++ b/plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.tsx @@ -30,11 +30,7 @@ export const isOrphan = (entity: Entity) => export const EntityOrphanWarning = () => { const navigate = useNavigate(); const [confirmationDialogOpen, setConfirmationDialogOpen] = useState(false); - const { entity } = useEntity(); - if (entity?.metadata?.annotations?.['backstage.io/orphan'] !== 'true') { - return null; - } const cleanUpAfterRemoval = async () => { setConfirmationDialogOpen(false); From 973e9d42dd226e9556102e0f1cd662c6ef3c5272 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Wed, 19 May 2021 13:53:52 +0200 Subject: [PATCH 6/8] catalog: Use route ref for navigation Signed-off-by: Johan Haals --- .../EntityOrphanWarning/EntityOrphanWarning.test.tsx | 8 +++++++- .../EntityOrphanWarning/EntityOrphanWarning.tsx | 6 ++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.test.tsx b/plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.test.tsx index b33c026d4e..b9582f019e 100644 --- a/plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.test.tsx +++ b/plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.test.tsx @@ -14,11 +14,12 @@ * limitations under the License. */ -import { ApiProvider, ApiRegistry } from '@backstage/core'; +import { ApiProvider, ApiRegistry, createRouteRef } from '@backstage/core'; import { CatalogApi, catalogApiRef, + catalogRouteRef, EntityProvider, } from '@backstage/plugin-catalog-react'; import { renderInTestApp } from '@backstage/test-utils'; @@ -54,6 +55,11 @@ describe('', () => { , + { + mountedRoutes: { + '/create': catalogRouteRef, + }, + }, ); expect( getByText( diff --git a/plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.tsx b/plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.tsx index 173e9093fc..070c36c56c 100644 --- a/plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.tsx +++ b/plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.tsx @@ -15,7 +15,8 @@ */ import { Entity } from '@backstage/catalog-model'; -import { useEntity } from '@backstage/plugin-catalog-react'; +import { useRouteRef } from '@backstage/core'; +import { catalogRouteRef, useEntity } from '@backstage/plugin-catalog-react'; import { Alert } from '@material-ui/lab'; import React, { useState } from 'react'; import { useNavigate } from 'react-router'; @@ -29,12 +30,13 @@ export const isOrphan = (entity: Entity) => */ export const EntityOrphanWarning = () => { const navigate = useNavigate(); + const catalogLink = useRouteRef(catalogRouteRef); const [confirmationDialogOpen, setConfirmationDialogOpen] = useState(false); const { entity } = useEntity(); const cleanUpAfterRemoval = async () => { setConfirmationDialogOpen(false); - navigate('/'); + navigate(catalogLink()); }; return ( From b203699e92b0647b404f026d9fdf364e3154ed03 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Wed, 19 May 2021 14:23:37 +0200 Subject: [PATCH 7/8] Add changeset Signed-off-by: Johan Haals --- .changeset/wise-mugs-sell.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/wise-mugs-sell.md diff --git a/.changeset/wise-mugs-sell.md b/.changeset/wise-mugs-sell.md new file mode 100644 index 0000000000..35b333ba75 --- /dev/null +++ b/.changeset/wise-mugs-sell.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog': patch +--- + +Display warning when Entity has orphan annotation. From d510f438c3b9c83c1b721833887d6c6c3d3e51c1 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Wed, 19 May 2021 14:29:06 +0200 Subject: [PATCH 8/8] Remove unused import Signed-off-by: Johan Haals --- .../components/EntityOrphanWarning/EntityOrphanWarning.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.test.tsx b/plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.test.tsx index b9582f019e..0b3b8de504 100644 --- a/plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.test.tsx +++ b/plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.test.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import { ApiProvider, ApiRegistry, createRouteRef } from '@backstage/core'; +import { ApiProvider, ApiRegistry } from '@backstage/core'; import { CatalogApi,