Merge pull request #5593 from splunk/feature/5536_make-catalogtable-configurable
[Fixes #5536] Make CatalogTable configurable
This commit is contained in:
@@ -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[];
|
||||
};
|
||||
};
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user