Merge pull request #27632 from tylerd-canva/consistent-catalog-table-title

Make title consistent across CatalogTable impls
This commit is contained in:
Fredrik Adelöw
2024-12-06 14:27:00 +01:00
committed by GitHub
8 changed files with 85 additions and 16 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog': minor
---
Consistent title behaviour across CatalogTable, CursorPaginatedCatalogTable, and OffsetPaginatedCatalogTable.
+2 -1
View File
@@ -156,7 +156,7 @@ export interface CatalogSearchResultListItemProps {
result?: IndexableDocument;
}
// @public (undocumented)
// @public
export const CatalogTable: {
(props: CatalogTableProps): React_2.JSX.Element;
columns: Readonly<{
@@ -214,6 +214,7 @@ export interface CatalogTableProps {
subtitle?: string;
// (undocumented)
tableOptions?: TableProps<CatalogTableRow>['options'];
title?: string;
}
// @public (undocumented)
@@ -84,6 +84,19 @@ describe('CatalogTable component', () => {
).resolves.toBeInTheDocument();
});
it('should a custom title and subtitle when passed in', async () => {
await renderInTestApp(
<ApiProvider apis={mockApis}>
<MockEntityListContextProvider>
<CatalogTable title="My Title" subtitle="My Subtitle" />
</MockEntityListContextProvider>
</ApiProvider>,
);
expect(screen.queryByText('My Title')).toBeInTheDocument();
expect(screen.queryByText('My Subtitle')).toBeInTheDocument();
});
it('should display entity names when loading has finished and no error occurred', async () => {
await renderInTestApp(
<ApiProvider apis={mockApis}>
@@ -49,6 +49,7 @@ import { defaultCatalogTableColumnsFunc } from './defaultCatalogTableColumnsFunc
import { useTranslationRef } from '@backstage/core-plugin-api/alpha';
import { catalogTranslationRef } from '../../alpha/translation';
import { FavoriteToggleIcon } from '@backstage/core-components';
import { CatalogTableToolbar } from './CatalogTableToolbar';
/**
* Props for {@link CatalogTable}.
@@ -60,6 +61,11 @@ export interface CatalogTableProps {
actions?: TableProps<CatalogTableRow>['actions'];
tableOptions?: TableProps<CatalogTableRow>['options'];
emptyContent?: ReactNode;
/**
* A static title to use for the table. If not provided, a title will be
* generated based on the current Kind and Type filters and total number of items.
*/
title?: string;
subtitle?: string;
}
@@ -73,7 +79,16 @@ const refCompare = (a: Entity, b: Entity) => {
return toRef(a).localeCompare(toRef(b));
};
/** @public */
/**
* CatalogTable is a wrapper around the Table component that is pre-configured
* to display catalog entities.
*
* @remarks
*
* See {@link https://backstage.io/docs/features/software-catalog/catalog-customization}
*
* @public
*/
export const CatalogTable = (props: CatalogTableProps) => {
const {
columns = defaultCatalogTableColumnsFunc,
@@ -173,14 +188,11 @@ export const CatalogTable = (props: CatalogTableProps) => {
const currentCount = typeof totalItems === 'number' ? `(${totalItems})` : '';
// TODO(timbonicus): remove the title from the CatalogTable once using EntitySearchBar
const titlePreamble = capitalize(filters.user?.value ?? 'all');
const title = [
titlePreamble,
currentType,
pluralize(currentKind),
currentCount,
]
.filter(s => s)
.join(' ');
const title =
props.title ||
[titlePreamble, currentType, pluralize(currentKind), currentCount]
.filter(s => s)
.join(' ');
const actions = props.actions || defaultActions;
const options = {
@@ -235,6 +247,9 @@ export const CatalogTable = (props: CatalogTableProps) => {
pageSizeOptions: [20, 50, 100],
...options,
}}
components={{
Toolbar: CatalogTableToolbar,
}}
title={title}
data={rows}
actions={actions}
@@ -63,6 +63,22 @@ describe('CursorPaginatedCatalogTable', () => {
);
};
it('should display the title and subtitle when passed in', async () => {
await renderInTestApp(
wrapInContext(
<CursorPaginatedCatalogTable
data={data}
columns={columns}
title="My Title"
subtitle="My Subtitle"
/>,
),
);
expect(screen.queryByText('My Title')).toBeInTheDocument();
expect(screen.queryByText('My Subtitle')).toBeInTheDocument();
});
it('should display all the items', async () => {
await renderInTestApp(
wrapInContext(
@@ -30,12 +30,10 @@ type PaginatedCatalogTableProps = {
*/
export function CursorPaginatedCatalogTable(props: PaginatedCatalogTableProps) {
const { columns, data, next, prev, title, isLoading, options, ...restProps } =
props;
const { columns, data, next, prev, options, ...restProps } = props;
return (
<Table
title={isLoading ? '' : title}
columns={columns}
data={data}
options={{
@@ -62,7 +60,6 @@ export function CursorPaginatedCatalogTable(props: PaginatedCatalogTableProps) {
/* this will enable the next button accordingly */
totalCount={next ? Number.MAX_VALUE : Number.MAX_SAFE_INTEGER}
localization={{ pagination: { labelDisplayedRows: '' } }}
isLoading={isLoading}
{...restProps}
/>
);
@@ -62,6 +62,28 @@ describe('OffsetPaginatedCatalogTable', () => {
);
};
it('should display the title and subtitle when passed in', async () => {
await renderInTestApp(
wrapInContext(
<OffsetPaginatedCatalogTable
data={data}
columns={columns}
title="My Title"
subtitle="My Subtitle"
/>,
{
setOffset: jest.fn(),
limit: Number.MAX_SAFE_INTEGER,
offset: 0,
totalItems: data.length,
},
),
);
expect(screen.queryByText('My Title')).toBeInTheDocument();
expect(screen.queryByText('My Subtitle')).toBeInTheDocument();
});
it('should display all the items', async () => {
await renderInTestApp(
wrapInContext(
@@ -27,7 +27,7 @@ import { CatalogTableToolbar } from './CatalogTableToolbar';
export function OffsetPaginatedCatalogTable(
props: TableProps<CatalogTableRow>,
) {
const { columns, data, isLoading, options } = props;
const { columns, data, options, ...restProps } = props;
const { setLimit, setOffset, limit, totalItems, offset } = useEntityList();
const [page, setPage] = React.useState(
@@ -65,7 +65,7 @@ export function OffsetPaginatedCatalogTable(
}}
totalCount={totalItems}
localization={{ pagination: { labelDisplayedRows: '' } }}
isLoading={isLoading}
{...restProps}
/>
);
}