复杂的编辑表格

需求描述

表格可以整体编辑;也可以单行弹框编辑;且整体编辑的时候,依然可以单行编辑

编辑只能给某一列(这里是参数运行值)修改,且根据数据内容的参数范围来判断展示不同的形式:input/数字输入/单选/多选

依据判断的参数范围内容:正则:xxx / 数字范围:[1,99] / 单选:[0,1] / 多选:['a','b','cc']

typescript 复制代码
// ConfigModalEdit.tsx

import {
  ModalForm,
  ProFormText,
} from '@ant-design/pro-components';
import { Button, Form, message } from 'antd';

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

export default (props) => {
  const { modalConfig, onCancel } = props
  const { visible, data } = modalConfig
  const [form] = Form.useForm<{ name: string; company: string }>();
  return (
    <ModalForm
      title="修改"
      open={visible}
      form={form}
      autoFocusFirstInput
      modalProps={{
        destroyOnClose: true,
        onCancel: () => console.log('run'),
      }}
      submitTimeout={2000}
      onFinish={async (values) => {
        await waitTime(2000);
        console.log(values.name);
        message.success('提交成功');
        return true;
      }}
    >
      
      <ProFormText width="sm" name="id" label="对应的select或者text类型" />
      
    </ModalForm>
  );
};
typescript 复制代码
// index.tsx

import { EditableProTable } from '@ant-design/pro-components';
import { Button, Form, Input, InputNumber, Radio, Select } from 'antd';
import React, { useEffect, useRef, useState } from 'react';
import ConfigModalEdit from './ConfigModalEdit';

const mockDefaultData: any[] = new Array(8).fill(1).map((_, index) => {

  return {
    id: index,
    name: `主题-${index}`,
    value: index,
    name2: `fq-${index}`,
    created_at: 1590486176000,
    type: index === 0 ? 'input' : index === 2 ? 'radio' : index === 3 ? 'select' :index ===4 ? 'input' : 'multiple_select'
  }
});
const EditTable: React.FC = () => {
  const [defaultData, setDefaultData] = useState<any[]>()
  const [dataSource, setDataSource] = useState<any[]>();
  const [editableKeys, setEditableKeys] = useState<React.Key[]>([]);
  const editableRowData= useRef();
  
  const [isEditable, setIsEditable] = useState(false);
  const [modalConfig, setModalConfig] = useState<any>({
    visible: false,
    recordParams: {
      data: {}
    },
  });
  const [editForm] = Form.useForm()
  
  const validator = (value, row) => {
    console.log('value11==', value, 'row=11=', row);
   
  }

  const columns = [
    {
      title: '参数',
      dataIndex: 'name',
      editable: false,
    },
    {
      title: '',
      dataIndex: 'type',
      hideInTable: true,
      renderFormItem:()=>''
    },
    {
      title: '参数运行值',
      dataIndex: 'value',
      renderFormItem: (_, { record }) => {
        // console.log('record==', record);
        const type = record?.type;
        // 判断数据类型并返回相应的DOM元素
        if (type === 'input') {
          return <Input />;
        } else if (type === 'multiple_select') {
          return <Select mode="multiple" />;
        } else if (type === 'select') {
          return <Select />;
        }
        else if (type === 'select') {
          return <InputNumber />;
        } else {
          return <Radio.Group value={record?.value}>
            <Radio value={1}>A</Radio>
            <Radio value={2}>B</Radio>
            <Radio value={3}>C</Radio>
            <Radio value={4}>D</Radio>
          </Radio.Group>
        }
      },
      formItemProps:{
        rules: [
          {
            validator: validator,
          }
        ]
      }
    },
    {
      title: '参数默认值',
      dataIndex: 'name2',
      editable: false,
    },
    {
      title: '参数范围',
      dataIndex: 'name',
      editable: false,

    },
    {
      title: '重启生效',
      dataIndex: 'name',
      editable: false,
    },
    {
      title: '操作',
      valueType: 'option',
      render: (_: any, record: any) => {
        return [
          <Button
            type="link"
            key="EditPassword"
            onClick={() => {
              setModalConfig({
                visible: true,
                data: record
              });
            }}
          >
            修改
          </Button>,
        ];
      },
    },
  ]

  useEffect(() => {
    setDefaultData(mockDefaultData)
    setDataSource(() => mockDefaultData)
  }, []);

  const handleEdit = () => {
    setDataSource(defaultData);
    setIsEditable(true);
    setEditableKeys([...defaultData?.map(item => item.id)]);
  };
  const handleCancel = () => {
    // 清除可编辑的行键
    setEditableKeys([]);
    // 将当前正在编辑的数据设置回原始数据
    setDataSource(() => defaultData);
    setIsEditable(false);
  };

  const toolBarRender = () => {
    return isEditable ? [
      <Button
        key="save"
      // onClick={handleSave}
      >
        保存数据
      </Button>,
      <Button key="cancel" onClick={handleCancel}>
        取消
      </Button>,
    ] : [
      <Button key="edit" type="primary" onClick={handleEdit}>
        编辑
      </Button>,
    ];
  };
  return (
    <>
      <EditableProTable
        headerTitle=""
        columns={columns}
        rowKey="id"
        // name='editableData'
        value={dataSource}
        onChange={setDataSource}
        recordCreatorProps={false}
        toolBarRender={toolBarRender}
        editable={{
          type: 'multiple',
          editableKeys,
          form: editForm,
          actionRender: (row)=>[<Button
            type="link"
            key="EditPassword"
            onClick={() => {
              setModalConfig({
                visible: true,
                data: row
              });
            }}
          >
            修改
          </Button>],
          onValuesChange: (record, recordList) => {
            setDataSource(recordList);
          },
          onChange: setEditableKeys,
        }}
      />

      <ConfigModalEdit
        modalConfig={modalConfig}
        onCancel={() => {
          setModalConfig({
            visible: false,
            data: {},
          });
        }}
      />
    </>)


};
export default EditTable;
相关推荐
腾讯TNTWeb前端团队29 分钟前
helux v5 发布了,像pinia一样优雅地管理你的react状态吧
前端·javascript·react.js
范文杰4 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪4 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪4 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy5 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom5 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom5 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom6 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom6 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom6 小时前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试