Merge pull request #5593 from splunk/feature/5536_make-catalogtable-configurable

[Fixes #5536] Make CatalogTable configurable
This commit is contained in:
Ben Lambert
2021-05-11 19:57:56 +02:00
committed by GitHub
7 changed files with 179 additions and 88 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog': patch
---
This makes the CatalogTable configurable with custom columns, passed through the CatalogPage component rendered on the home page.
@@ -20,6 +20,7 @@ import {
ContentHeader,
errorApiRef,
SupportButton,
TableColumn,
useApi,
useRouteRef,
} from '@backstage/core';
@@ -42,6 +43,7 @@ import {
CatalogFilterType,
} from '../CatalogFilter/CatalogFilter';
import { CatalogTable } from '../CatalogTable/CatalogTable';
import { EntityRow } from '../CatalogTable/types';
import { ResultsFilter } from '../ResultsFilter/ResultsFilter';
import { useOwnUser } from '../useOwnUser';
import CatalogLayout from './CatalogLayout';
@@ -61,6 +63,7 @@ const useStyles = makeStyles(theme => ({
export type CatalogPageProps = {
initiallySelectedFilter?: string;
columns?: TableColumn<EntityRow>[];
};
const CatalogPageContents = (props: CatalogPageProps) => {
@@ -210,6 +213,7 @@ const CatalogPageContents = (props: CatalogPageProps) => {
<CatalogTable
titlePreamble={selectedSidebarItem?.label ?? ''}
view={selectedTab}
columns={props.columns}
entities={matchingEntities}
loading={loading}
error={error}
@@ -15,26 +15,21 @@
*/
import {
Entity,
EntityName,
RELATION_OWNED_BY,
RELATION_PART_OF,
} from '@backstage/catalog-model';
import {
CodeSnippet,
OverflowTooltip,
Table,
TableColumn,
TableProps,
WarningPanel,
} from '@backstage/core';
import {
EntityRefLink,
EntityRefLinks,
formatEntityRefTitle,
getEntityRelations,
useStarredEntities,
} from '@backstage/plugin-catalog-react';
import { Chip } from '@material-ui/core';
import Edit from '@material-ui/icons/Edit';
import OpenInNew from '@material-ui/icons/OpenInNew';
import React from 'react';
@@ -46,88 +41,17 @@ import {
favouriteEntityIcon,
favouriteEntityTooltip,
} from '../FavouriteEntity/FavouriteEntity';
import * as columnFactories from './columns';
import { EntityRow } from './types';
type EntityRow = {
entity: Entity;
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="Component" />
),
},
{
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: 'Type',
field: 'entity.spec.type',
hidden: true,
},
{
title: 'Lifecycle',
field: 'entity.spec.lifecycle',
},
{
title: 'Description',
field: 'entity.metadata.description',
render: ({ entity }) => (
<OverflowTooltip
text={entity.metadata.description}
placement="bottom-start"
/>
),
width: 'auto',
},
{
title: 'Tags',
field: 'entity.metadata.tags',
cellStyle: {
padding: '0px 16px 0px 20px',
},
render: ({ entity }) => (
<>
{entity.metadata.tags &&
entity.metadata.tags.map(t => (
<Chip
key={t}
label={t}
size="small"
variant="outlined"
style={{ marginBottom: '0px' }}
/>
))}
</>
),
},
const defaultColumns: TableColumn<EntityRow>[] = [
columnFactories.createNameColumn(),
columnFactories.createSystemColumn(),
columnFactories.createOwnerColumn(),
columnFactories.createSpecTypeColumn(),
columnFactories.createSpecLifecycleColumn(),
columnFactories.createMetadataDescriptionColumn(),
columnFactories.createTagsColumn(),
];
type CatalogTableProps = {
@@ -136,6 +60,7 @@ type CatalogTableProps = {
loading: boolean;
error?: any;
view?: string;
columns?: TableColumn<EntityRow>[];
};
export const CatalogTable = ({
@@ -144,6 +69,7 @@ export const CatalogTable = ({
error,
titlePreamble,
view,
columns,
}: CatalogTableProps) => {
const { isStarredEntity, toggleStarredEntity } = useStarredEntities();
@@ -224,7 +150,7 @@ export const CatalogTable = ({
};
});
const typeColumn = columns.find(c => c.title === 'Type');
const typeColumn = (columns || defaultColumns).find(c => c.title === 'Type');
if (typeColumn) {
typeColumn.hidden = view !== 'Other';
}
@@ -232,7 +158,7 @@ export const CatalogTable = ({
return (
<Table<EntityRow>
isLoading={loading}
columns={columns}
columns={columns || defaultColumns}
options={{
paging: true,
pageSize: 20,
@@ -248,3 +174,5 @@ export const CatalogTable = ({
/>
);
};
CatalogTable.columns = columnFactories;
@@ -0,0 +1,110 @@
/*
* 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 React from 'react';
import { EntityRefLink, EntityRefLinks } from '@backstage/plugin-catalog-react';
import { OverflowTooltip, TableColumn } from '@backstage/core';
import { Chip } from '@material-ui/core';
import { EntityRow } from './types';
export function createNameColumn(): TableColumn<EntityRow> {
return {
title: 'Name',
field: 'resolved.name',
highlight: true,
render: ({ entity }) => (
<EntityRefLink entityRef={entity} defaultKind="Component" />
),
};
}
export function createSystemColumn(): TableColumn<EntityRow> {
return {
title: 'System',
field: 'resolved.partOfSystemRelationTitle',
render: ({ resolved }) => (
<EntityRefLinks
entityRefs={resolved.partOfSystemRelations}
defaultKind="system"
/>
),
};
}
export function createOwnerColumn(): TableColumn<EntityRow> {
return {
title: 'Owner',
field: 'resolved.ownedByRelationsTitle',
render: ({ resolved }) => (
<EntityRefLinks
entityRefs={resolved.ownedByRelations}
defaultKind="group"
/>
),
};
}
export function createSpecTypeColumn(): TableColumn<EntityRow> {
return {
title: 'Type',
field: 'entity.spec.type',
hidden: true,
};
}
export function createSpecLifecycleColumn(): TableColumn<EntityRow> {
return {
title: 'Lifecycle',
field: 'entity.spec.lifecycle',
};
}
export function createMetadataDescriptionColumn(): TableColumn<EntityRow> {
return {
title: 'Description',
field: 'entity.metadata.description',
render: ({ entity }) => (
<OverflowTooltip
text={entity.metadata.description}
placement="bottom-start"
/>
),
width: 'auto',
};
}
export function createTagsColumn(): TableColumn<EntityRow> {
return {
title: 'Tags',
field: 'entity.metadata.tags',
cellStyle: {
padding: '0px 16px 0px 20px',
},
render: ({ entity }) => (
<>
{entity.metadata.tags &&
entity.metadata.tags.map(t => (
<Chip
key={t}
label={t}
size="small"
variant="outlined"
style={{ marginBottom: '0px' }}
/>
))}
</>
),
};
}
@@ -0,0 +1,16 @@
/*
* 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 { CatalogTable } from './CatalogTable';
@@ -0,0 +1,27 @@
/*
* 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, EntityName } from '@backstage/catalog-model';
export type EntityRow = {
entity: Entity;
resolved: {
name: string;
partOfSystemRelationTitle?: string;
partOfSystemRelations: EntityName[];
ownedByRelationsTitle?: string;
ownedByRelations: EntityName[];
};
};
+1
View File
@@ -17,6 +17,7 @@
export { AboutCard } from './components/AboutCard';
export { EntityLayout } from './components/EntityLayout';
export { EntityPageLayout } from './components/EntityPageLayout';
export { CatalogTable } from './components/CatalogTable';
export * from './components/EntitySwitch';
export { Router } from './components/Router';
export {