diff --git a/packages/core/client/src/schema-component/antd/table-v2/Table.tsx b/packages/core/client/src/schema-component/antd/table-v2/Table.tsx index 2974ea6c2..5901355ce 100644 --- a/packages/core/client/src/schema-component/antd/table-v2/Table.tsx +++ b/packages/core/client/src/schema-component/antd/table-v2/Table.tsx @@ -4,11 +4,12 @@ import { ArrayField } from '@formily/core'; import { ISchema, observer, RecursionField, Schema, useField, useFieldSchema } from '@formily/react'; import { Table as AntdTable, TableColumnProps } from 'antd'; import { default as classNames, default as cls } from 'classnames'; -import React from 'react'; -import ReactDragListView from 'react-drag-listview'; +import React, { useCallback, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import { DndContext } from '../..'; import { RecordIndexProvider, RecordProvider, useSchemaInitializer } from '../../../'; +import { SortableContext, useSortable } from '@dnd-kit/sortable'; +import { useMemoizedFn } from 'ahooks'; const isColumnComponent = (schema: Schema) => { return schema['x-component']?.endsWith('.Column') > -1; @@ -67,64 +68,35 @@ const useTableColumns = () => { }); }; -export const components = { - header: { - wrapper: (props) => { - return ( - - - - ); - }, - cell: (props) => { - return ( - - ); - }, - }, - body: { - wrapper: (props) => { - return ( - - - - ); - }, - row: (props) => { - return ; - }, - cell: (props) => ( - - ), - }, -}; -const SortHandle = () => { - return ; +const topActiveClass = css` + & > td { + border-top: 2px solid rgba(241, 139, 98, 0.6) !important; + } +` +const bottomActiveClass = css` + & > td { + border-bottom: 2px solid rgba(241, 139, 98, 0.6) !important; + } +` + +const SortableRow = (props) => { + const id = props['data-row-key']?.toString() + const { setNodeRef, isOver, active, over } = useSortable({ + id + }) + + const className = (active?.data.current?.sortable.index ?? -1) > (over?.data.current?.sortable.index ?? -1) ? topActiveClass : bottomActiveClass + + return +} + + +const SortHandle = (props) => { + const { listeners } = useSortable({ + id: props.id + }) + return ; }; const TableIndex = (props) => { @@ -154,43 +126,127 @@ const usePaginationProps = (pagination1, pagination2) => { export const Table: any = observer((props: any) => { const field = useField(); - const columns = useTableColumns(); - const { pagination: pagination1, useProps, onChange, ...others1 } = props; - const { pagination: pagination2, ...others2 } = useProps?.() || {}; - const { + const columns = useTableColumns(); + const { pagination: pagination1, useProps, onChange, ...others1 } = props; + const { pagination: pagination2, ...others2 } = useProps?.() || {}; + const { dragSort = false, showIndex = true, - onRowDragEnd, onRowSelectionChange, onChange: onTableChange, rowSelection, + rowKey, ...others } = { ...others1, ...others2 } as any; + const onRowDragEnd = useMemoizedFn(others.onRowDragEnd || (() => {})) const paginationProps = usePaginationProps(pagination1, pagination2); + + const components = useMemo(() => { + return { + header: { + wrapper: (props) => { + return ( + + + + ); + }, + cell: (props) => { + return ( + + ); + }, + }, + body: { + wrapper: (props) => { + return ( + { + if (!e.active || !e.over) { + console.warn('move cancel') + return + } + + const fromIndex = e.active?.data.current?.sortable?.index + const toIndex = e.over?.data.current?.sortable?.index + const from = field.value[fromIndex]; + const to = field.value[toIndex]; + field.move(fromIndex, toIndex); + onRowDragEnd({ fromIndex, toIndex, from, to }); + }}> + + + ); + }, + row: (props) => { + return + }, + cell: (props) => ( + + ), + }, + }; + }, [field, onRowDragEnd, dragSort]) + + const defaultRowKey = (record: any) => { + return field.value?.indexOf?.(record); + }; + + const getRowKey = (record: any) => { + if (typeof rowKey === 'string') { + return record[rowKey]?.toString(); + } else { + return (rowKey ?? defaultRowKey)(record)?.toString() + } + } + const restProps = { rowSelection: rowSelection ? { - type: 'checkbox', - selectedRowKeys: field?.data?.selectedRowKeys || [], - onChange(selectedRowKeys: any[], selectedRows: any[]) { - field.data = field.data || {}; - field.data.selectedRowKeys = selectedRowKeys; - onRowSelectionChange?.(selectedRowKeys, selectedRows); - }, - renderCell: (checked, record, index, originNode) => { - if (!dragSort && !showIndex) { - return originNode; - } - const current = props?.pagination?.current; - const pageSize = props?.pagination?.pageSize || 20; - if (current) { - index = index + (current - 1) * pageSize; - } - return ( -
{ + if (!dragSort && !showIndex) { + return originNode; + } + const current = props?.pagination?.current; + const pageSize = props?.pagination?.pageSize || 20; + if (current) { + index = index + (current - 1) * pageSize; + } + return ( +
{ } } `, - )} - > -
+
- {dragSort && } - {showIndex && } -
-
+ {dragSort && } + {showIndex && } +
+
{ display: none; } `, - )} - > - {originNode} -
+ )} + > + {originNode}
- ); - }, - ...rowSelection, - } +
+ ); + }, + ...rowSelection, + } : undefined, }; - const defaultRowKey = (record: any) => { - return field.value?.indexOf?.(record); - }; + + const SortableWrapper = useCallback(({ children }) => { + return dragSort ? React.createElement(SortableContext, { + items: field.value.map(getRowKey), + children: children, + }) : React.createElement(React.Fragment, { + children + }) + }, [field, dragSort]) + return (
{ } `} > - { - const from = field.value[fromIndex]; - const to = field.value[toIndex]; - field.move(fromIndex, toIndex); - onRowDragEnd({ fromIndex, toIndex, from, to }); - }} - lineClassName={css` - border-bottom: 2px solid rgba(241, 139, 98, 0.6) !important; - `} - > + { columns={columns} dataSource={field?.value?.slice?.()} /> - +
); });