chore: Update typing for Table component (#23398)

Co-authored-by: Cody Leff <cody@preset.io>
This commit is contained in:
Hugh A. Miles II 2023-03-20 13:26:27 -07:00 committed by GitHub
parent 65a3a4d908
commit 2fa8f989ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 60 additions and 105 deletions

View File

@ -42,11 +42,7 @@ import NullCell from 'src/components/Table/cell-renderers/NullCell';
import TimeCell from 'src/components/Table/cell-renderers/TimeCell';
import { EmptyStateMedium } from 'src/components/EmptyState';
import { getDatasourceSamples } from 'src/components/Chart/chartAction';
import Table, {
ColumnsType,
TablePaginationConfig,
TableSize,
} from 'src/components/Table';
import Table, { ColumnsType, TableSize } from 'src/components/Table';
import MetadataBar, {
ContentType,
MetadataType,
@ -302,7 +298,7 @@ export default function DrillDetailPane({
recordCount={resultsPage?.total}
usePagination
loading={isLoading}
onChange={(pagination: TablePaginationConfig) =>
onChange={pagination =>
setPageIndex(pagination.current ? pagination.current - 1 : 0)
}
resizable

View File

@ -404,7 +404,7 @@ export const ServerPagination: ComponentStory<typeof Table> = args => {
const [data, setData] = useState(generateData(0, 5));
const [loading, setLoading] = useState(false);
const handleChange: OnChangeFunction = (
const handleChange: OnChangeFunction<BasicData> = (
pagination,
filters,
sorter,
@ -610,7 +610,7 @@ const shoppingData: ShoppingData[] = [
},
];
export const HeaderRenderers: ComponentStory<typeof Table> = args => {
export const HeaderRenderers: ComponentStory<typeof Table> = () => {
const [orderDateFormatting, setOrderDateFormatting] = useState('formatted');
const [priceLocale, setPriceLocale] = useState(LocaleCode.en_US);
const shoppingColumns: ColumnsType<ShoppingData> = [
@ -672,7 +672,7 @@ export const HeaderRenderers: ComponentStory<typeof Table> = args => {
];
return (
<Table
<Table<ShoppingData>
data={shoppingData}
columns={shoppingColumns}
size={TableSize.SMALL}

View File

@ -16,17 +16,24 @@
* specific language governing permissions and limitations
* under the License.
*/
import { Table as AntTable } from 'antd';
import AntTable, {
TablePaginationConfig,
TableProps as AntTableProps,
} from 'antd/lib/table';
import classNames from 'classnames';
import { useResizeDetector } from 'react-resize-detector';
import React, { useEffect, useRef, useState, useCallback } from 'react';
import { VariableSizeGrid as Grid } from 'react-window';
import { StyledComponent } from '@emotion/styled';
import { useTheme, styled } from '@superset-ui/core';
import { TablePaginationConfig } from 'antd/lib/table';
import { TableProps, TableSize, ETableAction } from './index';
const StyledCell: StyledComponent<any> = styled('div')<any>(
import { TableSize, ETableAction } from './index';
interface VirtualTableProps<RecordType> extends AntTableProps<RecordType> {
height?: number;
}
const StyledCell = styled('div')<{ height?: number }>(
({ theme, height }) => `
white-space: nowrap;
overflow: hidden;
@ -40,7 +47,7 @@ const StyledCell: StyledComponent<any> = styled('div')<any>(
`,
);
const StyledTable: StyledComponent<any> = styled(AntTable)<any>(
const StyledTable = styled(AntTable)<{ height?: number }>(
({ theme }) => `
th.ant-table-cell {
font-weight: ${theme.typography.weights.bold};
@ -61,7 +68,9 @@ const StyledTable: StyledComponent<any> = styled(AntTable)<any>(
const SMALL = 39;
const MIDDLE = 47;
const VirtualTable = (props: TableProps) => {
const VirtualTable = <RecordType extends object>(
props: VirtualTableProps<RecordType>,
) => {
const { columns, pagination, onChange, height, scroll, size } = props;
const [tableWidth, setTableWidth] = useState<number>(0);
const onResize = useCallback((width: number) => {

View File

@ -17,33 +17,18 @@
* under the License.
*/
import React, { useState, useEffect, useRef, ReactElement } from 'react';
import { Table as AntTable, ConfigProvider } from 'antd';
import {
ColumnType,
ColumnGroupType,
import AntTable, {
ColumnsType,
TableProps as AntTableProps,
} from 'antd/es/table';
import { PaginationProps } from 'antd/es/pagination';
import { Key } from 'antd/lib/table/interface';
import { t, useTheme, logging } from '@superset-ui/core';
} from 'antd/lib/table';
import ConfigProvider from 'antd/lib/config-provider';
import { PaginationProps } from 'antd/lib/pagination';
import { t, useTheme, logging, styled } from '@superset-ui/core';
import Loading from 'src/components/Loading';
import styled, { StyledComponent } from '@emotion/styled';
import InteractiveTableUtils from './utils/InteractiveTableUtils';
import VirtualTable from './VirtualTable';
export const SUPERSET_TABLE_COLUMN = 'superset/table-column';
export interface TableDataType {
key: React.Key;
}
export interface TablePaginationConfig extends PaginationProps {
extra?: object;
}
export type ColumnsType<RecordType = unknown> = (
| ColumnGroupType<RecordType>
| ColumnType<RecordType>
)[];
export enum SelectionType {
'DISABLED' = 'disabled',
@ -51,36 +36,7 @@ export enum SelectionType {
'MULTI' = 'multi',
}
export interface Locale {
/**
* Text contained within the Table UI.
*/
filterTitle: string;
filterConfirm: string;
filterReset: string;
filterEmptyText: string;
filterCheckall: string;
filterSearchPlaceholder: string;
emptyText: string;
selectAll: string;
selectInvert: string;
selectNone: string;
selectionAll: string;
sortTitle: string;
expand: string;
collapse: string;
triggerDesc: string;
triggerAsc: string;
cancelSort: string;
}
export type SortOrder = 'descend' | 'ascend' | null;
export interface SorterResult<RecordType> {
column?: ColumnType<RecordType>;
order?: SortOrder;
field?: Key | Key[];
columnKey?: Key;
}
export enum ETableAction {
PAGINATE = 'paginate',
@ -88,27 +44,24 @@ export enum ETableAction {
FILTER = 'filter',
}
export interface TableCurrentDataSource<RecordType> {
currentDataSource: RecordType[];
action: ETableAction;
export { ColumnsType };
export type OnChangeFunction<RecordType> =
AntTableProps<RecordType>['onChange'];
export enum TableSize {
SMALL = 'small',
MIDDLE = 'middle',
}
export type OnChangeFunction = (
pagination: TablePaginationConfig,
filters: Record<string, (Key | boolean)[] | null>,
sorter: SorterResult<any> | SorterResult<any>[],
extra: TableCurrentDataSource<any>,
) => void;
export interface TableProps extends AntTableProps<TableProps> {
export interface TableProps<RecordType> {
/**
* Data that will populate the each row and map to the column key.
*/
data: object[];
data: RecordType[];
/**
* Table column definitions.
*/
columns: ColumnsType<any>;
columns: ColumnsType<RecordType>;
/**
* Array of row keys to represent list of selected rows.
*/
@ -116,13 +69,13 @@ export interface TableProps extends AntTableProps<TableProps> {
/**
* Callback function invoked when a row is selected by user.
*/
handleRowSelection?: Function;
handleRowSelection?: (newSelectedRowKeys: React.Key[]) => void;
/**
* Controls the size of the table.
*/
size: TableSize;
/**
* Adjusts the padding around elements for different amounts of spacing between elements.
* Controls if table rows are selectable and if multiple select is supported.
*/
selectionType?: SelectionType;
/*
@ -165,7 +118,7 @@ export interface TableProps extends AntTableProps<TableProps> {
/**
* Enables setting the text displayed in various components and tooltips within the Table UI.
*/
locale?: Locale;
locale?: Partial<AntTableProps<RecordType>['locale']>;
/**
* Restricts the visible height of the table and allows for internal scrolling within the table
* when the number of rows exceeds the visible space.
@ -183,20 +136,11 @@ export interface TableProps extends AntTableProps<TableProps> {
/**
* Invoked when the tables sorting, paging, or filtering is changed.
*/
onChange?: OnChangeFunction;
}
interface IPaginationOptions {
hideOnSinglePage: boolean;
pageSize: number;
pageSizeOptions: string[];
onShowSizeChange: Function;
total?: number;
}
export enum TableSize {
SMALL = 'small',
MIDDLE = 'middle',
onChange?: OnChangeFunction<RecordType>;
/**
* Returns props that should be applied to each row component.
*/
onRow?: AntTableProps<RecordType>['onRow'];
}
const defaultRowSelection: React.Key[] = [];
@ -204,7 +148,7 @@ const defaultRowSelection: React.Key[] = [];
const PAGINATION_HEIGHT = 40;
const HEADER_HEIGHT = 68;
const StyledTable: StyledComponent<any> = styled(AntTable)<any>(
const StyledTable = styled(AntTable)<{ height?: number }>(
({ theme, height }) => `
.ant-table-body {
overflow: auto;
@ -231,11 +175,9 @@ const StyledTable: StyledComponent<any> = styled(AntTable)<any>(
.ant-pagination-item-active {
border-color: ${theme.colors.primary.base};
}
}
`,
`,
);
const StyledVirtualTable: StyledComponent<any> = styled(VirtualTable)<any>(
const StyledVirtualTable = styled(VirtualTable)(
({ theme }) => `
.virtual-table .ant-table-container:before,
.virtual-table .ant-table-container:after {
@ -277,7 +219,9 @@ selectionMap[SelectionType.MULTI] = 'checkbox';
selectionMap[SelectionType.SINGLE] = 'radio';
selectionMap[SelectionType.DISABLED] = null;
export function Table(props: TableProps) {
export function Table<RecordType extends object>(
props: TableProps<RecordType>,
) {
const {
data,
columns,
@ -299,12 +243,15 @@ export function Table(props: TableProps) {
virtualize = false,
onChange = noop,
recordCount,
onRow,
} = props;
const wrapperRef = useRef<HTMLDivElement | null>(null);
const [derivedColumns, setDerivedColumns] = useState(columns);
const [pageSize, setPageSize] = useState(defaultPageSize);
const [mergedLocale, setMergedLocale] = useState({ ...defaultLocale });
const [mergedLocale, setMergedLocale] = useState<
Required<AntTableProps<RecordType>>['locale']
>({ ...defaultLocale });
const [selectedRowKeys, setSelectedRowKeys] =
useState<React.Key[]>(selectedRows);
const interactiveTableUtils = useRef<InteractiveTableUtils | null>(null);
@ -387,7 +334,7 @@ export function Table(props: TableProps) {
const theme = useTheme();
const paginationSettings: IPaginationOptions | false = usePagination
const paginationSettings: PaginationProps | false = usePagination
? {
hideOnSinglePage: true,
pageSize,
@ -420,12 +367,13 @@ export function Table(props: TableProps) {
loading: { spinning: loading ?? false, indicator: <Loading /> },
hasData: hideData ? false : data,
columns: derivedColumns,
dataSource: hideData ? [undefined] : data,
dataSource: hideData ? undefined : data,
size,
pagination: paginationSettings,
locale: mergedLocale,
showSorterTooltip: false,
onChange,
onRow,
theme,
height: bodyHeight,
};

View File

@ -188,7 +188,9 @@ const useDatasetChartRecords = (datasetId: string) => {
);
// Called by table with updated table state to fetch new data
// @ts-ignore
const onChange: OnChangeFunction = useCallback(
// @ts-ignore
(tablePagination, tableFilters, tableSorter) => {
const pageIndex = (tablePagination.current ?? 1) - 1;
const pageSize = tablePagination.pageSize ?? 0;