Use EntityTable everywhere

This commit is contained in:
Oliver Sand
2021-02-12 10:40:42 +01:00
parent 6141ec38fb
commit bd27885876
19 changed files with 237 additions and 616 deletions
@@ -1,167 +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 {
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 { makeStyles } from '@material-ui/core';
import React from 'react';
import { ApiTypeTitle } from '../ApiDefinitionCard';
type EntityRow = {
entity: ApiEntity;
resolved: {
name: string;
partOfSystemRelationTitle?: string;
partOfSystemRelations: EntityName[];
ownedByRelationsTitle?: string;
ownedByRelations: EntityName[];
};
};
const columns: TableColumn<EntityRow>[] = [
{
title: 'Name',
field: 'resolved.name',
highlight: true,
render: ({ entity }) => (
<EntityRefLink entityRef={entity} defaultKind="API" />
),
},
{
title: 'System',
field: 'resolved.partOfSystemRelationTitle',
render: ({ resolved }) => (
<EntityRefLinks
entityRefs={resolved.partOfSystemRelations}
defaultKind="system"
/>
),
},
{
title: 'Owner',
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: 'entity.metadata.description',
width: 'auto',
},
];
type Props = {
title: string;
variant?: string;
entities: ApiEntity[];
emptyComponent?: JSX.Element;
};
const useStyles = makeStyles(theme => ({
empty: {
padding: theme.spacing(2),
display: 'flex',
justifyContent: 'center',
},
}));
export const ApisTable = ({
entities,
title,
emptyComponent,
variant = 'gridItem',
}: Props) => {
const classes = useStyles();
const tableStyle: React.CSSProperties = {
minWidth: '0',
width: '100%',
};
if (variant === 'gridItem') {
tableStyle.height = 'calc(100% - 10px)';
}
const rows = entities.map(entity => {
const partOfSystemRelations = getEntityRelations(entity, RELATION_PART_OF, {
kind: 'system',
});
const ownedByRelations = getEntityRelations(entity, RELATION_OWNED_BY);
return {
entity,
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<EntityRow>
columns={columns}
title={title}
style={tableStyle}
emptyComponent={
emptyComponent && <div className={classes.empty}>{emptyComponent}</div>
}
options={{
// TODO: Toolbar padding if off compared to other cards, should be: padding: 16px 24px;
search: false,
paging: false,
actionsColumnIndex: -1,
padding: 'dense',
}}
data={rows}
/>
);
};
@@ -26,9 +26,13 @@ import {
Progress,
WarningPanel,
} from '@backstage/core';
import { useEntity, useRelatedEntities } from '@backstage/plugin-catalog-react';
import {
EntityTable,
useEntity,
useRelatedEntities,
} from '@backstage/plugin-catalog-react';
import React, { PropsWithChildren } from 'react';
import { ApisTable } from './ApisTable';
import { apiEntityColumns } from './presets';
const ApisCard = ({
children,
@@ -74,7 +78,7 @@ export const ConsumedApisCard = ({ variant = 'gridItem' }: Props) => {
}
return (
<ApisTable
<EntityTable
title="Consumed APIs"
variant={variant}
emptyComponent={
@@ -85,6 +89,7 @@ export const ConsumedApisCard = ({ variant = 'gridItem' }: Props) => {
</Link>
</div>
}
columns={apiEntityColumns}
entities={entities as ApiEntity[]}
/>
);
@@ -22,9 +22,13 @@ import {
Progress,
WarningPanel,
} from '@backstage/core';
import { useEntity, useRelatedEntities } from '@backstage/plugin-catalog-react';
import {
EntityTable,
useEntity,
useRelatedEntities,
} from '@backstage/plugin-catalog-react';
import React, { PropsWithChildren } from 'react';
import { ApisTable } from './ApisTable';
import { apiEntityColumns } from './presets';
const ApisCard = ({
children,
@@ -69,7 +73,7 @@ export const HasApisCard = ({ variant = 'gridItem' }: Props) => {
}
return (
<ApisTable
<EntityTable
title="APIs"
variant={variant}
emptyComponent={
@@ -80,6 +84,7 @@ export const HasApisCard = ({ variant = 'gridItem' }: Props) => {
</Link>
</div>
}
columns={apiEntityColumns}
entities={entities as ApiEntity[]}
/>
);
@@ -26,9 +26,13 @@ import {
Progress,
WarningPanel,
} from '@backstage/core';
import { useEntity, useRelatedEntities } from '@backstage/plugin-catalog-react';
import {
EntityTable,
useEntity,
useRelatedEntities,
} from '@backstage/plugin-catalog-react';
import React, { PropsWithChildren } from 'react';
import { ApisTable } from './ApisTable';
import { apiEntityColumns } from './presets';
const ApisCard = ({
children,
@@ -74,7 +78,7 @@ export const ProvidedApisCard = ({ variant = 'gridItem' }: Props) => {
}
return (
<ApisTable
<EntityTable
title="Provided APIs"
variant={variant}
emptyComponent={
@@ -85,6 +89,7 @@ export const ProvidedApisCard = ({ variant = 'gridItem' }: Props) => {
</Link>
</div>
}
columns={apiEntityColumns}
entities={entities as ApiEntity[]}
/>
);
@@ -0,0 +1,42 @@
/*
* 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 { ApiEntity } from '@backstage/catalog-model';
import { TableColumn } from '@backstage/core';
import { EntityTable } from '@backstage/plugin-catalog-react';
import React from 'react';
import { ApiTypeTitle } from '../ApiDefinitionCard';
export function createSpecApiTypeColumn(): TableColumn<ApiEntity> {
return {
title: 'Type',
field: 'spec.type',
render: entity => <ApiTypeTitle apiEntity={entity} />,
};
}
// TODO: This could be moved to plugin-catalog-react if we wouldn't have a
// special createSpecApiTypeColumn. But this is requited to use ApiTypeTitle to
// resolve the display name of an entity. Is the display name really worth it?
export const apiEntityColumns: TableColumn<ApiEntity>[] = [
EntityTable.columns.createEntityRefColumn({ defaultKind: 'API' }),
EntityTable.columns.createSystemColumn(),
EntityTable.columns.createOwnerColumn(),
EntityTable.columns.createSpecLifecycleColumn(),
createSpecApiTypeColumn(),
EntityTable.columns.createMetadataDescriptionColumn(),
];
@@ -27,11 +27,10 @@ import {
WarningPanel,
} from '@backstage/core';
import {
ComponentsTable,
EntityTable,
useEntity,
useRelatedEntities,
} from '@backstage/plugin-catalog-react';
import React, { PropsWithChildren } from 'react';
const ComponentsCard = ({
@@ -78,7 +77,7 @@ export const ConsumingComponentsCard = ({ variant = 'gridItem' }: Props) => {
}
return (
<ComponentsTable
<EntityTable
title="Consumers"
variant={variant}
emptyComponent={
@@ -89,6 +88,7 @@ export const ConsumingComponentsCard = ({ variant = 'gridItem' }: Props) => {
</Link>
</div>
}
columns={EntityTable.componentEntityColumns}
entities={entities as ComponentEntity[]}
/>
);
@@ -27,7 +27,7 @@ import {
WarningPanel,
} from '@backstage/core';
import {
ComponentsTable,
EntityTable,
useEntity,
useRelatedEntities,
} from '@backstage/plugin-catalog-react';
@@ -77,7 +77,7 @@ export const ProvidingComponentsCard = ({ variant = 'gridItem' }: Props) => {
}
return (
<ComponentsTable
<EntityTable
title="Providers"
variant={variant}
emptyComponent={
@@ -88,6 +88,7 @@ export const ProvidingComponentsCard = ({ variant = 'gridItem' }: Props) => {
</Link>
</div>
}
columns={EntityTable.componentEntityColumns}
entities={entities as ComponentEntity[]}
/>
);