mirror of
https://github.com/portainer/portainer.git
synced 2025-07-19 13:29:41 +02:00
chore(deps): upgrade react-table to v8 [EE-4837] (#8245)
This commit is contained in:
parent
f20d3e72b9
commit
757461d58b
140 changed files with 1805 additions and 2872 deletions
|
@ -1,36 +1,40 @@
|
|||
import {
|
||||
useTable,
|
||||
useFilters,
|
||||
useGlobalFilter,
|
||||
useSortBy,
|
||||
usePagination,
|
||||
Column,
|
||||
Row,
|
||||
TableInstance,
|
||||
Table as TableInstance,
|
||||
TableState,
|
||||
TableRowProps,
|
||||
useExpanded,
|
||||
} from 'react-table';
|
||||
import { ReactNode } from 'react';
|
||||
import { useRowSelectColumn } from '@lineup-lite/hooks';
|
||||
useReactTable,
|
||||
Row,
|
||||
getCoreRowModel,
|
||||
getPaginationRowModel,
|
||||
getFilteredRowModel,
|
||||
getSortedRowModel,
|
||||
getFacetedRowModel,
|
||||
getFacetedUniqueValues,
|
||||
getFacetedMinMaxValues,
|
||||
getExpandedRowModel,
|
||||
TableOptions,
|
||||
} from '@tanstack/react-table';
|
||||
import { ReactNode, useMemo } from 'react';
|
||||
import clsx from 'clsx';
|
||||
import _ from 'lodash';
|
||||
|
||||
import { IconProps } from '@@/Icon';
|
||||
|
||||
import { Table } from './Table';
|
||||
import { multiple } from './filter-types';
|
||||
import { useRowSelect } from './useRowSelect';
|
||||
import { BasicTableSettings } from './types';
|
||||
import { DatatableHeader } from './DatatableHeader';
|
||||
import { DatatableFooter } from './DatatableFooter';
|
||||
import { DatatableContent } from './DatatableContent';
|
||||
import { defaultGetRowId } from './defaultGetRowId';
|
||||
import { emptyPlugin } from './emptyReactTablePlugin';
|
||||
import { Table } from './Table';
|
||||
import { useGoToHighlightedRow } from './useGoToHighlightedRow';
|
||||
import { BasicTableSettings } from './types';
|
||||
import { DatatableContent } from './DatatableContent';
|
||||
import { createSelectColumn } from './select-column';
|
||||
import { TableRow } from './TableRow';
|
||||
|
||||
export interface Props<D extends Record<string, unknown>> {
|
||||
export interface Props<
|
||||
D extends Record<string, unknown>,
|
||||
TSettings extends BasicTableSettings = BasicTableSettings
|
||||
> {
|
||||
dataset: D[];
|
||||
columns: readonly Column<D>[];
|
||||
columns: TableOptions<D>['columns'];
|
||||
renderTableSettings?(instance: TableInstance<D>): ReactNode;
|
||||
renderTableActions?(selectedRows: D[]): ReactNode;
|
||||
disableSelect?: boolean;
|
||||
|
@ -39,29 +43,20 @@ export interface Props<D extends Record<string, unknown>> {
|
|||
emptyContentLabel?: string;
|
||||
title?: string;
|
||||
titleIcon?: IconProps['icon'];
|
||||
initialTableState?: Partial<TableState<D>>;
|
||||
initialTableState?: Partial<TableState>;
|
||||
isLoading?: boolean;
|
||||
totalCount?: number;
|
||||
description?: ReactNode;
|
||||
pageCount?: number;
|
||||
initialSortBy?: BasicTableSettings['sortBy'];
|
||||
initialPageSize?: BasicTableSettings['pageSize'];
|
||||
highlightedItemId?: string;
|
||||
|
||||
searchValue: string;
|
||||
onSearchChange(search: string): void;
|
||||
onSortByChange(colId: string, desc: boolean): void;
|
||||
onPageSizeChange(pageSize: number): void;
|
||||
|
||||
// send state up
|
||||
onPageChange?(page: number): void;
|
||||
|
||||
renderRow?(
|
||||
row: Row<D>,
|
||||
rowProps: TableRowProps,
|
||||
highlightedItemId?: string
|
||||
): ReactNode;
|
||||
expandable?: boolean;
|
||||
settingsManager: TSettings & {
|
||||
search: string;
|
||||
setSearch: (value: string) => void;
|
||||
};
|
||||
renderRow?(row: Row<D>, highlightedItemId?: string): ReactNode;
|
||||
getRowCanExpand?(row: Row<D>): boolean;
|
||||
noWidget?: boolean;
|
||||
}
|
||||
|
||||
|
@ -81,78 +76,83 @@ export function Datatable<D extends Record<string, unknown>>({
|
|||
totalCount = dataset.length,
|
||||
description,
|
||||
pageCount,
|
||||
|
||||
initialSortBy,
|
||||
initialPageSize = 10,
|
||||
onPageChange = () => {},
|
||||
|
||||
onPageSizeChange,
|
||||
onSortByChange,
|
||||
searchValue,
|
||||
onSearchChange,
|
||||
|
||||
onPageChange = () => null,
|
||||
settingsManager: settings,
|
||||
renderRow = defaultRenderRow,
|
||||
expandable = false,
|
||||
highlightedItemId,
|
||||
noWidget,
|
||||
getRowCanExpand,
|
||||
}: Props<D>) {
|
||||
const isServerSidePagination = typeof pageCount !== 'undefined';
|
||||
|
||||
const tableInstance = useTable<D>(
|
||||
{
|
||||
defaultCanFilter: false,
|
||||
columns,
|
||||
data: dataset,
|
||||
filterTypes: { multiple },
|
||||
initialState: {
|
||||
pageSize: initialPageSize,
|
||||
sortBy: initialSortBy ? [initialSortBy] : [],
|
||||
globalFilter: searchValue,
|
||||
...initialTableState,
|
||||
},
|
||||
isRowSelectable,
|
||||
autoResetExpanded: false,
|
||||
autoResetSelectedRows: false,
|
||||
getRowId,
|
||||
...(isServerSidePagination ? { manualPagination: true, pageCount } : {}),
|
||||
},
|
||||
useFilters,
|
||||
useGlobalFilter,
|
||||
useSortBy,
|
||||
expandable ? useExpanded : emptyPlugin,
|
||||
usePagination,
|
||||
useRowSelect,
|
||||
!disableSelect ? useRowSelectColumn : emptyPlugin
|
||||
const enableRowSelection = getIsSelectionEnabled(
|
||||
disableSelect,
|
||||
isRowSelectable
|
||||
);
|
||||
|
||||
const allColumns = useMemo(
|
||||
() => _.compact([!disableSelect && createSelectColumn<D>(), ...columns]),
|
||||
[disableSelect, columns]
|
||||
);
|
||||
|
||||
const tableInstance = useReactTable<D>({
|
||||
columns: allColumns,
|
||||
data: dataset,
|
||||
initialState: {
|
||||
pagination: {
|
||||
pageSize: settings.pageSize,
|
||||
},
|
||||
sorting: settings.sortBy ? [settings.sortBy] : [],
|
||||
globalFilter: settings.search,
|
||||
|
||||
...initialTableState,
|
||||
},
|
||||
defaultColumn: {
|
||||
enableColumnFilter: false,
|
||||
enableHiding: true,
|
||||
},
|
||||
enableRowSelection,
|
||||
autoResetExpanded: false,
|
||||
globalFilterFn,
|
||||
getRowId,
|
||||
getCoreRowModel: getCoreRowModel(),
|
||||
getFilteredRowModel: getFilteredRowModel(),
|
||||
getSortedRowModel: getSortedRowModel(),
|
||||
getPaginationRowModel: getPaginationRowModel(),
|
||||
getFacetedRowModel: getFacetedRowModel(),
|
||||
getFacetedUniqueValues: getFacetedUniqueValues(),
|
||||
getFacetedMinMaxValues: getFacetedMinMaxValues(),
|
||||
getExpandedRowModel: getExpandedRowModel(),
|
||||
getRowCanExpand,
|
||||
...(isServerSidePagination ? { manualPagination: true, pageCount } : {}),
|
||||
});
|
||||
|
||||
const tableState = tableInstance.getState();
|
||||
|
||||
useGoToHighlightedRow(
|
||||
isServerSidePagination,
|
||||
tableInstance.state.pageSize,
|
||||
tableInstance.rows,
|
||||
tableState.pagination.pageSize,
|
||||
tableInstance.getCoreRowModel().rows,
|
||||
handlePageChange,
|
||||
highlightedItemId
|
||||
);
|
||||
|
||||
const selectedItems = tableInstance.selectedFlatRows.map(
|
||||
(row) => row.original
|
||||
);
|
||||
const selectedRowModel = tableInstance.getSelectedRowModel();
|
||||
const selectedItems = selectedRowModel.rows.map((row) => row.original);
|
||||
|
||||
return (
|
||||
<Table.Container noWidget={noWidget}>
|
||||
<DatatableHeader
|
||||
onSearchChange={handleSearchBarChange}
|
||||
searchValue={searchValue}
|
||||
searchValue={settings.search}
|
||||
title={title}
|
||||
titleIcon={titleIcon}
|
||||
description={description}
|
||||
renderTableActions={() => renderTableActions(selectedItems)}
|
||||
renderTableSettings={() => renderTableSettings(tableInstance)}
|
||||
description={description}
|
||||
/>
|
||||
<DatatableContent<D>
|
||||
tableInstance={tableInstance}
|
||||
renderRow={(row, rowProps) =>
|
||||
renderRow(row, rowProps, highlightedItemId)
|
||||
}
|
||||
renderRow={(row) => renderRow(row, highlightedItemId)}
|
||||
emptyContentLabel={emptyContentLabel}
|
||||
isLoading={isLoading}
|
||||
onSortChange={handleSortChange}
|
||||
|
@ -161,8 +161,8 @@ export function Datatable<D extends Record<string, unknown>>({
|
|||
<DatatableFooter
|
||||
onPageChange={handlePageChange}
|
||||
onPageSizeChange={handlePageSizeChange}
|
||||
page={tableInstance.state.pageIndex}
|
||||
pageSize={tableInstance.state.pageSize}
|
||||
page={tableState.pagination.pageIndex}
|
||||
pageSize={tableState.pagination.pageSize}
|
||||
totalCount={totalCount}
|
||||
totalSelected={selectedItems.length}
|
||||
/>
|
||||
|
@ -171,38 +171,81 @@ export function Datatable<D extends Record<string, unknown>>({
|
|||
|
||||
function handleSearchBarChange(value: string) {
|
||||
tableInstance.setGlobalFilter(value);
|
||||
onSearchChange(value);
|
||||
settings.setSearch(value);
|
||||
}
|
||||
|
||||
function handlePageChange(page: number) {
|
||||
tableInstance.gotoPage(page);
|
||||
tableInstance.setPageIndex(page);
|
||||
onPageChange(page);
|
||||
}
|
||||
|
||||
function handleSortChange(colId: string, desc: boolean) {
|
||||
onSortByChange(colId, desc);
|
||||
settings.setSortBy(colId, desc);
|
||||
}
|
||||
|
||||
function handlePageSizeChange(pageSize: number) {
|
||||
tableInstance.setPageSize(pageSize);
|
||||
onPageSizeChange(pageSize);
|
||||
settings.setPageSize(pageSize);
|
||||
}
|
||||
}
|
||||
|
||||
function defaultRenderRow<D extends Record<string, unknown>>(
|
||||
row: Row<D>,
|
||||
rowProps: TableRowProps,
|
||||
highlightedItemId?: string
|
||||
) {
|
||||
return (
|
||||
<Table.Row<D>
|
||||
key={rowProps.key}
|
||||
cells={row.cells}
|
||||
className={clsx(rowProps.className, {
|
||||
<TableRow<D>
|
||||
cells={row.getVisibleCells()}
|
||||
className={clsx({
|
||||
active: highlightedItemId === row.id,
|
||||
})}
|
||||
role={rowProps.role}
|
||||
style={rowProps.style}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function getIsSelectionEnabled<D extends Record<string, unknown>>(
|
||||
disabledSelect?: boolean,
|
||||
isRowSelectable?: Props<D>['isRowSelectable']
|
||||
) {
|
||||
if (disabledSelect) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isRowSelectable) {
|
||||
return isRowSelectable;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function globalFilterFn<D>(
|
||||
row: Row<D>,
|
||||
columnId: string,
|
||||
filterValue: null | string
|
||||
): boolean {
|
||||
const value = row.getValue(columnId);
|
||||
|
||||
if (filterValue === null || filterValue === '') {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (value == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const filterValueLower = filterValue.toLowerCase();
|
||||
|
||||
if (
|
||||
typeof value === 'string' ||
|
||||
typeof value === 'number' ||
|
||||
typeof value === 'boolean'
|
||||
) {
|
||||
return value.toString().toLowerCase().includes(filterValueLower);
|
||||
}
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
return value.some((item) => item.toLowerCase().includes(filterValueLower));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue