react ant可编辑表格实现拖拽排序EditableProTable实现拖拽排序

  1. 首先是要添加依赖,如果已经有了可以不用理会
		//package.json里面的依赖版本
		"@ant-design/pro-table": "^2.30.8",
		"@dnd-kit/core": "^6.1.0",
		"@dnd-kit/modifiers": "^7.0.0",
		"@dnd-kit/sortable": "^8.0.0",
  1. 直接上代码
    注意事项代码中都注明了
import type { ProColumns } from '@ant-design/pro-table';
import {
    EditableProTable
} from '@ant-design/pro-table';
import React, {useContext, useMemo, useState} from 'react';
import { HolderOutlined, PlusOutlined } from '@ant-design/icons';
import { Button, notification, Drawer, Tag, Popconfirm, message, Divider, Form, Space, Spin, Select } from 'antd';
import { history, Link, useIntl } from 'umi';
import { addFlowEntry, deleteFlowEntry, flowPublish, queryFlowEntryList } from '@/services/flowEntry-service';
import { SelectModel, TableFetchRequest } from '@/components/table/model';
import { FlowEntryDto, FlowEntryModel, FlowEntryRequest } from '@/types/flowEntry-type';
import { loadFlowCategoryData } from '@/services/flowCategory-service';
import PublishFlowForm from './components/formPublishedFlowEntry';
import NodeSetPage from './components/nodeSet';

import styles from './index.less';
import { DndContext, DragEndEvent } from '@dnd-kit/core';
import { restrictToVerticalAxis } from '@dnd-kit/modifiers';
import { arrayMove, SortableContext, useSortable, verticalListSortingStrategy } from '@dnd-kit/sortable';
import { SyntheticListenerMap } from '@dnd-kit/core/dist/hooks/utilities';
import { CSS } from '@dnd-kit/utilities';
import { Result } from '@/utils/request';

const waitTime = (time: number = 100) => {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve(true);
        }, time);
    });
};

type DataSourceType = {
    id: React.Key;
    title?: string;
    readonly?: string;
    decs?: string;
    state?: string;
    created_at?: number;
    update_at?: number;
    children?: DataSourceType[];
};

interface RowProps extends React.HTMLAttributes<HTMLTableRowElement> {
    'data-row-key': string;
}

interface RowContextProps {
    setActivatorNodeRef?: (element: HTMLElement | null) => void;
    listeners?: SyntheticListenerMap;
}

const DragHandle: React.FC = () => {
    const { setActivatorNodeRef, listeners } = useContext(RowContext);
    return (
        <Button
            type="text"
            size="small"
            icon={<HolderOutlined />}
            style={{ cursor: 'move' }}
            ref={setActivatorNodeRef}
            {...listeners}
        />
    );
};

const RowContext = React.createContext<RowContextProps>({});

const CusRow: React.FC<RowProps> = (props) => {
    const { attributes, listeners, setNodeRef, setActivatorNodeRef, transform, transition, isDragging } = useSortable({
        id: props['data-row-key'],
    });

    const style: React.CSSProperties = {
        ...props.style,
        transform: CSS.Translate.toString(transform),
        transition,
        ...(isDragging ? { position: 'relative', zIndex: 9999 } : {}),
    };

    const contextValue = useMemo<RowContextProps>(() => ({ setActivatorNodeRef, listeners }), [
        setActivatorNodeRef,
        listeners,
    ]);

    return (
        <RowContext.Provider value={contextValue}>
            <tr {...props} ref={setNodeRef} style={style} {...attributes} />
        </RowContext.Provider>
    );
};

export default () => {
    const [editableKeys, setEditableRowKeys] = useState<React.Key[]>([]);
    const [dataSource, setDataSource] = useState<readonly DataSourceType[]>([]);
    const [columnNames, setColumnNames] = useState<any[]>([{label:'test',value:'test'}]);
    const [tableName, setTableName] = useState<string>('');

    const FormColumns: ProColumns[] = [
        {
            key: 'sort',
            dataIndex: 'key',
            editable: false,
            width: 30,
            render: () => <DragHandle />,
        },
        {
            title: '列名',
            dataIndex: 'columnName',
            key: 'columnName',
            valueType: 'select',
            renderFormItem: (_, config, formInstance) => (
                <Select
                    options={columnNames}
                    onChange={(event: any) => {
                        let temp = dataSource;
                        for (let item of temp) {
                            if (item.id == config.record.id) {
                                item.columnName = event;
                                // item.objectFieldName = underlineToHump(event);
                                break;
                            }
                        }
                        setDataSource(temp);
                    }}
                />
            ),
            formItemProps: {
                rules: [
                    {
                        required: true,
                        message: '此项为必填项',
                    },
                ],
            },
        },
        {
            title: '字段名',
            dataIndex: 'objectFieldName',
            key: 'objectFieldName',
            formItemProps: {
                rules: [
                    {
                        required: true,
                        message: '此项为必填项',
                    },
                ],
            },
        },
        {
            title: 'Label名',
            dataIndex: 'labelName',
            key: 'labelName',
            formItemProps: {
                rules: [
                    {
                        required: true,
                        message: '此项为必填项',
                    },
                ],
            },
        },
        {
            title: '组件类别',
            dataIndex: 'objectFieldType',
            key: 'objectFieldType',
            valueType: 'select',
            valueEnum: {
                select: {
                    text: 'Select',
                },
                input: {
                    text: 'Input',
                },
                description: {
                    text: 'Description',
                },
            },
            formItemProps: {
                rules: [
                    {
                        required: true,
                        message: '此项为必填项',
                    },
                ],
            },
        },
        {
            title: '超链接',
            dataIndex: 'linkUrl',
            key: 'linkUrl',
        },
        {
            title: 'Cell数量',
            dataIndex: 'cellCount',
            key: 'cellCount',
            valueType: 'select',
            width: 100,
            valueEnum: {
                '1': {
                    text: '1',
                },
                '2': {
                    text: '2',
                },
                '3': {
                    text: '3',
                },
            },
            formItemProps: {
                rules: [
                    {
                        required: true,
                        message: '此项为必填项',
                    },
                ],
            },
        },
        {
            title: '编辑',
            dataIndex: 'isEdit',
            key: 'isEdit',
            valueType: 'select',
            width: 100,
            valueEnum: {
                Y: {
                    text: 'True',
                },
                N: {
                    text: 'False',
                },
            },
            formItemProps: {
                rules: [
                    {
                        required: true,
                        message: '此项为必填项',
                    },
                ],
            },
        },
        {
            title: '必填',
            dataIndex: 'isRequire',
            key: 'isRequire',
            valueType: 'select',
            width: 100,
            valueEnum: {
                Y: {
                    text: 'True',
                },
                N: {
                    text: 'False',
                },
            },
            formItemProps: {
                rules: [
                    {
                        required: true,
                        message: '此项为必填项',
                    },
                ],
            },
        },
        {
            title: '操作',
            valueType: 'option',
            width: 200,
            render: (text, record, _, action) => [
                <a
                    key="editable"
                    onClick={() => {
                        action?.startEditable?.(record.id);
                    }}
                >
                    编辑
                </a>,
                <a
                    key="delete"
                    onClick={() => {
                        setDataSource(dataSource.filter((item) => item.id !== record.id));
                    }}
                >
                    删除
                </a>,
            ],
        },
    ];

    const onDragEnd = ({ active, over }: DragEndEvent) => {
        if (active.id !== over?.id) {
            if (editableKeys.length > 0) {
                message.warning('编辑中不允许调整排序');
                return;
            }
            const tableDataSource = dataSource;
            const activeIndex = tableDataSource.findIndex((i) => i.id === active.id);
            const overIndex = tableDataSource.findIndex((i) => i.id === over?.id);
            const dagEndList = arrayMove(tableDataSource, activeIndex, overIndex);
            setDataSource([...dagEndList]);
        }
    };

    return (
        <>
            <DndContext onDragEnd={onDragEnd} modifiers={[restrictToVerticalAxis]}>
                <SortableContext items={dataSource.map((i) => i.id)} strategy={verticalListSortingStrategy}>
            <EditableProTable
                rowKey="id"
                headerTitle="可编辑表格"
                maxLength={5}
                scroll={{
                    x: 960,
                }}
                recordCreatorProps={{
                    position: 'bottom',
                    record: () => {
                        return {
                            id: dataSource.length + 1,
                            objectFieldType: 'description',
                            cellCount: '1',
                            isEdit: 'N',
                            isRequire: 'N',
                        };
                    },}}
                loading={false}
                columns={FormColumns}
                value={dataSource}
                onChange={setDataSource}
                editable={{
                    type: 'multiple',
                    editableKeys,
                    onSave: async (rowKey, data, row) => {
                        console.log(rowKey, data, row);
                        await waitTime(2000);
                    },
                    onChange: setEditableRowKeys,
                }}
                components={{
                    body: {
                        row: CusRow,
                    },
                }}
            />
                </SortableContext>
            </DndContext>
        </>
    );
};


  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值