Introduce external route for linking to the entity page from the explore plugin

Signed-off-by: Oliver Sand <oliver.sand@sda-se.com>
This commit is contained in:
Oliver Sand
2021-02-22 16:40:29 +01:00
committed by Patrik Oldsberg
parent 9d455f69a8
commit cfc83cac16
8 changed files with 75 additions and 23 deletions
+19
View File
@@ -0,0 +1,19 @@
---
'@backstage/plugin-explore': minor
---
Introduce external route for linking to the entity page from the explore plugin.
To use the explore plugin you have to bind the external route in your app:
```typescript
const app = createApp({
...
bindRoutes({ bind }) {
...
bind(explorePlugin.externalRoutes, {
catalogEntity: catalogPlugin.routes.catalogEntity,
});
},
});
```
+4 -1
View File
@@ -33,7 +33,7 @@ import {
CostInsightsPage,
CostInsightsProjectGrowthInstructionsPage,
} from '@backstage/plugin-cost-insights';
import { ExplorePage } from '@backstage/plugin-explore';
import { ExplorePage, explorePlugin } from '@backstage/plugin-explore';
import { GcpProjectsPage } from '@backstage/plugin-gcp-projects';
import { GraphiQLPage } from '@backstage/plugin-graphiql';
import { LighthousePage } from '@backstage/plugin-lighthouse';
@@ -79,6 +79,9 @@ const app = createApp({
bind(apiDocsPlugin.externalRoutes, {
createComponent: scaffolderPlugin.routes.root,
});
bind(explorePlugin.externalRoutes, {
catalogEntity: catalogPlugin.routes.catalogEntity,
});
},
});
@@ -15,13 +15,13 @@
*/
import { DomainEntity } from '@backstage/catalog-model';
import { render } from '@testing-library/react';
import { renderInTestApp } from '@backstage/test-utils';
import React from 'react';
import { MemoryRouter } from 'react-router-dom';
import { catalogEntityRouteRef } from '../../routes';
import { DomainCard } from './DomainCard';
describe('<DomainCard />', () => {
it('renders a domain card', () => {
it('renders a domain card', async () => {
const entity: DomainEntity = {
apiVersion: 'backstage.io/v1alpha1',
kind: 'Domain',
@@ -34,9 +34,14 @@ describe('<DomainCard />', () => {
owner: 'guest',
},
};
const { getByText } = render(<DomainCard entity={entity} />, {
wrapper: MemoryRouter,
});
const { getByText } = await renderInTestApp(
<DomainCard entity={entity} />,
{
mountedRoutes: {
'/catalog/:namespace/:kind/:name': catalogEntityRouteRef,
},
},
);
expect(getByText('artists')).toBeInTheDocument();
expect(getByText('Everything about artists')).toBeInTheDocument();
@@ -14,15 +14,14 @@
* limitations under the License.
*/
import { DomainEntity, RELATION_OWNED_BY } from '@backstage/catalog-model';
import { ItemCard } from '@backstage/core';
import { ItemCard, useRouteRef } from '@backstage/core';
import {
EntityRefLinks,
entityRoute,
entityRouteParams,
getEntityRelations,
} from '@backstage/plugin-catalog-react';
import React from 'react';
import { generatePath } from 'react-router-dom';
import { catalogEntityRouteRef } from '../../routes';
type DomainCardProps = {
entity: DomainEntity;
@@ -30,6 +29,7 @@ type DomainCardProps = {
export const DomainCard = ({ entity }: DomainCardProps) => {
const ownedByRelations = getEntityRelations(entity, RELATION_OWNED_BY);
const catalogEntityRoute = useRouteRef(catalogEntityRouteRef);
return (
<ItemCard
@@ -44,11 +44,7 @@ export const DomainCard = ({ entity }: DomainCardProps) => {
/>
}
label="Explore"
// TODO: Use useRouteRef here to generate the path
href={generatePath(
`/catalog/${entityRoute.path}`,
entityRouteParams(entity),
)}
href={catalogEntityRoute(entityRouteParams(entity))}
/>
);
};
@@ -15,13 +15,13 @@
*/
import { DomainEntity } from '@backstage/catalog-model';
import { render } from '@testing-library/react';
import { renderInTestApp } from '@backstage/test-utils';
import React from 'react';
import { MemoryRouter } from 'react-router-dom';
import { catalogEntityRouteRef } from '../../routes';
import { DomainCardGrid } from './DomainCardGrid';
describe('<DomainCardGrid />', () => {
it('renders a grid of domain cards', () => {
it('renders a grid of domain cards', async () => {
const entities: DomainEntity[] = [
{
apiVersion: 'backstage.io/v1alpha1',
@@ -44,9 +44,14 @@ describe('<DomainCardGrid />', () => {
},
},
];
const { getByText } = render(<DomainCardGrid entities={entities} />, {
wrapper: MemoryRouter,
});
const { getByText } = await renderInTestApp(
<DomainCardGrid entities={entities} />,
{
mountedRoutes: {
'/catalog/:namespace/:kind/:name': catalogEntityRouteRef,
},
},
);
expect(getByText('artists')).toBeInTheDocument();
expect(getByText('playback')).toBeInTheDocument();
@@ -20,6 +20,7 @@ import { catalogApiRef } from '@backstage/plugin-catalog-react';
import { renderInTestApp } from '@backstage/test-utils';
import { waitFor } from '@testing-library/react';
import React from 'react';
import { catalogEntityRouteRef } from '../../routes';
import { DomainExplorerContent } from './DomainExplorerContent';
describe('<DomainExplorerContent />', () => {
@@ -71,6 +72,11 @@ describe('<DomainExplorerContent />', () => {
<Wrapper>
<DomainExplorerContent />
</Wrapper>,
{
mountedRoutes: {
'/catalog/:namespace/:kind/:name': catalogEntityRouteRef,
},
},
);
await waitFor(() => {
@@ -86,6 +92,11 @@ describe('<DomainExplorerContent />', () => {
<Wrapper>
<DomainExplorerContent />
</Wrapper>,
{
mountedRoutes: {
'/catalog/:namespace/:kind/:name': catalogEntityRouteRef,
},
},
);
await waitFor(() =>
@@ -101,6 +112,11 @@ describe('<DomainExplorerContent />', () => {
<Wrapper>
<DomainExplorerContent />
</Wrapper>,
{
mountedRoutes: {
'/catalog/:namespace/:kind/:name': catalogEntityRouteRef,
},
},
);
await waitFor(() =>
+4 -1
View File
@@ -16,7 +16,7 @@
import { createApiFactory, createPlugin } from '@backstage/core';
import { exploreToolsConfigRef } from '@backstage/plugin-explore-react';
import { exploreRouteRef } from './routes';
import { catalogEntityRouteRef, exploreRouteRef } from './routes';
import { exampleTools } from './util/examples';
export const explorePlugin = createPlugin({
@@ -37,4 +37,7 @@ export const explorePlugin = createPlugin({
routes: {
explore: exploreRouteRef,
},
externalRoutes: {
catalogEntity: catalogEntityRouteRef,
},
});
+6 -1
View File
@@ -14,7 +14,7 @@
* limitations under the License.
*/
import { createRouteRef } from '@backstage/core';
import { createExternalRouteRef, createRouteRef } from '@backstage/core';
const NoIcon = () => null;
@@ -22,3 +22,8 @@ export const exploreRouteRef = createRouteRef({
icon: NoIcon,
title: 'Explore',
});
export const catalogEntityRouteRef = createExternalRouteRef({
id: 'catalog-entity',
params: ['namespace', 'kind', 'name'],
});