diff --git a/.changeset/clean-starfishes-drop.md b/.changeset/clean-starfishes-drop.md new file mode 100644 index 0000000000..884bb8de9f --- /dev/null +++ b/.changeset/clean-starfishes-drop.md @@ -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. diff --git a/plugins/catalog/src/components/CatalogPage/CatalogPage.tsx b/plugins/catalog/src/components/CatalogPage/CatalogPage.tsx index fd3d63edd7..bbb26d7be7 100644 --- a/plugins/catalog/src/components/CatalogPage/CatalogPage.tsx +++ b/plugins/catalog/src/components/CatalogPage/CatalogPage.tsx @@ -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[]; }; const CatalogPageContents = (props: CatalogPageProps) => { @@ -210,6 +213,7 @@ const CatalogPageContents = (props: CatalogPageProps) => { [] = [ - { - title: 'Name', - field: 'resolved.name', - highlight: true, - render: ({ entity }) => ( - - ), - }, - { - title: 'System', - field: 'resolved.partOfSystemRelationTitle', - render: ({ resolved }) => ( - - ), - }, - { - title: 'Owner', - field: 'resolved.ownedByRelationsTitle', - render: ({ resolved }) => ( - - ), - }, - { - title: 'Type', - field: 'entity.spec.type', - hidden: true, - }, - { - title: 'Lifecycle', - field: 'entity.spec.lifecycle', - }, - { - title: 'Description', - field: 'entity.metadata.description', - render: ({ entity }) => ( - - ), - width: 'auto', - }, - { - title: 'Tags', - field: 'entity.metadata.tags', - cellStyle: { - padding: '0px 16px 0px 20px', - }, - render: ({ entity }) => ( - <> - {entity.metadata.tags && - entity.metadata.tags.map(t => ( - - ))} - - ), - }, +const defaultColumns: TableColumn[] = [ + 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[]; }; 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 ( isLoading={loading} - columns={columns} + columns={columns || defaultColumns} options={{ paging: true, pageSize: 20, @@ -248,3 +174,5 @@ export const CatalogTable = ({ /> ); }; + +CatalogTable.columns = columnFactories; diff --git a/plugins/catalog/src/components/CatalogTable/columns.tsx b/plugins/catalog/src/components/CatalogTable/columns.tsx new file mode 100644 index 0000000000..4f65e4b0c7 --- /dev/null +++ b/plugins/catalog/src/components/CatalogTable/columns.tsx @@ -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 { + return { + title: 'Name', + field: 'resolved.name', + highlight: true, + render: ({ entity }) => ( + + ), + }; +} + +export function createSystemColumn(): TableColumn { + return { + title: 'System', + field: 'resolved.partOfSystemRelationTitle', + render: ({ resolved }) => ( + + ), + }; +} + +export function createOwnerColumn(): TableColumn { + return { + title: 'Owner', + field: 'resolved.ownedByRelationsTitle', + render: ({ resolved }) => ( + + ), + }; +} + +export function createSpecTypeColumn(): TableColumn { + return { + title: 'Type', + field: 'entity.spec.type', + hidden: true, + }; +} + +export function createSpecLifecycleColumn(): TableColumn { + return { + title: 'Lifecycle', + field: 'entity.spec.lifecycle', + }; +} + +export function createMetadataDescriptionColumn(): TableColumn { + return { + title: 'Description', + field: 'entity.metadata.description', + render: ({ entity }) => ( + + ), + width: 'auto', + }; +} + +export function createTagsColumn(): TableColumn { + return { + title: 'Tags', + field: 'entity.metadata.tags', + cellStyle: { + padding: '0px 16px 0px 20px', + }, + render: ({ entity }) => ( + <> + {entity.metadata.tags && + entity.metadata.tags.map(t => ( + + ))} + + ), + }; +} diff --git a/plugins/catalog/src/components/CatalogTable/index.ts b/plugins/catalog/src/components/CatalogTable/index.ts new file mode 100644 index 0000000000..9148a22a41 --- /dev/null +++ b/plugins/catalog/src/components/CatalogTable/index.ts @@ -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'; diff --git a/plugins/catalog/src/components/CatalogTable/types.ts b/plugins/catalog/src/components/CatalogTable/types.ts new file mode 100644 index 0000000000..b1a0ce2739 --- /dev/null +++ b/plugins/catalog/src/components/CatalogTable/types.ts @@ -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[]; + }; +}; diff --git a/plugins/catalog/src/index.ts b/plugins/catalog/src/index.ts index 7ab7b95dd7..fb269fc484 100644 --- a/plugins/catalog/src/index.ts +++ b/plugins/catalog/src/index.ts @@ -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 {