Fix InteractiveTable: React, less hooks rendered than previous render (#85043)
fix: react-hooks error if data length switches from above or below pageSize
This commit is contained in:
@@ -1,8 +1,11 @@
|
|||||||
import { Meta, StoryFn, StoryObj } from '@storybook/react';
|
import { Meta, StoryFn, StoryObj } from '@storybook/react';
|
||||||
import React, { useCallback, useState } from 'react';
|
import React, { useCallback, useMemo, useState } from 'react';
|
||||||
|
|
||||||
import { InteractiveTable, CellProps, LinkButton } from '@grafana/ui';
|
import { InteractiveTable, CellProps, LinkButton } from '@grafana/ui';
|
||||||
|
|
||||||
|
import { Field } from '../Forms/Field';
|
||||||
|
import { Input } from '../Input/Input';
|
||||||
|
|
||||||
import { FetchDataArgs, InteractiveTableHeaderTooltip } from './InteractiveTable';
|
import { FetchDataArgs, InteractiveTableHeaderTooltip } from './InteractiveTable';
|
||||||
import mdx from './InteractiveTable.mdx';
|
import mdx from './InteractiveTable.mdx';
|
||||||
|
|
||||||
@@ -125,9 +128,9 @@ const meta: Meta<typeof InteractiveTable<CarData>> = {
|
|||||||
argTypes: {},
|
argTypes: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
type TableStory = StoryObj<typeof InteractiveTable<CarData>>;
|
type TableStoryObj = StoryObj<typeof InteractiveTable<CarData>>;
|
||||||
|
|
||||||
export const Basic: TableStory = {
|
export const Basic: TableStoryObj = {
|
||||||
args: {
|
args: {
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
@@ -169,7 +172,7 @@ const ExpandedCell = ({ car }: CarData) => {
|
|||||||
return <p>{car}</p>;
|
return <p>{car}</p>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const WithRowExpansion: TableStory = {
|
export const WithRowExpansion: TableStoryObj = {
|
||||||
args: {
|
args: {
|
||||||
renderExpandedRow: ExpandedCell,
|
renderExpandedRow: ExpandedCell,
|
||||||
},
|
},
|
||||||
@@ -216,11 +219,33 @@ export const WithCustomCell: StoryObj<typeof InteractiveTable<WithCustomCellData
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const WithPagination: TableStory = {
|
export const WithPagination: StoryFn<typeof InteractiveTable> = (args) => {
|
||||||
args: {
|
const [filter, setFilter] = useState('');
|
||||||
pageSize: 15,
|
|
||||||
data: pageableData,
|
const data = useMemo(() => {
|
||||||
},
|
if (filter) {
|
||||||
|
return pageableData.filter((d) => d.firstName.toLowerCase().includes(filter.toLowerCase()));
|
||||||
|
}
|
||||||
|
return pageableData;
|
||||||
|
}, [filter]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Field label={'Filter data'}>
|
||||||
|
<Input
|
||||||
|
placeholder={'Filter by first name'}
|
||||||
|
onChange={(event) => {
|
||||||
|
setFilter(event.currentTarget.value);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Field>
|
||||||
|
<InteractiveTable {...args} data={data} />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
WithPagination.args = {
|
||||||
|
pageSize: 15,
|
||||||
};
|
};
|
||||||
|
|
||||||
const headerTooltips: Record<string, InteractiveTableHeaderTooltip> = {
|
const headerTooltips: Record<string, InteractiveTableHeaderTooltip> = {
|
||||||
@@ -238,7 +263,7 @@ const headerTooltips: Record<string, InteractiveTableHeaderTooltip> = {
|
|||||||
iconName: 'plus-square',
|
iconName: 'plus-square',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
export const WithHeaderTooltips: TableStory = {
|
export const WithHeaderTooltips: TableStoryObj = {
|
||||||
args: {
|
args: {
|
||||||
headerTooltips,
|
headerTooltips,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -141,6 +141,8 @@ interface BaseProps<TableData extends object> {
|
|||||||
headerTooltips?: Record<string, InteractiveTableHeaderTooltip>;
|
headerTooltips?: Record<string, InteractiveTableHeaderTooltip>;
|
||||||
/**
|
/**
|
||||||
* Number of rows per page. A value of zero disables pagination. Defaults to 0.
|
* Number of rows per page. A value of zero disables pagination. Defaults to 0.
|
||||||
|
* A React hooks error will be thrown if pageSize goes from greater than 0 to 0 or vice versa. If enabling pagination,
|
||||||
|
* make sure pageSize remains a non-zero value.
|
||||||
*/
|
*/
|
||||||
pageSize?: number;
|
pageSize?: number;
|
||||||
/**
|
/**
|
||||||
@@ -196,7 +198,7 @@ export function InteractiveTable<TableData extends object>({
|
|||||||
const tableHooks: Array<PluginHook<TableData>> = [useSortBy, useExpanded];
|
const tableHooks: Array<PluginHook<TableData>> = [useSortBy, useExpanded];
|
||||||
|
|
||||||
const multiplePages = data.length > pageSize;
|
const multiplePages = data.length > pageSize;
|
||||||
const paginationEnabled = pageSize > 0 && multiplePages;
|
const paginationEnabled = pageSize > 0;
|
||||||
|
|
||||||
if (paginationEnabled) {
|
if (paginationEnabled) {
|
||||||
tableHooks.push(usePagination);
|
tableHooks.push(usePagination);
|
||||||
@@ -304,7 +306,7 @@ export function InteractiveTable<TableData extends object>({
|
|||||||
})}
|
})}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
{paginationEnabled && (
|
{paginationEnabled && multiplePages && (
|
||||||
<span>
|
<span>
|
||||||
<Pagination
|
<Pagination
|
||||||
currentPage={tableInstance.state.pageIndex + 1}
|
currentPage={tableInstance.state.pageIndex + 1}
|
||||||
|
|||||||
Reference in New Issue
Block a user