Merge pull request #27632 from tylerd-canva/consistent-catalog-table-title
Make title consistent across CatalogTable impls
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog': minor
|
||||
---
|
||||
|
||||
Consistent title behaviour across CatalogTable, CursorPaginatedCatalogTable, and OffsetPaginatedCatalogTable.
|
||||
@@ -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}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user