|
|
@@ -3,9 +3,18 @@ import {
|
|
|
useReactTable,
|
|
|
getCoreRowModel,
|
|
|
Header,
|
|
|
+ RowSelectionState,
|
|
|
} from '@tanstack/react-table';
|
|
|
import {ColumnType} from 'antd/es/table';
|
|
|
-import {useEffect, useMemo, useState} from 'react';
|
|
|
+import {
|
|
|
+ Dispatch,
|
|
|
+ FC,
|
|
|
+ SetStateAction,
|
|
|
+ useEffect,
|
|
|
+ useMemo,
|
|
|
+ useRef,
|
|
|
+ useState,
|
|
|
+} from 'react';
|
|
|
import {DragStartEvent, DragEndEvent} from '@dnd-kit/core';
|
|
|
import {arrayMove} from '@dnd-kit/sortable';
|
|
|
import {
|
|
|
@@ -14,8 +23,41 @@ import {
|
|
|
useTableSearchDispatch,
|
|
|
} from '@hooks';
|
|
|
|
|
|
-function parseColumn<T>(columns: ColumnType<T>[]) {
|
|
|
- const hepler = createColumnHelper<Record<string, any>>();
|
|
|
+type TableCheckProps = {
|
|
|
+ checked: boolean;
|
|
|
+ indeterminate: boolean;
|
|
|
+ onChange: (e: unknown) => void;
|
|
|
+ enabled?: boolean;
|
|
|
+};
|
|
|
+
|
|
|
+const TableCheck: FC<TableCheckProps> = function({
|
|
|
+ checked,
|
|
|
+ indeterminate,
|
|
|
+ onChange,
|
|
|
+ enabled = true,
|
|
|
+}) {
|
|
|
+ const inputRef = useRef<HTMLInputElement>(null);
|
|
|
+
|
|
|
+ useEffect(function() {
|
|
|
+ if (!inputRef.current) return;
|
|
|
+
|
|
|
+ inputRef.current.indeterminate = !checked && indeterminate;
|
|
|
+ }, [checked, indeterminate]);
|
|
|
+
|
|
|
+ return (
|
|
|
+ <input
|
|
|
+ ref={inputRef}
|
|
|
+ type="checkbox"
|
|
|
+ checked={checked}
|
|
|
+ disabled={!enabled}
|
|
|
+ onChange={onChange}
|
|
|
+ style={{cursor: 'pointer'}}
|
|
|
+ />
|
|
|
+ );
|
|
|
+};
|
|
|
+
|
|
|
+function parseColumn<T>(columns: ColumnType<T>[], enableSelect?: boolean) {
|
|
|
+ const helper = createColumnHelper<Record<string, any>>();
|
|
|
|
|
|
const tableColumns = columns.map(function(val) {
|
|
|
const {dataIndex, title, render, align, fixed} = val;
|
|
|
@@ -26,7 +68,7 @@ function parseColumn<T>(columns: ColumnType<T>[]) {
|
|
|
};
|
|
|
|
|
|
if (render) {
|
|
|
- return hepler.display({
|
|
|
+ return helper.display({
|
|
|
id: dataIndex!.toString(),
|
|
|
header: title?.toString(),
|
|
|
cell(props) {
|
|
|
@@ -40,7 +82,7 @@ function parseColumn<T>(columns: ColumnType<T>[]) {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
- return hepler.accessor(dataIndex!.toString(), {
|
|
|
+ return helper.accessor(dataIndex!.toString(), {
|
|
|
header: title?.toString(),
|
|
|
cell: props => props.getValue(),
|
|
|
minSize: 0,
|
|
|
@@ -48,8 +90,37 @@ function parseColumn<T>(columns: ColumnType<T>[]) {
|
|
|
});
|
|
|
});
|
|
|
|
|
|
+ enableSelect && tableColumns.unshift(
|
|
|
+ helper.accessor('select', {
|
|
|
+ header({table}) {
|
|
|
+ return (
|
|
|
+ <TableCheck
|
|
|
+ checked={table.getIsAllRowsSelected()}
|
|
|
+ indeterminate={table.getIsSomeRowsSelected()}
|
|
|
+ onChange={table.getToggleAllRowsSelectedHandler()}
|
|
|
+ />
|
|
|
+ );
|
|
|
+ },
|
|
|
+ cell({row}) {
|
|
|
+ return (
|
|
|
+ <TableCheck
|
|
|
+ checked={row.getIsSelected()}
|
|
|
+ indeterminate={row.getIsSomeSelected()}
|
|
|
+ onChange={row.getToggleSelectedHandler()}
|
|
|
+ enabled={row.getCanSelect()}
|
|
|
+ />
|
|
|
+ );
|
|
|
+ },
|
|
|
+ meta: {
|
|
|
+ align: 'center',
|
|
|
+ fixed: false,
|
|
|
+ disabledSort: true,
|
|
|
+ },
|
|
|
+ }),
|
|
|
+ );
|
|
|
+
|
|
|
tableColumns.unshift(
|
|
|
- hepler.display({
|
|
|
+ helper.display({
|
|
|
header: '序号',
|
|
|
id: 'no',
|
|
|
cell({row}) {
|
|
|
@@ -73,40 +144,41 @@ export function useTable<T extends Record<string, any>>(
|
|
|
pageSize: number;
|
|
|
preloadKey?: string;
|
|
|
searchContext: ReturnType<typeof createSearchContext>;
|
|
|
+ rowSelection?: RowSelectionState;
|
|
|
+ setRowSelection?: Dispatch<SetStateAction<RowSelectionState>>;
|
|
|
+ enableSelect?: boolean;
|
|
|
},
|
|
|
) {
|
|
|
+ const {enableSelect} = options;
|
|
|
const columnList = useMemo(
|
|
|
function() {
|
|
|
- return parseColumn(columns);
|
|
|
+ return parseColumn(columns, enableSelect);
|
|
|
},
|
|
|
- [columns],
|
|
|
+ [columns, enableSelect],
|
|
|
);
|
|
|
const preload = usePreloadSettingData(options.preloadKey);
|
|
|
|
|
|
const [columnSizing, setColumnSizing] = useState(function() {
|
|
|
- if (preload?.tableWidth) {
|
|
|
+ if (preload?.tableWidth)
|
|
|
return JSON.parse(preload.tableWidth) as Record<string, number>;
|
|
|
- }
|
|
|
|
|
|
- const obj: Record<string, number> = {no: 64};
|
|
|
+ const obj: Record<string, number> = {no: 64, select: 20};
|
|
|
|
|
|
columns.forEach(function({dataIndex, width}) {
|
|
|
- if (dataIndex && width) {
|
|
|
+ if (dataIndex && width)
|
|
|
obj[dataIndex.toString()] = Number(width);
|
|
|
- }
|
|
|
});
|
|
|
|
|
|
return obj;
|
|
|
});
|
|
|
|
|
|
const [columnOrder, setColumnOrder] = useState(function() {
|
|
|
- if (preload?.tableOrder) {
|
|
|
+ if (preload?.tableOrder)
|
|
|
return JSON.parse(preload?.tableOrder) as string[];
|
|
|
- }
|
|
|
|
|
|
const nextList = columns.map(val => val.dataIndex!.toString());
|
|
|
|
|
|
- return ['no', ...nextList];
|
|
|
+ return ['select', 'no', ...nextList];
|
|
|
});
|
|
|
|
|
|
const dispatch = useTableSearchDispatch(options.searchContext);
|
|
|
@@ -124,17 +196,21 @@ export function useTable<T extends Record<string, any>>(
|
|
|
[columnOrder, columnSizing, dispatch],
|
|
|
);
|
|
|
|
|
|
+ const [rowSelection, setRowSelection] = useState<RowSelectionState>({});
|
|
|
+
|
|
|
const table = useReactTable({
|
|
|
data,
|
|
|
columns: columnList,
|
|
|
state: {
|
|
|
columnSizing,
|
|
|
columnOrder,
|
|
|
+ rowSelection,
|
|
|
},
|
|
|
getCoreRowModel: getCoreRowModel(),
|
|
|
onColumnSizingChange: setColumnSizing,
|
|
|
columnResizeMode: 'onChange',
|
|
|
onColumnOrderChange: setColumnOrder,
|
|
|
+ onRowSelectionChange: setRowSelection,
|
|
|
});
|
|
|
|
|
|
const [active, setActive] = useState<Header<
|
|
|
@@ -149,22 +225,20 @@ export function useTable<T extends Record<string, any>>(
|
|
|
function onDragEnd({active, over}: DragEndEvent) {
|
|
|
setActive(null);
|
|
|
|
|
|
- if (!over) {
|
|
|
+ if (!over)
|
|
|
return;
|
|
|
- }
|
|
|
|
|
|
const {id: activeId} = active,
|
|
|
{id: overId} = over;
|
|
|
const {disabledSort} = (over.data.current as any).header.column.columnDef
|
|
|
.meta;
|
|
|
|
|
|
- if (disabledSort) {
|
|
|
+ if (disabledSort)
|
|
|
return;
|
|
|
- }
|
|
|
|
|
|
- if (activeId === overId) {
|
|
|
+ if (activeId === overId)
|
|
|
return;
|
|
|
- }
|
|
|
+
|
|
|
const {setColumnOrder} = table;
|
|
|
|
|
|
setColumnOrder(function(prev) {
|