diff --git a/.changeset/new-steaks-taste.md b/.changeset/new-steaks-taste.md new file mode 100644 index 0000000000..fc719cc19d --- /dev/null +++ b/.changeset/new-steaks-taste.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-api-docs': minor +--- + +add actions prop to the ApiExplorerPage diff --git a/plugins/api-docs/src/components/ApiExplorerPage/ApiExplorerPage.test.tsx b/plugins/api-docs/src/components/ApiExplorerPage/ApiExplorerPage.test.tsx index 518c3c7001..ac1c3d5361 100644 --- a/plugins/api-docs/src/components/ApiExplorerPage/ApiExplorerPage.test.tsx +++ b/plugins/api-docs/src/components/ApiExplorerPage/ApiExplorerPage.test.tsx @@ -15,7 +15,11 @@ */ import { Entity, RELATION_MEMBER_OF } from '@backstage/catalog-model'; -import { CatalogApi, catalogApiRef } from '@backstage/plugin-catalog-react'; +import { + CatalogApi, + catalogApiRef, + entityRouteRef, +} from '@backstage/plugin-catalog-react'; import { MockStorageApi, wrapInTestApp } from '@backstage/test-utils'; import { render } from '@testing-library/react'; import React from 'react'; @@ -32,6 +36,9 @@ import { ConfigApi, configApiRef, } from '@backstage/core-plugin-api'; +import { TableColumn, TableProps } from '@backstage/core-components'; +import DashboardIcon from '@material-ui/icons/Dashboard'; +import { CatalogTableRow } from '@backstage/plugin-catalog'; describe('ApiCatalogPage', () => { const catalogApi: Partial = { @@ -96,6 +103,11 @@ describe('ApiCatalogPage', () => { > {children} , + { + mountedRoutes: { + '/catalog/:namespace/:kind/:name': entityRouteRef, + }, + }, ), ); @@ -106,4 +118,82 @@ describe('ApiCatalogPage', () => { const { findByText } = renderWrapped(); expect(await findByText(/My Company API Explorer/)).toBeInTheDocument(); }); + + it('should render the default column of the grid', async () => { + const { getAllByRole } = await renderWrapped(); + + const columnHeader = getAllByRole('button').filter( + c => c.tagName === 'SPAN', + ); + const columnHeaderLabels = columnHeader.map(c => c.textContent); + + expect(columnHeaderLabels).toEqual([ + 'Name', + 'System', + 'Owner', + 'Type', + 'Lifecycle', + 'Description', + 'Tags', + 'Actions', + ]); + }); + + it('should render the custom column passed as prop', async () => { + const columns: TableColumn[] = [ + { title: 'Foo', field: 'entity.foo' }, + { title: 'Bar', field: 'entity.bar' }, + { title: 'Baz', field: 'entity.spec.lifecycle' }, + ]; + const { getAllByRole } = await renderWrapped( + , + ); + + const columnHeader = getAllByRole('button').filter( + c => c.tagName === 'SPAN', + ); + const columnHeaderLabels = columnHeader.map(c => c.textContent); + + expect(columnHeaderLabels).toEqual(['Foo', 'Bar', 'Baz', 'Actions']); + }); + + it('should render the default actions of an item in the grid', async () => { + const { findByTitle, findByText } = await renderWrapped( + , + ); + expect(await findByText(/Owned \(1\)/)).toBeInTheDocument(); + expect(await findByTitle(/View/)).toBeInTheDocument(); + expect(await findByTitle(/View/)).toBeInTheDocument(); + expect(await findByTitle(/Edit/)).toBeInTheDocument(); + expect(await findByTitle(/Add to favorites/)).toBeInTheDocument(); + }); + + it('should render the custom actions of an item passed as prop', async () => { + const actions: TableProps['actions'] = [ + () => { + return { + icon: () => , + tooltip: 'Foo Action', + disabled: false, + onClick: () => jest.fn(), + }; + }, + () => { + return { + icon: () => , + tooltip: 'Bar Action', + disabled: true, + onClick: () => jest.fn(), + }; + }, + ]; + + const { findByTitle, findByText } = await renderWrapped( + , + ); + expect(await findByText(/Owned \(1\)/)).toBeInTheDocument(); + expect(await findByTitle(/Foo Action/)).toBeInTheDocument(); + expect(await findByTitle(/Bar Action/)).toBeInTheDocument(); + expect((await findByTitle(/Bar Action/)).firstChild).toBeDisabled(); + }); }); diff --git a/plugins/api-docs/src/components/ApiExplorerPage/ApiExplorerPage.tsx b/plugins/api-docs/src/components/ApiExplorerPage/ApiExplorerPage.tsx index 2f74aaa166..f28574145e 100644 --- a/plugins/api-docs/src/components/ApiExplorerPage/ApiExplorerPage.tsx +++ b/plugins/api-docs/src/components/ApiExplorerPage/ApiExplorerPage.tsx @@ -21,6 +21,7 @@ import { PageWithHeader, SupportButton, TableColumn, + TableProps, } from '@backstage/core-components'; import { configApiRef, useApi, useRouteRef } from '@backstage/core-plugin-api'; import { @@ -56,11 +57,13 @@ const defaultColumns: TableColumn[] = [ type ApiExplorerPageProps = { initiallySelectedFilter?: UserListFilterKind; columns?: TableColumn[]; + actions?: TableProps['actions']; }; export const ApiExplorerPage = ({ initiallySelectedFilter = 'all', columns, + actions, }: ApiExplorerPageProps) => { const configApi = useApi(configApiRef); const generatedSubtitle = `${ @@ -94,7 +97,10 @@ export const ApiExplorerPage = ({ - +