Merge branch 'master' of https://github.com/spotify/backstage into lintMod
This commit is contained in:
@@ -16,7 +16,7 @@
|
||||
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { ApiProvider, ApiRegistry, storageApiRef } from '@backstage/core';
|
||||
import { CatalogApi, catalogApiRef } from '@backstage/plugin-catalog';
|
||||
import { CatalogApi, catalogApiRef } from '@backstage/plugin-catalog-react';
|
||||
import { MockStorageApi, wrapInTestApp } from '@backstage/test-utils';
|
||||
import { render } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
import { Content, ContentHeader, SupportButton, useApi } from '@backstage/core';
|
||||
import { catalogApiRef } from '@backstage/plugin-catalog';
|
||||
import { catalogApiRef } from '@backstage/plugin-catalog-react';
|
||||
import { Button } from '@material-ui/core';
|
||||
import React from 'react';
|
||||
import { Link as RouterLink } from 'react-router-dom';
|
||||
|
||||
@@ -14,7 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ApiEntityV1alpha1, Entity } from '@backstage/catalog-model';
|
||||
import {
|
||||
ApiEntityV1alpha1,
|
||||
Entity,
|
||||
EntityName,
|
||||
RELATION_OWNED_BY,
|
||||
RELATION_PART_OF,
|
||||
} from '@backstage/catalog-model';
|
||||
import {
|
||||
Table,
|
||||
TableColumn,
|
||||
@@ -22,47 +28,77 @@ import {
|
||||
TableState,
|
||||
useQueryParamState,
|
||||
} from '@backstage/core';
|
||||
import {
|
||||
EntityRefLink,
|
||||
EntityRefLinks,
|
||||
formatEntityRefTitle,
|
||||
getEntityRelations,
|
||||
} from '@backstage/plugin-catalog-react';
|
||||
import { Chip } from '@material-ui/core';
|
||||
import { Alert } from '@material-ui/lab';
|
||||
import React from 'react';
|
||||
import { ApiTypeTitle } from '../ApiDefinitionCard';
|
||||
import { EntityLink } from '../EntityLink';
|
||||
|
||||
const columns: TableColumn<Entity>[] = [
|
||||
type EntityRow = {
|
||||
entity: ApiEntityV1alpha1;
|
||||
resolved: {
|
||||
name: string;
|
||||
partOfSystemRelationTitle?: string;
|
||||
partOfSystemRelations: EntityName[];
|
||||
ownedByRelationsTitle?: string;
|
||||
ownedByRelations: EntityName[];
|
||||
};
|
||||
};
|
||||
|
||||
const columns: TableColumn<EntityRow>[] = [
|
||||
{
|
||||
title: 'Name',
|
||||
field: 'metadata.name',
|
||||
field: 'resolved.name',
|
||||
highlight: true,
|
||||
render: (entity: any) => (
|
||||
<EntityLink entity={entity}>{entity.metadata.name}</EntityLink>
|
||||
render: ({ entity }) => (
|
||||
<EntityRefLink entityRef={entity} defaultKind="API" />
|
||||
),
|
||||
},
|
||||
{
|
||||
title: 'System',
|
||||
field: 'resolved.partOfSystemRelationTitle',
|
||||
render: ({ resolved }) => (
|
||||
<EntityRefLinks
|
||||
entityRefs={resolved.partOfSystemRelations}
|
||||
defaultKind="system"
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: 'Owner',
|
||||
field: 'spec.owner',
|
||||
},
|
||||
{
|
||||
title: 'Lifecycle',
|
||||
field: 'spec.lifecycle',
|
||||
},
|
||||
{
|
||||
title: 'Type',
|
||||
field: 'spec.type',
|
||||
render: (entity: Entity) => (
|
||||
<ApiTypeTitle apiEntity={entity as ApiEntityV1alpha1} />
|
||||
field: 'resolved.ownedByRelationsTitle',
|
||||
render: ({ resolved }) => (
|
||||
<EntityRefLinks
|
||||
entityRefs={resolved.ownedByRelations}
|
||||
defaultKind="group"
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: 'Lifecycle',
|
||||
field: 'entity.spec.lifecycle',
|
||||
},
|
||||
{
|
||||
title: 'Type',
|
||||
field: 'entity.spec.type',
|
||||
render: ({ entity }) => <ApiTypeTitle apiEntity={entity} />,
|
||||
},
|
||||
{
|
||||
title: 'Description',
|
||||
field: 'metadata.description',
|
||||
field: 'entity.metadata.description',
|
||||
},
|
||||
{
|
||||
title: 'Tags',
|
||||
field: 'metadata.tags',
|
||||
field: 'entity.metadata.tags',
|
||||
cellStyle: {
|
||||
padding: '0px 16px 0px 20px',
|
||||
},
|
||||
render: (entity: Entity) => (
|
||||
render: ({ entity }) => (
|
||||
<>
|
||||
{entity.metadata.tags &&
|
||||
entity.metadata.tags.map(t => (
|
||||
@@ -123,8 +159,36 @@ export const ApiExplorerTable = ({
|
||||
);
|
||||
}
|
||||
|
||||
const rows = entities.map(entity => {
|
||||
const partOfSystemRelations = getEntityRelations(entity, RELATION_PART_OF, {
|
||||
kind: 'system',
|
||||
});
|
||||
const ownedByRelations = getEntityRelations(entity, RELATION_OWNED_BY);
|
||||
|
||||
return {
|
||||
entity: entity as ApiEntityV1alpha1,
|
||||
resolved: {
|
||||
name: formatEntityRefTitle(entity, {
|
||||
defaultKind: 'API',
|
||||
}),
|
||||
ownedByRelationsTitle: ownedByRelations
|
||||
.map(r => formatEntityRefTitle(r, { defaultKind: 'group' }))
|
||||
.join(', '),
|
||||
ownedByRelations,
|
||||
partOfSystemRelationTitle: partOfSystemRelations
|
||||
.map(r =>
|
||||
formatEntityRefTitle(r, {
|
||||
defaultKind: 'system',
|
||||
}),
|
||||
)
|
||||
.join(', '),
|
||||
partOfSystemRelations,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
return (
|
||||
<Table
|
||||
<Table<EntityRow>
|
||||
isLoading={loading}
|
||||
columns={columns}
|
||||
options={{
|
||||
@@ -134,7 +198,7 @@ export const ApiExplorerTable = ({
|
||||
padding: 'dense',
|
||||
showEmptyDataSourceMessage: !loading,
|
||||
}}
|
||||
data={entities}
|
||||
data={rows}
|
||||
filters={filters}
|
||||
initialState={queryParamState}
|
||||
onStateChange={setQueryParamState}
|
||||
|
||||
@@ -14,37 +14,73 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ApiEntity } from '@backstage/catalog-model';
|
||||
import {
|
||||
ApiEntity,
|
||||
EntityName,
|
||||
RELATION_OWNED_BY,
|
||||
RELATION_PART_OF,
|
||||
} from '@backstage/catalog-model';
|
||||
import { Table, TableColumn } from '@backstage/core';
|
||||
import {
|
||||
EntityRefLink,
|
||||
EntityRefLinks,
|
||||
formatEntityRefTitle,
|
||||
getEntityRelations,
|
||||
} from '@backstage/plugin-catalog-react';
|
||||
import React from 'react';
|
||||
import { ApiTypeTitle } from '../ApiDefinitionCard';
|
||||
import { EntityLink } from '../EntityLink';
|
||||
|
||||
const columns: TableColumn<ApiEntity>[] = [
|
||||
type EntityRow = {
|
||||
entity: ApiEntity;
|
||||
resolved: {
|
||||
partOfSystemRelationTitle?: string;
|
||||
partOfSystemRelations: EntityName[];
|
||||
ownedByRelationsTitle?: string;
|
||||
ownedByRelations: EntityName[];
|
||||
};
|
||||
};
|
||||
|
||||
const columns: TableColumn<EntityRow>[] = [
|
||||
{
|
||||
title: 'Name',
|
||||
field: 'metadata.name',
|
||||
field: 'entity.metadata.name',
|
||||
highlight: true,
|
||||
render: (entity: any) => (
|
||||
<EntityLink entity={entity}>{entity.metadata.name}</EntityLink>
|
||||
render: ({ entity }) => (
|
||||
<EntityRefLink entityRef={entity}>{entity.metadata.name}</EntityRefLink>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: 'System',
|
||||
field: 'resolved.partOfSystemRelationTitle',
|
||||
render: ({ resolved }) => (
|
||||
<EntityRefLinks
|
||||
entityRefs={resolved.partOfSystemRelations}
|
||||
defaultKind="system"
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: 'Owner',
|
||||
field: 'spec.owner',
|
||||
field: 'resolved.ownedByRelationsTitle',
|
||||
render: ({ resolved }) => (
|
||||
<EntityRefLinks
|
||||
entityRefs={resolved.ownedByRelations}
|
||||
defaultKind="group"
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: 'Lifecycle',
|
||||
field: 'spec.lifecycle',
|
||||
field: 'entity.spec.lifecycle',
|
||||
},
|
||||
{
|
||||
title: 'Type',
|
||||
field: 'spec.type',
|
||||
render: (entity: ApiEntity) => <ApiTypeTitle apiEntity={entity} />,
|
||||
field: 'entity.spec.type',
|
||||
render: ({ entity }) => <ApiTypeTitle apiEntity={entity} />,
|
||||
},
|
||||
{
|
||||
title: 'Description',
|
||||
field: 'metadata.description',
|
||||
field: 'entity.metadata.description',
|
||||
width: 'auto',
|
||||
},
|
||||
];
|
||||
@@ -65,8 +101,40 @@ export const ApisTable = ({ entities, title, variant = 'gridItem' }: Props) => {
|
||||
tableStyle.height = 'calc(100% - 10px)';
|
||||
}
|
||||
|
||||
const rows = entities
|
||||
// TODO: For now we skip all APIs that we can't find without a warning!
|
||||
.filter(e => e !== undefined)
|
||||
.map(entity => {
|
||||
const partOfSystemRelations = getEntityRelations(
|
||||
entity,
|
||||
RELATION_PART_OF,
|
||||
{
|
||||
kind: 'system',
|
||||
},
|
||||
);
|
||||
const ownedByRelations = getEntityRelations(entity, RELATION_OWNED_BY);
|
||||
|
||||
return {
|
||||
entity: entity as ApiEntity,
|
||||
resolved: {
|
||||
ownedByRelationsTitle: ownedByRelations
|
||||
.map(r => formatEntityRefTitle(r, { defaultKind: 'group' }))
|
||||
.join(', '),
|
||||
ownedByRelations,
|
||||
partOfSystemRelationTitle: partOfSystemRelations
|
||||
.map(r =>
|
||||
formatEntityRefTitle(r, {
|
||||
defaultKind: 'system',
|
||||
}),
|
||||
)
|
||||
.join(', '),
|
||||
partOfSystemRelations,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
return (
|
||||
<Table<ApiEntity>
|
||||
<Table<EntityRow>
|
||||
columns={columns}
|
||||
title={title}
|
||||
style={tableStyle}
|
||||
@@ -77,8 +145,7 @@ export const ApisTable = ({ entities, title, variant = 'gridItem' }: Props) => {
|
||||
actionsColumnIndex: -1,
|
||||
padding: 'dense',
|
||||
}}
|
||||
// TODO: For now we skip all APIs that we can't find without a warning!
|
||||
data={entities.filter(e => e !== undefined) as ApiEntity[]}
|
||||
data={rows}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -14,9 +14,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Entity, RELATION_CONSUMES_API } from '@backstage/catalog-model';
|
||||
import {
|
||||
Entity,
|
||||
RELATION_CONSUMES_API,
|
||||
RELATION_OWNED_BY,
|
||||
RELATION_PART_OF,
|
||||
} from '@backstage/catalog-model';
|
||||
import { ApiProvider, ApiRegistry } from '@backstage/core';
|
||||
import { CatalogApi, catalogApiRef } from '@backstage/plugin-catalog';
|
||||
import { CatalogApi, catalogApiRef } from '@backstage/plugin-catalog-react';
|
||||
import { renderInTestApp } from '@backstage/test-utils';
|
||||
import { waitFor } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
@@ -99,10 +104,27 @@ describe('<ConsumedApisCard />', () => {
|
||||
},
|
||||
spec: {
|
||||
type: 'openapi',
|
||||
owner: 'Test',
|
||||
lifecycle: 'production',
|
||||
definition: '...',
|
||||
},
|
||||
relations: [
|
||||
{
|
||||
type: RELATION_PART_OF,
|
||||
target: {
|
||||
kind: 'System',
|
||||
name: 'MySystem',
|
||||
namespace: 'default',
|
||||
},
|
||||
},
|
||||
{
|
||||
type: RELATION_OWNED_BY,
|
||||
target: {
|
||||
kind: 'Group',
|
||||
name: 'Test',
|
||||
namespace: 'default',
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
apiDocsConfig.getApiDefinitionWidget.mockReturnValue({
|
||||
type: 'openapi',
|
||||
@@ -121,6 +143,7 @@ describe('<ConsumedApisCard />', () => {
|
||||
expect(getByText(/target-name/i)).toBeInTheDocument();
|
||||
expect(getByText(/OpenAPI/)).toBeInTheDocument();
|
||||
expect(getByText(/Test/i)).toBeInTheDocument();
|
||||
expect(getByText(/MySystem/i)).toBeInTheDocument();
|
||||
expect(getByText(/production/i)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -14,9 +14,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Entity, RELATION_PROVIDES_API } from '@backstage/catalog-model';
|
||||
import {
|
||||
Entity,
|
||||
RELATION_OWNED_BY,
|
||||
RELATION_PART_OF,
|
||||
RELATION_PROVIDES_API,
|
||||
} from '@backstage/catalog-model';
|
||||
import { ApiProvider, ApiRegistry } from '@backstage/core';
|
||||
import { CatalogApi, catalogApiRef } from '@backstage/plugin-catalog';
|
||||
import { CatalogApi, catalogApiRef } from '@backstage/plugin-catalog-react';
|
||||
import { renderInTestApp } from '@backstage/test-utils';
|
||||
import { waitFor } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
@@ -99,10 +104,27 @@ describe('<ProvidedApisCard />', () => {
|
||||
},
|
||||
spec: {
|
||||
type: 'openapi',
|
||||
owner: 'Test',
|
||||
lifecycle: 'production',
|
||||
definition: '...',
|
||||
},
|
||||
relations: [
|
||||
{
|
||||
type: RELATION_PART_OF,
|
||||
target: {
|
||||
kind: 'System',
|
||||
name: 'MySystem',
|
||||
namespace: 'default',
|
||||
},
|
||||
},
|
||||
{
|
||||
type: RELATION_OWNED_BY,
|
||||
target: {
|
||||
kind: 'Group',
|
||||
name: 'Test',
|
||||
namespace: 'default',
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
apiDocsConfig.getApiDefinitionWidget.mockReturnValue({
|
||||
type: 'openapi',
|
||||
@@ -120,6 +142,7 @@ describe('<ProvidedApisCard />', () => {
|
||||
expect(getByText(/Provided APIs/i)).toBeInTheDocument();
|
||||
expect(getByText(/target-name/i)).toBeInTheDocument();
|
||||
expect(getByText(/OpenAPI/)).toBeInTheDocument();
|
||||
expect(getByText(/MySystem/)).toBeInTheDocument();
|
||||
expect(getByText(/Test/i)).toBeInTheDocument();
|
||||
expect(getByText(/production/i)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
@@ -14,35 +14,71 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ComponentEntity } from '@backstage/catalog-model';
|
||||
import {
|
||||
ComponentEntity,
|
||||
EntityName,
|
||||
RELATION_OWNED_BY,
|
||||
RELATION_PART_OF,
|
||||
} from '@backstage/catalog-model';
|
||||
import { Table, TableColumn } from '@backstage/core';
|
||||
import {
|
||||
EntityRefLink,
|
||||
EntityRefLinks,
|
||||
formatEntityRefTitle,
|
||||
getEntityRelations,
|
||||
} from '@backstage/plugin-catalog-react';
|
||||
import React from 'react';
|
||||
import { EntityLink } from '../EntityLink';
|
||||
|
||||
const columns: TableColumn<ComponentEntity>[] = [
|
||||
type EntityRow = {
|
||||
entity: ComponentEntity;
|
||||
resolved: {
|
||||
partOfSystemRelationTitle?: string;
|
||||
partOfSystemRelations: EntityName[];
|
||||
ownedByRelationsTitle?: string;
|
||||
ownedByRelations: EntityName[];
|
||||
};
|
||||
};
|
||||
|
||||
const columns: TableColumn<EntityRow>[] = [
|
||||
{
|
||||
title: 'Name',
|
||||
field: 'metadata.name',
|
||||
field: 'entity.metadata.name',
|
||||
highlight: true,
|
||||
render: (entity: any) => (
|
||||
<EntityLink entity={entity}>{entity.metadata.name}</EntityLink>
|
||||
render: ({ entity }) => (
|
||||
<EntityRefLink entityRef={entity}>{entity.metadata.name}</EntityRefLink>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: 'System',
|
||||
field: 'resolved.partOfSystemRelationTitle',
|
||||
render: ({ resolved }) => (
|
||||
<EntityRefLinks
|
||||
entityRefs={resolved.partOfSystemRelations}
|
||||
defaultKind="system"
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: 'Owner',
|
||||
field: 'spec.owner',
|
||||
field: 'resolved.ownedByRelationsTitle',
|
||||
render: ({ resolved }) => (
|
||||
<EntityRefLinks
|
||||
entityRefs={resolved.ownedByRelations}
|
||||
defaultKind="group"
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: 'Lifecycle',
|
||||
field: 'spec.lifecycle',
|
||||
field: 'entity.spec.lifecycle',
|
||||
},
|
||||
{
|
||||
title: 'Type',
|
||||
field: 'spec.type',
|
||||
field: 'entity.spec.type',
|
||||
},
|
||||
{
|
||||
title: 'Description',
|
||||
field: 'metadata.description',
|
||||
field: 'entity.metadata.description',
|
||||
width: 'auto',
|
||||
},
|
||||
];
|
||||
@@ -68,8 +104,40 @@ export const ComponentsTable = ({
|
||||
tableStyle.height = 'calc(100% - 10px)';
|
||||
}
|
||||
|
||||
const rows = entities
|
||||
// TODO: For now we skip all Components that we can't find without a warning!
|
||||
.filter(e => e !== undefined)
|
||||
.map(entity => {
|
||||
const partOfSystemRelations = getEntityRelations(
|
||||
entity,
|
||||
RELATION_PART_OF,
|
||||
{
|
||||
kind: 'system',
|
||||
},
|
||||
);
|
||||
const ownedByRelations = getEntityRelations(entity, RELATION_OWNED_BY);
|
||||
|
||||
return {
|
||||
entity: entity as ComponentEntity,
|
||||
resolved: {
|
||||
ownedByRelationsTitle: ownedByRelations
|
||||
.map(r => formatEntityRefTitle(r, { defaultKind: 'group' }))
|
||||
.join(', '),
|
||||
ownedByRelations,
|
||||
partOfSystemRelationTitle: partOfSystemRelations
|
||||
.map(r =>
|
||||
formatEntityRefTitle(r, {
|
||||
defaultKind: 'system',
|
||||
}),
|
||||
)
|
||||
.join(', '),
|
||||
partOfSystemRelations,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
return (
|
||||
<Table<ComponentEntity>
|
||||
<Table<EntityRow>
|
||||
columns={columns}
|
||||
title={title}
|
||||
style={tableStyle}
|
||||
@@ -80,8 +148,7 @@ export const ComponentsTable = ({
|
||||
actionsColumnIndex: -1,
|
||||
padding: 'dense',
|
||||
}}
|
||||
// TODO: For now we skip all APIs that we can't find without a warning!
|
||||
data={entities.filter(e => e !== undefined) as ComponentEntity[]}
|
||||
data={rows}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -14,9 +14,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Entity, RELATION_API_CONSUMED_BY } from '@backstage/catalog-model';
|
||||
import {
|
||||
Entity,
|
||||
RELATION_API_CONSUMED_BY,
|
||||
RELATION_OWNED_BY,
|
||||
RELATION_PART_OF,
|
||||
} from '@backstage/catalog-model';
|
||||
import { ApiProvider, ApiRegistry } from '@backstage/core';
|
||||
import { CatalogApi, catalogApiRef } from '@backstage/plugin-catalog';
|
||||
import { CatalogApi, catalogApiRef } from '@backstage/plugin-catalog-react';
|
||||
import { renderInTestApp } from '@backstage/test-utils';
|
||||
import { waitFor } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
@@ -104,9 +109,26 @@ describe('<ConsumingComponentsCard />', () => {
|
||||
},
|
||||
spec: {
|
||||
type: 'service',
|
||||
owner: 'Test',
|
||||
lifecycle: 'production',
|
||||
},
|
||||
relations: [
|
||||
{
|
||||
type: RELATION_PART_OF,
|
||||
target: {
|
||||
kind: 'System',
|
||||
name: 'MySystem',
|
||||
namespace: 'default',
|
||||
},
|
||||
},
|
||||
{
|
||||
type: RELATION_OWNED_BY,
|
||||
target: {
|
||||
kind: 'Group',
|
||||
name: 'Test',
|
||||
namespace: 'default',
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const { getByText } = await renderInTestApp(
|
||||
@@ -119,6 +141,7 @@ describe('<ConsumingComponentsCard />', () => {
|
||||
expect(getByText(/Consumers/i)).toBeInTheDocument();
|
||||
expect(getByText(/target-name/i)).toBeInTheDocument();
|
||||
expect(getByText(/Test/i)).toBeInTheDocument();
|
||||
expect(getByText(/MySystem/i)).toBeInTheDocument();
|
||||
expect(getByText(/production/i)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -14,9 +14,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Entity, RELATION_API_PROVIDED_BY } from '@backstage/catalog-model';
|
||||
import {
|
||||
Entity,
|
||||
RELATION_API_PROVIDED_BY,
|
||||
RELATION_OWNED_BY,
|
||||
RELATION_PART_OF,
|
||||
} from '@backstage/catalog-model';
|
||||
import { ApiProvider, ApiRegistry } from '@backstage/core';
|
||||
import { CatalogApi, catalogApiRef } from '@backstage/plugin-catalog';
|
||||
import { CatalogApi, catalogApiRef } from '@backstage/plugin-catalog-react';
|
||||
import { renderInTestApp } from '@backstage/test-utils';
|
||||
import { waitFor } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
@@ -104,9 +109,26 @@ describe('<ProvidingComponentsCard />', () => {
|
||||
},
|
||||
spec: {
|
||||
type: 'service',
|
||||
owner: 'Test',
|
||||
lifecycle: 'production',
|
||||
},
|
||||
relations: [
|
||||
{
|
||||
type: RELATION_PART_OF,
|
||||
target: {
|
||||
kind: 'System',
|
||||
name: 'MySystem',
|
||||
namespace: 'default',
|
||||
},
|
||||
},
|
||||
{
|
||||
type: RELATION_OWNED_BY,
|
||||
target: {
|
||||
kind: 'Group',
|
||||
name: 'Test',
|
||||
namespace: 'default',
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const { getByText } = await renderInTestApp(
|
||||
@@ -119,6 +141,7 @@ describe('<ProvidingComponentsCard />', () => {
|
||||
expect(getByText(/Providers/i)).toBeInTheDocument();
|
||||
expect(getByText(/target-name/i)).toBeInTheDocument();
|
||||
expect(getByText(/Test/i)).toBeInTheDocument();
|
||||
expect(getByText(/MySystem/i)).toBeInTheDocument();
|
||||
expect(getByText(/production/i)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* 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 { Entity } from '@backstage/catalog-model';
|
||||
import { renderInTestApp } from '@backstage/test-utils';
|
||||
import React from 'react';
|
||||
import { EntityLink } from './EntityLink';
|
||||
|
||||
describe('<EntityLink />', () => {
|
||||
it('provides link to entity page', async () => {
|
||||
const entity: Entity = {
|
||||
apiVersion: 'v1',
|
||||
kind: 'Component',
|
||||
metadata: {
|
||||
name: 'my-name',
|
||||
namespace: 'my-namespace',
|
||||
},
|
||||
};
|
||||
const { getByText } = await renderInTestApp(
|
||||
<EntityLink entity={entity}>inner</EntityLink>,
|
||||
);
|
||||
expect(getByText(/inner/i)).toBeInTheDocument();
|
||||
expect(getByText(/inner/i)).toHaveAttribute(
|
||||
'href',
|
||||
'/catalog/my-namespace/component/my-name',
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* 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 { Entity } from '@backstage/catalog-model';
|
||||
import { entityRoute, entityRouteParams } from '@backstage/plugin-catalog';
|
||||
import { Link } from '@material-ui/core';
|
||||
import React, { PropsWithChildren } from 'react';
|
||||
import { generatePath, Link as RouterLink } from 'react-router-dom';
|
||||
|
||||
type Props = {
|
||||
entity: Entity;
|
||||
};
|
||||
|
||||
// TODO: Could be useful for others too, as part of the catalog plugin
|
||||
export const EntityLink = ({ entity, children }: PropsWithChildren<Props>) => {
|
||||
return (
|
||||
<Link
|
||||
component={RouterLink}
|
||||
to={generatePath(
|
||||
`/catalog/${entityRoute.path}`,
|
||||
entityRouteParams(entity),
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</Link>
|
||||
);
|
||||
};
|
||||
@@ -1,17 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export { EntityLink } from './EntityLink';
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { useApi } from '@backstage/core';
|
||||
import { catalogApiRef } from '@backstage/plugin-catalog';
|
||||
import { catalogApiRef } from '@backstage/plugin-catalog-react';
|
||||
import { useAsyncRetry } from 'react-use';
|
||||
|
||||
// TODO: Maybe this hook is interesting for others too?
|
||||
|
||||
Reference in New Issue
Block a user