feat: Table initial loading (#19343)

* feat: add initial loading state for Table

Signed-off-by: Matthew Clarke <mclarke@spotify.com>

* Please answer yes or no.
feat: add loading state for Table component

Signed-off-by: Matthew Clarke <mclarke@spotify.com>

* chore: changeset

Signed-off-by: Matthew Clarke <mclarke@spotify.com>

* test: add test

Signed-off-by: Matthew Clarke <mclarke@spotify.com>

* docs: api reports

Signed-off-by: Matthew Clarke <mclarke@spotify.com>

---------

Signed-off-by: Matthew Clarke <mclarke@spotify.com>
This commit is contained in:
Matthew Clarke
2023-08-17 09:46:03 -04:00
committed by GitHub
parent 3b5eb94a4f
commit 47782f4bfa
5 changed files with 75 additions and 1 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/core-components': patch
---
Add loading indicator to Table
+2
View File
@@ -1356,6 +1356,8 @@ export interface TableProps<T extends object = {}>
// (undocumented)
initialState?: TableState;
// (undocumented)
isLoading?: boolean;
// (undocumented)
onStateChange?: (state: TableState) => any;
// (undocumented)
subtitle?: string;
@@ -89,6 +89,43 @@ export const DefaultTable = () => {
);
};
export const LoadingTable = () => {
const classes = useStyles();
const columns: TableColumn[] = [
{
title: 'Column 1',
field: 'col1',
highlight: true,
},
{
title: 'Column 2',
field: 'col2',
},
{
title: 'Numeric value',
field: 'number',
type: 'numeric',
},
{
title: 'A Date',
field: 'date',
type: 'date',
},
];
return (
<div className={classes.container}>
<Table
options={{ paging: false }}
data={[]}
columns={columns}
isLoading
title="Backstage Table"
/>
</div>
);
};
export const EmptyTable = () => {
const classes = useStyles();
const columns: TableColumn[] = [
@@ -48,6 +48,11 @@ describe('<Table />', () => {
expect(rendered.getByText('second value, second row')).toBeInTheDocument();
});
it('renders loading without exploding', async () => {
const rendered = await renderInTestApp(<Table {...minProps} isLoading />);
expect(rendered.getByTestId('loading-indicator')).toBeInTheDocument();
});
describe('with style rows', () => {
describe('with CSS Properties object', () => {
const styledColumn2 = {
@@ -53,6 +53,7 @@ import React, {
import { SelectProps } from '../Select/Select';
import { Filter, Filters, SelectedFilters, Without } from './Filters';
import CircularProgress from '@material-ui/core/CircularProgress';
// Material-table is not using the standard icons available in in material-ui. https://github.com/mbrn/material-table/issues/51
const tableIcons: Icons = {
@@ -236,6 +237,7 @@ export interface TableProps<T extends object = {}>
filters?: TableFilter[];
initialState?: TableState;
emptyContent?: ReactNode;
isLoading?: boolean;
onStateChange?: (state: TableState) => any;
}
@@ -309,6 +311,7 @@ export function Table<T extends object = {}>(props: TableProps<T>) {
emptyContent,
onStateChange,
components,
isLoading: isLoading,
...restProps
} = props;
const tableClasses = useTableStyles();
@@ -470,6 +473,28 @@ export function Table<T extends object = {}>(props: TableProps<T>) {
const columnCount = columns.length;
const Body = useCallback(
bodyProps => {
if (isLoading) {
return (
<tbody data-testid="loading-indicator">
<tr>
<td colSpan={columnCount}>
<Box
sx={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
width: '100%',
minHeight: '15rem',
}}
>
<CircularProgress size="5rem" />
</Box>
</td>
</tr>
</tbody>
);
}
if (emptyContent && hasNoRows) {
return (
<tbody>
@@ -482,7 +507,7 @@ export function Table<T extends object = {}>(props: TableProps<T>) {
return <MTableBody {...bodyProps} />;
},
[hasNoRows, emptyContent, columnCount],
[hasNoRows, emptyContent, columnCount, isLoading],
);
return (